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,
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);
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,
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);
}
}
/**
+ * 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.
*
* @param ctx An #Ecore_IMF_Context.
#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
{
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;
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);
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 ();
}
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 ();
}
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());
}
}
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;
}
}
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;
}
}
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;
}
}
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;
}
}
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;
}
}
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);
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
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
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;
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());
+ }
}
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)
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);
}
}
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);
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;
}
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 */
}
ecore_imf_context_preedit_changed_event_add(ctx);
+ ecore_imf_context_event_callback_call(ctx, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, NULL);
}
free(new_text);
// 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);
+ }
}
}
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);
}
}
}