Hi, EFL developers.

ATM, edje entry doesn't display the style of preedit string such as
underline, reverse, and Highlight.
It's because XIM module doesn't provide the style attribute.
This patch is made for providing the style attibute information to entry or
other editable widget.

edje_test.patch.txt is for verifying this patch. (This patch is written by
Woohyun and Woohyun will commit edje_entry patch with edc patch)

Would you please review ecore_imf_xim_attribute.patch.txt file?

Thanks.
Index: src/modules/immodules/xim/ecore_imf_xim.c
===================================================================
--- src/modules/immodules/xim/ecore_imf_xim.c   (revision 66175)
+++ src/modules/immodules/xim/ecore_imf_xim.c   (working copy)
@@ -23,6 +23,8 @@
 static Eina_List *open_ims = NULL;
 #endif
 
+#define FEEDBACK_MASK (XIMReverse | XIMUnderline | XIMHighlight)
+
 typedef struct _XIM_Im_Info XIM_Im_Info;
 struct _XIM_Im_Info
 {
@@ -51,6 +53,7 @@
    Eina_Bool      finalizing;
    Eina_Bool      has_focus;
    Eina_Bool      in_toplevel;
+   XIMFeedback   *feedbacks;
 
    XIMCallback    preedit_start_cb;
    XIMCallback    preedit_done_cb;
@@ -63,6 +66,12 @@
 void                    imf_context_data_destroy(Ecore_IMF_Context_Data 
*imf_context_data);
 
 #ifdef ENABLE_XIM
+static void add_feedback_attr (Eina_List **attrs,
+                               const char   *str,
+                               XIMFeedback   feedback,
+                               int           start_pos,
+                               int           end_pos);
+
 static void reinitialize_ic(Ecore_IMF_Context *ctx);
 static void reinitialize_all_ics(XIM_Im_Info *info);
 static void set_ic_client_window(Ecore_IMF_Context *ctx,
@@ -99,6 +108,19 @@
                                  XPointer call_data);
 #endif
 
+static unsigned int
+utf8_offset_to_index(const char *str, int offset)
+{
+   int index = 0;
+   int i;
+   for (i = 0; i < offset; i++)
+     {
+        eina_unicode_utf8_get_next(str, &index);
+     }
+
+   return index;
+}
+
 static void
 _ecore_imf_context_xim_add(Ecore_IMF_Context *ctx)
 {
@@ -204,6 +226,43 @@
 }
 
 static void
+_ecore_imf_context_xim_preedit_string_with_attributes_get(Ecore_IMF_Context 
*ctx,
+                                          char             **str,
+                                          Eina_List        **attrs,
+                                          int               *cursor_pos)
+{
+   EINA_LOG_DBG("in");
+
+   Ecore_IMF_Context_Data *imf_context_data = ecore_imf_context_data_get(ctx);
+
+   _ecore_imf_context_xim_preedit_string_get(ctx, str, cursor_pos);
+
+   if (!attrs) return;
+   if (!imf_context_data || !imf_context_data->feedbacks) return;
+
+   int i = 0;
+   XIMFeedback last_feedback = 0;
+   int start = -1;
+
+   for (i = 0; i < imf_context_data->preedit_length; i++)
+     {
+        XIMFeedback new_feedback = imf_context_data->feedbacks[i] & 
FEEDBACK_MASK;
+
+        if (new_feedback != last_feedback)
+          {
+             if (start >= 0)
+               add_feedback_attr (attrs, *str, last_feedback, start, i);
+
+             last_feedback = new_feedback;
+             start = i;
+          }
+     }
+
+   if (start >= 0)
+     add_feedback_attr (attrs, *str, last_feedback, start, i);
+}
+
+static void
 _ecore_imf_context_xim_focus_in(Ecore_IMF_Context *ctx)
 {
    EINA_LOG_DBG("in");
@@ -291,11 +350,18 @@
 
    XFree(preedit_attr);
 
+   if (imf_context_data->feedbacks)
+     {
+        free(imf_context_data->feedbacks);
+        imf_context_data->feedbacks = NULL;
+     }
+
    if(imf_context_data->preedit_length)
      {
         imf_context_data->preedit_length = 0;
         free(imf_context_data->preedit_chars);
         imf_context_data->preedit_chars = NULL;
+
         ecore_imf_context_preedit_changed_event_add(ctx);
      }
 
@@ -333,6 +399,36 @@
 }
 
 static void
+add_feedback_attr (Eina_List **attrs,
+                   const char   *str,
+                   XIMFeedback   feedback,
+                   int           start_pos,
+                   int           end_pos)
+{
+   Ecore_IMF_Preedit_Attr *attr = NULL;
+
+   unsigned int start_index = utf8_offset_to_index (str, start_pos);
+   unsigned int end_index = utf8_offset_to_index (str, end_pos);
+
+   if (feedback & FEEDBACK_MASK)
+    {
+        attr = (Ecore_IMF_Preedit_Attr *)calloc(1, 
sizeof(Ecore_IMF_Preedit_Attr));
+        attr->start_index = start_index;
+        attr->end_index = end_index;
+        *attrs = eina_list_append(*attrs, (void *)attr);
+    }
+
+   if (feedback & XIMUnderline)
+     attr->preedit_type = ECORE_IMF_PREEDIT_TYPE_SUB1;
+
+   if (feedback & XIMReverse)
+     attr->preedit_type = ECORE_IMF_PREEDIT_TYPE_SUB2;
+
+   if (feedback & XIMHighlight)
+     attr->preedit_type = ECORE_IMF_PREEDIT_TYPE_SUB3;
+}
+
+static void
 _ecore_imf_context_xim_cursor_location_set (Ecore_IMF_Context   *ctx,
                                             int x, int y, int w, int h)
 {
@@ -608,7 +704,7 @@
    .use_preedit_set = _ecore_imf_context_xim_use_preedit_set,
    .input_mode_set = NULL,
    .filter_event = _ecore_imf_context_xim_filter_event,
-   .preedit_string_with_attributes_get = NULL,
+   .preedit_string_with_attributes_get = 
_ecore_imf_context_xim_preedit_string_with_attributes_get,
    .prediction_allow_set = NULL,
    .autocapital_type_set = NULL,
    .control_panel_show = NULL,
@@ -712,6 +808,13 @@
      XDestroyIC(imf_context_data->ic);
 
    free(imf_context_data->preedit_chars);
+
+   if (imf_context_data->feedbacks)
+     {
+        free(imf_context_data->feedbacks);
+        imf_context_data->feedbacks = NULL;
+     }
+
    free(imf_context_data->locale);
    free(imf_context_data);
 }
@@ -811,6 +914,7 @@
    Eina_Unicode *new_text = NULL;
    Eina_UStrbuf *preedit_bufs = NULL;
    int new_text_length;
+   int i = 0;
 
    preedit_bufs = eina_ustrbuf_new();
    if(imf_context_data->preedit_chars) {
@@ -854,6 +958,20 @@
       imf_context_data->preedit_length =
           eina_unicode_strlen(imf_context_data->preedit_chars);
 
+      if (imf_context_data->feedbacks)
+        {
+           free(imf_context_data->feedbacks);
+           imf_context_data->feedbacks = NULL;
+        }
+
+      if (imf_context_data->preedit_length > 0)
+        {
+           imf_context_data->feedbacks = 
calloc(imf_context_data->preedit_length, sizeof(XIMFeedback));
+
+           for (i = 0; i < imf_context_data->preedit_length; i++)
+             imf_context_data->feedbacks[i] = t->feedback[i];
+        }
+
       ecore_imf_context_preedit_changed_event_add(ctx);
    }
 
Index: src/lib/edje_entry.c
===================================================================
--- src/lib/edje_entry.c        (revision 66173)
+++ src/lib/edje_entry.c        (working copy)
@@ -2986,6 +2986,12 @@
    char *preedit_string;
    int i;
    Eina_Bool preedit_end_state = EINA_FALSE;
+   Eina_List *attrs = NULL;
+   Ecore_IMF_Preedit_Attr *attr;
+   Eina_List *l;
+   Eina_Strbuf *buf;
+   char *preedit_tag_index;
+   char *pretag = NULL;
 
    if ((!rp) || (!ev)) return ECORE_CALLBACK_PASS_ON;
 
@@ -2998,7 +3004,8 @@
 
    if (en->imf_context != ev->ctx) return ECORE_CALLBACK_PASS_ON;
 
-   ecore_imf_context_preedit_string_get(en->imf_context, &preedit_string, 
&cursor_pos);
+   ecore_imf_context_preedit_string_with_attributes_get(en->imf_context, 
&preedit_string, &attrs, &cursor_pos);
+
    if (!preedit_string) return ECORE_CALLBACK_PASS_ON;
 
    if (!strcmp(preedit_string, ""))
@@ -3017,6 +3024,35 @@
    preedit_start_pos = evas_textblock_cursor_pos_get(en->cursor);
 
    /* insert preedit character(s) */
+   if (strlen(preedit_string) > 0)
+     {
+        buf = eina_strbuf_new();
+        if (attrs)
+          {
+             EINA_LIST_FOREACH(attrs, l, attr)
+               {
+                  printf("[%s] type : %d, start : %d, end : %d\n", __func__, 
attr->preedit_type, attr->start_index, attr->end_index);
+
+                  if (attr->preedit_type == ECORE_IMF_PREEDIT_TYPE_SUB1)
+                    {
+                       eina_strbuf_append(buf, "<preedit>");
+                       eina_strbuf_append_n(buf, preedit_string + 
attr->start_index, attr->end_index - attr->start_index + 1);
+                       eina_strbuf_append(buf, "</>");
+                    }
+
+                  else if (attr->preedit_type == ECORE_IMF_PREEDIT_TYPE_SUB2 ||
+                           attr->preedit_type == ECORE_IMF_PREEDIT_TYPE_SUB3)
+                    {
+                       eina_strbuf_append(buf, "<preedit_sel>");
+                       eina_strbuf_append_n(buf, preedit_string + 
attr->start_index, attr->end_index - attr->start_index + 1);
+                       eina_strbuf_append(buf, "</>");
+                    }
+               }
+          }
+        printf("[%s] buf : %s\n", __func__, eina_strbuf_string_get(buf));
+        eina_strbuf_free(buf);
+     }
+
    if ((rp->part->entry_mode == EDJE_ENTRY_EDIT_MODE_PASSWORD) &&
        _edje_password_show_last)
      {
@@ -3066,6 +3102,12 @@
    _edje_emit(rp->edje, "preedit,changed", rp->part->name);
    _edje_emit(ed, "cursor,changed", rp->part->name);
 
+   /* delete attribute list */
+   if (attrs)
+     {
+        EINA_LIST_FREE(attrs, attr) free(attr);
+     }
+
    free(preedit_string);
 
    return ECORE_CALLBACK_DONE;
------------------------------------------------------------------------------
10 Tips for Better Server Consolidation
Server virtualization is being driven by many needs.  
But none more important than the need to reduce IT complexity 
while improving strategic productivity.  Learn More! 
http://www.accelacomm.com/jaw/sdnl/114/51507609/
_______________________________________________
enlightenment-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel

Reply via email to