From a7e1e75d877599f88ea837d2374df3c83edbbd65 Mon Sep 17 00:00:00 2001 From: Jihoon Kim Date: Thu, 6 Oct 2016 11:38:17 +0900 Subject: [PATCH] Fix autoperiod bug Change-Id: Ie8066bd134defe133107e5d8fc2403f2a009b154 Signed-off-by: Jihoon Kim --- ism/extras/wayland_immodule/wayland_imcontext.c | 243 ++++++++++++++++++++- ism/modules/panelagent/wayland/isf_wsc_context.h | 1 - .../wayland/wayland_panel_agent_module.cpp | 172 --------------- 3 files changed, 240 insertions(+), 176 deletions(-) diff --git a/ism/extras/wayland_immodule/wayland_imcontext.c b/ism/extras/wayland_immodule/wayland_imcontext.c index 3ac6687..5ea4a98 100644 --- a/ism/extras/wayland_immodule/wayland_imcontext.c +++ b/ism/extras/wayland_immodule/wayland_imcontext.c @@ -28,6 +28,7 @@ #include #include #include +#include #ifdef HAVE_VCONF #include #endif @@ -52,6 +53,30 @@ #define MOD_NUM_MASK 0x100 #define MOD_Mod5_MASK 0x80 +#define VCONFKEY_AUTOPERIOD_ALLOW_BOOL "file/private/isf/autoperiod_allow" + +typedef enum { + INPUT_LANG_URDU, + INPUT_LANG_HINDI, + INPUT_LANG_BENGALI_IN, + INPUT_LANG_BENGALI_BD, + INPUT_LANG_ASSAMESE, + INPUT_LANG_PUNJABI, + INPUT_LANG_NEPALI, + INPUT_LANG_ORIYA, + INPUT_LANG_MAITHILI, + INPUT_LANG_ARMENIAN, + INPUT_LANG_CN, + INPUT_LANG_CN_HK, + INPUT_LANG_CN_TW, + INPUT_LANG_JAPANESE, + INPUT_LANG_KHMER, + INPUT_LANG_BURMESE, + INPUT_LANG_OTHER +} Input_Language; + +const double DOUBLE_SPACE_INTERVAL = 1.0; + static Eina_Bool _clear_hide_timer(); static Ecore_Timer *_hide_timer = NULL; @@ -82,8 +107,36 @@ static Evas *_active_context_canvas = NULL; static unsigned int _active_context_window_id = 0; static Ecore_Device *_ime_device = NULL; + +static double space_key_time = 0.0; +static Eina_Bool autoperiod_allow = EINA_FALSE; +static Input_Language input_lang = INPUT_LANG_OTHER; // +typedef struct __Punctuations { + const char *code; + Input_Language lang; + Eina_Unicode punc_code; +} Punctuations; + +static Punctuations __punctuations [] = { + { "ur_PK", INPUT_LANG_URDU, 0x06D4 }, + { "hi_IN", INPUT_LANG_HINDI, 0x0964 }, + { "bn_IN", INPUT_LANG_BENGALI_IN, 0x0964 }, + { "bn_BD", INPUT_LANG_BENGALI_BD, 0x0964 }, + { "as_IN", INPUT_LANG_ASSAMESE, 0x0964 }, + { "pa_IN", INPUT_LANG_PUNJABI, 0x0964 }, + { "ne_NP", INPUT_LANG_NEPALI, 0x0964 }, + { "or_IN", INPUT_LANG_ORIYA, 0x0964 }, + { "mai_IN", INPUT_LANG_MAITHILI, 0x0964 }, + { "hy_AM", INPUT_LANG_ARMENIAN, 0x0589 }, + { "zh_CN", INPUT_LANG_CN, 0x3002 }, + { "zh_HK", INPUT_LANG_CN_HK, 0x3002 }, + { "zh_TW", INPUT_LANG_CN_TW, 0x3002 }, + { "ja_JP", INPUT_LANG_JAPANESE, 0x3002 }, + { "km_KH", INPUT_LANG_KHMER, 0x17D4 }, +}; + struct _WaylandIMContext { Ecore_IMF_Context *ctx; @@ -156,6 +209,146 @@ struct _WaylandIMContext static void _input_panel_hide(Ecore_IMF_Context *ctx, Eina_Bool instant); static Eina_Bool show_input_panel(Ecore_IMF_Context *ctx); +static void +get_input_language () +{ + unsigned int i; + char *input_lang_str = vconf_get_str (VCONFKEY_ISF_INPUT_LANGUAGE); + if (!input_lang_str) return; + + input_lang = INPUT_LANG_OTHER; + + for (i = 0; i < (sizeof (__punctuations) / sizeof (__punctuations[0])); i++) { + if (strcmp (input_lang_str, __punctuations[i].code) == 0) { + input_lang = __punctuations[i].lang; + break; + } + } + + free (input_lang_str); +} + +static void autoperiod_allow_changed_cb (keynode_t *key, void* data) +{ + autoperiod_allow = vconf_keynode_get_bool (key); +} + +static void input_language_changed_cb (keynode_t *key, void* data) +{ + get_input_language (); +} + +static Eina_Bool +check_symbol (Eina_Unicode ucode, Eina_Unicode symbols[], int symbol_num) +{ + int i; + for (i = 0; i < symbol_num; i++) { + // Check symbol + if (ucode == symbols[i]) + return EINA_TRUE; + } + + return EINA_FALSE; +} + +static Eina_Bool +check_space_symbol (Eina_Unicode uchar) +{ + Eina_Unicode space_symbols[] = {' ', 0x00A0 /* no-break space */, 0x3000 /* ideographic space */}; + const int symbol_num = sizeof (space_symbols) / sizeof (space_symbols[0]); + + return check_symbol (uchar, space_symbols, symbol_num); +} + +static void +autoperiod_insert (Ecore_IMF_Context *ctx) +{ + char *plain_str = NULL; + int cursor_pos = 0; + Eina_Unicode *ustr = NULL; + Ecore_IMF_Event_Delete_Surrounding ev; + char *fullstop_mark = NULL; + size_t ulen = 0; + int del_chars = 0; + WaylandIMContext *imcontext = NULL; + + if (autoperiod_allow == EINA_FALSE) + return; + + if (!ctx) return; + + Ecore_IMF_Input_Panel_Layout layout = ecore_imf_context_input_panel_layout_get (ctx); + if (layout != ECORE_IMF_INPUT_PANEL_LAYOUT_NORMAL) + return; + + if ((ecore_time_get () - space_key_time) > DOUBLE_SPACE_INTERVAL) + goto done; + + imcontext = (WaylandIMContext *)ecore_imf_context_data_get (ctx); + if (!imcontext) return; + + ecore_imf_context_surrounding_get (ctx, &plain_str, NULL); + if (!plain_str) goto done; + + cursor_pos = imcontext->cursor_position; + + // Convert string from UTF-8 to unicode + ustr = eina_unicode_utf8_to_unicode (plain_str, NULL); + if (!ustr) goto done; + + ulen = eina_unicode_strlen (ustr); + + if (cursor_pos < 2 || cursor_pos > (int)ulen) { + LOGD ("invalid range. cursor pos : %d, length : %d\n", cursor_pos, ulen); + goto done; + } + + if (check_space_symbol (ustr[cursor_pos-1])) { + // any character + press space key twice in short time + if (!(iswpunct (ustr[cursor_pos-2]) || check_space_symbol (ustr[cursor_pos-2]))) { + del_chars = 1; + } + // any character + space + press space key twice in short time + else if (cursor_pos >= 3 && + check_space_symbol (ustr[cursor_pos-2]) && + !(iswpunct (ustr[cursor_pos-3]) || check_space_symbol (ustr[cursor_pos-3]))) { + del_chars = 2; + } + + if (del_chars > 0) { + ev.ctx = ctx; + ev.n_chars = del_chars; + ev.offset = del_chars * -1; + + ecore_imf_context_delete_surrounding_event_add (ctx, ev.offset, ev.n_chars); + ecore_imf_context_event_callback_call (ctx, ECORE_IMF_CALLBACK_DELETE_SURROUNDING, &ev); + + if (input_lang == INPUT_LANG_OTHER) { + fullstop_mark = strdup ("."); + } + else { + Eina_Unicode wbuf[2] = {0}; + wbuf[0] = __punctuations[input_lang].punc_code; + + fullstop_mark = eina_unicode_unicode_to_utf8 (wbuf, NULL); + } + + ecore_imf_context_commit_event_add (ctx, fullstop_mark); + ecore_imf_context_event_callback_call (ctx, ECORE_IMF_CALLBACK_COMMIT, (void *)fullstop_mark); + + if (fullstop_mark) { + free (fullstop_mark); + fullstop_mark = NULL; + } + } + } + +done: + if (plain_str) free (plain_str); + if (ustr) free (ustr); + space_key_time = ecore_time_get (); +} + static Ecore_IMF_Context * get_using_ctx () { @@ -570,6 +763,19 @@ text_input_commit_string(void *data, clear_preedit(imcontext); + if (!text) + return; + + Eina_Unicode *ustr = eina_unicode_utf8_to_unicode (text, NULL); + + if (ustr) { + if (eina_unicode_strcmp (ustr, L" ") == 0 || + eina_unicode_strcmp (ustr, L" ") == 0) + autoperiod_insert (imcontext->ctx); + + free(ustr); + } + ecore_imf_context_commit_event_add(imcontext->ctx, text); ecore_imf_context_event_callback_call(imcontext->ctx, ECORE_IMF_CALLBACK_COMMIT, (void *)text); } @@ -1508,7 +1714,7 @@ text_input_get_surrounding_text (void *data, /* 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); + 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); @@ -1652,7 +1858,19 @@ EAPI void initialize () { register_key_handler (); + /* get input language vconf value */ + get_input_language (); + #ifdef HAVE_VCONF + /* get autoperiod allow vconf value */ + int val; + if (vconf_get_bool (VCONFKEY_AUTOPERIOD_ALLOW_BOOL, &val) == 0) { + if (val == EINA_TRUE) + autoperiod_allow = EINA_TRUE; + } + + vconf_notify_key_changed (VCONFKEY_AUTOPERIOD_ALLOW_BOOL, autoperiod_allow_changed_cb, NULL); + vconf_notify_key_changed (VCONFKEY_ISF_INPUT_LANGUAGE, input_language_changed_cb, NULL); vconf_notify_key_changed (VCONFKEY_ISF_HW_KEYBOARD_INPUT_DETECTED, keyboard_mode_changed_cb, NULL); #endif @@ -1673,6 +1891,8 @@ EAPI void uninitialize () _conformant_change_handler_del (); #ifdef HAVE_VCONF + vconf_ignore_key_changed (VCONFKEY_AUTOPERIOD_ALLOW_BOOL, autoperiod_allow_changed_cb); + vconf_ignore_key_changed (VCONFKEY_ISF_INPUT_LANGUAGE, input_language_changed_cb); vconf_ignore_key_changed (VCONFKEY_ISF_HW_KEYBOARD_INPUT_DETECTED, keyboard_mode_changed_cb); #endif @@ -1687,7 +1907,7 @@ wayland_im_context_add(Ecore_IMF_Context *ctx) { WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx); - LOGD("context_add. ctx : %p", ctx); + LOGD("ctx : %p", ctx); if (!imcontext) return; @@ -1715,7 +1935,7 @@ wayland_im_context_del (Ecore_IMF_Context *ctx) WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx); Ecore_Event_Key *ev; - LOGD ("context_del. ctx : %p, focused_ctx : %p, show_req_ctx : %p", ctx, _focused_ctx, _show_req_ctx); + LOGD ("ctx : %p, focused_ctx : %p, show_req_ctx : %p", ctx, _focused_ctx, _show_req_ctx); if (!imcontext) return; @@ -2082,6 +2302,13 @@ wayland_im_context_filter_event(Ecore_IMF_Context *ctx, do { if (!ecore_key_ev.timestamp && (ecore_key_ev.modifiers & MOD_Mod5_MASK)) { + if (type == ECORE_IMF_EVENT_KEY_DOWN) { + if (strcmp (ecore_key_ev.key, "space") == 0 || + strcmp (ecore_key_ev.key, "KP_Space") == 0 ) { + autoperiod_insert (ctx); + } + } + LOGD("Return! This is SW keyboard fake event!"); break; } @@ -2124,6 +2351,16 @@ wayland_im_context_filter_event(Ecore_IMF_Context *ctx, LOGD ("elapsed : %.3f ms, serial (last, require) : (%d, %d)", (ecore_time_get() - start_time)*1000, imcontext->last_key_event_filter.serial, serial); } while (0); + if (type == ECORE_IMF_EVENT_KEY_DOWN) { + LOGD ("ret : %d, type : %d, key : %s\n", ret, type, ecore_key_ev.key); + if (ret == EINA_FALSE) { + if (strcmp (ecore_key_ev.key, "space") == 0 || + strcmp (ecore_key_ev.key, "KP_Space") == 0) { + autoperiod_insert (ctx); + } + } + } + //Deal with the next key event in list. Ecore_Event_Key *ev = NULL; if (eina_list_count (imcontext->keysym_list)) { diff --git a/ism/modules/panelagent/wayland/isf_wsc_context.h b/ism/modules/panelagent/wayland/isf_wsc_context.h index 4a4ff19..feaf48d 100644 --- a/ism/modules/panelagent/wayland/isf_wsc_context.h +++ b/ism/modules/panelagent/wayland/isf_wsc_context.h @@ -47,7 +47,6 @@ typedef enum { struct weescim; -const double DOUBLE_SPACE_INTERVAL = 1.0; const double HIDE_TIMER_INTERVAL = 0.05; const double WILL_SHOW_TIMER_INTERVAL = 5.0; diff --git a/ism/modules/panelagent/wayland/wayland_panel_agent_module.cpp b/ism/modules/panelagent/wayland/wayland_panel_agent_module.cpp index b834371..b6c1aba 100644 --- a/ism/modules/panelagent/wayland/wayland_panel_agent_module.cpp +++ b/ism/modules/panelagent/wayland/wayland_panel_agent_module.cpp @@ -140,50 +140,6 @@ struct _WSCContextISFImpl { } }; -typedef enum { - INPUT_LANG_URDU, - INPUT_LANG_HINDI, - INPUT_LANG_BENGALI_IN, - INPUT_LANG_BENGALI_BD, - INPUT_LANG_ASSAMESE, - INPUT_LANG_PUNJABI, - INPUT_LANG_NEPALI, - INPUT_LANG_ORIYA, - INPUT_LANG_MAITHILI, - INPUT_LANG_ARMENIAN, - INPUT_LANG_CN, - INPUT_LANG_CN_HK, - INPUT_LANG_CN_TW, - INPUT_LANG_JAPANESE, - INPUT_LANG_KHMER, - INPUT_LANG_BURMESE, - INPUT_LANG_OTHER -} Input_Language; - -struct __Punctuations { - const char *code; - Input_Language lang; - wchar_t punc_code; -}; - -static __Punctuations __punctuations [] = { - { "ur_PK", INPUT_LANG_URDU, 0x06D4 }, - { "hi_IN", INPUT_LANG_HINDI, 0x0964 }, - { "bn_IN", INPUT_LANG_BENGALI_IN, 0x0964 }, - { "bn_BD", INPUT_LANG_BENGALI_BD, 0x0964 }, - { "as_IN", INPUT_LANG_ASSAMESE, 0x0964 }, - { "pa_IN", INPUT_LANG_PUNJABI, 0x0964 }, - { "ne_NP", INPUT_LANG_NEPALI, 0x0964 }, - { "or_IN", INPUT_LANG_ORIYA, 0x0964 }, - { "mai_IN", INPUT_LANG_MAITHILI, 0x0964 }, - { "hy_AM", INPUT_LANG_ARMENIAN, 0x0589 }, - { "zh_CN", INPUT_LANG_CN, 0x3002 }, - { "zh_HK", INPUT_LANG_CN_HK, 0x3002 }, - { "zh_TW", INPUT_LANG_CN_TW, 0x3002 }, - { "ja_JP", INPUT_LANG_JAPANESE, 0x3002 }, - { "km_KH", INPUT_LANG_KHMER, 0x17D4 }, -}; - /* private functions */ static void panel_slot_update_preedit_caret (int context, @@ -246,15 +202,11 @@ static uint32 _active_helper_option static bool _on_the_spot = true; static bool _change_keyboard_mode_by_focus_move = false; static bool _support_hw_keyboard_mode = false; -static double space_key_time = 0.0; -static Eina_Bool autoperiod_allow = EINA_FALSE; static Eina_Bool autocap_allow = EINA_FALSE; static bool _x_key_event_is_valid = false; -static Input_Language input_lang = INPUT_LANG_OTHER; - static Ecore_Timer *_resource_check_timer = NULL; //FIXME: remove this definitions @@ -1020,67 +972,6 @@ check_space_symbol (Eina_Unicode uchar) return check_symbol (uchar, space_symbols, symbol_num); } -static void -autoperiod_insert (WSCContextISF *wsc_ctx) -{ - LOGD (""); - char *plain_str = NULL; - int cursor_pos = 0; - Eina_Unicode *ustr = NULL; - char *fullstop_mark = NULL; - size_t ulen = 0; - - if (autoperiod_allow == EINA_FALSE) - return; - - if (!wsc_ctx) return; - - Ecore_IMF_Input_Panel_Layout layout = wsc_context_input_panel_layout_get (wsc_ctx); - if (layout != ECORE_IMF_INPUT_PANEL_LAYOUT_NORMAL) - return; - - if ((ecore_time_get () - space_key_time) > DOUBLE_SPACE_INTERVAL) - goto done; - - wsc_context_surrounding_get (wsc_ctx, &plain_str, &cursor_pos); - if (!plain_str) goto done; - - // Convert string from UTF-8 to unicode - ustr = eina_unicode_utf8_to_unicode (plain_str, NULL); - if (!ustr) goto done; - - ulen = eina_unicode_strlen (ustr); - - if (cursor_pos < 2 || cursor_pos > (int)ulen) goto done; - - if (check_space_symbol (ustr[cursor_pos-1]) && - !(iswpunct (ustr[cursor_pos-2]) || check_space_symbol (ustr[cursor_pos-2]))) { - wsc_context_delete_surrounding (wsc_ctx, -1, 1); - - if (input_lang == INPUT_LANG_OTHER) { - fullstop_mark = strdup ("."); - } - else { - wchar_t wbuf[2] = {0}; - wbuf[0] = __punctuations[input_lang].punc_code; - - WideString wstr = WideString (wbuf); - fullstop_mark = strdup (utf8_wcstombs (wstr).c_str ()); - } - - wsc_context_commit_string (wsc_ctx, fullstop_mark); - - if (fullstop_mark) { - free (fullstop_mark); - } - } - -done: - if (plain_str) free (plain_str); - if (ustr) free (ustr); - space_key_time = ecore_time_get (); -} - static Eina_Bool analyze_surrounding_text (WSCContextISF *wsc_ctx) { @@ -1228,31 +1119,6 @@ caps_mode_check (WSCContextISF *wsc_ctx, Eina_Bool force, Eina_Bool noti) return uppercase; } -static void -get_input_language () -{ - char *input_lang_str = vconf_get_str (VCONFKEY_ISF_INPUT_LANGUAGE); - if (!input_lang_str) return; - - input_lang = INPUT_LANG_OTHER; - - for (unsigned int i = 0; i < (sizeof (__punctuations) / sizeof (__punctuations[0])); i++) { - if (strcmp (input_lang_str, __punctuations[i].code) == 0) { - input_lang = __punctuations[i].lang; - break; - } - } - - free (input_lang_str); -} - -static void autoperiod_allow_changed_cb (keynode_t *key, void* data) -{ - SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n"; - - autoperiod_allow = vconf_keynode_get_bool (key); -} - static void autocapital_allow_changed_cb (keynode_t *key, void* data) { SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n"; @@ -1260,13 +1126,6 @@ static void autocapital_allow_changed_cb (keynode_t *key, void* data) autocap_allow = vconf_keynode_get_bool (key); } -static void input_language_changed_cb (keynode_t *key, void* data) -{ - SCIM_DEBUG_MAIN (3) << __FUNCTION__ << "...\n"; - - get_input_language (); -} - void context_scim_imdata_get (WSCContextISF *wsc_ctx, void* data, int* length) { WSCContextISF* context_scim = wsc_ctx; @@ -1355,14 +1214,6 @@ isf_wsc_context_init (void) isf_wsc_input_panel_init (); //isf_wsc_context_set_hardware_keyboard_mode(context_scim); - /* get autoperiod allow vconf value */ - if (vconf_get_bool (VCONFKEY_AUTOPERIOD_ALLOW_BOOL, &val) == 0) { - if (val == EINA_TRUE) - autoperiod_allow = EINA_TRUE; - } - - vconf_notify_key_changed (VCONFKEY_AUTOPERIOD_ALLOW_BOOL, autoperiod_allow_changed_cb, NULL); - /* get autocapital allow vconf value */ if (vconf_get_bool (VCONFKEY_AUTOCAPITAL_ALLOW_BOOL, &val) == 0) { if (val == EINA_TRUE) @@ -1370,11 +1221,6 @@ isf_wsc_context_init (void) } vconf_notify_key_changed (VCONFKEY_AUTOCAPITAL_ALLOW_BOOL, autocapital_allow_changed_cb, NULL); - - /* get input language vconf value */ - get_input_language (); - - vconf_notify_key_changed (VCONFKEY_ISF_INPUT_LANGUAGE, input_language_changed_cb, NULL); } } @@ -1387,9 +1233,7 @@ isf_wsc_context_shutdown (void) if (_scim_initialized) { _scim_initialized = false; - vconf_ignore_key_changed (VCONFKEY_AUTOPERIOD_ALLOW_BOOL, autoperiod_allow_changed_cb); vconf_ignore_key_changed (VCONFKEY_AUTOCAPITAL_ALLOW_BOOL, autocapital_allow_changed_cb); - vconf_ignore_key_changed (VCONFKEY_ISF_INPUT_LANGUAGE, input_language_changed_cb); isf_wsc_input_panel_shutdown (); finalize (); @@ -2628,11 +2472,6 @@ panel_slot_process_key_event (int context, const KeyEvent &key) if ((_focused_ic != NULL) && (_focused_ic != ic)) return; - if (key.is_key_press ()) { - if (key.code == SCIM_KEY_space || - key.code == SCIM_KEY_KP_Space) - autoperiod_insert (ic); - } send_wl_key_event (ic, key, false); } @@ -2657,9 +2496,6 @@ panel_slot_commit_string (int context, const WideString &wstr, bool remote_mode) check_input_resource (ic, INPUT_RESOURCE_LOCAL); } - if (utf8_wcstombs (wstr) == String (" ") || utf8_wcstombs (wstr) == String (" ")) - autoperiod_insert (ic); - if (ic->impl->need_commit_preedit) _hide_preedit_string (ic->id, false); wsc_context_commit_string (ic, utf8_wcstombs (wstr).c_str ()); @@ -3392,14 +3228,6 @@ public: WSCContextISF* ic = find_ic (context_id); if (!ic) return; - if (ret == EINA_FALSE) { - if (key.is_key_press ()) { - if (key.code == SCIM_KEY_space || - key.code == SCIM_KEY_KP_Space) { - autoperiod_insert (ic); - } - } - } #if ENABLE_GRAB_KEYBOARD if (ret == EINA_FALSE) { send_wl_key_event (ic, key, false); -- 2.7.4