Very basic Input Method support. For now, it only uses X default to support things...
authorsachiel <sachiel@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Mon, 8 Dec 2008 00:28:37 +0000 (00:28 +0000)
committersachiel <sachiel@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Mon, 8 Dec 2008 00:28:37 +0000 (00:28 +0000)
git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/ecore@38008 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

src/lib/ecore_x/xlib/ecore_x.c
src/lib/ecore_x/xlib/ecore_x_events.c
src/lib/ecore_x/xlib/ecore_x_private.h

index 8a1eb1b..2f89f00 100644 (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;
 }
index fba9f14..e5b3fe2 100644 (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;
index 4baefa5..4d03466 100644 (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];