Very basic Input Method support. For now, it only uses X default to support things like composed characters with deadkeys kb layouts.

SVN revision: 38008
This commit is contained in:
Iván Briano 2008-12-08 00:28:37 +00:00
parent 8ea28f64b7
commit d4d14f54ed
3 changed files with 91 additions and 7 deletions

View File

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

View File

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

View File

@ -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];