Tizen 2.1 release
[platform/core/uifw/e17.git] / src / bin / e_entry.c
1 #include "e.h"
2
3 #ifdef HAVE_ECORE_IMF
4 #include <Ecore_IMF.h>
5 #include <Ecore_IMF_Evas.h>
6 #endif
7
8 typedef struct _E_Entry_Smart_Data E_Entry_Smart_Data;
9
10 struct _E_Entry_Smart_Data
11 {
12    Evas_Object *entry_object;
13    Evas_Object *editable_object;
14    E_Menu *popup;
15    Ecore_Event_Handler *selection_handler;
16 #ifdef HAVE_ECORE_IMF
17    Ecore_IMF_Context *imf_context;
18 #endif
19
20    int enabled;
21    int focused;
22    int selection_dragging;
23    int selection_mode;
24    float valign;
25    int min_width;
26    int height;
27    int preedit_start_pos;
28    int preedit_end_pos;
29    Eina_Bool have_preedit : 1;
30 };
31
32 /* local subsystem functions */
33 static void _e_entry_key_down_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
34 static void _e_entry_key_up_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
35 static void _e_entry_mouse_down_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
36 static void _e_entry_mouse_up_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
37 static void _e_entry_mouse_move_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
38 static Eina_Bool _e_entry_x_selection_notify_handler(void *data, int type, void *event);
39
40 static void _e_entry_x_selection_update(Evas_Object *entry);
41 static void _e_entry_key_down_windows(Evas_Object *entry, Evas_Event_Key_Down *event);
42 static void _e_entry_key_down_emacs(Evas_Object *entry, Evas_Event_Key_Down *event);
43
44 static void _e_entry_smart_add(Evas_Object *object);
45 static void _e_entry_smart_del(Evas_Object *object);
46 static void _e_entry_smart_move(Evas_Object *object, Evas_Coord x, Evas_Coord y);
47 static void _e_entry_smart_resize(Evas_Object *object, Evas_Coord w, Evas_Coord h);
48 static void _e_entry_smart_show(Evas_Object *object);
49 static void _e_entry_smart_hide(Evas_Object *object);
50 static void _e_entry_color_set(Evas_Object *object, int r, int g, int b, int a);
51 static void _e_entry_clip_set(Evas_Object *object, Evas_Object *clip);
52 static void _e_entry_clip_unset(Evas_Object *object);
53 static void _e_entry_cb_menu_post(void *data, E_Menu *m);
54 static void _e_entry_cb_cut(void *data, E_Menu *m, E_Menu_Item *mi);
55 static void _e_entry_cb_copy(void *data, E_Menu *m, E_Menu_Item *mi);
56 static void _e_entry_cb_paste(void *data, E_Menu *m, E_Menu_Item *mi);
57 static void _e_entry_cb_select_all(void *data, E_Menu *m, E_Menu_Item *mi);
58 static void _e_entry_cb_delete(void *data, E_Menu *m, E_Menu_Item *mi);
59 static void _e_entry_imf_cursor_info_set(Evas_Object *object);
60 static void _e_entry_imf_context_reset(Evas_Object *object);
61 #ifdef HAVE_ECORE_IMF
62 static Eina_Bool _e_entry_cb_imf_retrieve_surrounding(void *data, Ecore_IMF_Context *ctx, char **text, int *cursor_pos);
63 static void _e_entry_cb_imf_event_commit(void *data, Ecore_IMF_Context *ctx __UNUSED__, void *event_info);
64 static void _e_entry_cb_imf_event_preedit_changed(void *data, Ecore_IMF_Context *ctx __UNUSED__, void *event_info);
65 static void _e_entry_cb_imf_event_delete_surrounding(void *data, Ecore_IMF_Context *ctx __UNUSED__, void *event_info);
66 #endif
67
68 /* local subsystem globals */
69 static Evas_Smart *_e_entry_smart = NULL;
70 static int _e_entry_smart_use = 0;
71 static int _e_entry_emacs_keybindings = 0;
72
73
74 /* externally accessible functions */
75
76 /**
77  * Creates a new entry object. An entry is a field where the user can type
78  * single-line text.
79  * Use the "changed" smart callback to know when the content of the entry is
80  * changed
81  *
82  * @param evas the evas where the entry object should be added
83  * @return Returns the new entry object
84  */
85 EAPI Evas_Object *
86 e_entry_add(Evas *evas)
87 {
88    if (!_e_entry_smart)
89      {
90         static const Evas_Smart_Class sc =
91           {
92              "e_entry",
93              EVAS_SMART_CLASS_VERSION,
94              _e_entry_smart_add,
95              _e_entry_smart_del,
96              _e_entry_smart_move,
97              _e_entry_smart_resize,
98              _e_entry_smart_show,
99              _e_entry_smart_hide,
100              _e_entry_color_set,
101              _e_entry_clip_set,
102              _e_entry_clip_unset,
103              NULL,
104              NULL,
105              NULL,
106              NULL,
107              NULL,
108              NULL,
109              NULL
110           };
111         _e_entry_smart = evas_smart_class_new(&sc);
112         _e_entry_smart_use = 0;
113      }
114
115    _e_entry_smart_use++;
116    return evas_object_smart_add(evas, _e_entry_smart);
117 }
118
119 /**
120  * Sets the text of the entry object
121  *
122  * @param entry an entry object
123  * @param text the text to set
124  */
125 EAPI void
126 e_entry_text_set(Evas_Object *entry, const char *text)
127 {
128    E_Entry_Smart_Data *sd;
129
130    if (evas_object_smart_smart_get(entry) != _e_entry_smart) SMARTERRNR();
131    if ((!entry) || (!(sd = evas_object_smart_data_get(entry))))
132      return;
133
134    e_editable_text_set(sd->editable_object, text);
135    evas_object_smart_callback_call(entry, "changed", NULL);
136 }
137
138 /**
139  * Gets the text of the entry object
140  *
141  * @param entry an entry object
142  * @return Returns the text of the entry object
143  */
144 EAPI const char *
145 e_entry_text_get(Evas_Object *entry)
146 {
147    E_Entry_Smart_Data *sd;
148
149    if (evas_object_smart_smart_get(entry) != _e_entry_smart) SMARTERR(NULL);
150    if ((!entry) || (!(sd = evas_object_smart_data_get(entry))))
151      return NULL;
152    return e_editable_text_get(sd->editable_object);
153 }
154
155 /**
156  * Clears the entry object
157  *
158  * @param entry an entry object
159  */
160 EAPI void
161 e_entry_clear(Evas_Object *entry)
162 {
163    if (evas_object_smart_smart_get(entry) != _e_entry_smart) SMARTERRNR();
164    e_entry_text_set(entry, "");
165 }
166
167 /**
168  * Gets the editable object used by the entry object. It will allow you to have
169  * better control on the text, the cursor or the selection of the entry with
170  * the e_editable_*() functions.
171  *
172  * @param entry an entry object
173  * @return Returns the editable object used by the entry object
174  */
175 EAPI Evas_Object *
176 e_entry_editable_object_get(Evas_Object *entry)
177 {
178    E_Entry_Smart_Data *sd;
179
180    if (evas_object_smart_smart_get(entry) != _e_entry_smart) SMARTERR(NULL);
181    if ((!entry) || (!(sd = evas_object_smart_data_get(entry))))
182      return NULL;
183    return sd->editable_object;
184 }
185
186 /**
187  * Sets whether or not the entry object is in password mode. In password mode,
188  * the entry displays '*' instead of the characters
189  *
190  * @param entry an entry object
191  * @param password_mode 1 to turn on password mode, 0 to turn it off
192  */
193 EAPI void
194 e_entry_password_set(Evas_Object *entry, int password_mode)
195 {
196    E_Entry_Smart_Data *sd;
197
198    if (evas_object_smart_smart_get(entry) != _e_entry_smart) SMARTERRNR();
199    if ((!entry) || (!(sd = evas_object_smart_data_get(entry))))
200      return;
201    e_editable_password_set(sd->editable_object, password_mode);
202 #ifdef HAVE_ECORE_IMF
203    if (sd->imf_context)
204      ecore_imf_context_input_mode_set(sd->imf_context,
205                                       password_mode ? ECORE_IMF_INPUT_MODE_FULL & ECORE_IMF_INPUT_MODE_INVISIBLE :
206                                       ECORE_IMF_INPUT_MODE_FULL);
207 #endif
208 }
209
210 /**
211  * Gets the minimum size of the entry object
212  *
213  * @param entry an entry object
214  * @param minw the location where to store the minimun width of the entry
215  * @param minh the location where to store the minimun height of the entry
216  */
217 EAPI void
218 e_entry_size_min_get(Evas_Object *entry, Evas_Coord *minw, Evas_Coord *minh)
219 {
220    E_Entry_Smart_Data *sd;
221
222    if (evas_object_smart_smart_get(entry) != _e_entry_smart) SMARTERRNR();
223    if ((!entry) || (!(sd = evas_object_smart_data_get(entry))))
224      return;
225
226    if (minw) *minw = sd->min_width;
227    if (minh) *minh = sd->height;
228 }
229
230 /**
231  * Focuses the entry object. It will receives keyboard events and the user could
232  * then type some text (the entry should also be enabled. The cursor and the
233  * selection will be shown
234  *
235  * @param entry the entry to focus
236  */
237 EAPI void
238 e_entry_focus(Evas_Object *entry)
239 {
240    E_Entry_Smart_Data *sd;
241
242    if (evas_object_smart_smart_get(entry) != _e_entry_smart) SMARTERRNR();
243    if ((!entry) || (!(sd = evas_object_smart_data_get(entry))))
244      return;
245    if (sd->focused)
246      return;
247
248    evas_object_focus_set(entry, 1);
249    edje_object_signal_emit(sd->entry_object, "e,state,focused", "e");
250    if (!sd->selection_dragging)
251      {
252         _e_entry_imf_context_reset(entry);
253         e_editable_cursor_move_to_end(sd->editable_object);
254         _e_entry_imf_cursor_info_set(entry);
255
256         e_editable_selection_move_to_end(sd->editable_object);
257      }
258    if (sd->enabled)
259      e_editable_cursor_show(sd->editable_object);
260    e_editable_selection_show(sd->editable_object);
261 #ifdef HAVE_ECORE_IMF
262    if (sd->imf_context)
263      ecore_imf_context_focus_in(sd->imf_context);
264 #endif
265    sd->focused = 1;
266 }
267
268 /**
269  * Unfocuses the entry object. It will no longer receives keyboard events so
270  * the user could no longer type some text. The cursor and the selection will
271  * be hidden
272  *
273  * @param entry the entry object to unfocus
274  */
275 EAPI void
276 e_entry_unfocus(Evas_Object *entry)
277 {
278    E_Entry_Smart_Data *sd;
279
280    if (evas_object_smart_smart_get(entry) != _e_entry_smart) SMARTERRNR();
281    if ((!entry) || (!(sd = evas_object_smart_data_get(entry))))
282      return;
283    if (!sd->focused)
284      return;
285
286    evas_object_focus_set(entry, 0);
287    edje_object_signal_emit(sd->entry_object, "e,state,unfocused", "e");
288    e_editable_cursor_hide(sd->editable_object);
289    e_editable_selection_hide(sd->editable_object);
290 #ifdef HAVE_ECORE_IMF
291    if (sd->imf_context)
292      {
293         ecore_imf_context_reset(sd->imf_context);
294         ecore_imf_context_focus_out(sd->imf_context);
295      }
296 #endif
297    sd->focused = 0;
298 }
299
300 /**
301  * Enables the entry object: the user will be able to type text
302  *
303  * @param entry the entry object to enable
304  */
305 EAPI void
306 e_entry_enable(Evas_Object *entry)
307 {
308    E_Entry_Smart_Data *sd;
309
310    if (evas_object_smart_smart_get(entry) != _e_entry_smart) SMARTERRNR();
311    if ((!entry) || (!(sd = evas_object_smart_data_get(entry))))
312      return;
313    if (sd->enabled)
314      return;
315
316    edje_object_signal_emit(sd->entry_object, "e,state,enabled", "e");
317    e_editable_enable(sd->editable_object);
318    if (sd->focused)
319      e_editable_cursor_show(sd->editable_object);
320    sd->enabled = 1;
321 }
322
323 /**
324  * Disables the entry object: the user won't be able to type anymore. Selection
325  * will still be possible (to copy the text)
326  *
327  * @param entry the entry object to disable
328  */
329 EAPI void
330 e_entry_disable(Evas_Object *entry)
331 {
332    E_Entry_Smart_Data *sd;
333
334    if (evas_object_smart_smart_get(entry) != _e_entry_smart) SMARTERRNR();
335    if ((!entry) || (!(sd = evas_object_smart_data_get(entry))))
336      return;
337    if (!sd->enabled)
338      return;
339
340    edje_object_signal_emit(sd->entry_object, "e,state,disabled", "e");
341    e_editable_disable(sd->editable_object);
342    e_editable_cursor_hide(sd->editable_object);
343    sd->enabled = 0;
344 }
345
346
347 /* Private functions */
348
349 /* Called when a key has been pressed by the user */
350 static void
351 _e_entry_key_down_cb(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info)
352 {
353    E_Entry_Smart_Data *sd;
354
355    if ((!obj) || (!(sd = evas_object_smart_data_get(obj))))
356      return;
357
358 #ifdef HAVE_ECORE_IMF
359    if (sd->imf_context)
360      {
361         Ecore_IMF_Event_Key_Down ev;
362
363         ecore_imf_evas_event_key_down_wrap(event_info, &ev);
364         if (ecore_imf_context_filter_event(sd->imf_context,
365                                            ECORE_IMF_EVENT_KEY_DOWN,
366                                            (Ecore_IMF_Event *) &ev))
367           return;
368      }
369 #endif
370
371    if (_e_entry_emacs_keybindings)
372      _e_entry_key_down_emacs(obj, event_info);
373    else
374      _e_entry_key_down_windows(obj, event_info);
375 }
376
377 /* Called when a key has been released by the user */
378 #ifdef HAVE_ECORE_IMF
379 static void
380 _e_entry_key_up_cb(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info)
381 #else
382 static void
383 _e_entry_key_up_cb(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
384 #endif
385 {
386    E_Entry_Smart_Data *sd;
387
388    if ((!obj) || (!(sd = evas_object_smart_data_get(obj))))
389      return;
390
391 #ifdef HAVE_ECORE_IMF
392    if (sd->imf_context)
393      {
394         Ecore_IMF_Event_Key_Up ev;
395
396         ecore_imf_evas_event_key_up_wrap(event_info, &ev);
397         if (ecore_imf_context_filter_event(sd->imf_context,
398                                            ECORE_IMF_EVENT_KEY_UP,
399                                            (Ecore_IMF_Event *) &ev))
400           return;
401      }
402 #endif
403 }
404
405 /* Called when the entry object is pressed by the mouse */
406 static void
407 _e_entry_mouse_down_cb(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info)
408 {
409    E_Entry_Smart_Data *sd;
410    Evas_Event_Mouse_Down *event;
411    Evas_Coord ox, oy;
412    int pos;
413
414    if ((!obj) || (!(sd = evas_object_smart_data_get(obj))))
415      return;
416    if (!(event = event_info))
417      return;
418
419 #ifdef HAVE_ECORE_IMF
420    if (sd->imf_context)
421      {
422         Ecore_IMF_Event_Mouse_Down ev;
423
424         ecore_imf_evas_event_mouse_down_wrap(event_info, &ev);
425         if (ecore_imf_context_filter_event(sd->imf_context,
426                                            ECORE_IMF_EVENT_MOUSE_DOWN,
427                                            (Ecore_IMF_Event *) &ev))
428           return;
429      }
430 #endif
431
432    _e_entry_imf_context_reset(obj);
433
434    evas_object_geometry_get(sd->editable_object, &ox, &oy, NULL, NULL);
435    pos = e_editable_pos_get_from_coords(sd->editable_object,
436                                         event->canvas.x - ox,
437                                         event->canvas.y - oy);
438
439    if (event->button == 1)
440      {
441         if (event->flags & EVAS_BUTTON_TRIPLE_CLICK)
442           {
443              e_editable_select_all(sd->editable_object);
444              _e_entry_x_selection_update(obj);
445           }
446         else if (event->flags & EVAS_BUTTON_DOUBLE_CLICK)
447           {
448              e_editable_select_word(sd->editable_object, pos);
449              _e_entry_x_selection_update(obj);
450           }
451         else
452           {
453              e_editable_cursor_pos_set(sd->editable_object, pos);
454              if (!evas_key_modifier_is_set(event->modifiers, "Shift"))
455                e_editable_selection_pos_set(sd->editable_object, pos);
456
457              sd->selection_dragging = 1;
458           }
459      }
460    else if (event->button == 2)
461      {
462         E_Win *win;
463
464         e_editable_cursor_pos_set(sd->editable_object, pos);
465         e_editable_selection_pos_set(sd->editable_object, pos);
466
467         if ((win = e_win_evas_object_win_get(obj)))
468           ecore_x_selection_primary_request(win->evas_win,
469                                             ECORE_X_SELECTION_TARGET_UTF8_STRING);
470      }
471    else if (event->button == 3)
472      {
473         E_Menu_Item *mi;
474         E_Manager *man;
475         E_Container *con;
476         int x, y;
477         int cursor_pos, selection_pos;
478         int start_pos, end_pos;
479         int s_enabled, s_selecting, s_empty, s_passwd;
480
481         cursor_pos = e_editable_cursor_pos_get(sd->editable_object);
482         selection_pos = e_editable_selection_pos_get(sd->editable_object);
483         start_pos = (cursor_pos <= selection_pos) ? cursor_pos : selection_pos;
484         end_pos = (cursor_pos >= selection_pos) ? cursor_pos : selection_pos;
485
486         s_selecting = (start_pos != end_pos);
487         s_enabled = sd->enabled;
488         s_empty = !e_editable_text_length_get(sd->editable_object);
489         s_passwd = e_editable_password_get(sd->editable_object);
490
491         if (!s_selecting && !s_enabled && s_empty) return;
492
493         man = e_manager_current_get();
494         con = e_container_current_get(man);
495         ecore_x_pointer_xy_get(con->win, &x, &y);
496
497         /* Popup a menu */
498         sd->popup = e_menu_new();
499         e_menu_post_deactivate_callback_set(sd->popup,
500                                             _e_entry_cb_menu_post, sd);
501         if (s_selecting)
502           {
503              if (s_enabled)
504                {
505                   mi = e_menu_item_new(sd->popup);
506                   e_menu_item_label_set(mi, _("Delete"));
507                   e_util_menu_item_theme_icon_set(mi, "edit-delete");
508                   e_menu_item_callback_set(mi, _e_entry_cb_delete, sd);
509
510                   mi = e_menu_item_new(sd->popup);
511                   e_menu_item_separator_set(mi, 1);
512
513                   if (!s_passwd)
514                     {
515                        mi = e_menu_item_new(sd->popup);
516                        e_menu_item_label_set(mi, _("Cut"));
517                        e_util_menu_item_theme_icon_set(mi, "edit-cut");
518                        e_menu_item_callback_set(mi, _e_entry_cb_cut, sd);
519                     }
520                }
521              if (!s_passwd)
522                {
523                   mi = e_menu_item_new(sd->popup);
524                   e_menu_item_label_set(mi, _("Copy"));
525                   e_util_menu_item_theme_icon_set(mi, "edit-copy");
526                   e_menu_item_callback_set(mi, _e_entry_cb_copy, sd);
527                }
528           }
529         if (sd->enabled)
530           {
531              mi = e_menu_item_new(sd->popup);
532              e_menu_item_label_set(mi, _("Paste"));
533              e_util_menu_item_theme_icon_set(mi, "edit-paste");
534              e_menu_item_callback_set(mi, _e_entry_cb_paste, sd);
535           }
536         if (!s_empty)
537           {
538              mi = e_menu_item_new(sd->popup);
539              e_menu_item_separator_set(mi, 1);
540
541              mi = e_menu_item_new(sd->popup);
542              e_menu_item_label_set(mi, _("Select All"));
543              e_util_menu_item_theme_icon_set(mi, "edit-select-all");
544              e_menu_item_callback_set(mi, _e_entry_cb_select_all, sd);
545           }
546
547         e_menu_activate_mouse(sd->popup, e_util_zone_current_get(man),
548                               x, y, 1, 1,
549                               E_MENU_POP_DIRECTION_DOWN, event->timestamp);
550      }
551
552    _e_entry_imf_cursor_info_set(obj);
553 }
554
555 /* Called when the entry object is released by the mouse */
556 #ifdef HAVE_ECORE_IMF
557 static void
558 _e_entry_mouse_up_cb(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info)
559 #else
560 static void
561 _e_entry_mouse_up_cb(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
562 #endif
563 {
564    E_Entry_Smart_Data *sd;
565
566    if ((!obj) || (!(sd = evas_object_smart_data_get(obj))))
567      return;
568
569 #ifdef HAVE_ECORE_IMF
570    if (sd->imf_context)
571      {
572         Ecore_IMF_Event_Mouse_Up ev;
573
574         ecore_imf_evas_event_mouse_up_wrap(event_info, &ev);
575         if (ecore_imf_context_filter_event(sd->imf_context,
576                                            ECORE_IMF_EVENT_MOUSE_UP,
577                                            (Ecore_IMF_Event *) &ev))
578           return;
579      }
580 #endif
581
582    if (sd->selection_dragging)
583      {
584         sd->selection_dragging = 0;
585         _e_entry_x_selection_update(obj);
586      }
587 }
588
589 /* Called when the mouse moves over the entry object */
590 static void
591 _e_entry_mouse_move_cb(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info)
592 {
593    E_Entry_Smart_Data *sd;
594    Evas_Event_Mouse_Move *event;
595    Evas_Coord ox, oy;
596    int pos;
597
598    if ((!obj) || (!(sd = evas_object_smart_data_get(obj))))
599      return;
600    if (!(event = event_info))
601      return;
602
603 #ifdef HAVE_ECORE_IMF
604    if (sd->imf_context)
605      {
606         Ecore_IMF_Event_Mouse_Move ev;
607
608         ecore_imf_evas_event_mouse_move_wrap(event_info, &ev);
609         if (ecore_imf_context_filter_event(sd->imf_context,
610                                            ECORE_IMF_EVENT_MOUSE_MOVE,
611                                            (Ecore_IMF_Event *) &ev))
612           return;
613      }
614 #endif
615
616    if (sd->selection_dragging)
617      {
618         evas_object_geometry_get(sd->editable_object, &ox, &oy, NULL, NULL);
619         pos = e_editable_pos_get_from_coords(sd->editable_object,
620                                              event->cur.canvas.x - ox,
621                                              event->cur.canvas.y - oy);
622         _e_entry_imf_context_reset(obj);
623         e_editable_cursor_pos_set(sd->editable_object, pos);
624         _e_entry_imf_cursor_info_set(obj);
625      }
626 }
627
628 /* Called when the the "selection_notify" event is emitted */
629 static Eina_Bool
630 _e_entry_x_selection_notify_handler(void *data, int type __UNUSED__, void *event)
631 {
632    Evas_Object *entry;
633    E_Entry_Smart_Data *sd;
634    Ecore_X_Event_Selection_Notify *ev;
635    Evas_Object *editable;
636    int cursor_pos, selection_pos;
637    int start_pos, end_pos;
638    int selecting;
639    int changed = 0;
640
641    if ((!(entry = data)) || (!(sd = evas_object_smart_data_get(entry))))
642      return 1;
643    if (!sd->focused)
644      return 1;
645
646    editable = sd->editable_object;
647    cursor_pos = e_editable_cursor_pos_get(editable);
648    selection_pos = e_editable_selection_pos_get(editable);
649    start_pos = (cursor_pos <= selection_pos) ? cursor_pos : selection_pos;
650    end_pos = (cursor_pos >= selection_pos) ? cursor_pos : selection_pos;
651    selecting = (start_pos != end_pos);
652
653    ev = event;
654    if ((ev->selection == ECORE_X_SELECTION_CLIPBOARD) ||
655        (ev->selection == ECORE_X_SELECTION_PRIMARY))
656      {
657         if (strcmp(ev->target, ECORE_X_SELECTION_TARGET_UTF8_STRING) == 0)
658           {
659              Ecore_X_Selection_Data_Text *text_data;
660
661              text_data = ev->data;
662              if (selecting && !_e_entry_emacs_keybindings)
663                changed |= e_editable_delete(editable, start_pos, end_pos);
664              changed |= e_editable_insert(editable, start_pos, text_data->text);
665           }
666      }
667
668    if (changed)
669      evas_object_smart_callback_call(entry, "changed", NULL);
670
671    return ECORE_CALLBACK_PASS_ON;
672 }
673
674 /* Updates the X selection with the selected text of the entry */
675 static void
676 _e_entry_x_selection_update(Evas_Object *entry)
677 {
678    E_Entry_Smart_Data *sd;
679    Evas_Object *editable;
680    E_Win *win;
681    int cursor_pos, selection_pos;
682    int start_pos, end_pos;
683    int selecting;
684    char *text;
685
686    if ((!entry) || (!(sd = evas_object_smart_data_get(entry))))
687      return;
688    if (!(win = e_win_evas_object_win_get(entry)))
689      return;
690
691    editable = sd->editable_object;
692    if (e_editable_password_get(editable)) return;
693
694    cursor_pos = e_editable_cursor_pos_get(editable);
695    selection_pos = e_editable_selection_pos_get(editable);
696    start_pos = (cursor_pos <= selection_pos) ? cursor_pos : selection_pos;
697    end_pos = (cursor_pos >= selection_pos) ? cursor_pos : selection_pos;
698    selecting = (start_pos != end_pos);
699
700    if ((!selecting) ||
701        (!(text = e_editable_text_range_get(editable, start_pos, end_pos))))
702      return;
703
704    ecore_x_selection_primary_set(win->evas_win, text, strlen(text) + 1);
705    free(text);
706 }
707
708 /* Treats the "key down" event to mimick the behavior of Windows/Gtk2/Qt */
709 static void
710 _e_entry_key_down_windows(Evas_Object *entry, Evas_Event_Key_Down *event)
711 {
712    E_Entry_Smart_Data *sd;
713    Evas_Object *editable;
714    int cursor_pos, selection_pos;
715    int start_pos, end_pos;
716    int selecting;
717    int changed = 0;
718    int selection_changed = 0;
719    char *range;
720    E_Win *win;
721
722    if ((!entry) || (!(sd = evas_object_smart_data_get(entry))))
723      return;
724    if ((!event) || (!event->keyname))
725      return;
726
727    editable = sd->editable_object;
728    cursor_pos = e_editable_cursor_pos_get(editable);
729    selection_pos = e_editable_selection_pos_get(editable);
730    start_pos = (cursor_pos <= selection_pos) ? cursor_pos : selection_pos;
731    end_pos = (cursor_pos >= selection_pos) ? cursor_pos : selection_pos;
732    selecting = (start_pos != end_pos);
733
734    if ((!strcmp(event->key, "Escape")) ||
735        (!strcmp(event->key, "Return")) || (!strcmp(event->key, "KP_Enter")))
736      _e_entry_imf_context_reset(entry);
737
738    /* Move the cursor/selection to the left */
739    if (strcmp(event->key, "Left") == 0 ||
740        ((strcmp(event->key, "KP_Left") == 0) && (!event->string)))
741      {
742         if (evas_key_modifier_is_set(event->modifiers, "Shift"))
743           {
744              e_editable_cursor_move_left(editable);
745              selection_changed = 1;
746           }
747         else if (selecting)
748           {
749              if (cursor_pos < selection_pos)
750                e_editable_selection_pos_set(editable, cursor_pos);
751              else
752                e_editable_cursor_pos_set(editable, selection_pos);
753           }
754         else
755           {
756              e_editable_cursor_move_left(editable);
757              e_editable_selection_pos_set(editable,
758                                           e_editable_cursor_pos_get(editable));
759           }
760      }
761    /* Move the cursor/selection to the right */
762    else if (strcmp(event->key, "Right") == 0 ||
763             ((strcmp(event->key, "KP_Right") == 0) && (!event->string)))
764      {
765         if (evas_key_modifier_is_set(event->modifiers, "Shift"))
766           {
767              e_editable_cursor_move_right(editable);
768              selection_changed = 1;
769           }
770         else if (selecting)
771           {
772              if (cursor_pos > selection_pos)
773                e_editable_selection_pos_set(editable, cursor_pos);
774              else
775                e_editable_cursor_pos_set(editable, selection_pos);
776           }
777         else
778           {
779              e_editable_cursor_move_right(editable);
780              e_editable_selection_pos_set(editable,
781                                           e_editable_cursor_pos_get(editable));
782           }
783      }
784    /* Move the cursor/selection to the start of the entry */
785    else if (strcmp(event->keyname, "Home") == 0 ||
786             ((strcmp(event->key, "KP_Home") == 0) && (!event->string)))
787      {
788         e_editable_cursor_move_to_start(editable);
789         if (!evas_key_modifier_is_set(event->modifiers, "Shift"))
790           e_editable_selection_pos_set(editable,
791                                        e_editable_cursor_pos_get(editable));
792         else
793           selection_changed = 1;
794      }
795    /* Move the cursor/selection to the end of the entry */
796    else if (strcmp(event->keyname, "End") == 0 ||
797             ((strcmp(event->key, "KP_End") == 0) && (!event->string)))
798      {
799         e_editable_cursor_move_to_end(editable);
800         if (!evas_key_modifier_is_set(event->modifiers, "Shift"))
801           e_editable_selection_pos_set(editable,
802                                        e_editable_cursor_pos_get(editable));
803         else
804           selection_changed = 1;
805      }
806    /* Delete the previous character */
807    else if ((sd->enabled) && (strcmp(event->keyname, "BackSpace") == 0))
808      {
809         if (selecting)
810           changed = e_editable_delete(editable, start_pos, end_pos);
811         else
812           changed = e_editable_delete(editable, cursor_pos - 1, cursor_pos);
813      }
814    /* Delete the next character */
815    else if ((sd->enabled) && ((strcmp(event->keyname, "Delete") == 0) ||
816             ((strcmp(event->key, "KP_Delete") == 0) && (!event->string))))
817      {
818         if (selecting)
819           changed = e_editable_delete(editable, start_pos, end_pos);
820         else
821           changed = e_editable_delete(editable, cursor_pos, cursor_pos + 1);
822      }
823    /* Ctrl + A,C,X,V */
824    else if (evas_key_modifier_is_set(event->modifiers, "Control"))
825      {
826         if (strcmp(event->keyname, "a") == 0)
827           {
828              e_editable_select_all(editable);
829              selection_changed = 1;
830           }
831         else if ((strcmp(event->keyname, "x") == 0) ||
832                  (strcmp(event->keyname, "c") == 0))
833           {
834              if (!e_editable_password_get(editable) && selecting)
835                {
836                   range = e_editable_text_range_get(editable, start_pos, end_pos);
837                   if (range)
838                     {
839                        if ((win = e_win_evas_object_win_get(entry)))
840                          ecore_x_selection_clipboard_set(win->evas_win,
841                                                          range,
842                                                          strlen(range) + 1);
843                        free(range);
844                     }
845                   if ((sd->enabled) && (strcmp(event->keyname, "x") == 0))
846                     changed = e_editable_delete(editable, start_pos, end_pos);
847                }
848           }
849         else if ((sd->enabled) && (strcmp(event->keyname, "v") == 0))
850           {
851              if ((win = e_win_evas_object_win_get(entry)))
852                ecore_x_selection_clipboard_request(win->evas_win,
853                                                    ECORE_X_SELECTION_TARGET_UTF8_STRING);
854           }
855      }
856    /* Otherwise, we insert the corresponding character */
857    else if ((event->string) && ((sd->enabled)) &&
858             ((strlen(event->string) != 1) || (event->string[0] >= 0x20)))
859      {
860         if (selecting)
861           changed |= e_editable_delete(editable, start_pos, end_pos);
862         changed |= e_editable_insert(editable, start_pos, event->string);
863      }
864
865    _e_entry_imf_cursor_info_set(entry);
866
867    if (changed)
868      evas_object_smart_callback_call(entry, "changed", NULL);
869    if (selection_changed)
870      _e_entry_x_selection_update(entry);
871 }
872
873 /* Treats the "key down" event to mimick the behavior of Emacs */
874 static void
875 _e_entry_key_down_emacs(Evas_Object *entry, Evas_Event_Key_Down *event)
876 {
877    E_Entry_Smart_Data *sd;
878    Evas_Object *editable;
879    int cursor_pos, selection_pos;
880    int start_pos, end_pos;
881    int selecting;
882    int changed = 0;
883    int selection_changed = 0;
884    char *range;
885    E_Win *win;
886
887    if ((!entry) || (!(sd = evas_object_smart_data_get(entry))))
888      return;
889    if ((!event) || (!event->keyname))
890      return;
891
892    editable = sd->editable_object;
893    cursor_pos = e_editable_cursor_pos_get(editable);
894    selection_pos = e_editable_selection_pos_get(editable);
895    start_pos = (cursor_pos <= selection_pos) ? cursor_pos : selection_pos;
896    end_pos = (cursor_pos >= selection_pos) ? cursor_pos : selection_pos;
897    selecting = (start_pos != end_pos);
898
899    if ((!strcmp(event->key, "Escape")) ||
900        (!strcmp(event->key, "Return")) || (!strcmp(event->key, "KP_Enter")))
901      _e_entry_imf_context_reset(entry);
902
903    /* Move the cursor/selection to the left */
904    if ((strcmp(event->key, "Left") == 0) ||
905        ((evas_key_modifier_is_set(event->modifiers, "Control")) &&
906         (strcmp(event->key, "b") == 0)))
907      {
908         e_editable_cursor_move_left(editable);
909         if (sd->selection_mode)
910           selection_changed = 1;
911         else
912           e_editable_selection_pos_set(editable,
913                                        e_editable_cursor_pos_get(editable));
914      }
915    /* Move the cursor/selection to the right */
916    else if ((strcmp(event->key, "Right") == 0) ||
917             ((evas_key_modifier_is_set(event->modifiers, "Control")) &&
918              (strcmp(event->key, "f") == 0)))
919      {
920         e_editable_cursor_move_right(editable);
921         if (sd->selection_mode)
922           selection_changed = 1;
923         else
924           e_editable_selection_pos_set(editable,
925                                        e_editable_cursor_pos_get(editable));
926      }
927    /* Move the cursor/selection to the start of the entry */
928    else if ((strcmp(event->keyname, "Home") == 0) ||
929             ((evas_key_modifier_is_set(event->modifiers, "Control")) &&
930              (strcmp(event->key, "a") == 0)))
931      {
932         e_editable_cursor_move_to_start(editable);
933         if (sd->selection_mode)
934           selection_changed = 1;
935         else
936           e_editable_selection_pos_set(editable,
937                                        e_editable_cursor_pos_get(editable));
938      }
939    /* Move the cursor/selection to the end of the entry */
940    else if ((strcmp(event->keyname, "End") == 0) ||
941             ((evas_key_modifier_is_set(event->modifiers, "Control")) &&
942              (strcmp(event->key, "e") == 0)))
943      {
944         e_editable_cursor_move_to_end(editable);
945         if (sd->selection_mode)
946           selection_changed = 1;
947         else
948           e_editable_selection_pos_set(editable,
949                                        e_editable_cursor_pos_get(editable));
950      }
951    /* Delete the previous character */
952    else if ((sd->enabled) && (strcmp(event->keyname, "BackSpace") == 0))
953      changed = e_editable_delete(editable, cursor_pos - 1, cursor_pos);
954    /* Delete the next character */
955    else if ((sd->enabled) &&
956             ((evas_key_modifier_is_set(event->modifiers, "Control")) &&
957              (strcmp(event->key, "d") == 0)))
958      changed = e_editable_delete(editable, cursor_pos, cursor_pos + 1);
959    /* Delete until end of line */
960    else if ((sd->enabled) &&
961             ((evas_key_modifier_is_set(event->modifiers, "Control")) &&
962              (strcmp(event->key, "k") == 0)))
963      changed = e_editable_delete(editable, cursor_pos,
964                                  e_editable_text_length_get(editable));
965    /* Toggle the selection mode */
966    else if ((evas_key_modifier_is_set(event->modifiers, "Control")) &&
967             (strcmp(event->key, "space") == 0))
968      {
969         if (sd->selection_mode)
970           {
971              e_editable_selection_pos_set(editable, cursor_pos);
972              sd->selection_mode = 0;
973           }
974         else
975           sd->selection_mode = 1;
976      }
977    /* Cut/Copy */
978    else if ((evas_key_modifier_is_set(event->modifiers, "Control") ||
979              evas_key_modifier_is_set(event->modifiers, "Shift")) &&
980             (strcmp(event->key, "w") == 0))
981      {
982         if (!e_editable_password_get(editable) && selecting)
983           {
984              range = e_editable_text_range_get(editable, start_pos, end_pos);
985              if (range)
986                {
987                   if ((win = e_win_evas_object_win_get(entry)))
988                     ecore_x_selection_clipboard_set(win->evas_win,
989                                                     range,
990                                                     strlen(range) + 1);
991                   free(range);
992                }
993              if ((sd->enabled) && (evas_key_modifier_is_set(event->modifiers, "Control")))
994                {
995                   changed = e_editable_delete(editable, start_pos, end_pos);
996                   sd->selection_mode = 0;
997                }
998           }
999      }
1000    /* Paste */
1001    else if ((sd->enabled) &&
1002             ((evas_key_modifier_is_set(event->modifiers, "Control")) &&
1003              (strcmp(event->key, "y") == 0)))
1004      {
1005         if ((win = e_win_evas_object_win_get(entry)))
1006           ecore_x_selection_clipboard_request(win->evas_win,
1007                                               ECORE_X_SELECTION_TARGET_UTF8_STRING);
1008      }
1009    /* Otherwise, we insert the corresponding character */
1010    else if ((event->string) &&
1011             ((strlen(event->string) != 1) ||
1012              (event->string[0] >= 0x20 && event->string[0] != 0x7f)))
1013      changed = e_editable_insert(editable, cursor_pos, event->string);
1014
1015    _e_entry_imf_cursor_info_set(entry);
1016
1017    if (changed)
1018      evas_object_smart_callback_call(entry, "changed", NULL);
1019    if (selection_changed)
1020      _e_entry_x_selection_update(entry);
1021 }
1022
1023 /* Editable object's smart methods */
1024
1025 static void
1026 _e_entry_smart_add(Evas_Object *object)
1027 {
1028    Evas *evas;
1029    E_Entry_Smart_Data *sd;
1030    Evas_Object *o;
1031    int cw, ch;
1032 #ifdef HAVE_ECORE_IMF
1033    const char *ctx_id;
1034    const Ecore_IMF_Context_Info *ctx_info;
1035 #endif
1036
1037    if ((!object) || !(evas = evas_object_evas_get(object)))
1038      return;
1039
1040    sd = calloc(1, sizeof(E_Entry_Smart_Data));
1041    if (!sd) return;
1042
1043    evas_object_smart_data_set(object, sd);
1044
1045 #ifdef HAVE_ECORE_IMF
1046    ctx_id = ecore_imf_context_default_id_get();
1047    if (ctx_id)
1048      {
1049         ctx_info = ecore_imf_context_info_by_id_get(ctx_id);
1050         if (!ctx_info->canvas_type ||
1051             strcmp(ctx_info->canvas_type, "evas") == 0)
1052           sd->imf_context = ecore_imf_context_add(ctx_id);
1053         else
1054           {
1055              ctx_id = ecore_imf_context_default_id_by_canvas_type_get("evas");
1056              if (ctx_id)
1057                sd->imf_context = ecore_imf_context_add(ctx_id);
1058              else
1059                sd->imf_context = NULL;
1060           }
1061      }
1062    else
1063      sd->imf_context = NULL;
1064
1065    if (sd->imf_context)
1066      {
1067         ecore_imf_context_client_window_set(sd->imf_context,
1068                                             (long *)ecore_evas_window_get(ecore_evas_ecore_evas_get(evas)));
1069         ecore_imf_context_client_canvas_set(sd->imf_context, evas);
1070         ecore_imf_context_retrieve_surrounding_callback_set(sd->imf_context,
1071                                                             _e_entry_cb_imf_retrieve_surrounding,
1072                                                             sd);
1073         ecore_imf_context_event_callback_add(sd->imf_context, ECORE_IMF_CALLBACK_COMMIT, _e_entry_cb_imf_event_commit, object);
1074         ecore_imf_context_event_callback_add(sd->imf_context, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, _e_entry_cb_imf_event_preedit_changed, object);
1075         ecore_imf_context_event_callback_add(sd->imf_context, ECORE_IMF_CALLBACK_DELETE_SURROUNDING, _e_entry_cb_imf_event_delete_surrounding, sd);
1076      }
1077 #endif
1078
1079    sd->enabled = 1;
1080    sd->focused = 0;
1081    sd->selection_dragging = 0;
1082    sd->selection_mode = 0;
1083    sd->valign = 0.5;
1084
1085    o = edje_object_add(evas);
1086    sd->entry_object = o;
1087    e_theme_edje_object_set(o, "base/theme/widgets", "e/widgets/entry");
1088    evas_object_smart_member_add(o, object);
1089
1090    o = e_editable_add(evas);
1091    sd->editable_object = o;
1092    e_editable_theme_set(o, "base/theme/widgets", "e/widgets/entry");
1093    e_editable_cursor_hide(o);
1094    e_editable_char_size_get(o, &cw, &ch);
1095    edje_extern_object_min_size_set(o, cw, ch);
1096    edje_object_part_swallow(sd->entry_object, "e.swallow.text", o);
1097    edje_object_size_min_calc(sd->entry_object, &sd->min_width, &sd->height);
1098    evas_object_show(o);
1099
1100    evas_object_event_callback_add(object, EVAS_CALLBACK_KEY_DOWN,
1101                                   _e_entry_key_down_cb, NULL);
1102    evas_object_event_callback_add(object, EVAS_CALLBACK_KEY_UP,
1103                                   _e_entry_key_up_cb, NULL);
1104    evas_object_event_callback_add(object, EVAS_CALLBACK_MOUSE_DOWN,
1105                                   _e_entry_mouse_down_cb, NULL);
1106    evas_object_event_callback_add(object, EVAS_CALLBACK_MOUSE_UP,
1107                                   _e_entry_mouse_up_cb, NULL);
1108    evas_object_event_callback_add(object, EVAS_CALLBACK_MOUSE_MOVE,
1109                                   _e_entry_mouse_move_cb, NULL);
1110    sd->selection_handler =
1111      ecore_event_handler_add(ECORE_X_EVENT_SELECTION_NOTIFY,
1112                              _e_entry_x_selection_notify_handler, object);
1113 }
1114
1115 static void
1116 _e_entry_smart_del(Evas_Object *object)
1117 {
1118    E_Entry_Smart_Data *sd;
1119
1120    if ((!object) || !(sd = evas_object_smart_data_get(object)))
1121      return;
1122
1123 #ifdef HAVE_ECORE_IMF
1124    if (sd->imf_context)
1125      {
1126         ecore_imf_context_event_callback_del(sd->imf_context, ECORE_IMF_CALLBACK_COMMIT, _e_entry_cb_imf_event_commit);
1127         ecore_imf_context_event_callback_del(sd->imf_context, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, _e_entry_cb_imf_event_preedit_changed);
1128         ecore_imf_context_event_callback_del(sd->imf_context, ECORE_IMF_CALLBACK_DELETE_SURROUNDING, _e_entry_cb_imf_event_delete_surrounding);
1129
1130         ecore_imf_context_del(sd->imf_context);
1131      }
1132 #endif
1133
1134    evas_object_event_callback_del(object, EVAS_CALLBACK_KEY_DOWN,
1135                                   _e_entry_key_down_cb);
1136    evas_object_event_callback_del(object, EVAS_CALLBACK_KEY_UP,
1137                                   _e_entry_key_up_cb);
1138    evas_object_event_callback_del(object, EVAS_CALLBACK_MOUSE_DOWN,
1139                                   _e_entry_mouse_down_cb);
1140    evas_object_event_callback_del(object, EVAS_CALLBACK_MOUSE_UP,
1141                                   _e_entry_mouse_up_cb);
1142    evas_object_event_callback_del(object, EVAS_CALLBACK_MOUSE_MOVE,
1143                                   _e_entry_mouse_move_cb);
1144
1145    if (sd->selection_handler)
1146      ecore_event_handler_del(sd->selection_handler);
1147    evas_object_del(sd->editable_object);
1148    evas_object_del(sd->entry_object);
1149    free(sd);
1150 }
1151
1152 static void
1153 _e_entry_smart_move(Evas_Object *object, Evas_Coord x, Evas_Coord y)
1154 {
1155    E_Entry_Smart_Data *sd;
1156    Evas_Coord prev_x, prev_y;
1157    Evas_Coord ox, oy;
1158
1159    if ((!object) || !(sd = evas_object_smart_data_get(object)))
1160      return;
1161
1162    evas_object_geometry_get(object, &prev_x, &prev_y, NULL, NULL);
1163    evas_object_geometry_get(sd->entry_object, &ox, &oy, NULL, NULL);
1164    evas_object_move(sd->entry_object, ox + (x - prev_x), oy + (y - prev_y));
1165 }
1166
1167 static void
1168 _e_entry_smart_resize(Evas_Object *object, Evas_Coord w, Evas_Coord h)
1169 {
1170    E_Entry_Smart_Data *sd;
1171    Evas_Coord x, y;
1172
1173    if ((!object) || !(sd = evas_object_smart_data_get(object)))
1174      return;
1175
1176    evas_object_geometry_get(object, &x, &y, NULL, NULL);
1177    evas_object_move(sd->entry_object, x, y + ((h - sd->height) * sd->valign));
1178    evas_object_resize(sd->entry_object, w, sd->height);
1179 }
1180
1181 static void
1182 _e_entry_smart_show(Evas_Object *object)
1183 {
1184    E_Entry_Smart_Data *sd;
1185
1186    if ((!object) || !(sd = evas_object_smart_data_get(object)))
1187      return;
1188    evas_object_show(sd->entry_object);
1189 }
1190
1191 static void
1192 _e_entry_smart_hide(Evas_Object *object)
1193 {
1194    E_Entry_Smart_Data *sd;
1195
1196    if ((!object) || !(sd = evas_object_smart_data_get(object)))
1197      return;
1198    evas_object_hide(sd->entry_object);
1199 }
1200
1201 static void
1202 _e_entry_color_set(Evas_Object *object, int r, int g, int b, int a)
1203 {
1204    E_Entry_Smart_Data *sd;
1205
1206    if ((!object) || !(sd = evas_object_smart_data_get(object)))
1207      return;
1208    evas_object_color_set(sd->entry_object, r, g, b, a);
1209 }
1210
1211 static void
1212 _e_entry_clip_set(Evas_Object *object, Evas_Object *clip)
1213 {
1214    E_Entry_Smart_Data *sd;
1215
1216    if ((!object) || !(sd = evas_object_smart_data_get(object)))
1217      return;
1218    evas_object_clip_set(sd->entry_object, clip);
1219 }
1220
1221 static void
1222 _e_entry_clip_unset(Evas_Object *object)
1223 {
1224    E_Entry_Smart_Data *sd;
1225
1226    if ((!object) || !(sd = evas_object_smart_data_get(object)))
1227      return;
1228    evas_object_clip_unset(sd->entry_object);
1229 }
1230
1231 static void
1232 _e_entry_cb_menu_post(void *data, E_Menu *m __UNUSED__)
1233 {
1234    E_Entry_Smart_Data *sd;
1235
1236    sd = data;
1237    if (!sd->popup) return;
1238    e_object_del(E_OBJECT(sd->popup));
1239    sd->popup = NULL;
1240 }
1241
1242 static void
1243 _e_entry_cb_cut(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
1244 {
1245    E_Entry_Smart_Data *sd;
1246    Evas_Object *editable;
1247    int cursor_pos, selection_pos;
1248    int start_pos, end_pos;
1249    int selecting, changed;
1250    char *range;
1251    E_Win *win;
1252
1253    sd = data;
1254    if (!sd->enabled) return;
1255
1256    editable = sd->editable_object;
1257    cursor_pos = e_editable_cursor_pos_get(editable);
1258    selection_pos = e_editable_selection_pos_get(editable);
1259    start_pos = (cursor_pos <= selection_pos) ? cursor_pos : selection_pos;
1260    end_pos = (cursor_pos >= selection_pos) ? cursor_pos : selection_pos;
1261    selecting = (start_pos != end_pos);
1262    if (!selecting) return;
1263
1264    range = e_editable_text_range_get(editable, start_pos, end_pos);
1265    if (range)
1266      {
1267         if ((win = e_win_evas_object_win_get(sd->entry_object)))
1268           ecore_x_selection_clipboard_set(win->evas_win,
1269                                           range, strlen(range) + 1);
1270         free(range);
1271      }
1272    changed = e_editable_delete(editable, start_pos, end_pos);
1273    if (changed)
1274      evas_object_smart_callback_call(sd->entry_object, "changed", NULL);
1275 }
1276
1277 static void
1278 _e_entry_cb_copy(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
1279 {
1280    E_Entry_Smart_Data *sd;
1281    Evas_Object *editable;
1282    int cursor_pos, selection_pos;
1283    int start_pos, end_pos;
1284    int selecting;
1285    char *range;
1286    E_Win *win;
1287
1288    sd = data;
1289
1290    editable = sd->editable_object;
1291    cursor_pos = e_editable_cursor_pos_get(editable);
1292    selection_pos = e_editable_selection_pos_get(editable);
1293    start_pos = (cursor_pos <= selection_pos) ? cursor_pos : selection_pos;
1294    end_pos = (cursor_pos >= selection_pos) ? cursor_pos : selection_pos;
1295    selecting = (start_pos != end_pos);
1296    if (!selecting) return;
1297
1298    range = e_editable_text_range_get(editable, start_pos, end_pos);
1299    if (range)
1300      {
1301         if ((win = e_win_evas_object_win_get(sd->entry_object)))
1302           ecore_x_selection_clipboard_set(win->evas_win,
1303                                           range, strlen(range) + 1);
1304         free(range);
1305      }
1306 }
1307
1308 static void
1309 _e_entry_cb_paste(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
1310 {
1311    E_Entry_Smart_Data *sd;
1312    E_Win *win;
1313
1314    sd = data;
1315    if (!sd->enabled) return;
1316
1317    if ((win = e_win_evas_object_win_get(sd->entry_object)))
1318      ecore_x_selection_clipboard_request(win->evas_win,
1319                                          ECORE_X_SELECTION_TARGET_UTF8_STRING);
1320 }
1321
1322 static void
1323 _e_entry_cb_select_all(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
1324 {
1325    E_Entry_Smart_Data *sd;
1326
1327    sd = data;
1328    e_editable_select_all(sd->editable_object);
1329    _e_entry_x_selection_update(sd->entry_object);
1330 }
1331
1332 static void
1333 _e_entry_cb_delete(void *data, E_Menu *m __UNUSED__, E_Menu_Item *mi __UNUSED__)
1334 {
1335    E_Entry_Smart_Data *sd;
1336    Evas_Object *editable;
1337    int cursor_pos, selection_pos;
1338    int start_pos, end_pos;
1339    int selecting;
1340    char *range;
1341
1342    sd = data;
1343    if (!sd->enabled) return;
1344
1345    editable = sd->editable_object;
1346    cursor_pos = e_editable_cursor_pos_get(editable);
1347    selection_pos = e_editable_selection_pos_get(editable);
1348    start_pos = (cursor_pos <= selection_pos) ? cursor_pos : selection_pos;
1349    end_pos = (cursor_pos >= selection_pos) ? cursor_pos : selection_pos;
1350    selecting = (start_pos != end_pos);
1351    if (!selecting) return;
1352
1353    range = e_editable_text_range_get(editable, start_pos, end_pos);
1354    if (range)
1355      {
1356         e_editable_delete(editable, start_pos, end_pos);
1357         evas_object_smart_callback_call(sd->entry_object, "changed", NULL);
1358         free(range);
1359      }
1360 }
1361
1362 static void
1363 _e_entry_imf_context_reset(Evas_Object *object)
1364 {
1365    E_Entry_Smart_Data *sd;
1366
1367    if ((!object) || !(sd = evas_object_smart_data_get(object)))
1368      return;
1369
1370 #ifdef HAVE_ECORE_IMF
1371    if (sd->imf_context)
1372      ecore_imf_context_reset(sd->imf_context);
1373 #endif
1374 }
1375
1376 static void
1377 _e_entry_imf_cursor_info_set(Evas_Object *object)
1378 {
1379    E_Entry_Smart_Data *sd;
1380 #ifdef HAVE_ECORE_IMF
1381    Evas_Coord cx, cy, cw, ch;
1382    Evas_Object *editable;
1383 #endif
1384
1385    if ((!object) || !(sd = evas_object_smart_data_get(object)))
1386      return;
1387
1388 #ifdef HAVE_ECORE_IMF
1389    if (!sd || !sd->imf_context) return;
1390
1391    editable = sd->editable_object;
1392
1393    e_editable_cursor_geometry_get(editable, &cx, &cy, &cw, &ch);
1394
1395    ecore_imf_context_cursor_position_set(sd->imf_context,
1396                                          e_editable_cursor_pos_get(editable));
1397    ecore_imf_context_cursor_location_set(sd->imf_context, cx, cy, cw, ch);
1398 #endif
1399 }
1400
1401 #ifdef HAVE_ECORE_IMF
1402 static Eina_Bool
1403 _e_entry_cb_imf_retrieve_surrounding(void *data, Ecore_IMF_Context *ctx __UNUSED__, char **text, int *cursor_pos)
1404 {
1405    E_Entry_Smart_Data *sd;
1406
1407    sd = data;
1408
1409    if (text)
1410      {
1411         const char *str;
1412
1413         str = e_editable_text_get(sd->editable_object);
1414         *text = str ? strdup(str) : strdup("");
1415      }
1416
1417    if (cursor_pos)
1418      *cursor_pos = e_editable_cursor_pos_get(sd->editable_object);
1419
1420    return EINA_TRUE;
1421 }
1422
1423 static void
1424 _e_entry_cb_imf_event_commit(void *data, Ecore_IMF_Context *ctx __UNUSED__, void *event_info)
1425 {
1426    Evas_Object *entry;
1427    E_Entry_Smart_Data *sd;
1428    Evas_Object *editable;
1429    char *commit_str = event_info;
1430    int cursor_pos, selection_pos;
1431    int start_pos, end_pos;
1432    int selecting;
1433    int changed = 0;
1434
1435    if ((!(entry = data)) || (!(sd = evas_object_smart_data_get(entry))))
1436      return;
1437
1438    if (!sd->imf_context)
1439      return;
1440
1441    editable = sd->editable_object;
1442    cursor_pos = e_editable_cursor_pos_get(editable);
1443    selection_pos = e_editable_selection_pos_get(editable);
1444    start_pos = (cursor_pos <= selection_pos) ? cursor_pos : selection_pos;
1445    end_pos = (cursor_pos >= selection_pos) ? cursor_pos : selection_pos;
1446    selecting = (start_pos != end_pos);
1447
1448    if (selecting)
1449      changed |= e_editable_delete(editable, start_pos, end_pos);
1450
1451    /* delete preedit characters */
1452    if (sd->have_preedit)
1453      {
1454         if (sd->preedit_start_pos != sd->preedit_end_pos)
1455           e_editable_delete(editable, sd->preedit_start_pos, sd->preedit_end_pos);
1456         sd->have_preedit = EINA_FALSE;
1457         start_pos = sd->preedit_start_pos;
1458      }
1459
1460    changed |= e_editable_insert(editable, start_pos, commit_str);
1461
1462    _e_entry_imf_cursor_info_set(entry);
1463
1464    if (changed)
1465      evas_object_smart_callback_call(entry, "changed", NULL);
1466 }
1467
1468 static void
1469 _e_entry_cb_imf_event_preedit_changed(void *data, Ecore_IMF_Context *ctx __UNUSED__, void *event_info __UNUSED__)
1470 {
1471    Evas_Object *entry;
1472    E_Entry_Smart_Data *sd;
1473    Evas_Object *editable;
1474    int cursor_pos, selection_pos;
1475    char *preedit_string = NULL;
1476    int start_pos, end_pos;
1477    int selecting;
1478    int changed = 0;
1479
1480    if ((!(entry = data)) || (!(sd = evas_object_smart_data_get(entry))))
1481      return;
1482
1483    if (!sd->imf_context)
1484      return;
1485
1486    /* Get the preedit string from IMF */
1487    ecore_imf_context_preedit_string_get(sd->imf_context, &preedit_string, &cursor_pos);
1488    if (!preedit_string) return;
1489
1490    editable = sd->editable_object;
1491    cursor_pos = e_editable_cursor_pos_get(editable);
1492    selection_pos = e_editable_selection_pos_get(editable);
1493    start_pos = (cursor_pos <= selection_pos) ? cursor_pos : selection_pos;
1494    end_pos = (cursor_pos >= selection_pos) ? cursor_pos : selection_pos;
1495    selecting = (start_pos != end_pos);
1496
1497    if (selecting)
1498      changed |= e_editable_delete(editable, start_pos, end_pos);
1499
1500    /* delete preedit characters */
1501    if (sd->have_preedit)
1502      {
1503         if (sd->preedit_start_pos != sd->preedit_end_pos)
1504           e_editable_delete(editable, sd->preedit_start_pos, sd->preedit_end_pos);
1505      }
1506
1507    cursor_pos = e_editable_cursor_pos_get(editable);
1508    sd->preedit_start_pos = cursor_pos;
1509
1510    /* insert preedit character(s) */
1511    changed |= e_editable_insert(editable, cursor_pos, preedit_string);
1512
1513    sd->preedit_end_pos = e_editable_cursor_pos_get(editable);
1514
1515    if (!strcmp(preedit_string, ""))
1516      sd->have_preedit = EINA_FALSE;
1517    else
1518      sd->have_preedit = EINA_TRUE;
1519
1520    _e_entry_imf_cursor_info_set(entry);
1521
1522    if (changed)
1523      evas_object_smart_callback_call(entry, "preedit,changed", NULL);
1524
1525    free(preedit_string);
1526 }
1527
1528 static void
1529 _e_entry_cb_imf_event_delete_surrounding(void *data, Ecore_IMF_Context *ctx __UNUSED__, void *event_info)
1530 {
1531    E_Entry_Smart_Data *sd;
1532    Ecore_IMF_Event_Delete_Surrounding *ev = event_info;
1533    Evas_Object *editable;
1534    int cursor_pos;
1535
1536    sd = data;
1537
1538    if ((!sd) || (!sd->imf_context))
1539      return;
1540
1541    editable = sd->editable_object;
1542    cursor_pos = e_editable_cursor_pos_get(editable);
1543    e_editable_delete(editable,
1544                      cursor_pos + ev->offset,
1545                      cursor_pos + ev->offset + ev->n_chars);
1546 }
1547 #endif