diff --git a/legacy/ecore/src/lib/ecore_imf/Ecore_IMF.h b/legacy/ecore/src/lib/ecore_imf/Ecore_IMF.h index 8bd29aeb32..adea35d553 100644 --- a/legacy/ecore/src/lib/ecore_imf/Ecore_IMF.h +++ b/legacy/ecore/src/lib/ecore_imf/Ecore_IMF.h @@ -64,6 +64,17 @@ EAPI extern int ECORE_IMF_EVENT_PREEDIT_CHANGED; EAPI extern int ECORE_IMF_EVENT_COMMIT; EAPI extern int ECORE_IMF_EVENT_DELETE_SURROUNDING; +typedef void (*Ecore_IMF_Event_Cb) (void *data, Ecore_IMF_Context *ctx, void *event_info); + +typedef enum +{ + ECORE_IMF_CALLBACK_PREEDIT_START, + ECORE_IMF_CALLBACK_PREEDIT_END, + ECORE_IMF_CALLBACK_PREEDIT_CHANGED, + ECORE_IMF_CALLBACK_COMMIT, + ECORE_IMF_CALLBACK_DELETE_SURROUNDING +} Ecore_IMF_Callback_Type; + typedef enum { ECORE_IMF_EVENT_MOUSE_DOWN, @@ -388,6 +399,9 @@ EAPI void ecore_imf_context_preedit_end_event_add(Ecore EAPI void ecore_imf_context_preedit_changed_event_add(Ecore_IMF_Context *ctx); EAPI void ecore_imf_context_commit_event_add(Ecore_IMF_Context *ctx, const char *str); EAPI void ecore_imf_context_delete_surrounding_event_add(Ecore_IMF_Context *ctx, int offset, int n_chars); +EAPI void ecore_imf_context_event_callback_add(Ecore_IMF_Context *ctx, Ecore_IMF_Callback_Type type, Ecore_IMF_Event_Cb func, const void *data); +EAPI void *ecore_imf_context_event_callback_del(Ecore_IMF_Context *ctx, Ecore_IMF_Callback_Type type, Ecore_IMF_Event_Cb func); +EAPI void ecore_imf_context_event_callback_call(Ecore_IMF_Context *ctx, Ecore_IMF_Callback_Type type, void *event_info); EAPI void ecore_imf_context_prediction_allow_set(Ecore_IMF_Context *ctx, Eina_Bool prediction); EAPI Eina_Bool ecore_imf_context_prediction_allow_get(Ecore_IMF_Context *ctx); EAPI void ecore_imf_context_autocapital_type_set(Ecore_IMF_Context *ctx, Ecore_IMF_Autocapital_Type autocapital_type); diff --git a/legacy/ecore/src/lib/ecore_imf/ecore_imf_context.c b/legacy/ecore/src/lib/ecore_imf/ecore_imf_context.c index a96e701a59..b65ee26352 100644 --- a/legacy/ecore/src/lib/ecore_imf/ecore_imf_context.c +++ b/legacy/ecore/src/lib/ecore_imf/ecore_imf_context.c @@ -223,6 +223,8 @@ ecore_imf_context_info_get(Ecore_IMF_Context *ctx) EAPI void ecore_imf_context_del(Ecore_IMF_Context *ctx) { + Ecore_IMF_Func_Node *fn; + if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) { ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, @@ -230,6 +232,13 @@ ecore_imf_context_del(Ecore_IMF_Context *ctx) return; } if (ctx->klass->del) ctx->klass->del(ctx); + + if (ctx->callbacks) + { + EINA_LIST_FREE(ctx->callbacks, fn) + free(fn); + } + ECORE_MAGIC_SET(ctx, ECORE_MAGIC_NONE); free(ctx); } @@ -1015,6 +1024,134 @@ ecore_imf_context_delete_surrounding_event_add(Ecore_IMF_Context *ctx, int offse ev, _ecore_imf_event_free_delete_surrounding, NULL); } +/** + * Add (register) a callback function to a given context event. + * + * This function adds a function callback to the context @p ctx when the + * event of type @p type occurs on it. The function pointer is @p + * func. + * + * The event type @p type to trigger the function may be one of + * #ECORE_IMF_CALLBACK_PREEDIT_START, #ECORE_IMF_CALLBACK_PREEDIT_END, + * #ECORE_IMF_CALLBACK_PREEDIT_CHANGED, #ECORE_IMF_CALLBACK_COMMIT and + * #ECORE_IMF_CALLBACK_DELETE_SURROUNDING. + * + * @param ctx Ecore_IMF_Context to attach a callback to. + * @param type The type of event that will trigger the callback + * @param func The (callback) function to be called when the event is + * triggered + * @param data The data pointer to be passed to @p func + * @ingroup Ecore_IMF_Context_Module_Group + * @since 1.2.0 + */ +EAPI void +ecore_imf_context_event_callback_add(Ecore_IMF_Context *ctx, Ecore_IMF_Callback_Type type, Ecore_IMF_Event_Cb func, const void *data) +{ + Ecore_IMF_Func_Node *fn = NULL; + + if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) + { + ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, + "ecore_imf_context_event_callback_add"); + return; + } + + if (!func) return; + + fn = calloc(1, sizeof (Ecore_IMF_Func_Node)); + if (!fn) return; + + fn->func = func; + fn->data = data; + fn->type = type; + + ctx->callbacks = eina_list_append(ctx->callbacks, fn); +} + +/** + * Delete (unregister) a callback function registered to a given + * context event. + * + * This function removes a function callback from the context @p ctx when the + * event of type @p type occurs on it. The function pointer is @p + * func. + * + * @see ecore_imf_context_event_callback_add() for more details + * + * @param ctx Ecore_IMF_Context to remove a callback from. + * @param type The type of event that was trigerring the callback + * @param func The (callback) function that was to be called when the event was triggered + * @return the data pointer + * @ingroup Ecore_IMF_Context_Module_Group + * @since 1.2.0 + */ +EAPI void * +ecore_imf_context_event_callback_del(Ecore_IMF_Context *ctx, Ecore_IMF_Callback_Type type, Ecore_IMF_Event_Cb func) +{ + Eina_List *l = NULL; + Eina_List *l_next = NULL; + Ecore_IMF_Func_Node *fn = NULL; + + if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) + { + ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, + "ecore_imf_context_event_callback_del"); + return; + } + + if (!func) return NULL; + if (!ctx->callbacks) return NULL; + + EINA_LIST_FOREACH_SAFE(ctx->callbacks, l, l_next, fn) + { + if ((fn) && (fn->func == func) && (fn->type == type)) + { + void *tmp = fn->data; + free(fn); + ctx->callbacks = eina_list_remove_list(ctx->callbacks, l); + return tmp; + } + } + return NULL; +} + +/** + * Call a given callback on the context @p ctx. + * + * ecore_imf_context_preedit_start_event_add, ecore_imf_context_preedit_end_event_add, + * ecore_imf_context_preedit_changed_event_add, ecore_imf_context_commit_event_add and + * ecore_imf_context_delete_surrounding_event_add APIs are asynchronous + * because those API adds each event to the event queue. + * + * This API provides the way to call each callback function immediately. + * + * @param ctx Ecore_IMF_Context. + * @param type The type of event that will trigger the callback + * @param event_info The pointer to event specific struct or information to + * pass to the callback functions registered on this event + * @ingroup Ecore_IMF_Context_Module_Group + * @since 1.2.0 + */ +EAPI void +ecore_imf_context_event_callback_call(Ecore_IMF_Context *ctx, Ecore_IMF_Callback_Type type, void *event_info) +{ + Ecore_IMF_Func_Node *fn = NULL; + Eina_List *l = NULL; + + if (!ECORE_MAGIC_CHECK(ctx, ECORE_MAGIC_CONTEXT)) + { + ECORE_MAGIC_FAIL(ctx, ECORE_MAGIC_CONTEXT, + "ecore_imf_context_event_callback_call"); + return; + } + + EINA_LIST_FOREACH(ctx->callbacks, l, fn) + { + if ((fn) && (fn->type == type) && (fn->func)) + fn->func(fn->data, ctx, event_info); + } +} + /** * Ask the Input Method Context to show the control panel of using Input Method. * diff --git a/legacy/ecore/src/lib/ecore_imf/ecore_imf_private.h b/legacy/ecore/src/lib/ecore_imf/ecore_imf_private.h index 07a5b0937a..d9dae80339 100644 --- a/legacy/ecore/src/lib/ecore_imf/ecore_imf_private.h +++ b/legacy/ecore/src/lib/ecore_imf/ecore_imf_private.h @@ -35,6 +35,7 @@ extern int _ecore_imf_log_dom; #define CRIT(...) EINA_LOG_DOM_CRIT(_ecore_imf_log_dom, __VA_ARGS__) typedef struct _Ecore_IMF_Module Ecore_IMF_Module; +typedef struct _Ecore_IMF_Func_Node Ecore_IMF_Func_Node; struct _Ecore_IMF_Context { @@ -47,6 +48,7 @@ struct _Ecore_IMF_Context void *client_canvas; Eina_Bool (*retrieve_surrounding_func)(void *data, Ecore_IMF_Context *ctx, char **text, int *cursor_pos); void *retrieve_surrounding_data; + Eina_List *callbacks; Ecore_IMF_Autocapital_Type autocapital_type; Ecore_IMF_Input_Panel_Layout input_panel_layout; Ecore_IMF_Input_Panel_Lang input_panel_lang; @@ -61,6 +63,13 @@ struct _Ecore_IMF_Module Ecore_IMF_Context *(*exit)(void); }; +struct _Ecore_IMF_Func_Node +{ + void (*func) (); + const void *data; + Ecore_IMF_Callback_Type type; +}; + void ecore_imf_module_init(void); void ecore_imf_module_shutdown(void); Eina_List *ecore_imf_module_available_get(void); diff --git a/legacy/ecore/src/modules/immodules/scim/scim_imcontext.cpp b/legacy/ecore/src/modules/immodules/scim/scim_imcontext.cpp index b4edfe4400..6cb72c2954 100644 --- a/legacy/ecore/src/modules/immodules/scim/scim_imcontext.cpp +++ b/legacy/ecore/src/modules/immodules/scim/scim_imcontext.cpp @@ -806,8 +806,10 @@ isf_imf_context_reset (Ecore_IMF_Context *ctx) if (context_scim->impl->need_commit_preedit) { if (wstr.length ()) - ecore_imf_context_commit_event_add (context_scim->ctx, utf8_wcstombs (wstr).c_str ()); - + { + ecore_imf_context_commit_event_add (context_scim->ctx, utf8_wcstombs (wstr).c_str ()); + ecore_imf_context_event_callback_call(context_scim->ctx, ECORE_IMF_CALLBACK_COMMIT, (void *)utf8_wcstombs(wstr).c_str()); + } _panel_client.prepare (context_scim->id); _panel_client.send (); } @@ -951,8 +953,10 @@ isf_imf_context_focus_out (Ecore_IMF_Context *ctx) if (context_scim->impl->need_commit_preedit) { if (wstr.length ()) - ecore_imf_context_commit_event_add (context_scim->ctx, utf8_wcstombs (wstr).c_str ()); - + { + ecore_imf_context_commit_event_add (context_scim->ctx, utf8_wcstombs (wstr).c_str ()); + ecore_imf_context_event_callback_call(context_scim->ctx, ECORE_IMF_CALLBACK_COMMIT, (void *)utf8_wcstombs(wstr).c_str()); + } _panel_client.prepare (context_scim->id); _panel_client.send (); } @@ -1520,6 +1524,7 @@ panel_slot_commit_string (int context, const WideString &wstr) return; ecore_imf_context_commit_event_add (ic->ctx, utf8_wcstombs (wstr).c_str ()); + ecore_imf_context_event_callback_call(ic->ctx, ECORE_IMF_CALLBACK_COMMIT, (void *)utf8_wcstombs(wstr).c_str()); } } @@ -1818,7 +1823,9 @@ turn_on_ic (EcoreIMFContextISF *ic) if (ic->impl->use_preedit && ic->impl->preedit_string.length ()) { ecore_imf_context_preedit_start_event_add (ic->ctx); + ecore_imf_context_event_callback_call(ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_START, NULL); ecore_imf_context_preedit_changed_event_add (ic->ctx); + ecore_imf_context_event_callback_call(ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL); ic->impl->preedit_started = true; } } @@ -1848,7 +1855,9 @@ turn_off_ic (EcoreIMFContextISF *ic) if (ic->impl->use_preedit && ic->impl->preedit_string.length ()) { ecore_imf_context_preedit_changed_event_add (ic->ctx); + ecore_imf_context_event_callback_call(ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL); ecore_imf_context_preedit_end_event_add (ic->ctx); + ecore_imf_context_event_callback_call(ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_END, NULL); ic->impl->preedit_started = false; } } @@ -2183,7 +2192,9 @@ open_specific_factory (EcoreIMFContextISF *ic, if (ic->impl->use_preedit && ic->impl->preedit_string.length ()) { ecore_imf_context_preedit_changed_event_add (ic->ctx); + ecore_imf_context_event_callback_call(ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL); ecore_imf_context_preedit_end_event_add (ic->ctx); + ecore_imf_context_event_callback_call(ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_END, NULL); ic->impl->preedit_started = false; } } @@ -2452,6 +2463,7 @@ slot_show_preedit_string (IMEngineInstanceBase *si) if (!ic->impl->preedit_started) { ecore_imf_context_preedit_start_event_add (_focused_ic->ctx); + ecore_imf_context_event_callback_call(_focused_ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_START, NULL); ic->impl->preedit_started = true; } } @@ -2502,10 +2514,14 @@ slot_hide_preedit_string (IMEngineInstanceBase *si) if (ic->impl->use_preedit) { if (emit) - ecore_imf_context_preedit_changed_event_add (ic->ctx); + { + ecore_imf_context_preedit_changed_event_add (ic->ctx); + ecore_imf_context_event_callback_call(ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL); + } if (ic->impl->preedit_started) { ecore_imf_context_preedit_end_event_add (ic->ctx); + ecore_imf_context_event_callback_call(ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_END, NULL); ic->impl->preedit_started = false; } } @@ -2551,9 +2567,11 @@ slot_update_preedit_caret (IMEngineInstanceBase *si, int caret) if (!ic->impl->preedit_started) { ecore_imf_context_preedit_start_event_add (ic->ctx); + ecore_imf_context_event_callback_call(ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_START, NULL); ic->impl->preedit_started = true; } ecore_imf_context_preedit_changed_event_add (ic->ctx); + ecore_imf_context_event_callback_call(ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL); } else _panel_client.update_preedit_caret (ic->id, caret); @@ -2578,11 +2596,13 @@ slot_update_preedit_string (IMEngineInstanceBase *si, if (!ic->impl->preedit_started) { ecore_imf_context_preedit_start_event_add (_focused_ic->ctx); + ecore_imf_context_event_callback_call(_focused_ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_START, NULL); ic->impl->preedit_started = true; } ic->impl->preedit_caret = str.length (); ic->impl->preedit_updating = true; ecore_imf_context_preedit_changed_event_add (ic->ctx); + ecore_imf_context_event_callback_call(ic->ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL); ic->impl->preedit_updating = false; } else @@ -2614,7 +2634,10 @@ slot_commit_string (IMEngineInstanceBase *si, EcoreIMFContextISF *ic = static_cast (si->get_frontend_data ()); if (ic && ic->ctx) - ecore_imf_context_commit_event_add (ic->ctx, utf8_wcstombs (str).c_str ()); + { + ecore_imf_context_commit_event_add (ic->ctx, utf8_wcstombs (str).c_str ()); + ecore_imf_context_event_callback_call(ic->ctx, ECORE_IMF_CALLBACK_COMMIT, (void *)utf8_wcstombs(str).c_str()); + } } static void @@ -2761,7 +2784,12 @@ slot_delete_surrounding_text (IMEngineInstanceBase *si, if (ic && ic->impl && _focused_ic == ic) { + Ecore_IMF_Event_Delete_Surrounding ev; + ev.ctx = _focused_ic->ctx; + ev.n_chars = len; + ev.offset = offset; ecore_imf_context_delete_surrounding_event_add (_focused_ic->ctx, offset, len); + ecore_imf_context_event_callback_call(_focused_ic->ctx, ECORE_IMF_CALLBACK_DELETE_SURROUNDING, &ev); return true; } return false; @@ -2803,6 +2831,9 @@ fallback_commit_string_cb (IMEngineInstanceBase *si __UNUSED__, SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n"; if (_focused_ic && _focused_ic->impl) - ecore_imf_context_commit_event_add (_focused_ic->ctx, utf8_wcstombs (str).c_str ()); + { + ecore_imf_context_commit_event_add (_focused_ic->ctx, utf8_wcstombs (str).c_str ()); + ecore_imf_context_event_callback_call(_focused_ic->ctx, ECORE_IMF_CALLBACK_COMMIT, (void *)utf8_wcstombs(str).c_str()); + } } diff --git a/legacy/ecore/src/modules/immodules/xim/ecore_imf_xim.c b/legacy/ecore/src/modules/immodules/xim/ecore_imf_xim.c index e81e486124..ea7ee7f47d 100644 --- a/legacy/ecore/src/modules/immodules/xim/ecore_imf_xim.c +++ b/legacy/ecore/src/modules/immodules/xim/ecore_imf_xim.c @@ -389,6 +389,7 @@ _ecore_imf_context_xim_reset(Ecore_IMF_Context *ctx) imf_context_data->preedit_chars = NULL; ecore_imf_context_preedit_changed_event_add(ctx); + ecore_imf_context_event_callback_call(ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL); } if (result) @@ -397,6 +398,7 @@ _ecore_imf_context_xim_reset(Ecore_IMF_Context *ctx) if (result_utf8) { ecore_imf_context_commit_event_add(ctx, result_utf8); + ecore_imf_context_event_callback_call(ctx, ECORE_IMF_CALLBACK_COMMIT, result_utf8); free(result_utf8); } } @@ -707,6 +709,7 @@ _ecore_imf_context_xim_filter_event(Ecore_IMF_Context *ctx, if (unicode[0] >= 0x20 && unicode[0] != 0x7f) { ecore_imf_context_commit_event_add(ctx, compose); + ecore_imf_context_event_callback_call(ctx, ECORE_IMF_CALLBACK_COMMIT, compose); result = EINA_TRUE; } free(compose); @@ -872,8 +875,10 @@ preedit_start_callback(XIC xic __UNUSED__, imf_context_data = ecore_imf_context_data_get(ctx); if (imf_context_data->finalizing == EINA_FALSE) - ecore_imf_context_preedit_start_event_add(ctx); - + { + ecore_imf_context_preedit_start_event_add(ctx); + ecore_imf_context_event_callback_call(ctx, ECORE_IMF_CALLBACK_PREEDIT_START, NULL); + } return -1; } @@ -893,10 +898,14 @@ preedit_done_callback(XIC xic __UNUSED__, free(imf_context_data->preedit_chars); imf_context_data->preedit_chars = NULL; ecore_imf_context_preedit_changed_event_add(ctx); + ecore_imf_context_event_callback_call(ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL); } if (imf_context_data->finalizing == EINA_FALSE) - ecore_imf_context_preedit_end_event_add(ctx); + { + ecore_imf_context_preedit_end_event_add(ctx); + ecore_imf_context_event_callback_call(ctx, ECORE_IMF_CALLBACK_PREEDIT_END, NULL); + } } /* FIXME */ @@ -1023,6 +1032,7 @@ done: } ecore_imf_context_preedit_changed_event_add(ctx); + ecore_imf_context_event_callback_call(ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL); } free(new_text); @@ -1044,7 +1054,10 @@ preedit_caret_callback(XIC xic __UNUSED__, // printf("call_data->position:%d\n", call_data->position); imf_context_data->preedit_cursor = call_data->position; if (imf_context_data->finalizing == EINA_FALSE) - ecore_imf_context_preedit_changed_event_add(ctx); + { + ecore_imf_context_preedit_changed_event_add(ctx); + ecore_imf_context_event_callback_call(ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL); + } } } @@ -1210,6 +1223,7 @@ reinitialize_ic(Ecore_IMF_Context *ctx) free(imf_context_data->preedit_chars); imf_context_data->preedit_chars = NULL; ecore_imf_context_preedit_changed_event_add(ctx); + ecore_imf_context_event_callback_call(ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL); } } } diff --git a/legacy/edje/src/lib/edje_entry.c b/legacy/edje/src/lib/edje_entry.c index e48fc7a856..b7254e9b60 100644 --- a/legacy/edje/src/lib/edje_entry.c +++ b/legacy/edje/src/lib/edje_entry.c @@ -2,9 +2,9 @@ #ifdef HAVE_ECORE_IMF static Eina_Bool _edje_entry_imf_retrieve_surrounding_cb(void *data, Ecore_IMF_Context *ctx, char **text, int *cursor_pos); -static Eina_Bool _edje_entry_imf_event_commit_cb(void *data, int type, void *event); -static Eina_Bool _edje_entry_imf_event_preedit_changed_cb(void *data, int type, void *event); -static Eina_Bool _edje_entry_imf_event_delete_surrounding_cb(void *data, int type, void *event); +static void _edje_entry_imf_event_commit_cb(void *data, Ecore_IMF_Context *ctx, void *event_info); +static void _edje_entry_imf_event_preedit_changed_cb(void *data, Ecore_IMF_Context *ctx, void *event_info); +static void _edje_entry_imf_event_delete_surrounding_cb(void *data, Ecore_IMF_Context *ctx, void *event); #endif typedef struct _Entry Entry; @@ -39,10 +39,6 @@ struct _Entry #ifdef HAVE_ECORE_IMF Eina_Bool have_preedit : 1; Ecore_IMF_Context *imf_context; - - Ecore_Event_Handler *imf_ee_handler_commit; - Ecore_Event_Handler *imf_ee_handler_delete; - Ecore_Event_Handler *imf_ee_handler_changed; #endif }; @@ -401,6 +397,7 @@ static void _sel_extend(Evas_Textblock_Cursor *c, Evas_Object *o, Entry *en) { if (!en->sel_end) return; + _edje_entry_imf_context_reset(en); _sel_enable(c, o, en); if (!evas_textblock_cursor_compare(c, en->sel_end)) return; evas_textblock_cursor_copy(c, en->sel_end); @@ -410,13 +407,13 @@ _sel_extend(Evas_Textblock_Cursor *c, Evas_Object *o, Entry *en) en->selection = NULL; } _edje_emit(en->rp->edje, "selection,changed", en->rp->part->name); - _edje_entry_imf_context_reset(en); } static void _sel_preextend(Evas_Textblock_Cursor *c, Evas_Object *o, Entry *en) { if (!en->sel_end) return; + _edje_entry_imf_context_reset(en); _sel_enable(c, o, en); if (!evas_textblock_cursor_compare(c, en->sel_start)) return; evas_textblock_cursor_copy(c, en->sel_start); @@ -426,7 +423,6 @@ _sel_preextend(Evas_Textblock_Cursor *c, Evas_Object *o, Entry *en) en->selection = NULL; } _edje_emit(en->rp->edje, "selection,changed", en->rp->part->name); - _edje_entry_imf_context_reset(en); } static void @@ -1093,6 +1089,10 @@ _edje_key_down_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, v } #endif + if ((!strcmp(ev->key, "Escape")) || + (!strcmp(ev->key, "Return")) || (!strcmp(ev->key, "KP_Enter"))) + _edje_entry_imf_context_reset(en); + old_cur_pos = evas_textblock_cursor_pos_get(en->cursor); control = evas_key_modifier_is_set(ev->modifiers, "Control"); @@ -1291,10 +1291,6 @@ _edje_key_down_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, v _edje_emit(ed, "entry,key,end", rp->part->name); ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD; } - else if (!strcmp(ev->key, "Shift_L") || !strcmp(ev->key, "Shift_R")) - { - return; - } else if ((control) && (!strcmp(ev->key, "v"))) { _edje_emit(ed, "entry,paste,request", rp->part->name); @@ -1508,7 +1504,6 @@ _edje_key_down_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, v if (!cursor_changed && (old_cur_pos != evas_textblock_cursor_pos_get(en->cursor))) _edje_emit(ed, "cursor,changed", rp->part->name); - _edje_entry_imf_context_reset(en); _edje_entry_imf_cursor_info_set(en); _edje_entry_real_part_configure(rp); } @@ -1585,6 +1580,8 @@ _edje_part_mouse_down_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUS } #endif + _edje_entry_imf_context_reset(en); + en->select_mod_start = EINA_FALSE; en->select_mod_end = EINA_FALSE; if (rp->part->select_mode == EDJE_ENTRY_SELECTION_MODE_DEFAULT) @@ -1705,7 +1702,6 @@ _edje_part_mouse_down_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUS } evas_textblock_cursor_free(tc); - _edje_entry_imf_context_reset(en); _edje_entry_imf_cursor_info_set(en); _edje_entry_real_part_configure(rp); @@ -1745,6 +1741,8 @@ _edje_part_mouse_up_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED } #endif + _edje_entry_imf_context_reset(en); + tc = evas_object_textblock_cursor_new(rp->object); evas_textblock_cursor_copy(en->cursor, tc); evas_object_geometry_get(rp->object, &x, &y, &w, &h); @@ -1817,7 +1815,6 @@ _edje_part_mouse_up_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED } evas_textblock_cursor_free(tc); - _edje_entry_imf_context_reset(en); _edje_entry_imf_cursor_info_set(en); _edje_entry_real_part_configure(rp); } @@ -2075,9 +2072,9 @@ _edje_entry_real_part_init(Edje_Real_Part *rp) ecore_imf_context_retrieve_surrounding_callback_set(en->imf_context, _edje_entry_imf_retrieve_surrounding_cb, rp->edje); - en->imf_ee_handler_commit = ecore_event_handler_add(ECORE_IMF_EVENT_COMMIT, _edje_entry_imf_event_commit_cb, rp->edje); - en->imf_ee_handler_delete = ecore_event_handler_add(ECORE_IMF_EVENT_DELETE_SURROUNDING, _edje_entry_imf_event_delete_surrounding_cb, rp->edje); - en->imf_ee_handler_changed = ecore_event_handler_add(ECORE_IMF_EVENT_PREEDIT_CHANGED, _edje_entry_imf_event_preedit_changed_cb, rp->edje); + ecore_imf_context_event_callback_add(en->imf_context, ECORE_IMF_CALLBACK_COMMIT, _edje_entry_imf_event_commit_cb, rp->edje); + ecore_imf_context_event_callback_add(en->imf_context, ECORE_IMF_CALLBACK_DELETE_SURROUNDING, _edje_entry_imf_event_delete_surrounding_cb, rp->edje); + ecore_imf_context_event_callback_add(en->imf_context, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, _edje_entry_imf_event_preedit_changed_cb, rp->edje); ecore_imf_context_input_mode_set(en->imf_context, rp->part->entry_mode == EDJE_ENTRY_EDIT_MODE_PASSWORD ? ECORE_IMF_INPUT_MODE_INVISIBLE : ECORE_IMF_INPUT_MODE_FULL); @@ -2114,23 +2111,9 @@ _edje_entry_real_part_shutdown(Edje_Real_Part *rp) { if (en->imf_context) { - if (en->imf_ee_handler_commit) - { - ecore_event_handler_del(en->imf_ee_handler_commit); - en->imf_ee_handler_commit = NULL; - } - - if (en->imf_ee_handler_delete) - { - ecore_event_handler_del(en->imf_ee_handler_delete); - en->imf_ee_handler_delete = NULL; - } - - if (en->imf_ee_handler_changed) - { - ecore_event_handler_del(en->imf_ee_handler_changed); - en->imf_ee_handler_changed = NULL; - } + ecore_imf_context_event_callback_del(en->imf_context, ECORE_IMF_CALLBACK_COMMIT, _edje_entry_imf_event_commit_cb); + ecore_imf_context_event_callback_del(en->imf_context, ECORE_IMF_CALLBACK_DELETE_SURROUNDING, _edje_entry_imf_event_delete_surrounding_cb); + ecore_imf_context_event_callback_del(en->imf_context, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, _edje_entry_imf_event_preedit_changed_cb); ecore_imf_context_del(en->imf_context); en->imf_context = NULL; @@ -2209,7 +2192,7 @@ _edje_entry_text_markup_set(Edje_Real_Part *rp, const char *text) { Entry *en = rp->entry_data; if (!en) return; - + _edje_entry_imf_context_reset(en); // set text as markup _sel_clear(en->cursor, rp->object, en); evas_object_textblock_text_markup_set(rp->object, text); @@ -2248,6 +2231,8 @@ _edje_entry_text_markup_insert(Edje_Real_Part *rp, const char *text) { Entry *en = rp->entry_data; if (!en) return; + _edje_entry_imf_context_reset(en); + // prepend markup @ cursor pos if (en->have_selection) _range_del(en->cursor, rp->object, en); @@ -2259,9 +2244,7 @@ _edje_entry_text_markup_insert(Edje_Real_Part *rp, const char *text) _edje_emit(rp->edje, "entry,changed", rp->part->name); _edje_emit(rp->edje, "cursor,changed", rp->part->name); - _edje_entry_imf_context_reset(en); _edje_entry_imf_cursor_info_set(en); - _edje_entry_real_part_configure(rp); } @@ -2298,6 +2281,9 @@ _edje_entry_select_all(Edje_Real_Part *rp) { Entry *en = rp->entry_data; if (!en) return; + + _edje_entry_imf_context_reset(en); + _sel_clear(en->cursor, rp->object, en); _curs_start(en->cursor, rp->object, en); _sel_enable(en->cursor, rp->object, en); @@ -2305,7 +2291,6 @@ _edje_entry_select_all(Edje_Real_Part *rp) _curs_end(en->cursor, rp->object, en); _sel_extend(en->cursor, rp->object, en); - _edje_entry_imf_context_reset(en); _edje_entry_imf_cursor_info_set(en); _edje_entry_real_part_configure(rp); } @@ -2315,12 +2300,14 @@ _edje_entry_select_begin(Edje_Real_Part *rp) { Entry *en = rp->entry_data; if (!en) return; + + _edje_entry_imf_context_reset(en); + _sel_clear(en->cursor, rp->object, en); _sel_enable(en->cursor, rp->object, en); _sel_start(en->cursor, rp->object, en); _sel_extend(en->cursor, rp->object, en); - _edje_entry_imf_context_reset(en); _edje_entry_imf_cursor_info_set(en); _edje_entry_real_part_configure(rp); @@ -2331,9 +2318,9 @@ _edje_entry_select_extend(Edje_Real_Part *rp) { Entry *en = rp->entry_data; if (!en) return; + _edje_entry_imf_context_reset(en); _sel_extend(en->cursor, rp->object, en); - _edje_entry_imf_context_reset(en); _edje_entry_imf_cursor_info_set(en); _edje_entry_real_part_configure(rp); @@ -2580,13 +2567,14 @@ _edje_entry_cursor_next(Edje_Real_Part *rp, Edje_Cursor cur) Entry *en = rp->entry_data; Evas_Textblock_Cursor *c = _cursor_get(rp, cur); if (!c) return EINA_FALSE; + + _edje_entry_imf_context_reset(en); + if (!evas_textblock_cursor_char_next(c)) { return EINA_FALSE; } _sel_update(c, rp->object, rp->entry_data); - - _edje_entry_imf_context_reset(en); _edje_entry_imf_cursor_info_set(en); _edje_emit(rp->edje, "cursor,changed", rp->part->name); @@ -2600,6 +2588,9 @@ _edje_entry_cursor_prev(Edje_Real_Part *rp, Edje_Cursor cur) Entry *en = rp->entry_data; Evas_Textblock_Cursor *c = _cursor_get(rp, cur); if (!c) return EINA_FALSE; + + _edje_entry_imf_context_reset(en); + if (!evas_textblock_cursor_char_prev(c)) { if (evas_textblock_cursor_paragraph_prev(c)) goto ok; @@ -2608,7 +2599,6 @@ _edje_entry_cursor_prev(Edje_Real_Part *rp, Edje_Cursor cur) ok: _sel_update(c, rp->object, rp->entry_data); - _edje_entry_imf_context_reset(en); _edje_entry_imf_cursor_info_set(en); _edje_emit(rp->edje, "cursor,changed", rp->part->name); @@ -2624,6 +2614,9 @@ _edje_entry_cursor_up(Edje_Real_Part *rp, Edje_Cursor cur) Evas_Coord lx, ly, lw, lh, cx, cy, cw, ch; int ln; if (!c) return EINA_FALSE; + + _edje_entry_imf_context_reset(en); + ln = evas_textblock_cursor_line_geometry_get(c, NULL, NULL, NULL, NULL); ln--; if (ln < 0) return EINA_FALSE; @@ -2640,7 +2633,6 @@ _edje_entry_cursor_up(Edje_Real_Part *rp, Edje_Cursor cur) } _sel_update(c, rp->object, rp->entry_data); - _edje_entry_imf_context_reset(en); _edje_entry_imf_cursor_info_set(en); _edje_emit(rp->edje, "cursor,changed", rp->part->name); @@ -2656,6 +2648,9 @@ _edje_entry_cursor_down(Edje_Real_Part *rp, Edje_Cursor cur) Evas_Coord lx, ly, lw, lh, cx, cy, cw, ch; int ln; if (!c) return EINA_FALSE; + + _edje_entry_imf_context_reset(en); + ln = evas_textblock_cursor_line_geometry_get(c, NULL, NULL, NULL, NULL); ln++; if (!evas_object_textblock_line_number_geometry_get(rp->object, ln, @@ -2671,7 +2666,6 @@ _edje_entry_cursor_down(Edje_Real_Part *rp, Edje_Cursor cur) } _sel_update(c, rp->object, rp->entry_data); - _edje_entry_imf_context_reset(en); _edje_entry_imf_cursor_info_set(en); _edje_emit(rp->edje, "cursor,changed", rp->part->name); _edje_entry_real_part_configure(rp); @@ -2684,10 +2678,12 @@ _edje_entry_cursor_begin(Edje_Real_Part *rp, Edje_Cursor cur) Entry *en = rp->entry_data; Evas_Textblock_Cursor *c = _cursor_get(rp, cur); if (!c) return; + + _edje_entry_imf_context_reset(en); + evas_textblock_cursor_paragraph_first(c); _sel_update(c, rp->object, rp->entry_data); - _edje_entry_imf_context_reset(en); _edje_entry_imf_cursor_info_set(en); _edje_emit(rp->edje, "cursor,changed", rp->part->name); _edje_entry_real_part_configure(rp); @@ -2699,10 +2695,12 @@ _edje_entry_cursor_end(Edje_Real_Part *rp, Edje_Cursor cur) Entry *en = rp->entry_data; Evas_Textblock_Cursor *c = _cursor_get(rp, cur); if (!c) return; + + _edje_entry_imf_context_reset(en); + _curs_end(c, rp->object, rp->entry_data); _sel_update(c, rp->object, rp->entry_data); - _edje_entry_imf_context_reset(en); _edje_entry_imf_cursor_info_set(en); _edje_emit(rp->edje, "cursor,changed", rp->part->name); @@ -2735,10 +2733,11 @@ _edje_entry_cursor_line_begin(Edje_Real_Part *rp, Edje_Cursor cur) Entry *en = rp->entry_data; Evas_Textblock_Cursor *c = _cursor_get(rp, cur); if (!c) return; + _edje_entry_imf_context_reset(en); + evas_textblock_cursor_line_char_first(c); _sel_update(c, rp->object, rp->entry_data); - _edje_entry_imf_context_reset(en); _edje_entry_imf_cursor_info_set(en); _edje_emit(rp->edje, "cursor,changed", rp->part->name); @@ -2751,10 +2750,10 @@ _edje_entry_cursor_line_end(Edje_Real_Part *rp, Edje_Cursor cur) Entry *en = rp->entry_data; Evas_Textblock_Cursor *c = _cursor_get(rp, cur); if (!c) return; + _edje_entry_imf_context_reset(en); evas_textblock_cursor_line_char_last(c); _sel_update(c, rp->object, rp->entry_data); - _edje_entry_imf_context_reset(en); _edje_entry_imf_cursor_info_set(en); _edje_emit(rp->edje, "cursor,changed", rp->part->name); _edje_entry_real_part_configure(rp); @@ -2813,10 +2812,10 @@ _edje_entry_cursor_pos_set(Edje_Real_Part *rp, Edje_Cursor cur, int pos) if (evas_textblock_cursor_pos_get(c) == pos) return; + _edje_entry_imf_context_reset(en); evas_textblock_cursor_pos_set(c, pos); _sel_update(c, rp->object, rp->entry_data); - _edje_entry_imf_context_reset(en); _edje_entry_imf_cursor_info_set(en); _edje_emit(rp->edje, "cursor,changed", rp->part->name); _edje_entry_real_part_configure(rp); @@ -2911,30 +2910,25 @@ _edje_entry_imf_retrieve_surrounding_cb(void *data, Ecore_IMF_Context *ctx __UNU return EINA_TRUE; } -static Eina_Bool -_edje_entry_imf_event_commit_cb(void *data, int type __UNUSED__, void *event) +static void +_edje_entry_imf_event_commit_cb(void *data, Ecore_IMF_Context *ctx, void *event_info) { Edje *ed = data; Edje_Real_Part *rp = ed->focused_part; Entry *en; - Ecore_IMF_Event_Commit *ev = event; - Evas_Textblock_Cursor *tc; - Eina_Bool cursor_move = EINA_FALSE; + char *commit_str = event_info; int start_pos; - if ((!rp) || (!ev) || (!ev->str)) return ECORE_CALLBACK_PASS_ON; + if ((!rp)) return; en = rp->entry_data; if ((!en) || (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK) || (rp->part->entry_mode < EDJE_ENTRY_EDIT_MODE_SELECTABLE)) - return ECORE_CALLBACK_PASS_ON; - - if (!en->imf_context) return ECORE_CALLBACK_PASS_ON; - if (en->imf_context != ev->ctx) return ECORE_CALLBACK_PASS_ON; + return; if (en->have_selection) { - if (strcmp(ev->str, "")) + if (strcmp(commit_str, "")) { /* delete selected characters */ _range_del_emit(ed, en->cursor, rp->object, en); @@ -2942,16 +2936,7 @@ _edje_entry_imf_event_commit_cb(void *data, int type __UNUSED__, void *event) } } - tc = evas_object_textblock_cursor_new(rp->object); - - /* calculate the cursor position to insert commit string */ - if (en->preedit_start) - evas_textblock_cursor_copy(en->preedit_start, tc); - else - evas_textblock_cursor_copy(en->cursor, tc); - - start_pos = evas_textblock_cursor_pos_get(tc); - + start_pos = evas_textblock_cursor_pos_get(en->cursor); #ifdef HAVE_ECORE_IMF /* delete preedit characters */ @@ -2959,17 +2944,16 @@ _edje_entry_imf_event_commit_cb(void *data, int type __UNUSED__, void *event) _preedit_clear(en); #endif - if (evas_textblock_cursor_compare(en->cursor, tc)) - cursor_move = EINA_TRUE; if ((rp->part->entry_mode == EDJE_ENTRY_EDIT_MODE_PASSWORD) && _edje_password_show_last) _edje_entry_hide_visible_password(en->rp); if ((rp->part->entry_mode == EDJE_ENTRY_EDIT_MODE_PASSWORD) && _edje_password_show_last && (!en->preedit_start)) { - _text_filter_format_prepend(en, tc, "+ password=off"); - _text_filter_text_prepend(en, tc, ev->str); - _text_filter_format_prepend(en, tc, "- password"); + _text_filter_format_prepend(en, en->cursor, "+ password=off"); + _text_filter_text_prepend(en, en->cursor, commit_str); + _text_filter_format_prepend(en, en->cursor, "- password"); + if (en->pw_timer) { ecore_timer_del(en->pw_timer); @@ -2979,15 +2963,8 @@ _edje_entry_imf_event_commit_cb(void *data, int type __UNUSED__, void *event) _password_timer_cb, en); } else - _text_filter_text_prepend(en, tc, ev->str); + _text_filter_text_prepend(en, en->cursor, commit_str); - if (!cursor_move) - { - /* move cursor to the end of commit string */ - evas_textblock_cursor_copy(tc, en->cursor); - } - - evas_textblock_cursor_free(tc); _edje_entry_imf_cursor_info_set(en); _anchors_get(en->cursor, rp->object, en); @@ -2997,24 +2974,22 @@ _edje_entry_imf_event_commit_cb(void *data, int type __UNUSED__, void *event) Edje_Entry_Change_Info *info = calloc(1, sizeof(*info)); info->insert = EINA_TRUE; info->change.insert.pos = start_pos; - info->change.insert.content = eina_stringshare_add(ev->str); + info->change.insert.content = eina_stringshare_add(commit_str); info->change.insert.plain_length = eina_unicode_utf8_get_len(info->change.insert.content); _edje_emit_full(ed, "entry,changed,user", rp->part->name, info, _free_entry_change_info); _edje_emit(ed, "cursor,changed", rp->part->name); } - - return ECORE_CALLBACK_DONE; } -static Eina_Bool -_edje_entry_imf_event_preedit_changed_cb(void *data, int type __UNUSED__, void *event) +static void +_edje_entry_imf_event_preedit_changed_cb(void *data, Ecore_IMF_Context *ctx, void *event_info) { Edje *ed = data; Edje_Real_Part *rp = ed->focused_part; Entry *en; - Ecore_IMF_Event_Preedit_Changed *ev = event; + char *str = event_info; int cursor_pos; int preedit_start_pos, preedit_end_pos; char *preedit_string; @@ -3024,21 +2999,19 @@ _edje_entry_imf_event_preedit_changed_cb(void *data, int type __UNUSED__, void * Ecore_IMF_Preedit_Attr *attr; Eina_Strbuf *buf; - if ((!rp) || (!ev)) return ECORE_CALLBACK_PASS_ON; + if ((!rp)) return; en = rp->entry_data; if ((!en) || (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK) || (rp->part->entry_mode < EDJE_ENTRY_EDIT_MODE_SELECTABLE)) - return ECORE_CALLBACK_PASS_ON; + return; - if (!en->imf_context) return ECORE_CALLBACK_PASS_ON; - - if (en->imf_context != ev->ctx) return ECORE_CALLBACK_PASS_ON; + if (!en->imf_context) return; 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 (!preedit_string) return; if (!strcmp(preedit_string, "")) preedit_end_state = EINA_TRUE; @@ -3140,28 +3113,23 @@ _edje_entry_imf_event_preedit_changed_cb(void *data, int type __UNUSED__, void * } free(preedit_string); - - return ECORE_CALLBACK_DONE; } -static Eina_Bool -_edje_entry_imf_event_delete_surrounding_cb(void *data, int type __UNUSED__, void *event) +static void +_edje_entry_imf_event_delete_surrounding_cb(void *data, Ecore_IMF_Context *ctx, void *event_info) { Edje *ed = data; Edje_Real_Part *rp = ed->focused_part; Entry *en; - Ecore_IMF_Event_Delete_Surrounding *ev = event; + Ecore_IMF_Event_Delete_Surrounding *ev = event_info; Evas_Textblock_Cursor *del_start, *del_end; int cursor_pos; - if ((!rp) || (!ev)) return ECORE_CALLBACK_PASS_ON; + if ((!rp) || (!ev)) return; en = rp->entry_data; if ((!en) || (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK) || (rp->part->entry_mode < EDJE_ENTRY_EDIT_MODE_SELECTABLE)) - return ECORE_CALLBACK_PASS_ON; - - if (!en->imf_context) return ECORE_CALLBACK_PASS_ON; - if (en->imf_context != ev->ctx) return ECORE_CALLBACK_PASS_ON; + return; cursor_pos = evas_textblock_cursor_pos_get(en->cursor); @@ -3175,8 +3143,6 @@ _edje_entry_imf_event_delete_surrounding_cb(void *data, int type __UNUSED__, voi evas_textblock_cursor_free(del_start); evas_textblock_cursor_free(del_end); - - return ECORE_CALLBACK_DONE; } #endif