From: Jihoon Kim <imfine98@gmail.com>

Long time ago, in
http://www.mail-archive.com/enlightenment-devel@lists.sourceforge.net/msg32795.html
mail thread and IRC,

I talked with about problem of asynchronous event API such as
ecore_imf_context_commit_event_add,
ecore_imf_context_preedit_changed_event_add, so on.

In short, The problem is that key event and text_set APIs are processed
immediately, but commit event and preedit changed event is processed
asynchronously  because those APIs add each event to ecore event queue.

To fix these problems, I've decided to create synchronous event APIs such
as ecore_imf_context_event_callback_add, del and call.

For considering compatibility, sync and async event callback functions are
used in xim and scim immodule.



SVN revision: 67290
This commit is contained in:
Jihoon Kim 2012-01-18 04:38:04 +00:00 committed by Carsten Haitzler
parent 537bc81acb
commit c652e4e78a
6 changed files with 292 additions and 121 deletions

View File

@ -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);

View File

@ -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.
*

View File

@ -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);

View File

@ -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<EcoreIMFContextISF *> (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());
}
}

View File

@ -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);
}
}
}

View File

@ -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