raster pushed a commit to branch master.

http://git.enlightenment.org/apps/terminology.git/commit/?id=0104ce64a9e910ab1f2119bfd1ea78a8a61a28c5

commit 0104ce64a9e910ab1f2119bfd1ea78a8a61a28c5
Author: Carsten Haitzler (Rasterman) <ras...@rasterman.com>
Date:   Wed Jan 7 22:35:49 2015 +0900

    input methods - display preedit text inside grid - makes it work on wayland
    
    @fix - this makes preedit text while composiing display within
    terminology like elm entry and edje entry do. no overlayed preedit
    window/box. this means that the pre-display has to be done by
    terminology, which this does, but it means wayland now can display
    preedit strings in terminology like in elm/edje entries too.
---
 src/bin/termio.c | 134 ++++++++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 128 insertions(+), 6 deletions(-)

diff --git a/src/bin/termio.c b/src/bin/termio.c
index 0c92195..cd06b4d 100644
--- a/src/bin/termio.c
+++ b/src/bin/termio.c
@@ -7,6 +7,7 @@
 #include "termiolink.h"
 #include "termpty.h"
 #include "termcmd.h"
+#include "termptydbl.h"
 #include "utf8.h"
 #include "col.h"
 #include "keyin.h"
@@ -77,6 +78,7 @@ struct _Termio
    Evas_Object *win, *theme, *glayer;
    Config *config;
    const char *sel_str;
+   const char *preedit_str;
    Eina_List *cur_chids;
    Ecore_Job *sel_reset_job;
    double set_sel_at;
@@ -2844,6 +2846,8 @@ _imf_cursor_set(Termio *sd)
    evas_object_geometry_get(sd->cursor.obj, &cx, &cy, &cw, &ch);
    if (sd->khdl.imf)
      ecore_imf_context_cursor_location_set(sd->khdl.imf, cx, cy, cw, ch);
+   if (sd->khdl.imf) ecore_imf_context_cursor_position_set
+     (sd->khdl.imf, (sd->cursor.y * sd->grid.w) + sd->cursor.x);
    /*
     ecore_imf_context_cursor_position_set(sd->imf, 0); // how to get it?
     */
@@ -3884,7 +3888,7 @@ _smart_apply(Evas_Object *obj)
    Evas_Coord ox, oy, ow, oh;
    Eina_List *l, *ln;
    Termblock *blk;
-   int x, y, w, ch1 = 0, ch2 = 0, inv = 0;
+   int x, y, w, ch1 = 0, ch2 = 0, inv = 0, preedit_x = 0, preedit_y = 0;
 
    EINA_SAFETY_ON_NULL_RETURN(sd);
    evas_object_geometry_get(obj, &ox, &oy, &ow, &oh);
@@ -4047,6 +4051,82 @@ _smart_apply(Evas_Object *obj)
           evas_object_textgrid_update_add(sd->grid.obj, ch1, y,
                                           ch2 - ch1 + 1, 1);
      }
+   if (sd->preedit_str)
+     {
+        int x = sd->cursor.x, y = sd->cursor.y;
+        Eina_Unicode *uni, g;
+        int len = 0, i, jump, xx, backx;
+        Eina_Bool dbl;
+        Evas_Textgrid_Cell *tc;
+
+        uni = eina_unicode_utf8_to_unicode(sd->preedit_str, &len);
+        if (uni)
+          {
+             for (i = 0; i < len; i++)
+               {
+                  jump = 1;
+                  g = uni[i];
+#if defined(SUPPORT_DBLWIDTH)
+                  dbl = _termpty_is_dblwidth_get(sd->pty, g);
+                  if (dbl) jump = 2;
+#endif
+                  backx = 0;
+                  if ((x + jump) > sd->grid.w)
+                    {
+                       if (y < (sd->grid.h - 1))
+                         {
+                            x = jump;
+                            backx = jump;
+                            y++;
+                         }
+                    }
+                  else
+                    {
+                       x += jump;
+                       backx = jump;
+                    }
+                  tc = evas_object_textgrid_cellrow_get(sd->grid.obj, y);
+                  xx = x - backx;
+                  tc[xx].bold = 1;
+                  tc[xx].bg = COL_BLACK;
+                  tc[xx].fg = COL_WHITE;
+                  tc[xx].fg_extended = 0;
+                  tc[xx].bg_extended = 0;
+                  tc[xx].underline = 1;
+                  tc[xx].strikethrough = 0;
+                  tc[xx].double_width = dbl;
+                  tc[xx].codepoint = g;
+#if defined(SUPPORT_DBLWIDTH)
+                  if (dbl)
+                    {
+                       xx = x - backx + 1;
+                       tc[xx].bold = 1;
+                       tc[xx].bg = COL_BLACK;
+                       tc[xx].fg = COL_WHITE;
+                       tc[xx].fg_extended = 0;
+                       tc[xx].bg_extended = 0;
+                       tc[xx].underline = 1;
+                       tc[xx].strikethrough = 0;
+                       tc[xx].double_width = 0;
+                       tc[xx].codepoint = 0;
+                    }
+#endif
+                  evas_object_textgrid_cellrow_set(sd->grid.obj, y, tc);
+                  if (x >= sd->grid.w)
+                    {
+                       if (y < (sd->grid.h - 1))
+                         {
+                            x = 0;
+                            y++;
+                         }
+                    }
+               }
+             evas_object_textgrid_update_add(sd->grid.obj, 0, sd->cursor.y,
+                                             sd->grid.w, y - sd->cursor.y + 1);
+          }
+        preedit_x = x - sd->cursor.x;
+        preedit_y = y - sd->cursor.y;
+     }
    termpty_cellcomp_thaw(sd->pty);
 
    EINA_LIST_FOREACH_SAFE(sd->pty->block.active, l, ln, blk)
@@ -4066,8 +4146,8 @@ _smart_apply(Evas_Object *obj)
    sd->cursor.x = sd->pty->state.cx;
    sd->cursor.y = sd->pty->state.cy;
    evas_object_move(sd->cursor.obj,
-                    ox + (sd->cursor.x * sd->font.chw),
-                    oy + (sd->cursor.y * sd->font.chh));
+                    ox + ((sd->cursor.x + preedit_x) * sd->font.chw),
+                    oy + ((sd->cursor.y + preedit_y) * sd->font.chh));
    if (sd->pty->selection.is_active)
      {
         int start_x, start_y, end_x, end_y;
@@ -4248,6 +4328,43 @@ _imf_event_commit_cb(void *data, Ecore_IMF_Context *ctx 
EINA_UNUSED, void *event
    DBG("IMF committed '%s'", str);
    if (!str) return;
    termpty_write(sd->pty, str, strlen(str));
+   if (sd->preedit_str)
+     {
+        eina_stringshare_del(sd->preedit_str);
+        sd->preedit_str = NULL;
+     }
+   _smart_update_queue(sd->self, sd);
+}
+
+static void
+_imf_event_delete_surrounding_cb(void *data, Ecore_IMF_Context *ctx 
EINA_UNUSED, void *event)
+{
+   Termio *sd = data;
+   Ecore_IMF_Event_Delete_Surrounding *ev = event;
+   DBG("IMF del surrounding %p %i %i", sd, ev->offset, ev->n_chars);
+}
+
+static void
+_imf_event_preedit_changed_cb(void *data, Ecore_IMF_Context *ctx, void *event 
EINA_UNUSED)
+{
+   Termio *sd = data;
+   char *preedit_string;
+   int cursor_pos;
+   ecore_imf_context_preedit_string_get(ctx, &preedit_string, &cursor_pos);
+   if (!preedit_string) return;
+   DBG("IMF preedit str '%s'", preedit_string);
+   if (sd->preedit_str) eina_stringshare_del(sd->preedit_str);
+   sd->preedit_str = eina_stringshare_add(preedit_string);
+   _smart_update_queue(sd->self, sd);
+   free(preedit_string);
+}
+
+static void
+_imf_event_selection_set_cb(void *data, Ecore_IMF_Context *ctx EINA_UNUSED, 
void *event)
+{
+   Termio *sd = data;
+   Ecore_IMF_Event_Selection *ev = event;
+   DBG("IMF selection set %p %i %i", sd, ev->start, ev->end);
 }
 
 
@@ -4360,10 +4477,13 @@ _smart_add(Evas_Object *obj)
 
         ecore_imf_context_event_callback_add
           (sd->khdl.imf, ECORE_IMF_CALLBACK_COMMIT, _imf_event_commit_cb, sd);
-
+        ecore_imf_context_event_callback_add
+          (sd->khdl.imf, ECORE_IMF_CALLBACK_DELETE_SURROUNDING, 
_imf_event_delete_surrounding_cb, sd);
+        ecore_imf_context_event_callback_add
+          (sd->khdl.imf, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, 
_imf_event_preedit_changed_cb, sd);
+        ecore_imf_context_event_callback_add
+          (sd->khdl.imf, ECORE_IMF_CALLBACK_SELECTION_SET, 
_imf_event_selection_set_cb, sd);
         /* make IMF usable by a terminal - no preedit, prediction... */
-        ecore_imf_context_use_preedit_set
-          (sd->khdl.imf, EINA_FALSE);
         ecore_imf_context_prediction_allow_set
           (sd->khdl.imf, EINA_FALSE);
         ecore_imf_context_autocapital_type_set
@@ -4423,9 +4543,11 @@ _smart_del(Evas_Object *obj)
    if (sd->link.down.dndobj) evas_object_del(sd->link.down.dndobj);
    keyin_compose_seq_reset(&sd->khdl);
    if (sd->sel_str) eina_stringshare_del(sd->sel_str);
+   if (sd->preedit_str) eina_stringshare_del(sd->preedit_str);
    if (sd->sel_reset_job) ecore_job_del(sd->sel_reset_job);
    EINA_LIST_FREE(sd->cur_chids, chid) eina_stringshare_del(chid);
    sd->sel_str = NULL;
+   sd->preedit_str = NULL;
    sd->sel_reset_job = NULL;
    sd->link.down.dndobj = NULL;
    sd->cursor.obj = NULL;

-- 


Reply via email to