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; };