This example demonstrates how to connect input method framework and handle preedit and commit string from input method framework.
To input Chinese, Japanese, Korean and other complex languages, the editor should be connected with input method framework.
Each entry should have each input context to connect with input service framework. Key event is processed by input method engine. The result is notified to application through ECORE_IMF_CALLBACK_PREEDIT_CHANGED and ECORE_IMF_CALLBACK_COMMIT event.
The full example follows.
#include <Ecore.h>
#include <Ecore_IMF.h>
#include <Ecore_IMF_Evas.h>
#include <Evas.h>
#include <stdio.h>
#define WIDTH 480
#define HEIGHT 800
typedef struct _Entry Entry;
struct _Entry
{
};
static void _imf_cursor_info_set(Entry *en);
static void
{
Entry *en = data;
if (!en) return;
if (en->imf_context)
{
return;
}
}
static void
_mouse_up_cb(
void *data,
Evas *e EINA_UNUSED,
Evas_Object *o EINA_UNUSED,
void *event_info)
{
Entry *en = data;
if (!en) return;
{
_imf_cursor_info_set(en);
return;
}
if (en->imf_context)
{
return;
}
if (en->rect)
{
{
_imf_cursor_info_set(en);
}
else
}
}
static void
_entry_focus_in_cb(
void *data,
Evas *e EINA_UNUSED,
Evas_Object *o EINA_UNUSED,
void *event_info EINA_UNUSED)
{
Entry *en = data;
if (!en) return;
if (en->imf_context)
_imf_cursor_info_set(en);
}
static void
_entry_focus_out_cb(
void *data,
Evas *e EINA_UNUSED,
Evas_Object *o EINA_UNUSED,
void *event_info EINA_UNUSED)
{
Entry *en = data;
if (!en) return;
if (en->imf_context)
{
}
}
static void
_canvas_focus_in_cb(
void *data EINA_UNUSED,
Evas *e,
void *event_info EINA_UNUSED)
{
Entry *en;
if (!obj) return;
if (en)
_entry_focus_in_cb(en, NULL, NULL, NULL);
}
static void
_canvas_focus_out_cb(
void *data EINA_UNUSED,
Evas *e,
void *event_info EINA_UNUSED)
{
Entry *en;
if (!obj) return;
if (en)
_entry_focus_out_cb(en, NULL, NULL, NULL);
}
static void
_imf_cursor_info_set(Entry *en)
{
int cursor_pos;
Evas_BiDi_Direction dir;
if (!en) return;
if (en->txt_obj)
if (en->cursor && en->imf_context)
{
}
}
static void
_preedit_del(Entry *en)
{
if (!en || !en->have_preedit) return;
if (!en->preedit_start || !en->preedit_end) return;
}
static void
_preedit_clear(Entry *en)
{
if (en->preedit_start)
{
en->preedit_start = NULL;
}
if (en->preedit_end)
{
en->preedit_end = NULL;
}
}
_ecore_imf_retrieve_surrounding_cb(
void *data,
Ecore_IMF_Context *ctx EINA_UNUSED,
char **text,
int *cursor_pos)
{
Entry *en = data;
const char *str;
if (text)
*text = str ? strdup(str) : strdup("");
if (cursor_pos && en->cursor)
}
static void
_ecore_imf_event_delete_surrounding_cb(
void *data,
Ecore_IMF_Context *ctx EINA_UNUSED,
void *event_info)
{
Entry *en = data;
int cursor_pos;
if ((!en) || (!ev) || (!en->cursor)) return;
}
static void
_ecore_imf_event_commit_cb(
void *data,
Ecore_IMF_Context *ctx EINA_UNUSED,
void *event_info)
{
Entry *en = data;
char *commit_str = (char *)event_info;
if (!en) return;
_preedit_del(en);
_preedit_clear(en);
printf("commit string : %s\n", commit_str);
if (en->cursor && commit_str)
_imf_cursor_info_set(en);
return;
}
static void
_ecore_imf_event_preedit_changed_cb(
void *data,
Ecore_IMF_Context *ctx,
void *event_info EINA_UNUSED)
{
Entry *en = data;
char *preedit_string;
int cursor_pos;
int preedit_start_pos, preedit_end_pos;
int i;
if (!en || !en->cursor) return;
printf("preedit string : %s\n", preedit_string);
if (!strcmp(preedit_string, ""))
_preedit_del(en);
if (strlen(preedit_string) > 0)
{
if (attrs)
{
{
{
}
{
}
}
}
}
if (!preedit_end_state)
{
if (!en->preedit_start)
if (!en->preedit_end)
for (i = 0; i < (preedit_end_pos - preedit_start_pos); i++)
{
}
}
_imf_cursor_info_set(en);
free(attr);
free(preedit_string);
}
static void
_key_down_cb(
void *data,
Evas *e EINA_UNUSED,
Evas_Object *o EINA_UNUSED,
void *event_info)
{
Entry *en = data;
if ((!en) || (!ev->
key) || (!en->cursor))
return;
if (en->imf_context)
{
return;
}
(void)alt;
(void)shift;
if (!strcmp(ev->
key,
"BackSpace"))
{
{
_imf_cursor_info_set(en);
}
return;
}
else if (!strcmp(ev->
key,
"Delete") ||
(!strcmp(ev->
key,
"KP_Delete") && !ev->
string))
{
}
else if ((control) && (!strcmp(ev->
key,
"v")))
{
}
else if ((control) && (!strcmp(ev->
key,
"a")))
{
}
else if ((control) && (!strcmp(ev->
key,
"A")))
{
}
else if ((control) && ((!strcmp(ev->
key,
"c") || (!strcmp(ev->
key,
"Insert")))))
{
}
else if ((control) && ((!strcmp(ev->
key,
"x") || (!strcmp(ev->
key,
"m")))))
{
}
else if ((control) && (!strcmp(ev->
key,
"z")))
{
}
else if ((control) && (!strcmp(ev->
key,
"y")))
{
}
else if ((!strcmp(ev->
key,
"Return")) || (!strcmp(ev->
key,
"KP_Enter")))
{
}
else
{
{
printf(
"key down string : %s\n", ev->
string);
}
}
_imf_cursor_info_set(en);
}
static void
_key_up_cb(
void *data,
Evas *e EINA_UNUSED,
Evas_Object *o EINA_UNUSED,
void *event_info)
{
Entry *en = data;
if (!en) return;
if (en->imf_context)
{
return;
}
}
static void
{
if (!en) return;
en->preedit_start = NULL;
en->preedit_end = NULL;
static const char *style_buf =
"DEFAULT='font=Sans font_size=30 color=#000 text_class=entry'"
"newline='br'"
"b='+ font=Sans:style=bold'";
if (!default_id)
{
fprintf(stderr, "Can't create ecore_imf_context\n");
return;
}
}
static void
delete_input_field(Entry *en)
{
if (!en) return;
if (en->rect)
{
en->rect = NULL;
}
if (en->cursor)
{
en->cursor = NULL;
}
if (en->preedit_start)
{
en->preedit_start = NULL;
}
if (en->preedit_end)
{
en->preedit_end = NULL;
}
if (en->txt_obj)
{
en->txt_obj = NULL;
}
if (en->txt_style)
{
en->txt_style = NULL;
}
if (en->imf_context)
{
en->imf_context = NULL;
}
}
int
main(void)
{
Ecore_Evas *ee;
Entry en1, en2;
{
fprintf(stderr, "failed to call ecore_evas_init()\n");
return EXIT_FAILURE;
}
if (!ee)
{
fprintf(stderr, "failed to call ecore_evas_new\n");
return EXIT_FAILURE;
}
if (!evas)
{
fprintf(stderr, "failed to call ecore_evas_get\n");
return EXIT_FAILURE;
}
memset(&en1, 0, sizeof(en1));
memset(&en2, 0, sizeof(en2));
create_input_field(evas, &en1, 40, 60, 400, 80);
create_input_field(evas, &en2, 40, 180, 400, 80);
delete_input_field(&en1);
delete_input_field(&en2);
return 0;
}