diff --git a/legacy/ecore/src/lib/ecore_x/xlib/ecore_x.c b/legacy/ecore/src/lib/ecore_x/xlib/ecore_x.c index 8a1eb1b281..2f89f0085f 100644 --- a/legacy/ecore/src/lib/ecore_x/xlib/ecore_x.c +++ b/legacy/ecore/src/lib/ecore_x/xlib/ecore_x.c @@ -37,6 +37,7 @@ Window _ecore_x_event_last_win = 0; int _ecore_x_event_last_root_x = 0; int _ecore_x_event_last_root_y = 0; int _ecore_x_xcursor = 0; +XIC _ecore_x_ic = NULL; /* Input context for composed characters */ Ecore_X_Window _ecore_x_private_win = 0; @@ -407,6 +408,40 @@ ecore_x_init(const char *name) _ecore_x_private_win = ecore_x_window_override_new(0, -77, -777, 123, 456); + /* Setup XIM */ + if (!_ecore_x_ic && XSupportsLocale()) + { + XIM im; + XIC ic; + XIMStyles *supported_styles; + XIMStyle chosen_style = 0; + Ecore_X_Window client_window = ecore_x_window_root_get(_ecore_x_private_win); + char *ret; + int i; + + XSetLocaleModifiers("@im=none"); + if ((im = XOpenIM(_ecore_x_disp, NULL, NULL, NULL)) == NULL) + goto _im_create_end; + ret = XGetIMValues(im, XNQueryInputStyle, &supported_styles, NULL); + if (ret || !supported_styles) + goto _im_create_error; + for (i = 0; i < supported_styles->count_styles; i++) + if (supported_styles->supported_styles[i] == (XIMPreeditNothing | XIMStatusNothing)) + chosen_style = supported_styles->supported_styles[i]; + XFree(supported_styles); + if (!chosen_style) + goto _im_create_error; + ic = XCreateIC(im, XNInputStyle, chosen_style, XNClientWindow, client_window, NULL); + if (ic) + { + _ecore_x_ic = ic; + goto _im_create_end; + } +_im_create_error: + XCloseIM(im); + } +_im_create_end: + return _ecore_x_init_count; } @@ -428,6 +463,14 @@ _ecore_x_shutdown(int close_display) _ecore_x_selection_shutdown(); _ecore_x_dnd_shutdown(); ecore_x_netwm_shutdown(); + if (_ecore_x_ic) + { + XIM xim; + xim = XIMOfIC(_ecore_x_ic); + XDestroyIC(_ecore_x_ic); + XCloseIM(xim); + _ecore_x_ic = NULL; + } if (_ecore_x_init_count < 0) _ecore_x_init_count = 0; return _ecore_x_init_count; } diff --git a/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_events.c b/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_events.c index fba9f14dd2..e5b3fe21fa 100644 --- a/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_events.c +++ b/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_events.c @@ -187,32 +187,59 @@ _ecore_x_event_handle_key_press(XEvent *xevent) Ecore_X_Event_Key_Down *e; char *keyname; int val; - char buf[256]; + char *buf; + int buflen = 256; KeySym sym; XComposeStatus status; e = calloc(1, sizeof(Ecore_X_Event_Key_Down)); if (!e) return; + buf = malloc(buflen); + if (!buf) + { + free(e); + return; + } keyname = XKeysymToString(XKeycodeToKeysym(xevent->xkey.display, xevent->xkey.keycode, 0)); if (!keyname) { - snprintf(buf, sizeof(buf), "Keycode-%i", xevent->xkey.keycode); + snprintf(buf, buflen, "Keycode-%i", xevent->xkey.keycode); keyname = buf; } e->keyname = strdup(keyname); if (!e->keyname) { + free(buf); free(e); return; } - val = XLookupString((XKeyEvent *)xevent, buf, sizeof(buf), &sym, &status); - if (val > 0) + if (_ecore_x_ic) { - buf[val] = 0; - e->key_compose = ecore_txt_convert(nl_langinfo(CODESET), "UTF-8", buf); + Status mbstatus; + val = Xutf8LookupString(_ecore_x_ic, (XKeyEvent *)xevent, buf, buflen - 1, &sym, &mbstatus); + if (mbstatus == XBufferOverflow) + { + buflen = val + 1; + buf = realloc(buf, buflen); + val = Xutf8LookupString(_ecore_x_ic, (XKeyEvent *)xevent, buf, buflen - 1, &sym, &mbstatus); + } + if (val > 0) + { + buf[val] = 0; + e->key_compose = strdup(buf); + } + } + else + { + val = XLookupString((XKeyEvent *)xevent, buf, sizeof(buf), &sym, &status); + if (val > 0) + { + buf[val] = 0; + e->key_compose = ecore_txt_convert(nl_langinfo(CODESET), "UTF-8", buf); + } + else e->key_compose = NULL; } - else e->key_compose = NULL; keyname = XKeysymToString(sym); if (keyname) e->keysymbol = strdup(keyname); else e->keysymbol = strdup(e->keyname); @@ -220,6 +247,7 @@ _ecore_x_event_handle_key_press(XEvent *xevent) { if (e->keyname) free(e->keyname); if (e->key_compose) free(e->key_compose); + free(buf); free(e); return; } @@ -231,7 +259,9 @@ _ecore_x_event_handle_key_press(XEvent *xevent) e->same_screen = xevent->xkey.same_screen; e->root_win = xevent->xkey.root; _ecore_x_event_last_time = e->time; + printf("ECORE_X KEY: %s %s\n", e->keyname, e->key_compose); ecore_event_add(ECORE_X_EVENT_KEY_DOWN, e, _ecore_x_event_free_key_down, NULL); + free(buf); } void @@ -706,6 +736,14 @@ _ecore_x_event_handle_focus_in(XEvent *xevent) { Ecore_X_Event_Window_Focus_In *e; + if (_ecore_x_ic) + { + char *str; + XSetICValues(_ecore_x_ic, XNFocusWindow, xevent->xfocus.window, NULL); + if ((str = Xutf8ResetIC(_ecore_x_ic))) + XFree(str); + XSetICFocus(_ecore_x_ic); + } e = calloc(1, sizeof(Ecore_X_Event_Window_Focus_In)); if (!e) return; e->win = xevent->xfocus.window; @@ -731,6 +769,8 @@ _ecore_x_event_handle_focus_out(XEvent *xevent) { Ecore_X_Event_Window_Focus_Out *e; + if (_ecore_x_ic) + XUnsetICFocus(_ecore_x_ic); e = calloc(1, sizeof(Ecore_X_Event_Window_Focus_Out)); if (!e) return; e->win = xevent->xfocus.window; diff --git a/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_private.h b/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_private.h index 4baefa523a..4d03466bb3 100644 --- a/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_private.h +++ b/legacy/ecore/src/lib/ecore_x/xlib/ecore_x_private.h @@ -146,6 +146,7 @@ extern Window _ecore_x_event_last_win; extern int _ecore_x_event_last_root_x; extern int _ecore_x_event_last_root_y; extern int _ecore_x_xcursor; +extern XIC _ecore_x_ic; extern Ecore_X_Atom _ecore_x_atoms_wm_protocols[ECORE_X_WM_PROTOCOL_NUM];