Added support for Ecore_IMF on E_Entry.

SVN revision: 32777
This commit is contained in:
andrunko 2007-11-19 18:42:40 +00:00 committed by andrunko
parent f8fa4e0156
commit 9940c3c023
3 changed files with 181 additions and 6 deletions

View File

@ -174,6 +174,7 @@ PKG_CHECK_MODULES(E, [
ecore-con
ecore-job
ecore-txt
ecore-im
edje
eet
embryo

View File

@ -3,6 +3,8 @@
*/
#include "e.h"
#include <Ecore_IMFF.h>
typedef struct _E_Entry_Smart_Data E_Entry_Smart_Data;
struct _E_Entry_Smart_Data
@ -11,6 +13,7 @@ struct _E_Entry_Smart_Data
Evas_Object *editable_object;
E_Menu *popup;
Ecore_Event_Handler *selection_handler;
Ecore_IMF_Context *imf_context;
int enabled;
int focused;
@ -23,6 +26,7 @@ struct _E_Entry_Smart_Data
/* local subsystem functions */
static void _e_entry_key_down_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
static void _e_entry_key_up_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
static void _e_entry_mouse_down_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
static void _e_entry_mouse_up_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
static void _e_entry_mouse_move_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
@ -47,6 +51,9 @@ static void _e_entry_cb_copy(void *data, E_Menu *m, E_Menu_Item *mi);
static void _e_entry_cb_paste(void *data, E_Menu *m, E_Menu_Item *mi);
static void _e_entry_cb_select_all(void *data, E_Menu *m, E_Menu_Item *mi);
static void _e_entry_cb_delete(void *data, E_Menu *m, E_Menu_Item *mi);
static int _e_entry_cb_imf_retrieve_surrounding(void *data, Ecore_IMF_Context *ctx, char **text, int *cursor_pos);
static int _e_entry_cb_imf_event_commit(void *data, int type, void *event);
static int _e_entry_cb_imf_event_delete_surrounding(void *data, int type, void *event);
/* local subsystem globals */
static Evas_Smart *_e_entry_smart = NULL;
@ -171,6 +178,10 @@ e_entry_password_set(Evas_Object *entry, int password_mode)
if ((!entry) || (!(sd = evas_object_smart_data_get(entry))))
return;
e_editable_password_set(sd->editable_object, password_mode);
if (sd->imf_context)
ecore_imf_context_input_mode_set(sd->imf_context,
password_mode ? ECORE_IMF_INPUT_MODE_FULL & ECORE_IMF_INPUT_MODE_INVISIBLE :
ECORE_IMF_INPUT_MODE_FULL);
}
/**
@ -214,11 +225,22 @@ e_entry_focus(Evas_Object *entry)
if (!sd->selection_dragging)
{
e_editable_cursor_move_to_end(sd->editable_object);
if (sd->imf_context)
{
ecore_imf_context_reset(sd->imf_context);
ecore_imf_context_cursor_position_set(sd->imf_context,
e_editable_cursor_pos_get(sd->editable_object));
}
e_editable_selection_move_to_end(sd->editable_object);
}
if (sd->enabled)
e_editable_cursor_show(sd->editable_object);
e_editable_selection_show(sd->editable_object);
if (sd->imf_context)
{
ecore_imf_context_reset(sd->imf_context);
ecore_imf_context_focus_in(sd->imf_context);
}
sd->focused = 1;
}
@ -243,6 +265,11 @@ e_entry_unfocus(Evas_Object *entry)
edje_object_signal_emit(sd->entry_object, "e,state,unfocused", "e");
e_editable_cursor_hide(sd->editable_object);
e_editable_selection_hide(sd->editable_object);
if (sd->imf_context)
{
ecore_imf_context_reset(sd->imf_context);
ecore_imf_context_focus_out(sd->imf_context);
}
sd->focused = 0;
}
@ -295,12 +322,34 @@ e_entry_disable(Evas_Object *entry)
static void
_e_entry_key_down_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
{
E_Entry_Smart_Data *sd;
if ((!obj) || (!(sd = evas_object_smart_data_get(obj))))
return;
if (sd->imf_context &&
ecore_imf_context_filter_event(sd->imf_context, EVAS_CALLBACK_KEY_DOWN, event_info))
return;
if (_e_entry_emacs_keybindings)
_e_entry_key_down_emacs(obj, event_info);
else
_e_entry_key_down_windows(obj, event_info);
}
/* Called when a key has been released by the user */
static void
_e_entry_key_up_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
{
E_Entry_Smart_Data *sd;
if ((!obj) || (!(sd = evas_object_smart_data_get(obj))))
return;
if (sd->imf_context)
ecore_imf_context_filter_event(sd->imf_context, EVAS_CALLBACK_KEY_UP, event_info);
}
/* Called when the entry object is pressed by the mouse */
static void
_e_entry_mouse_down_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
@ -314,7 +363,11 @@ _e_entry_mouse_down_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
return;
if (!(event = event_info))
return;
if (sd->imf_context &&
ecore_imf_context_filter_event(sd->imf_context, EVAS_CALLBACK_MOUSE_DOWN, event_info))
return;
evas_object_geometry_get(sd->editable_object, &ox, &oy, NULL, NULL);
pos = e_editable_pos_get_from_coords(sd->editable_object,
event->canvas.x - ox,
@ -446,6 +499,13 @@ _e_entry_mouse_down_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
E_MENU_POP_DIRECTION_DOWN, event->timestamp);
e_util_evas_fake_mouse_up_later(e, event->button);
}
if (sd->imf_context)
{
ecore_imf_context_reset(sd->imf_context);
ecore_imf_context_cursor_position_set(sd->imf_context,
e_editable_cursor_pos_get(sd->editable_object));
}
}
/* Called when the entry object is released by the mouse */
@ -457,6 +517,10 @@ _e_entry_mouse_up_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
if ((!obj) || (!(sd = evas_object_smart_data_get(obj))))
return;
if (sd->imf_context &&
ecore_imf_context_filter_event(sd->imf_context, EVAS_CALLBACK_MOUSE_UP, event_info))
return;
if (sd->selection_dragging)
{
sd->selection_dragging = 0;
@ -477,7 +541,11 @@ _e_entry_mouse_move_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
return;
if (!(event = event_info))
return;
if (sd->imf_context &&
ecore_imf_context_filter_event(sd->imf_context, EVAS_CALLBACK_MOUSE_MOVE, event_info))
return;
if (sd->selection_dragging)
{
evas_object_geometry_get(sd->editable_object, &ox, &oy, NULL, NULL);
@ -485,6 +553,12 @@ _e_entry_mouse_move_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
event->cur.canvas.x - ox,
event->cur.canvas.y - oy);
e_editable_cursor_pos_set(sd->editable_object, pos);
if (sd->imf_context)
{
ecore_imf_context_reset(sd->imf_context);
ecore_imf_context_cursor_position_set(sd->imf_context,
pos);
}
}
}
@ -715,7 +789,14 @@ _e_entry_key_down_windows(Evas_Object *entry, Evas_Event_Key_Down *event)
changed |= e_editable_delete(editable, start_pos, end_pos);
changed |= e_editable_insert(editable, start_pos, event->string);
}
if (sd->imf_context)
{
ecore_imf_context_reset(sd->imf_context);
ecore_imf_context_cursor_position_set(sd->imf_context,
e_editable_cursor_pos_get(editable));
}
if (changed)
evas_object_smart_callback_call(entry, "changed", NULL);
if (selection_changed)
@ -859,8 +940,14 @@ _e_entry_key_down_emacs(Evas_Object *entry, Evas_Event_Key_Down *event)
((strlen(event->string) != 1) ||
(event->string[0] >= 0x20 && event->string[0] != 0x7f)))
changed = e_editable_insert(editable, cursor_pos, event->string);
if (sd->imf_context)
{
ecore_imf_context_reset(sd->imf_context);
ecore_imf_context_cursor_position_set(sd->imf_context,
e_editable_cursor_pos_get(editable));
}
if (changed)
evas_object_smart_callback_call(entry, "changed", NULL);
if (selection_changed)
@ -884,7 +971,23 @@ _e_entry_smart_add(Evas_Object *object)
if (!sd) return;
evas_object_smart_data_set(object, sd);
sd->imf_context = ecore_imf_context_add(ecore_imf_context_default_id_get());
if (sd->imf_context)
{
ecore_imf_context_client_window_set(sd->imf_context,
ecore_evas_window_get(ecore_evas_ecore_evas_get(evas)));
ecore_imf_context_retrieve_surrounding_callback_set(sd->imf_context,
_e_entry_cb_imf_retrieve_surrounding,
sd);
ecore_event_handler_add(ECORE_IMF_EVENT_COMMIT,
_e_entry_cb_imf_event_commit,
object);
ecore_event_handler_add(ECORE_IMF_EVENT_DELETE_SURROUNDIND,
_e_entry_cb_imf_event_delete_surrounding,
sd);
}
sd->enabled = 1;
sd->focused = 0;
sd->selection_dragging = 0;
@ -908,6 +1011,8 @@ _e_entry_smart_add(Evas_Object *object)
evas_object_event_callback_add(object, EVAS_CALLBACK_KEY_DOWN,
_e_entry_key_down_cb, NULL);
evas_object_event_callback_add(object, EVAS_CALLBACK_KEY_UP,
_e_entry_key_up_cb, NULL);
evas_object_event_callback_add(object, EVAS_CALLBACK_MOUSE_DOWN,
_e_entry_mouse_down_cb, NULL);
evas_object_event_callback_add(object, EVAS_CALLBACK_MOUSE_UP,
@ -928,8 +1033,13 @@ _e_entry_smart_del(Evas_Object *object)
if ((!object) || !(sd = evas_object_smart_data_get(object)))
return;
if (sd->imf_context)
ecore_imf_context_del(sd->imf_context);
evas_object_event_callback_del(object, EVAS_CALLBACK_KEY_DOWN,
_e_entry_key_down_cb);
evas_object_event_callback_del(object, EVAS_CALLBACK_KEY_DOWN,
_e_entry_key_up_cb);
evas_object_event_callback_del(object, EVAS_CALLBACK_MOUSE_DOWN,
_e_entry_mouse_down_cb);
evas_object_event_callback_del(object, EVAS_CALLBACK_MOUSE_UP,
@ -1153,3 +1263,63 @@ _e_entry_cb_delete(void *data, E_Menu *m, E_Menu_Item *mi)
free(range);
}
}
static int
_e_entry_cb_imf_retrieve_surrounding(void *data, Ecore_IMF_Context *ctx, char **text, int *cursor_pos)
{
E_Entry_Smart_Data *sd;
sd = data;
if (text)
{
const char *str;
str = e_editable_text_get(sd->editable_object);
*text = str ? strdup(str) : strdup("");
}
if (cursor_pos)
*cursor_pos = e_editable_cursor_pos_get(sd->editable_object);
return 1;
}
static int
_e_entry_cb_imf_event_commit(void *data, int type, void *event)
{
Evas_Object *entry;
E_Entry_Smart_Data *sd;
Ecore_IMF_Event_Commit *ev = event;
if ((!(entry = data)) || (!(sd = evas_object_smart_data_get(entry))))
return 1;
if (sd->imf_context != ev->ctx)
return 1;
e_entry_text_set(entry, ev->str);
return 0;
}
static int
_e_entry_cb_imf_event_delete_surrounding(void *data, int type, void *event)
{
E_Entry_Smart_Data *sd;
Ecore_IMF_Event_Delete_Surrounding *ev = event;
Evas_Object *editable;
int cursor_pos;
sd = data;
if (sd->imf_context != ev->ctx)
return 1;
editable = sd->editable_object;
cursor_pos = e_editable_cursor_pos_get(editable);
e_editable_delete(editable,
cursor_pos + ev->offset,
cursor_pos + ev->offset + ev->n_chars);
return 0;
}

View File

@ -3,6 +3,8 @@
*/
#include "e.h"
#include <Ecore_IM.h>
EAPI int e_precache_end = 0;
/* local subsystem functions */
@ -311,6 +313,8 @@ main(int argc, char **argv)
"Perhaps you are out of memory?"));
exit(-1);
}
ecore_im_init();
_e_main_shutdown_push(ecore_im_shutdown);
// FIXME: SEGV's on shutdown if fm2 windows up - disable for now.
// _e_main_shutdown_push(ecore_shutdown);
ecore_job_init();