Modified to deliver surrounding text asynchronously 81/290981/5
authorInHong Han <inhong1.han@samsung.com>
Thu, 6 Apr 2023 03:43:47 +0000 (12:43 +0900)
committerInHong Han <inhong1.han@samsung.com>
Mon, 10 Apr 2023 06:38:11 +0000 (15:38 +0900)
The request is processed synchronously when IME gets surrounding text.
So if app is busy, the waiting time for IME will be longer, the text input
time will be delayed. Therefore, if the surrounding text of app is changed,
it was delivered to IME so that IME could use surrounding text immediately.

Change-Id: Id8ed0bf6cd4b553c6caedd4143f059f482c55741

ism/extras/wayland_immodule/wayland_imcontext.c
ism/modules/panelagent/wayland/isf_wsc_context.h
ism/modules/panelagent/wayland/wayland_panel_agent_module.cpp
ism/src/scim_helper.cpp

index 424d9fd..3dff2f3 100644 (file)
@@ -59,6 +59,7 @@
 #define HIDE_TIMER_INTERVAL     0.05
 #define WAIT_FOR_FILTER_DONE_SECOND 1.3
 #define MAX_WAIT_FOR_WL_SERVER 5.0
+#define MAX_SURROUNDING_BUFSIZE 4000
 
 #define MOD_SHIFT_MASK      0x01
 #define MOD_CAPS_MASK       0x02
@@ -219,6 +220,9 @@ struct _WaylandIMContext
     Eina_List *preedit_attrs;
     int32_t preedit_cursor;
 
+    char *surrounding_text;
+    int32_t surrounding_cursor;
+
     struct
     {
         Eina_List *attrs;
@@ -1244,12 +1248,91 @@ send_cursor_location(WaylandIMContext *imcontext)
 #endif
 }
 
+static char *get_splited_string(int start, int end, char *text)
+{
+    char *splited_string = NULL;
+    splited_string = (char *)malloc(sizeof(char) * (end - start + 2));
+    if (splited_string) {
+        strncpy(splited_string, text + start, end - start + 1);
+        splited_string[end - start + 1] = '\0';
+    } else {
+        LOGE ("malloc failed");
+    }
+
+    return splited_string;
+}
+
+static void
+send_surrounding_text(WaylandIMContext *imcontext)
+{
+    int cursor_pos;
+    char *surrounding = NULL;
+    Eina_Bool need_update = EINA_FALSE;
+
+    if (!imcontext || !imcontext->ctx) {
+        LOGE("No context!");
+        return;
+    }
+
+    if (ecore_imf_context_surrounding_get (imcontext->ctx, &surrounding, &cursor_pos)) {
+        SECURE_LOGD ("surrounding : '%s', cursor: %d", surrounding ? surrounding : "", cursor_pos);
+
+        if (imcontext->surrounding_text) {
+            if (strcmp (imcontext->surrounding_text, surrounding) != 0 || imcontext->surrounding_cursor != cursor_pos)
+                need_update = EINA_TRUE;
+        } else {
+            need_update = EINA_TRUE;
+        }
+
+        if (need_update) {
+            if (imcontext->input && imcontext->text_input) {
+                if (imcontext->surrounding_text)
+                    free (imcontext->surrounding_text);
+
+                imcontext->surrounding_text = strdup (surrounding);
+                imcontext->surrounding_cursor = cursor_pos;
+
+                size_t len = strlen (surrounding);
+                int block_index = 1;
+                int block_size = 0;
+                int start_index = 0;
+
+                if (len % MAX_SURROUNDING_BUFSIZE == 0 && len != 0)
+                    block_size = len / MAX_SURROUNDING_BUFSIZE;
+                else
+                    block_size = (len / MAX_SURROUNDING_BUFSIZE) + 1;
+
+                while (1) {
+                    int end_index = (start_index + MAX_SURROUNDING_BUFSIZE - 1) > (len - 1) ? (len - 1) : (start_index + MAX_SURROUNDING_BUFSIZE - 1);
+                    if (end_index < 0) end_index = 0;
+                    char *text = get_splited_string(start_index, end_index, surrounding);
+                    start_index += MAX_SURROUNDING_BUFSIZE;
+
+                    if (text) {
+                        wl_text_input_set_surrounding_text_ex(imcontext->text_input, text, cursor_pos, cursor_pos, block_index, block_size);
+                        free(text);
+                    }
+
+                    if (block_index >= block_size)
+                        break;
+
+                    block_index++;
+                }
+            }
+        }
+
+        if (surrounding)
+            free (surrounding);
+    }
+}
+
 static void
 update_state(WaylandIMContext *imcontext)
 {
     if (!imcontext->ctx)
         return;
 
+    send_surrounding_text (imcontext);
     send_cursor_location (imcontext);
 
     if (imcontext->input && imcontext->text_input) {
@@ -2038,6 +2121,8 @@ text_input_preedit_string(void                 *data,
                     NULL);
         }
     }
+
+    send_surrounding_text (imcontext);
 }
 
 static void
@@ -2603,68 +2688,7 @@ text_input_get_surrounding_text (void                 *data,
                                  uint32_t              maxlen_after,
                                  int32_t              fd)
 {
-    int cursor_pos;
-    char *surrounding = NULL;
     LOGD("fd: %d maxlen_before: %d maxlen_after: %d", fd, maxlen_before, maxlen_after);
-    WaylandIMContext *imcontext = (WaylandIMContext *)data;
-    if (!imcontext || !imcontext->ctx) {
-        LOGD ("No context!");
-        close(fd);
-        return;
-    }
-
-    /* cursor_pos is a byte index */
-    if (ecore_imf_context_surrounding_get (imcontext->ctx, &surrounding, &cursor_pos)) {
-        SECURE_LOGD ("surrounding : '%s', cursor: %d", surrounding ? surrounding : "", cursor_pos);
-        if (imcontext->text_input) {
-            Eina_Unicode *wide_surrounding = eina_unicode_utf8_to_unicode (surrounding, NULL);
-            size_t wlen = eina_unicode_strlen (wide_surrounding);
-
-            if (cursor_pos > (int)wlen || cursor_pos < 0)
-                cursor_pos = 0;
-
-            if (maxlen_before > cursor_pos)
-                maxlen_before = 0;
-            else
-                maxlen_before = cursor_pos - maxlen_before;
-
-            if (maxlen_after > wlen - cursor_pos)
-                maxlen_after = (uint32_t)wlen;
-            else
-                maxlen_after = cursor_pos + maxlen_after;
-
-            char *req_surrounding = eina_unicode_unicode_to_utf8_range (wide_surrounding + maxlen_before, maxlen_after - maxlen_before, NULL);
-
-            ssize_t ret = write(fd, &cursor_pos, sizeof(cursor_pos));
-            if (ret <= 0) {
-                LOGW ("write pipe failed, errno: %d", errno);
-            } else if (req_surrounding) {
-                char *_surrounding = req_surrounding;
-                size_t len = strlen(req_surrounding);
-                while (len) {
-                    ssize_t ret = write(fd, _surrounding, len);
-                    if (ret <= 0) {
-                        if (errno == EINTR)
-                            continue;
-                        LOGW ("write pipe failed, errno: %d", errno);
-                        break;
-                    }
-                    _surrounding += ret;
-                    len -= ret;
-                }
-            }
-
-            if (req_surrounding)
-                free (req_surrounding);
-
-            if (wide_surrounding)
-                free (wide_surrounding);
-        }
-
-        if (surrounding)
-            free (surrounding);
-    }
-    close(fd);
 }
 
 static void
@@ -3004,6 +3028,9 @@ wayland_im_context_add(Ecore_IMF_Context *ctx)
     imcontext->input_panel_position.x = -1;
     imcontext->input_panel_position.y = -1;
 
+    imcontext->surrounding_text = NULL;
+    imcontext->surrounding_cursor = 0;
+
     LOGD("text_input_manager : %p", imcontext->text_input_manager);
     imcontext->text_input =
         wl_text_input_manager_create_text_input(imcontext->text_input_manager);
@@ -3073,6 +3100,12 @@ wayland_im_context_del (Ecore_IMF_Context *ctx)
         imcontext->language = NULL;
     }
 
+    if (imcontext->surrounding_text) {
+        free (imcontext->surrounding_text);
+        imcontext->surrounding_text = NULL;
+        imcontext->surrounding_cursor = 0;
+    }
+
     // TIZEN_ONLY(20150922): Support to set input panel data
     if (imcontext->imdata) {
         free (imcontext->imdata);
@@ -3208,6 +3241,8 @@ wayland_im_context_focus_in(Ecore_IMF_Context *ctx)
     if (_TV)
         hw_keyboard_mode = EINA_FALSE;
 
+    send_surrounding_text (imcontext);
+
     if (ecore_imf_context_input_panel_enabled_get(ctx))
         if (!ecore_imf_context_input_panel_show_on_demand_get (ctx))
             ecore_imf_context_input_panel_show (ctx);
@@ -3325,6 +3360,7 @@ wayland_im_context_cursor_position_set (Ecore_IMF_Context *ctx,
             LOGD ("ctx : %p, cursor pos : %d", ctx, cursor_pos);
 
             set_autocapital (ctx);
+            send_surrounding_text (imcontext);
 
             if (!imcontext->preedit_text || strlen(imcontext->preedit_text) == 0)
                 wl_text_input_set_cursor_position (imcontext->text_input, cursor_pos);
index 70b2baa..27138b4 100644 (file)
@@ -91,10 +91,8 @@ struct _WSCContextISF {
 
     Ecore_Fd_Handler* surrounding_text_fd_read_handler;
     Ecore_Fd_Handler* selection_text_fd_read_handler;
-    Ecore_Fd_Handler* remote_surrounding_text_fd_read_handler;
 
     char *surrounding_text;
-    char *remote_surrounding_text;
     char *selection_text;
     char *preedit_str;
     char *language;
@@ -125,9 +123,7 @@ struct _WSCContextISF {
                        im_ctx(NULL),
                        surrounding_text_fd_read_handler(NULL),
                        selection_text_fd_read_handler(NULL),
-                       remote_surrounding_text_fd_read_handler(NULL),
                        surrounding_text(NULL),
-                       remote_surrounding_text(NULL),
                        selection_text(NULL),
                        preedit_str(NULL),
                        language(NULL),
@@ -167,7 +163,7 @@ void isf_wsc_context_focus_out (WSCContextISF *wsc_ctx);
 void isf_wsc_context_preedit_string_get (WSCContextISF *wsc_ctx, char** str, int *cursor_pos);
 void isf_wsc_context_autocapital_type_set (WSCContextISF* wsc_ctx, Ecore_IMF_Autocapital_Type autocapital_type);
 void isf_wsc_context_bidi_direction_set (WSCContextISF* wsc_ctx, Ecore_IMF_BiDi_Direction direction);
-void isf_wsc_context_send_surrounding_text (WSCContextISF* wsc_ctx, const char *text, int cursor);
+void isf_wsc_context_update_remote_surrounding_text (WSCContextISF* wsc_ctx, const char *text, int cursor);
 void isf_wsc_context_send_entry_metadata (WSCContextISF* wsc_ctx, Ecore_IMF_Input_Hints hint,
                                           Ecore_IMF_Input_Panel_Layout layout, int variation,
                                           Ecore_IMF_Autocapital_Type type, int return_key_disabled,
@@ -188,7 +184,6 @@ void isf_wsc_context_filter_key_event (WSCContextISF* wsc_ctx,
 #endif
 
 bool wsc_context_surrounding_get (WSCContextISF *wsc_ctx, char **text, int *cursor_pos);
-void wsc_context_remote_surrounding_get (WSCContextISF *wsc_ctx);
 Ecore_IMF_Input_Panel_Layout wsc_context_input_panel_layout_get(WSCContextISF *wsc_ctx);
 int wsc_context_input_panel_layout_variation_get (WSCContextISF *wsc_ctx);
 bool wsc_context_input_panel_caps_lock_mode_get(WSCContextISF *wsc_ctx);
index 6d3effa..59dc1de 100644 (file)
@@ -167,8 +167,6 @@ static void     _show_preedit_string          (int                     context);
 
 static void     panel_req_update_bidi_direction         (WSCContextISF     *ic, int direction);
 
-static void     remote_surrounding_get                  (WSCContextISF     *wsc_ctx);
-
 static void     wl_im_destroy                           (void);
 
 /* Panel iochannel handler*/
@@ -215,7 +213,6 @@ static bool                                             _support_hw_keyboard_mod
 static bool                                             _x_key_event_is_valid       = false;
 
 static Ecore_Timer                                     *_resource_check_timer       = NULL;
-static Ecore_Timer                                     *_request_surrounding_text_timer = NULL;
 
 static bool                                             _need_wl_im_init           = false;
 static struct _wl_im                                    *_wl_im_ctx                = NULL;
@@ -226,7 +223,6 @@ static bool                                             _send_focus_in_event
 
 #define WAYLAND_MODULE_CLIENT_ID (0)
 #define MAX_PREEDIT_BUFSIZE 4000
-#define GET_SURROUNDING_TIMER_INTERVAL 0.2
 
 #define MOD_SHIFT_MASK      0x01
 #define MOD_CAPS_MASK       0x02
@@ -463,7 +459,6 @@ _wsc_im_ctx_cursor_position (void *data, struct zwp_input_method_context_v1 *im_
 
     if (_TV) {
         g_info_manager->remoteinput_callback_cursor_position (cursor_pos);
-        remote_surrounding_get (wsc_ctx);
     }
 }
 
@@ -557,6 +552,66 @@ _wsc_im_ctx_input_panel_enabled (void *data, struct zwp_input_method_context_v1
 
     isf_wsc_context_input_panel_enabled_set (wsc_ctx, input_panel_enabled);
 }
+
+static void
+_wsc_im_ctx_surrounding_text_ex (void *data, struct zwp_input_method_context_v1 *im_ctx, const char *text, uint32_t cursor_pos, uint32_t anchor, uint32_t block_index, uint32_t block_size)
+{
+    WSCContextISF *wsc_ctx = (WSCContextISF*)data;
+    if (!wsc_ctx) return;
+
+    size_t len = strlen (text);
+    if (block_size == 1) {
+        if (wsc_ctx->surrounding_text) {
+            free (wsc_ctx->surrounding_text);
+            wsc_ctx->surrounding_text = NULL;
+        }
+
+        wsc_ctx->surrounding_text = (char *)malloc (sizeof(char) * (len + 1));
+        if (wsc_ctx->surrounding_text) {
+            memcpy (wsc_ctx->surrounding_text, text, len);
+            wsc_ctx->surrounding_text[len] = '\0';
+        } else {
+            LOGE ("malloc failed");
+        }
+
+        wsc_ctx->surrounding_cursor = cursor_pos;
+        SECURE_LOGD ("surrounding_text : %s, surrounding_cursor : %d", wsc_ctx->surrounding_text, wsc_ctx->surrounding_cursor);
+        isf_wsc_context_update_remote_surrounding_text (wsc_ctx, wsc_ctx->surrounding_text ? wsc_ctx->surrounding_text : "", wsc_ctx->surrounding_cursor);
+        g_info_manager->socket_update_surrounding_text (wsc_ctx->surrounding_text ? wsc_ctx->surrounding_text : "", wsc_ctx->surrounding_cursor);
+    } else {
+        if (block_index == 1) {
+            if (wsc_ctx->surrounding_text) {
+                free (wsc_ctx->surrounding_text);
+                wsc_ctx->surrounding_text = NULL;
+            }
+
+            wsc_ctx->surrounding_text = (char *)malloc (sizeof(char) * (len + 1));
+            if (wsc_ctx->surrounding_text) {
+                memcpy (wsc_ctx->surrounding_text, text, len);
+                wsc_ctx->surrounding_text[len] = '\0';
+            } else {
+                LOGE ("malloc failed");
+            }
+        } else {
+            int old_len = wsc_ctx->surrounding_text ? strlen (wsc_ctx->surrounding_text) : 0;
+            void *new_surrounding = realloc (wsc_ctx->surrounding_text, len + old_len + 1);
+            if (new_surrounding) {
+                wsc_ctx->surrounding_text = (char *)new_surrounding;
+                memcpy (wsc_ctx->surrounding_text + old_len, text, len);
+                wsc_ctx->surrounding_text[old_len + len] = '\0';
+            } else {
+                LOGE ("realloc failed");
+            }
+
+            if (block_index == block_size) {
+                wsc_ctx->surrounding_cursor = cursor_pos;
+                SECURE_LOGD ("surrounding_text : %s, surrounding_cursor : %d", wsc_ctx->surrounding_text, wsc_ctx->surrounding_cursor);
+                isf_wsc_context_update_remote_surrounding_text (wsc_ctx, wsc_ctx->surrounding_text ? wsc_ctx->surrounding_text : "", wsc_ctx->surrounding_cursor);
+                g_info_manager->socket_update_surrounding_text (wsc_ctx->surrounding_text ? wsc_ctx->surrounding_text : "", wsc_ctx->surrounding_cursor);
+            }
+        }
+    }
+}
 static const struct zwp_input_method_context_v1_listener wsc_im_context_listener = {
      _wsc_im_ctx_surrounding_text,
      _wsc_im_ctx_reset,
@@ -576,7 +631,8 @@ static const struct zwp_input_method_context_v1_listener wsc_im_context_listener
      _wsc_im_ctx_mime_type,
      _wsc_im_ctx_finalized_content,
      _wsc_im_ctx_prediction_hint_data,
-     _wsc_im_ctx_input_panel_enabled
+     _wsc_im_ctx_input_panel_enabled,
+     _wsc_im_ctx_surrounding_text_ex
 };
 
 #if ENABLE_GRAB_KEYBOARD
@@ -806,11 +862,6 @@ wl_im_destroy ()
         wsc_ctx->surrounding_text = NULL;
     }
 
-    if (wsc_ctx->remote_surrounding_text) {
-        free (wsc_ctx->remote_surrounding_text);
-        wsc_ctx->remote_surrounding_text = NULL;
-    }
-
     if (wsc_ctx->language) {
         free (wsc_ctx->language);
         wsc_ctx->language = NULL;
@@ -825,10 +876,6 @@ wl_im_destroy ()
         ecore_timer_del (_resource_check_timer);
     _resource_check_timer = NULL;
 
-    if (_request_surrounding_text_timer)
-        ecore_timer_del (_request_surrounding_text_timer);
-    _request_surrounding_text_timer = NULL;
-
     isf_wsc_context_del (wsc_ctx);
     delete wsc_ctx;
     _wl_im_ctx->wsc->wsc_ctx = NULL;
@@ -895,7 +942,7 @@ _wsc_im_show_input_panel (void *data, struct zwp_input_method_v1 *input_method,
     wsc->wsc_ctx->input_panel_shown_once = EINA_TRUE;
 
     if (_TV)
-        remote_surrounding_get (wsc->wsc_ctx);
+        isf_wsc_context_update_remote_surrounding_text (wsc->wsc_ctx, wsc->wsc_ctx->surrounding_text, wsc->wsc_ctx->surrounding_cursor);
 }
 
 static void
@@ -1300,11 +1347,8 @@ isf_wsc_context_add (WSCContextISF *wsc_ctx)
     WSCContextISF* context_scim = wsc_ctx;
 
     if (!context_scim) return;
-    context_scim->surrounding_text_fd_read_handler = NULL;
-    context_scim->selection_text_fd_read_handler = NULL;
-    context_scim->remote_surrounding_text_fd_read_handler = NULL;
     context_scim->surrounding_text = NULL;
-    context_scim->remote_surrounding_text = NULL;
+    context_scim->selection_text_fd_read_handler = NULL;
     context_scim->selection_text = NULL;
 
     context_scim->impl                      = new_ic_impl (context_scim);
@@ -1362,32 +1406,11 @@ isf_wsc_context_del (WSCContextISF *wsc_ctx)
         context_scim->selection_text = NULL;
     }
 
-    if (context_scim->surrounding_text_fd_read_handler) {
-        int fd = ecore_main_fd_handler_fd_get (context_scim->surrounding_text_fd_read_handler);
-        if (fd >= 0)
-            close (fd);
-        ecore_main_fd_handler_del (context_scim->surrounding_text_fd_read_handler);
-        context_scim->surrounding_text_fd_read_handler = NULL;
-    }
-
-    if (context_scim->remote_surrounding_text_fd_read_handler) {
-        int fd = ecore_main_fd_handler_fd_get (context_scim->remote_surrounding_text_fd_read_handler);
-        if (fd >= 0)
-            close (fd);
-        ecore_main_fd_handler_del (context_scim->remote_surrounding_text_fd_read_handler);
-        context_scim->remote_surrounding_text_fd_read_handler = NULL;
-    }
-
     if (context_scim->surrounding_text) {
         free (context_scim->surrounding_text);
         context_scim->surrounding_text = NULL;
     }
 
-    if (context_scim->remote_surrounding_text) {
-        free (context_scim->remote_surrounding_text);
-        context_scim->remote_surrounding_text = NULL;
-    }
-
     if (context_scim->id != _ic_list->id) {
         WSCContextISF * pre = _ic_list;
         WSCContextISF * cur = _ic_list->next;
@@ -1604,7 +1627,7 @@ isf_wsc_context_bidi_direction_set (WSCContextISF* wsc_ctx, Ecore_IMF_BiDi_Direc
 }
 
 void
-isf_wsc_context_send_surrounding_text (WSCContextISF* wsc_ctx, const char *text, int cursor)
+isf_wsc_context_update_remote_surrounding_text (WSCContextISF* wsc_ctx, const char *text, int cursor)
 {
     SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
 
@@ -1671,7 +1694,7 @@ isf_wsc_context_send_entry_metadata (WSCContextISF* wsc_ctx, Ecore_IMF_Input_Hin
             context_scim->impl->init_remote_entry_metadata = true;
 
             if (_TV)
-                remote_surrounding_get (wsc_ctx);
+                isf_wsc_context_update_remote_surrounding_text (wsc_ctx, wsc_ctx->surrounding_text, wsc_ctx->surrounding_cursor);
         }
     }
 }
@@ -2029,18 +2052,6 @@ wsc_send_preedit_style (WSCContextISF* wsc_ctx)
     }
 }
 
-static Eina_Bool
-get_surrounding_text_timer_cb (void *data)
-{
-    WSCContextISF* wsc_ctx = static_cast<WSCContextISF*>(data);
-    _request_surrounding_text_timer = NULL;
-
-    if (wsc_ctx)
-        remote_surrounding_get (wsc_ctx);
-
-    return ECORE_CALLBACK_CANCEL;
-}
-
 static void
 wsc_send_preedit (WSCContextISF* wsc_ctx, int32_t cursor)
 {
@@ -2063,12 +2074,6 @@ wsc_send_preedit (WSCContextISF* wsc_ctx, int32_t cursor)
                                             wsc_ctx->serial,
                                             wsc_ctx->preedit_str,
                                             utf8_wcstombs (wsc_ctx->impl->commit_string).c_str ());
-
-    if (_TV) {
-        if (_request_surrounding_text_timer)
-            ecore_timer_del (_request_surrounding_text_timer);
-        _request_surrounding_text_timer = ecore_timer_add (GET_SURROUNDING_TIMER_INTERVAL, get_surrounding_text_timer_cb, wsc_ctx);
-    }
 }
 
 bool wsc_context_surrounding_get (WSCContextISF *wsc_ctx, char **text, int *cursor_pos)
@@ -2089,99 +2094,6 @@ bool wsc_context_surrounding_get (WSCContextISF *wsc_ctx, char **text, int *curs
     return true;
 }
 
-static Eina_Bool
-remote_surrounding_text_fd_read_func (void* data, Ecore_Fd_Handler* fd_handler) {
-    if (fd_handler == NULL || data == NULL)
-        return ECORE_CALLBACK_RENEW;
-
-    WSCContextISF* wsc_ctx = (WSCContextISF*)data;
-
-    int fd = ecore_main_fd_handler_fd_get (fd_handler);
-    if (fd < 0)
-            return ECORE_CALLBACK_RENEW;
-
-    char buff[512];
-    int len = read (fd, buff, sizeof (buff) - 1);
-
-    if (len == 0) {
-        SECURE_LOGD ("remote_surrounding_text : %s, surrounding_cursor : %d", wsc_ctx->remote_surrounding_text, wsc_ctx->surrounding_cursor);
-        isf_wsc_context_send_surrounding_text (wsc_ctx, wsc_ctx->remote_surrounding_text ? wsc_ctx->remote_surrounding_text : "", wsc_ctx->surrounding_cursor);
-    } else if (len < 0) {
-        LOGW ("failed");
-    } else {
-        buff[len] = '\0';
-        if (wsc_ctx->remote_surrounding_text == NULL) {
-            if (len >= (int)sizeof(int)) {
-                /* Add one byte for terminating NULL character and subtract <int> byte for cursor position */
-                wsc_ctx->remote_surrounding_text = (char*)malloc (len + 1 - sizeof(int));
-                if (wsc_ctx->remote_surrounding_text) {
-                    memcpy(&(wsc_ctx->surrounding_cursor), buff, sizeof(int));
-                    memcpy (wsc_ctx->remote_surrounding_text, buff + sizeof(int), len - sizeof(int));
-                    wsc_ctx->remote_surrounding_text[len - sizeof(int)] = '\0';
-                    return ECORE_CALLBACK_RENEW;
-                } else {
-                    LOGE ("malloc failed");
-                }
-            }
-        } else {
-            int old_len = strlen (wsc_ctx->remote_surrounding_text);
-            void * _new = realloc (wsc_ctx->remote_surrounding_text, len + old_len + 1);
-            if (_new) {
-                wsc_ctx->remote_surrounding_text = (char*)_new;
-                memcpy (wsc_ctx->remote_surrounding_text + old_len, buff, len);
-                wsc_ctx->remote_surrounding_text[old_len + len] = '\0';
-                return ECORE_CALLBACK_RENEW;
-            } else {
-                LOGE ("realloc failed");
-            }
-        }
-    }
-
-    if (wsc_ctx->remote_surrounding_text_fd_read_handler) {
-        close (fd);
-        ecore_main_fd_handler_del (wsc_ctx->remote_surrounding_text_fd_read_handler);
-        wsc_ctx->remote_surrounding_text_fd_read_handler = NULL;
-    }
-
-    if (wsc_ctx->remote_surrounding_text) {
-        free (wsc_ctx->remote_surrounding_text);
-        wsc_ctx->remote_surrounding_text = NULL;
-    }
-
-    return ECORE_CALLBACK_CANCEL;
-}
-
-static void
-remote_surrounding_get (WSCContextISF *wsc_ctx)
-{
-    if (wsc_ctx && wsc_ctx->im_ctx && wsc_ctx->remote_surrounding_text_fd_read_handler)
-        return;
-
-    int filedes[2];
-    if (pipe2(filedes, O_CLOEXEC | O_NONBLOCK) == -1) {
-        LOGW ("create pipe failed");
-        return;
-    } else {
-        LOGD("%d,%d", filedes[0], filedes[1]);
-        if (wsc_ctx && wsc_ctx->im_ctx) {
-            zwp_input_method_context_v1_get_surrounding_text (wsc_ctx->im_ctx, UINT_MAX, UINT_MAX, filedes[1]);
-            Ecore_Wl2_Display *wl2_display = ecore_wl2_connected_display_get (NULL);
-            if (wl2_display)
-                ecore_wl2_display_flush (wl2_display);
-        }
-        close (filedes[1]);
-
-        if (wsc_ctx && wsc_ctx->im_ctx) {
-            if (wsc_ctx->remote_surrounding_text) {
-                free (wsc_ctx->remote_surrounding_text);
-                wsc_ctx->remote_surrounding_text = NULL;
-            }
-
-            wsc_ctx->remote_surrounding_text_fd_read_handler = ecore_main_fd_handler_add (filedes[0], ECORE_FD_READ, remote_surrounding_text_fd_read_func, wsc_ctx, NULL, NULL);
-        }
-    }
-}
-
 Ecore_IMF_Input_Panel_Layout wsc_context_input_panel_layout_get (WSCContextISF *wsc_ctx)
 {
     Ecore_IMF_Input_Panel_Layout layout = ECORE_IMF_INPUT_PANEL_LAYOUT_NORMAL;
@@ -3058,7 +2970,6 @@ _create_wsc_context (struct weescim *wsc, WSCContextISF *wsc_ctx, struct zwp_inp
     wsc->wsc_ctx = wsc_ctx;
     wsc_ctx->ctx = wsc;
     wsc_ctx->surrounding_text = NULL;
-    wsc_ctx->remote_surrounding_text = NULL;
     wsc_ctx->surrounding_cursor = 0;
     wsc_ctx->preedit_str = strdup ("");
     wsc_ctx->content_hint = WL_TEXT_INPUT_CONTENT_HINT_NONE;
@@ -3328,102 +3239,9 @@ public:
         panel_slot_recapture_string(context_id, offset, len, preedit, commit, attrs, INPUT_RESOURCE_LOCAL);
     }
 
-    static Eina_Bool
-    surrounding_text_fd_read_func (void* data, Ecore_Fd_Handler* fd_handler) {
-        if (fd_handler == NULL || data == NULL)
-            return ECORE_CALLBACK_RENEW;
-
-        WSCContextISF* wsc_ctx = (WSCContextISF*)data;
-
-        int fd = ecore_main_fd_handler_fd_get (fd_handler);
-        if (fd < 0)
-            return ECORE_CALLBACK_RENEW;
-
-        char buff[512];
-        int len = read (fd, buff, sizeof (buff) - 1);
-        if (len == 0) {
-            LOGD ("update, wsc_ctx->surrounding_cursor = %d", wsc_ctx->surrounding_cursor);
-            g_info_manager->socket_update_surrounding_text (wsc_ctx->surrounding_text ? wsc_ctx->surrounding_text : "", wsc_ctx->surrounding_cursor);
-        } else if (len < 0) {
-            LOGW ("failed");
-        } else {
-            buff[len] = '\0';
-            if (wsc_ctx->surrounding_text == NULL) {
-                if (len >= (int)sizeof(int)) {
-                    /* Add one byte for terminating NULL character and subtract <int> byte for cursor position */
-                    wsc_ctx->surrounding_text = (char*)malloc (len + 1 - sizeof(int));
-                    if (wsc_ctx->surrounding_text) {
-                        memcpy(&(wsc_ctx->surrounding_cursor), buff, sizeof(int));
-                        memcpy (wsc_ctx->surrounding_text, buff + sizeof(int), len - sizeof(int));
-                        wsc_ctx->surrounding_text[len - sizeof(int)] = '\0';
-                        return ECORE_CALLBACK_RENEW;
-                    } else {
-                        LOGE ("malloc failed");
-                    }
-                }
-            } else {
-                int old_len = strlen (wsc_ctx->surrounding_text);
-                void * _new = realloc (wsc_ctx->surrounding_text, len + old_len + 1);
-                if (_new) {
-                    wsc_ctx->surrounding_text = (char*)_new;
-                    memcpy (wsc_ctx->surrounding_text + old_len, buff, len);
-                    wsc_ctx->surrounding_text[old_len + len] = '\0';
-                    return ECORE_CALLBACK_RENEW;
-                } else {
-                    LOGE ("realloc failed");
-                }
-            }
-        }
-
-        if (wsc_ctx->surrounding_text_fd_read_handler) {
-            close (fd);
-            ecore_main_fd_handler_del (wsc_ctx->surrounding_text_fd_read_handler);
-            wsc_ctx->surrounding_text_fd_read_handler = NULL;
-        }
-
-        if (wsc_ctx->surrounding_text) {
-            free (wsc_ctx->surrounding_text);
-            wsc_ctx->surrounding_text = NULL;
-        }
-
-        return ECORE_CALLBACK_RENEW;
-    }
-
     void
     socket_helper_get_surrounding_text (int id, uint32 context_id, uint32 maxlen_before, uint32 maxlen_after) {
         LOGD ("client id:%d", id);
-
-        int filedes[2];
-        if (pipe2(filedes, O_CLOEXEC | O_NONBLOCK) == -1) {
-            LOGW ("create pipe failed");
-            return;
-        }
-        LOGD("%d,%d", filedes[0], filedes[1]);
-        WSCContextISF* ic = find_ic (context_id);
-        if (!ic) return;
-
-        if (ic->im_ctx)
-            zwp_input_method_context_v1_get_surrounding_text (ic->im_ctx, maxlen_before, maxlen_after, filedes[1]);
-
-        Ecore_Wl2_Display *wl2_display = ecore_wl2_connected_display_get (NULL);
-        if (wl2_display)
-            ecore_wl2_display_flush (wl2_display);
-        close (filedes[1]);
-
-        if (ic->surrounding_text_fd_read_handler) {
-            int fd = ecore_main_fd_handler_fd_get (ic->surrounding_text_fd_read_handler);
-            if (fd >= 0)
-                close (fd);
-            ecore_main_fd_handler_del (ic->surrounding_text_fd_read_handler);
-            ic->surrounding_text_fd_read_handler = NULL;
-        }
-
-        if (ic->surrounding_text) {
-            free (ic->surrounding_text);
-            ic->surrounding_text = NULL;
-        }
-
-        ic->surrounding_text_fd_read_handler = ecore_main_fd_handler_add (filedes[0], ECORE_FD_READ, surrounding_text_fd_read_func, ic, NULL, NULL);
     }
 
     void
index ea964e2..d659896 100644 (file)
@@ -165,7 +165,6 @@ public:
     char* surrounding_text;
     char* selection_text;
     uint32 cursor_pos;
-    int need_update_surrounding_text;
     int need_update_selection_text;
     uint32 layout;
     bool ise_show_flag;
@@ -177,6 +176,7 @@ public:
     bool engine_loader_flag;
     int floating_mode;
     bool prediction_allow;
+    int surrounding_cursor;
 
     HelperAgentSignalVoid           signal_exit;
     HelperAgentSignalVoid           signal_attach_input_context;
@@ -249,10 +249,9 @@ public:
 
 public:
     HelperAgentImpl (HelperAgent* thiz) : magic(0), magic_active(0), timeout(-1), focused_ic ((uint32) -1), thiz (thiz),
-        surrounding_text (NULL), selection_text (NULL), cursor_pos (0),
-        need_update_surrounding_text (0), need_update_selection_text (0),
+        surrounding_text (NULL), selection_text (NULL), cursor_pos (0), need_update_selection_text (0),
         layout (0), ise_show_flag (false), hw_keyboard_mode (false), need_update_entry_metadata (false), ise_focus_flag (false),
-        finalized_text(NULL), finalized_cursor_pos(0), engine_loader_flag(false), floating_mode(-1), prediction_allow(true) {
+        finalized_text(NULL), finalized_cursor_pos(0), engine_loader_flag(false), floating_mode(-1), prediction_allow(true), surrounding_cursor(0) {
     }
 
     ~HelperAgentImpl () {
@@ -609,7 +608,7 @@ public:
         }
     }
 private:
-    HelperAgentImpl () : magic (0), magic_active (0), timeout (-1), focused_ic ((uint32) -1), thiz (NULL), surrounding_text (NULL), selection_text (NULL), cursor_pos (0), need_update_surrounding_text (0), need_update_selection_text (0), layout (0), ise_show_flag (false), hw_keyboard_mode (false), need_update_entry_metadata (false), ise_focus_flag (false), finalized_text (NULL), finalized_cursor_pos (0), engine_loader_flag (false), floating_mode (-1), prediction_allow (true) { }
+    HelperAgentImpl () : magic (0), magic_active (0), timeout (-1), focused_ic ((uint32) -1), thiz (NULL), surrounding_text (NULL), selection_text (NULL), cursor_pos (0), need_update_selection_text (0), layout (0), ise_show_flag (false), hw_keyboard_mode (false), need_update_entry_metadata (false), ise_focus_flag (false), finalized_text (NULL), finalized_cursor_pos (0), engine_loader_flag (false), floating_mode (-1), prediction_allow (true), surrounding_cursor (0) { }
 };
 
 static MessageQueue message_queue;
@@ -980,14 +979,10 @@ HelperAgent::handle_message (MessageItem *message)
             MessageItemUpdateSurroundingText *subclass = static_cast<MessageItemUpdateSurroundingText*>(message);
             if (m_impl->surrounding_text != NULL)
                 free (m_impl->surrounding_text);
+
             m_impl->surrounding_text = strdup (subclass->get_text_ref().c_str ());
-            m_impl->cursor_pos = subclass->get_cursor_ref();
+            m_impl->surrounding_cursor = subclass->get_cursor_ref();
             SECURE_LOGD ("surrounding text: %s, %d", m_impl->surrounding_text, subclass->get_cursor_ref());
-            while (m_impl->need_update_surrounding_text > 0) {
-                m_impl->need_update_surrounding_text--;
-                m_impl->signal_update_surrounding_text (this, subclass->get_ic_ref(),
-                    subclass->get_text_ref(), subclass->get_cursor_ref());
-            }
             break;
         }
         case ISM_TRANS_CMD_UPDATE_SELECTION:
@@ -2120,17 +2115,37 @@ HelperAgent::update_input_context (uint32 type, uint32 value) const
 void
 HelperAgent::get_surrounding_text (const String &uuid, int maxlen_before, int maxlen_after) const
 {
-    if (m_impl->socket_active.is_connected () && (m_impl->need_update_surrounding_text == 0)) {
-        m_impl->send.clear ();
-        m_impl->send.put_command (SCIM_TRANS_CMD_REQUEST);
-        m_impl->send.put_data (m_impl->magic_active);
-        m_impl->send.put_command (SCIM_TRANS_CMD_GET_SURROUNDING_TEXT);
-        m_impl->send.put_data (uuid);
-        m_impl->send.put_data (maxlen_before);
-        m_impl->send.put_data (maxlen_after);
-        m_impl->send.write_to_socket (m_impl->socket_active, m_impl->magic_active);
+    String text = "";
+    String buffer;
+    int cursor = 0;
+    bool use_substring = false;
+
+    if (!m_impl->ise_focus_flag) {
+        if (m_impl->finalized_text) {
+            buffer = m_impl->finalized_text;
+            cursor = m_impl->finalized_cursor_pos;
+            use_substring = true;
+        }
+    } else {
+        if (m_impl->surrounding_text) {
+            buffer = m_impl->surrounding_text;
+            cursor = m_impl->surrounding_cursor;
+            use_substring = true;
+        }
+    }
+
+    if (use_substring) {
+        int pos = cursor - maxlen_before;
+        if (maxlen_before < 0) pos = 0;
+        if (pos > (int)buffer.length()) pos = (int)buffer.length();
+        if (pos < 0) pos = 0;
+        size_t len = (maxlen_after + (cursor - pos)) > 0 ? maxlen_after + (cursor - pos) : 0;
+        if (maxlen_after < 0) len = String::npos;
+        text = buffer.substr (pos, len);
     }
-    m_impl->need_update_surrounding_text++;
+
+    SECURE_LOGD ("surrounding text: %s, %d", text.c_str(), cursor);
+    m_impl->signal_update_surrounding_text (this, m_impl->focused_ic, text, cursor);
 }
 
 /**
@@ -2145,64 +2160,36 @@ HelperAgent::get_surrounding_text (const String &uuid, int maxlen_before, int ma
 void
 HelperAgent::get_surrounding_text (int maxlen_before, int maxlen_after, String &text, int &cursor)
 {
-    if (!m_impl->socket_active.is_connected ())
-        return;
+    String buffer;
+    bool use_substring = false;
 
+    cursor = 0;
+    text.clear ();
     if (!m_impl->ise_focus_flag) {
         if (m_impl->finalized_text) {
-            String buffer = m_impl->finalized_text;
+            buffer = m_impl->finalized_text;
             cursor = m_impl->finalized_cursor_pos;
-            int pos = cursor - maxlen_before;
-            if (maxlen_before < 0) pos = 0;
-            if (pos > (int)buffer.length()) pos = (int)buffer.length();
-            if (pos < 0) pos = 0;
-            size_t len = (maxlen_after + (cursor - pos)) > 0 ? maxlen_after + (cursor - pos) : 0;
-            if (maxlen_after < 0) len = String::npos;
-            text = buffer.substr (pos, len);
-        } else {
-            text.clear ();
-            cursor = 0;
+            use_substring = true;
         }
     } else {
-        m_impl->send.clear();
-        m_impl->send.put_command(SCIM_TRANS_CMD_REQUEST);
-        m_impl->send.put_data(m_impl->magic_active);
-        m_impl->send.put_command(SCIM_TRANS_CMD_GET_SURROUNDING_TEXT);
-        m_impl->send.put_data("");
-        m_impl->send.put_data(maxlen_before);
-        m_impl->send.put_data(maxlen_after);
-        m_impl->send.write_to_socket(m_impl->socket_active, m_impl->magic_active);
         if (m_impl->surrounding_text) {
-            free(m_impl->surrounding_text);
-            m_impl->surrounding_text = NULL;
+            buffer = m_impl->surrounding_text;
+            cursor = m_impl->surrounding_cursor;
+            use_substring = true;
         }
+    }
 
-        const int WAIT_FOR_SYNC_RESPONSE_TIMEOUT = 1000;
-        /* Now we are waiting for the ISM_TRANS_CMD_UPDATE_SURROUNDING_TEXT message */
-        if (wait_for_message(ISM_TRANS_CMD_UPDATE_SURROUNDING_TEXT, WAIT_FOR_SYNC_RESPONSE_TIMEOUT)) {
-            MessageItem *message = message_queue.get_pending_message_by_cmd(ISM_TRANS_CMD_UPDATE_SURROUNDING_TEXT);
-            handle_message(message);
-            message_queue.remove_message(message);
-
-            if (m_impl->surrounding_text) {
-                text = m_impl->surrounding_text;
-                cursor = m_impl->cursor_pos;
-            }
-        }
-
-        if (m_impl->surrounding_text) {
-            free(m_impl->surrounding_text);
-            m_impl->surrounding_text = NULL;
-        }
-
-        LOGD("message_queue size : %d", message_queue.get_message_size());
-
-        m_impl->send.clear ();
-        m_impl->send.put_command(SCIM_TRANS_CMD_REQUEST);
-        m_impl->send.put_data(m_impl->magic_active);
-        m_impl->send.put_command(SCIM_TRANS_CMD_PING);
-        m_impl->send.write_to_socket(m_impl->socket_active, m_impl->magic_active);
+    if (use_substring) {
+        int pos = cursor - maxlen_before;
+        if (maxlen_before < 0) pos = 0;
+        if (pos > (int)buffer.length()) pos = (int)buffer.length();
+        if (pos < 0) pos = 0;
+        size_t len = (maxlen_after + (cursor - pos)) > 0 ? maxlen_after + (cursor - pos) : 0;
+        if (maxlen_after < 0) len = String::npos;
+        text = buffer.substr (pos, len);
     }
+
+    SECURE_LOGD ("surrounding text: %s, %d", text.c_str(), cursor);
 }
 
 /**