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
{
Evas_Textblock_Style *txt_style;
Evas_Textblock_Cursor *cursor;
Evas_Textblock_Cursor *preedit_start;
Evas_Textblock_Cursor *preedit_end;
};
static void _imf_cursor_info_set(Entry *en);
static void
{
Entry *en = data;
if (!en) return;
if (en->imf_context)
{
return;
}
}
static void
{
Entry *en = data;
if (!en) return;
{
_imf_cursor_info_set(en);
return;
}
if (en->imf_context)
{
return;
}
{
_imf_cursor_info_set(en);
}
else
}
static void
_entry_focus_in_cb(
void *data,
Evas *e,
Evas_Object *obj,
void *event_info)
{
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,
Evas_Object *obj,
void *event_info)
{
Entry *en = data;
if (!en) return;
if (en->imf_context)
{
}
}
static void
_canvas_focus_in_cb(
void *data,
Evas *e,
void *event_info)
{
Entry *en;
if (!obj) return;
if (en)
_entry_focus_in_cb(en, NULL, NULL, NULL);
}
static void
_canvas_focus_out_cb(
void *data,
Evas *e,
void *event_info)
{
Entry *en;
if (!obj) return;
if (en)
_entry_focus_out_cb(en, NULL, NULL, NULL);
}
static void
_imf_cursor_info_set(Entry *en)
{
Evas_Coord x, y, w, h;
Evas_Coord cx, cy, cw, ch;
int cursor_pos;
if (!en) return;
}
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,
char **text,
int *cursor_pos)
{
Entry *en = data;
const char *str;
if (text)
*text = str ? strdup(str) : strdup("");
if (cursor_pos)
}
static void
_ecore_imf_event_delete_surrounding_cb(
void *data,
Ecore_IMF_Context *ctx,
void *event_info)
{
Entry *en = data;
Evas_Textblock_Cursor *del_start, *del_end;
int cursor_pos;
if ((!en) || (!ev)) return;
}
static void
{
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);
_imf_cursor_info_set(en);
return;
}
static void
_ecore_imf_event_preedit_changed_cb(
void *data,
Ecore_IMF_Context *ctx,
void *event_info)
{
Entry *en = data;
char *preedit_string;
int cursor_pos;
int preedit_start_pos, preedit_end_pos;
int i;
if (!en) 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
{
Entry *en = data;
if ((!en) || (!ev->
key))
return;
if (en->imf_context)
{
return;
}
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
{
Entry *en = data;
if (!en) return;
if (en->imf_context)
{
return;
}
}
static void
create_input_field(
Evas *evas, Entry *en, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h)
{
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)
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(int argc, char *argv[])
{
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;
}
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;
}