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
#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
Eina_List *preedit_attrs;
int32_t preedit_cursor;
+ char *surrounding_text;
+ int32_t surrounding_cursor;
+
struct
{
Eina_List *attrs;
#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) {
NULL);
}
}
+
+ send_surrounding_text (imcontext);
}
static void
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
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);
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);
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);
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);
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;
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),
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,
#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);
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*/
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;
#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
if (_TV) {
g_info_manager->remoteinput_callback_cursor_position (cursor_pos);
- remote_surrounding_get (wsc_ctx);
}
}
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,
_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
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;
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;
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
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);
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;
}
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";
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);
}
}
}
}
}
-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)
{
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)
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;
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;
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
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;
bool engine_loader_flag;
int floating_mode;
bool prediction_allow;
+ int surrounding_cursor;
HelperAgentSignalVoid signal_exit;
HelperAgentSignalVoid signal_attach_input_context;
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 () {
}
}
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;
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:
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);
}
/**
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);
}
/**