diff --git a/src/conio/x_cio.c b/src/conio/x_cio.c
index f274e12f7c748b14f6c9a1ae200bdd4381831c23..412c4500710c026423c088df276d4a2082b0c981 100644
--- a/src/conio/x_cio.c
+++ b/src/conio/x_cio.c
@@ -31,6 +31,7 @@
  * Note: If this box doesn't appear square, then you need to fix your tabs.	*
  ****************************************************************************/
 
+#include <locale.h>
 #include <stdarg.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -422,6 +423,32 @@ int x_init(void)
 		xp_dlclose(dl);
 		return(-1);
 	}
+	if((x11.XSetLocaleModifiers=xp_dlsym(dl,XSetLocaleModifiers))==NULL) {
+		xp_dlclose(dl);
+		return(-1);
+	}
+	if((x11.XOpenIM=xp_dlsym(dl,XOpenIM))==NULL) {
+		xp_dlclose(dl);
+		return(-1);
+	}
+	if((x11.XCreateIC=xp_dlsym(dl,XCreateIC))==NULL) {
+		xp_dlclose(dl);
+		return(-1);
+	}
+	if((x11.XwcLookupString=xp_dlsym(dl,XwcLookupString))==NULL) {
+		xp_dlclose(dl);
+		return(-1);
+	}
+	if((x11.XSetICFocus=xp_dlsym(dl,XSetICFocus))==NULL) {
+		xp_dlclose(dl);
+		return(-1);
+	}
+	if((x11.XFilterEvent=xp_dlsym(dl,XFilterEvent))==NULL) {
+		xp_dlclose(dl);
+		return(-1);
+	}
+	setlocale(LC_ALL, "");
+	x11.XSetLocaleModifiers("@im=none");
 
 	if(sem_init(&pastebuf_set, 0, 0)) {
 		xp_dlclose(dl);
diff --git a/src/conio/x_events.c b/src/conio/x_events.c
index 5203341af5c3db1ac77fda4f7d030c180e7c4617..347bf0f3d1c1fb8ce4134d2ea075083e4de596af 100644
--- a/src/conio/x_events.c
+++ b/src/conio/x_events.c
@@ -8,6 +8,7 @@
 
 #include <fcntl.h>
 #include <limits.h>
+#include <locale.h>
 #include <stdio.h>
 
 #include <X11/Xlib.h>
@@ -67,6 +68,8 @@ static Display *dpy=NULL;
 static Window win;
 static Visual visual;
 static XImage *xim;
+static XIM im;
+static XIC ic;
 static unsigned int depth=0;
 static int xfd;
 static unsigned long black;
@@ -81,7 +84,6 @@ static int g_shift;
 static int b_shift;
 static struct rectlist *last = NULL;
 
-
 /* Array of Graphics Contexts */
 static GC gc;
 
@@ -307,6 +309,13 @@ static int init_window()
 		x11.XSetWMProperties(dpy, win, NULL, NULL, 0, 0, NULL, wmhints, classhints);
 		x11.XFree(wmhints);
 	}
+	im = x11.XOpenIM(dpy, NULL, "CIOLIB", "CIOLIB");
+	if (im != NULL) {
+		ic = x11.XCreateIC(im, XNClientWindow, win, XNInputStyle, XIMPreeditNothing | XIMStatusNothing, NULL);
+		if (ic)
+			x11.XSetICFocus(ic);
+	}
+
 	if (classhints)
 		x11.XFree(classhints);
 
@@ -614,6 +623,8 @@ static void expose_rect(int x, int y, int width, int height)
 
 static int x11_event(XEvent *ev)
 {
+	if (x11.XFilterEvent(ev, win))
+		return 0;
 	switch (ev->type) {
 		case ClientMessage:
 			if (ev->xclient.format == 32 && ev->xclient.data.l[0] == WM_DELETE_WINDOW) {
@@ -813,183 +824,209 @@ static int x11_event(XEvent *ev)
 		case KeyPress:
 			{
 				static char buf[128];
+				static wchar_t wbuf[128];
 				KeySym ks;
 				int nlock = 0;
 				WORD scan = 0xffff;
+				Status lus = 0;
+				int cnt;
+				int i;
+				uint8_t ch;
 
-				x11.XLookupString((XKeyEvent *)ev, buf, sizeof(buf), &ks, 0);
-
-				switch (ks) {
-				
-					case XK_Escape:
-						scan = 1;
-						goto docode;
-
-					case XK_Tab:
-					case XK_ISO_Left_Tab:
-						scan = 15;
-						goto docode;
-			
-					case XK_Return:
-					case XK_KP_Enter:
-						scan = 28;
-						goto docode;
-
-					case XK_Print:
-						scan = 55;
-						goto docode;
-
-					case XK_F1:
-					case XK_F2:
-					case XK_F3:
-					case XK_F4:
-					case XK_F5:
-					case XK_F6:
-					case XK_F7:
-					case XK_F8:
-					case XK_F9:
-					case XK_F10:
-						scan = ks - XK_F1 + 59;
-						goto docode;
-
-					case XK_KP_7:
-						nlock = 1;
-					case XK_Home:
-					case XK_KP_Home:
-						scan = 71;
-						goto docode;
-
-					case XK_KP_8:
-						nlock = 1;
-					case XK_Up:
-					case XK_KP_Up:
-						scan = 72;
-						goto docode;
-
-					case XK_KP_9:
-						nlock = 1;
-					case XK_Prior:
-					case XK_KP_Prior:
-						scan = 73;
-						goto docode;
-
-					case XK_KP_Subtract:
-						scan = 74;
-						goto docode;
-
-					case XK_KP_4:
-						nlock = 1;
-					case XK_Left:
-					case XK_KP_Left:
-						scan = 75;
-						goto docode;
-
-					case XK_KP_5:
-						nlock = 1;
-					case XK_Begin:
-					case XK_KP_Begin:
-						scan = 76;
-						goto docode;
-
-					case XK_KP_6:
-						nlock = 1;
-					case XK_Right:
-					case XK_KP_Right:
-						scan = 77;
-						goto docode;
-
-					case XK_KP_Add:
-						scan = 78;
-						goto docode;
-
-					case XK_KP_1:
-						nlock = 1;
-					case XK_End:
-					case XK_KP_End:
-						scan = 79;
-						goto docode;
-
-					case XK_KP_2:
-						nlock = 1;
-					case XK_Down:
-					case XK_KP_Down:
-						scan = 80;
-						goto docode;
-
-					case XK_KP_3:
-						nlock = 1;
-					case XK_Next:
-					case XK_KP_Next:
-						scan = 81;
-						goto docode;
-
-					case XK_KP_0:
-						nlock = 1;
-					case XK_Insert:
-					case XK_KP_Insert:
-						scan = 82;
-						goto docode;
-
-					case XK_KP_Decimal:
-						nlock = 1;
-						scan = 83;
-						goto docode;
-
-					case XK_Delete:
-					case XK_KP_Delete:
-						/* scan = flipdelete ? 14 : 83; */
-						scan = 83;
-						goto docode;
-
-					case XK_BackSpace:
-						/* scan = flipdelete ? 83 : 14; */
-						scan = 14;
-						goto docode;
-
-					case XK_F11:
-						scan = 87;
-						goto docode;
-					case XK_F12:
-						scan = 88;
-						goto docode;
-
-
-					case XK_KP_Divide:
-						scan = Ascii2Scan['/'];
-						goto docode;
-
-					case XK_KP_Multiply:
-						scan = Ascii2Scan['*'];
-						goto docode;
-
-					default:
-						if (ks < ' ' || ks > '~')
-							break;
-						scan = Ascii2Scan[ks]; 
-						docode:
-						if (nlock)
-							scan |= 0x100;
+				if (ic)
+					cnt = x11.XwcLookupString(ic, (XKeyPressedEvent *)ev, wbuf, sizeof(wbuf)/sizeof(wbuf[0]), &ks, &lus);
+				else {
+					cnt = x11.XLookupString((XKeyEvent *)ev, buf, sizeof(buf), &ks, NULL);
+					lus = XLookupKeySym;
+				}
 
-						if ((scan & ~0x100) > 88) {
-							scan = 0xffff;
-							break;
+				switch(lus) {
+					case XLookupNone:
+						ks = 0xffff;
+						break;
+					case XLookupChars:
+					case XLookupBoth:
+						for (i = 0; i < cnt; i++) {
+							ch = cp_from_unicode_cp(getcodepage(), wbuf[i], 0);
+							if (ch) {
+								write(key_pipe[1], &ch, 1);
+							}
 						}
+						break;
+					case XLookupKeySym:
+						switch (ks) {
+						
+							case XK_Escape:
+								scan = 1;
+								goto docode;
+
+							case XK_Tab:
+							case XK_ISO_Left_Tab:
+								scan = 15;
+								goto docode;
+					
+							case XK_Return:
+							case XK_KP_Enter:
+								scan = 28;
+								goto docode;
+
+							case XK_Print:
+								scan = 55;
+								goto docode;
+
+							case XK_F1:
+							case XK_F2:
+							case XK_F3:
+							case XK_F4:
+							case XK_F5:
+							case XK_F6:
+							case XK_F7:
+							case XK_F8:
+							case XK_F9:
+							case XK_F10:
+								scan = ks - XK_F1 + 59;
+								goto docode;
+
+							case XK_KP_7:
+								nlock = 1;
+							case XK_Home:
+							case XK_KP_Home:
+								scan = 71;
+								goto docode;
+
+							case XK_KP_8:
+								nlock = 1;
+							case XK_Up:
+							case XK_KP_Up:
+								scan = 72;
+								goto docode;
+
+							case XK_KP_9:
+								nlock = 1;
+							case XK_Prior:
+							case XK_KP_Prior:
+								scan = 73;
+								goto docode;
+
+							case XK_KP_Subtract:
+								scan = 74;
+								goto docode;
+
+							case XK_KP_4:
+								nlock = 1;
+							case XK_Left:
+							case XK_KP_Left:
+								scan = 75;
+								goto docode;
+
+							case XK_KP_5:
+								nlock = 1;
+							case XK_Begin:
+							case XK_KP_Begin:
+								scan = 76;
+								goto docode;
+
+							case XK_KP_6:
+								nlock = 1;
+							case XK_Right:
+							case XK_KP_Right:
+								scan = 77;
+								goto docode;
+
+							case XK_KP_Add:
+								scan = 78;
+								goto docode;
+
+							case XK_KP_1:
+								nlock = 1;
+							case XK_End:
+							case XK_KP_End:
+								scan = 79;
+								goto docode;
+
+							case XK_KP_2:
+								nlock = 1;
+							case XK_Down:
+							case XK_KP_Down:
+								scan = 80;
+								goto docode;
+
+							case XK_KP_3:
+								nlock = 1;
+							case XK_Next:
+							case XK_KP_Next:
+								scan = 81;
+								goto docode;
+
+							case XK_KP_0:
+								nlock = 1;
+							case XK_Insert:
+							case XK_KP_Insert:
+								scan = 82;
+								goto docode;
+
+							case XK_KP_Decimal:
+								nlock = 1;
+								scan = 83;
+								goto docode;
+
+							case XK_Delete:
+							case XK_KP_Delete:
+								/* scan = flipdelete ? 14 : 83; */
+								scan = 83;
+								goto docode;
+
+							case XK_BackSpace:
+								/* scan = flipdelete ? 83 : 14; */
+								scan = 14;
+								goto docode;
+
+							case XK_F11:
+								scan = 87;
+								goto docode;
+							case XK_F12:
+								scan = 88;
+								goto docode;
+
+
+							case XK_KP_Divide:
+								scan = Ascii2Scan['/'];
+								goto docode;
+
+							case XK_KP_Multiply:
+								scan = Ascii2Scan['*'];
+								goto docode;
+
+							default:
+								if (ks < ' ' || ks > '~')
+									break;
+								scan = Ascii2Scan[ks]; 
+								docode:
+								if (nlock)
+									scan |= 0x100;
+
+								if ((scan & ~0x100) > 88) {
+									scan = 0xffff;
+									break;
+								}
 
-						if (ev->xkey.state & Mod1Mask) {
-							scan = ScanCodes[scan & 0xff].alt;
-						} else if ((ev->xkey.state & ShiftMask) || (scan & 0x100)) {
-							scan = ScanCodes[scan & 0xff].shift;
-						} else if (ev->xkey.state & ControlMask) {
-							scan = ScanCodes[scan & 0xff].ctrl;
-						}  else
-							scan = ScanCodes[scan & 0xff].base;
+								if (ev->xkey.state & Mod1Mask) {
+									scan = ScanCodes[scan & 0xff].alt;
+								} else if ((ev->xkey.state & ShiftMask) || (scan & 0x100)) {
+									scan = ScanCodes[scan & 0xff].shift;
+								} else if (ev->xkey.state & ControlMask) {
+									scan = ScanCodes[scan & 0xff].ctrl;
+								}  else
+									scan = ScanCodes[scan & 0xff].base;
 
+								break;
+						}
+						if (scan != 0xffff) {
+							uint16_t key=scan;
+							write(key_pipe[1], &key, (scan&0xff)?1:2);
+						}
 						break;
 				}
-				if (scan != 0xffff) {
-					uint16_t key=scan;
-					write(key_pipe[1], &key, (scan&0xff)?1:2);
-				}
 				return(1);
 			}
 		default:
diff --git a/src/conio/x_events.h b/src/conio/x_events.h
index 7bfb2c81deabca6b18271b18cac0d7ef5cd9d4c5..7b4f1f7b266b9ea91487bf6a9df332a6c0bce687 100644
--- a/src/conio/x_events.h
+++ b/src/conio/x_events.h
@@ -2,6 +2,7 @@
 #define _X_EVENTS_H_
 
 #include <X11/Xlib.h>
+#include <X11/Xresource.h>
 #include <X11/Xutil.h>
 #include <X11/keysym.h>
 #include <X11/Xatom.h>
@@ -84,6 +85,12 @@ struct x11 {
 	Colormap (*XCreateColormap)(Display *display, Window w, Visual *visual, int alloc);
 	XClassHint *(*XAllocClassHint)(void);
 	int (*XSetForeground)(Display *display, GC gc, unsigned long foreground);
+	char *(*XSetLocaleModifiers)(char *modifier_list);
+	XIM (*XOpenIM)(Display *display, XrmDatabase db, char *res_name, char *res_class);
+	XIC (*XCreateIC)(XIM im, ...);
+	int (*XwcLookupString)(XIC ic, XKeyPressedEvent *event, wchar_t *buffer_return, int wchars_buffer, KeySym *keysym_return, Status *status_return);
+	void (*XSetICFocus)(XIC ic);
+	Bool (*XFilterEvent)(XEvent *event, Window w);
 	Atom utf8;
 	Atom targets;
 };