574968daf4f29a576a74268e35b7a4d3881b7195
[framework/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    Ecore_Event_Handler *imf_ee_commit_handler;
20    Ecore_Event_Handler *imf_ee_delete_handler;
21    
22    int enabled;
23    int focused;
24    int selection_dragging;
25    int selection_mode;
26    float valign;
27    int min_width;
28    int height;
29 };
30
31 /* local subsystem functions */
32 static void _e_entry_key_down_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
33 static void _e_entry_key_up_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
34 static void _e_entry_mouse_down_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
35 static void _e_entry_mouse_up_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
36 static void _e_entry_mouse_move_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
37 static Eina_Bool _e_entry_x_selection_notify_handler(void *data, int type, void *event);
38
39 static void _e_entry_x_selection_update(Evas_Object *entry);
40 static void _e_entry_key_down_windows(Evas_Object *entry, Evas_Event_Key_Down *event);
41 static void _e_entry_key_down_emacs(Evas_Object *entry, Evas_Event_Key_Down *event);
42
43 static void _e_entry_smart_add(Evas_Object *object);
44 static void _e_entry_smart_del(Evas_Object *object);
45 static void _e_entry_smart_move(Evas_Object *object, Evas_Coord x, Evas_Coord y);
46 static void _e_entry_smart_resize(Evas_Object *object, Evas_Coord w, Evas_Coord h);
47 static void _e_entry_smart_show(Evas_Object *object);
48 static void _e_entry_smart_hide(Evas_Object *object);
49 static void _e_entry_color_set(Evas_Object *object, int r, int g, int b, int a);
50 static void _e_entry_clip_set(Evas_Object *object, Evas_Object *clip);
51 static void _e_entry_clip_unset(Evas_Object *object);
52 static void _e_entry_cb_menu_post(void *data, E_Menu *m);
53 static void _e_entry_cb_cut(void *data, E_Menu *m, E_Menu_Item *mi);
54 static void _e_entry_cb_copy(void *data, E_Menu *m, E_Menu_Item *mi);
55 static void _e_entry_cb_paste(void *data, E_Menu *m, E_Menu_Item *mi);
56 static void _e_entry_cb_select_all(void *data, E_Menu *m, E_Menu_Item *mi);
57 static void _e_entry_cb_delete(void *data, E_Menu *m, E_Menu_Item *mi);
58 #ifdef HAVE_ECORE_IMF
59 static Eina_Bool _e_entry_cb_imf_retrieve_surrounding(void *data, Ecore_IMF_Context *ctx, char **text, int *cursor_pos);
60 static Eina_Bool _e_entry_cb_imf_event_commit(void *data, int type, void *event);
61 static Eina_Bool _e_entry_cb_imf_event_delete_surrounding(void *data, int type, void *event);
62 #endif
63
64 /* local subsystem globals */
65 static Evas_Smart *_e_entry_smart = NULL;
66 static int _e_entry_smart_use = 0;
67 static int _e_entry_emacs_keybindings = 0;
68
69
70 /* externally accessible functions */
71
72 /**
73  * Creates a new entry object. An entry is a field where the user can type
74  * single-line text.
75  * Use the "changed" smart callback to know when the content of the entry is
76  * changed
77  *
78  * @param evas the evas where the entry object should be added
79  * @return Returns the new entry object
80  */
81 EAPI Evas_Object *
82 e_entry_add(Evas *evas)
83 {
84    if (!_e_entry_smart)
85      {
86         static const Evas_Smart_Class sc =
87           {
88              "e_entry",
89                EVAS_SMART_CLASS_VERSION,
90                _e_entry_smart_add,
91                _e_entry_smart_del,
92                _e_entry_smart_move,
93                _e_entry_smart_resize,
94                _e_entry_smart_show,
95                _e_entry_smart_hide,
96                _e_entry_color_set,
97                _e_entry_clip_set,
98                _e_entry_clip_unset,
99                NULL,
100                NULL,
101                NULL,
102                NULL,
103                NULL,
104                NULL,
105                NULL
106           };
107         _e_entry_smart = evas_smart_class_new(&sc);
108         _e_entry_smart_use = 0;
109      }
110    
111    _e_entry_smart_use++;
112    return evas_object_smart_add(evas, _e_entry_smart);
113 }
114
115 /**
116  * Sets the text of the entry object
117  *
118  * @param entry an entry object
119  * @param text the text to set
120  */
121 EAPI void
122 e_entry_text_set(Evas_Object *entry, const char *text)
123 {
124    E_Entry_Smart_Data *sd;
125    
126    if ((!entry) || (!(sd = evas_object_smart_data_get(entry))))
127      return;
128    
129    e_editable_text_set(sd->editable_object, text);
130    evas_object_smart_callback_call(entry, "changed", NULL);
131 }
132
133 /**
134  * Gets the text of the entry object
135  *
136  * @param entry an entry object
137  * @return Returns the text of the entry object
138  */
139 EAPI const char *
140 e_entry_text_get(Evas_Object *entry)
141 {
142    E_Entry_Smart_Data *sd;
143    
144    if ((!entry) || (!(sd = evas_object_smart_data_get(entry))))
145      return NULL;
146    return e_editable_text_get(sd->editable_object);
147 }
148
149 /**
150  * Clears the entry object
151  *
152  * @param entry an entry object
153  */
154 EAPI void
155 e_entry_clear(Evas_Object *entry)
156 {
157    e_entry_text_set(entry, "");
158 }
159
160 /**
161  * Gets the editable object used by the entry object. It will allow you to have
162  * better control on the text, the cursor or the selection of the entry with
163  * the e_editable_*() functions.
164  *
165  * @param entry an entry object
166  * @return Returns the editable object used by the entry object
167  */
168 EAPI Evas_Object *
169 e_entry_editable_object_get(Evas_Object *entry)
170 {
171    E_Entry_Smart_Data *sd;
172    
173    if ((!entry) || (!(sd = evas_object_smart_data_get(entry))))
174      return NULL;
175    return sd->editable_object;
176 }
177
178 /**
179  * Sets whether or not the entry object is in password mode. In password mode,
180  * the entry displays '*' instead of the characters
181  *
182  * @param entry an entry object
183  * @param password_mode 1 to turn on password mode, 0 to turn it off
184  */
185 EAPI void
186 e_entry_password_set(Evas_Object *entry, int password_mode)
187 {
188    E_Entry_Smart_Data *sd;
189    
190    if ((!entry) || (!(sd = evas_object_smart_data_get(entry))))
191      return;
192    e_editable_password_set(sd->editable_object, password_mode);
193 #ifdef HAVE_ECORE_IMF
194    if (sd->imf_context)
195      ecore_imf_context_input_mode_set(sd->imf_context,
196                                       password_mode ? ECORE_IMF_INPUT_MODE_FULL & ECORE_IMF_INPUT_MODE_INVISIBLE :
197                                                       ECORE_IMF_INPUT_MODE_FULL);
198 #endif
199 }
200
201 /**
202  * Gets the minimum size of the entry object
203  *
204  * @param entry an entry object
205  * @param minw the location where to store the minimun width of the entry
206  * @param minh the location where to store the minimun height of the entry
207  */
208 EAPI void
209 e_entry_size_min_get(Evas_Object *entry, Evas_Coord *minw, Evas_Coord *minh)
210 {
211    E_Entry_Smart_Data *sd;
212    
213    if ((!entry) || (!(sd = evas_object_smart_data_get(entry))))
214      return;
215    
216    if (minw) *minw = sd->min_width;
217    if (minh) *minh = sd->height;
218 }
219
220 /**
221  * Focuses the entry object. It will receives keyboard events and the user could
222  * then type some text (the entry should also be enabled. The cursor and the
223  * selection will be shown
224  *
225  * @param entry the entry to focus
226  */
227 EAPI void
228 e_entry_focus(Evas_Object *entry)
229 {
230    E_Entry_Smart_Data *sd;
231    
232    if ((!entry) || (!(sd = evas_object_smart_data_get(entry))))
233      return;
234    if (sd->focused)
235       return;
236    
237    evas_object_focus_set(entry, 1);
238    edje_object_signal_emit(sd->entry_object, "e,state,focused", "e");
239    if (!sd->selection_dragging)
240      {
241         e_editable_cursor_move_to_end(sd->editable_object);
242 #ifdef HAVE_ECORE_IMF
243         if (sd->imf_context)
244           {
245              ecore_imf_context_reset(sd->imf_context);
246              ecore_imf_context_cursor_position_set(sd->imf_context,
247                                                    e_editable_cursor_pos_get(sd->editable_object));
248           }
249 #endif
250         e_editable_selection_move_to_end(sd->editable_object);
251      }
252    if (sd->enabled)
253       e_editable_cursor_show(sd->editable_object);
254    e_editable_selection_show(sd->editable_object);
255 #ifdef HAVE_ECORE_IMF
256    if (sd->imf_context)
257      {
258         ecore_imf_context_reset(sd->imf_context);
259         ecore_imf_context_focus_in(sd->imf_context);
260      }
261 #endif
262    sd->focused = 1;
263 }
264
265 /**
266  * Unfocuses the entry object. It will no longer receives keyboard events so
267  * the user could no longer type some text. The cursor and the selection will
268  * be hidden
269  *
270  * @param entry the entry object to unfocus
271  */
272 EAPI void
273 e_entry_unfocus(Evas_Object *entry)
274 {
275    E_Entry_Smart_Data *sd;
276    
277    if ((!entry) || (!(sd = evas_object_smart_data_get(entry))))
278      return;
279    if (!sd->focused)
280      return;
281    
282    evas_object_focus_set(entry, 0);
283    edje_object_signal_emit(sd->entry_object, "e,state,unfocused", "e");
284    e_editable_cursor_hide(sd->editable_object);
285    e_editable_selection_hide(sd->editable_object);
286 #ifdef HAVE_ECORE_IMF
287    if (sd->imf_context)
288      {
289         ecore_imf_context_reset(sd->imf_context);
290         ecore_imf_context_focus_out(sd->imf_context);
291      }
292 #endif
293    sd->focused = 0;
294 }
295
296 /**
297  * Enables the entry object: the user will be able to type text
298  *
299  * @param entry the entry object to enable
300  */
301 EAPI void
302 e_entry_enable(Evas_Object *entry)
303 {
304    E_Entry_Smart_Data *sd;
305    
306    if ((!entry) || (!(sd = evas_object_smart_data_get(entry))))
307      return;
308    if (sd->enabled)
309      return;
310    
311    edje_object_signal_emit(sd->entry_object, "e,state,enabled", "e");
312    e_editable_enable(sd->editable_object);
313    if (sd->focused)
314      e_editable_cursor_show(sd->editable_object);
315    sd->enabled = 1;
316 }
317
318 /**
319  * Disables the entry object: the user won't be able to type anymore. Selection
320  * will still be possible (to copy the text)
321  *
322  * @param entry the entry object to disable
323  */
324 EAPI void
325 e_entry_disable(Evas_Object *entry)
326 {
327    E_Entry_Smart_Data *sd;
328    
329    if ((!entry) || (!(sd = evas_object_smart_data_get(entry))))
330      return;
331    if (!sd->enabled)
332      return;
333    
334    edje_object_signal_emit(sd->entry_object, "e,state,disabled", "e");
335    e_editable_disable(sd->editable_object);
336    e_editable_cursor_hide(sd->editable_object);
337    sd->enabled = 0;
338 }
339
340
341 /* Private functions */
342
343 /* Called when a key has been pressed by the user */
344 static void
345 _e_entry_key_down_cb(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info)
346 {
347    E_Entry_Smart_Data *sd;
348
349    if ((!obj) || (!(sd = evas_object_smart_data_get(obj))))
350      return;
351
352 #ifdef HAVE_ECORE_IMF
353    if (sd->imf_context)
354      {
355         Ecore_IMF_Event_Key_Down ev;
356
357         ecore_imf_evas_event_key_down_wrap(event_info, &ev);
358         if (ecore_imf_context_filter_event(sd->imf_context,
359                                            ECORE_IMF_EVENT_KEY_DOWN,
360                                            (Ecore_IMF_Event *) &ev))
361           return;
362      }
363 #endif
364
365    if (_e_entry_emacs_keybindings)
366      _e_entry_key_down_emacs(obj, event_info);
367    else
368      _e_entry_key_down_windows(obj, event_info);
369 }
370
371 /* Called when a key has been released by the user */
372 static void
373 _e_entry_key_up_cb(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info)
374 {
375    E_Entry_Smart_Data *sd;
376
377    if ((!obj) || (!(sd = evas_object_smart_data_get(obj))))
378      return;
379
380 #ifdef HAVE_ECORE_IMF
381    if (sd->imf_context)
382      {
383         Ecore_IMF_Event_Key_Up ev;
384
385         ecore_imf_evas_event_key_up_wrap(event_info, &ev);
386         if (ecore_imf_context_filter_event(sd->imf_context,
387                                            ECORE_IMF_EVENT_KEY_UP,
388                                            (Ecore_IMF_Event *) &ev))
389           return;
390      }
391 #endif
392 }
393
394 /* Called when the entry object is pressed by the mouse */
395 static void
396 _e_entry_mouse_down_cb(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info)
397 {
398    E_Entry_Smart_Data *sd;
399    Evas_Event_Mouse_Down *event;
400    Evas_Coord ox, oy;
401    int pos;
402    
403    if ((!obj) || (!(sd = evas_object_smart_data_get(obj))))
404      return;
405    if (!(event = event_info))
406      return;
407
408 #ifdef HAVE_ECORE_IMF
409    if (sd->imf_context)
410      {
411         Ecore_IMF_Event_Mouse_Down ev;
412
413         ecore_imf_evas_event_mouse_down_wrap(event_info, &ev);
414         if (ecore_imf_context_filter_event(sd->imf_context,
415                                            ECORE_IMF_EVENT_MOUSE_DOWN,
416                                            (Ecore_IMF_Event *) &ev))
417           return;
418      }
419 #endif
420
421    evas_object_geometry_get(sd->editable_object, &ox, &oy, NULL, NULL);
422    pos = e_editable_pos_get_from_coords(sd->editable_object,
423                                         event->canvas.x - ox,
424                                         event->canvas.y - oy);
425   
426    if (event->button == 1)
427      {
428         if (event->flags & EVAS_BUTTON_TRIPLE_CLICK)
429           {
430              e_editable_select_all(sd->editable_object);
431              _e_entry_x_selection_update(obj);
432           }
433         else if (event->flags & EVAS_BUTTON_DOUBLE_CLICK)
434           {
435              e_editable_select_word(sd->editable_object, pos);
436              _e_entry_x_selection_update(obj);
437           }
438         else
439           {
440              e_editable_cursor_pos_set(sd->editable_object, pos);
441              if (!evas_key_modifier_is_set(event->modifiers, "Shift"))
442                e_editable_selection_pos_set(sd->editable_object, pos);
443              
444              sd->selection_dragging = 1;
445           }
446      }
447    else if (event->button == 2)
448      {
449         E_Win *win;
450         
451         e_editable_cursor_pos_set(sd->editable_object, pos);
452         e_editable_selection_pos_set(sd->editable_object, pos);
453         
454         if ((win = e_win_evas_object_win_get(obj)))
455           ecore_x_selection_primary_request(win->evas_win,
456                                             ECORE_X_SELECTION_TARGET_UTF8_STRING);
457      }
458    else if (event->button == 3) 
459      {
460         E_Menu_Item *mi;
461         E_Manager *man;
462         E_Container *con;
463         int x, y;
464         int cursor_pos, selection_pos;
465         int start_pos, end_pos;
466         int s_enabled, s_selecting, s_empty, s_passwd;
467
468         cursor_pos = e_editable_cursor_pos_get(sd->editable_object);
469         selection_pos = e_editable_selection_pos_get(sd->editable_object);
470         start_pos = (cursor_pos <= selection_pos) ? cursor_pos : selection_pos;
471         end_pos = (cursor_pos >= selection_pos) ? cursor_pos : selection_pos;
472
473         s_selecting = (start_pos != end_pos);
474         s_enabled = sd->enabled;
475         s_empty = !e_editable_text_length_get(sd->editable_object);
476         s_passwd = e_editable_password_get(sd->editable_object);
477         
478         if (!s_selecting && !s_enabled && s_empty) return;
479
480         man = e_manager_current_get();
481         con = e_container_current_get(man);
482         ecore_x_pointer_xy_get(con->win, &x, &y);
483
484         /* Popup a menu */
485         sd->popup = e_menu_new();
486         e_menu_post_deactivate_callback_set(sd->popup, 
487                                             _e_entry_cb_menu_post, sd);
488         if (s_selecting)
489           {
490              if (s_enabled)
491                {
492                   mi = e_menu_item_new(sd->popup);
493                   e_menu_item_label_set(mi, _("Delete"));
494                   e_util_menu_item_theme_icon_set(mi, "edit-delete");
495                   e_menu_item_callback_set(mi, _e_entry_cb_delete, sd);
496              
497                   mi = e_menu_item_new(sd->popup);
498                   e_menu_item_separator_set(mi, 1);
499
500                   if (!s_passwd)
501                     {
502                        mi = e_menu_item_new(sd->popup);
503                        e_menu_item_label_set(mi, _("Cut"));
504                        e_util_menu_item_theme_icon_set(mi, "edit-cut");
505                        e_menu_item_callback_set(mi, _e_entry_cb_cut, sd);
506                     }
507                }
508              if (!s_passwd)
509                {
510                   mi = e_menu_item_new(sd->popup);
511                   e_menu_item_label_set(mi, _("Copy"));
512                   e_util_menu_item_theme_icon_set(mi, "edit-copy");
513                   e_menu_item_callback_set(mi, _e_entry_cb_copy, sd);
514                }
515           }
516         if (sd->enabled)
517           {
518              mi = e_menu_item_new(sd->popup);
519              e_menu_item_label_set(mi, _("Paste"));
520              e_util_menu_item_theme_icon_set(mi, "edit-paste");
521              e_menu_item_callback_set(mi, _e_entry_cb_paste, sd);
522           }
523         if (!s_empty)
524           {
525              mi = e_menu_item_new(sd->popup);
526              e_menu_item_separator_set(mi, 1);
527              
528              mi = e_menu_item_new(sd->popup);
529              e_menu_item_label_set(mi, _("Select All"));
530              e_util_menu_item_theme_icon_set(mi, "edit-select-all");
531              e_menu_item_callback_set(mi, _e_entry_cb_select_all, sd);
532           }
533
534         e_menu_activate_mouse(sd->popup, e_util_zone_current_get(man),
535                               x, y, 1, 1, 
536                               E_MENU_POP_DIRECTION_DOWN, event->timestamp);
537      }
538
539 #ifdef HAVE_ECORE_IMF
540    if (sd->imf_context)
541      {
542         ecore_imf_context_reset(sd->imf_context);
543         ecore_imf_context_cursor_position_set(sd->imf_context,
544                                               e_editable_cursor_pos_get(sd->editable_object));
545      }
546 #endif
547 }
548
549 /* Called when the entry object is released by the mouse */
550 static void
551 _e_entry_mouse_up_cb(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info)
552 {
553    E_Entry_Smart_Data *sd;
554    
555    if ((!obj) || (!(sd = evas_object_smart_data_get(obj))))
556      return;
557    
558 #ifdef HAVE_ECORE_IMF
559    if (sd->imf_context)
560      {
561         Ecore_IMF_Event_Mouse_Up ev;
562
563         ecore_imf_evas_event_mouse_up_wrap(event_info, &ev);
564         if (ecore_imf_context_filter_event(sd->imf_context,
565                                            ECORE_IMF_EVENT_MOUSE_UP,
566                                            (Ecore_IMF_Event *) &ev))
567           return;
568      }
569 #endif
570
571    if (sd->selection_dragging)
572      {
573         sd->selection_dragging = 0;
574         _e_entry_x_selection_update(obj);
575      }
576 }
577
578 /* Called when the mouse moves over the entry object */
579 static void
580 _e_entry_mouse_move_cb(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info)
581 {
582    E_Entry_Smart_Data *sd;
583    Evas_Event_Mouse_Move *event;
584    Evas_Coord ox, oy;
585    int pos;
586    
587    if ((!obj) || (!(sd = evas_object_smart_data_get(obj))))
588      return;
589    if (!(event = event_info))
590      return;
591
592 #ifdef HAVE_ECORE_IMF
593    if (sd->imf_context)
594      {
595         Ecore_IMF_Event_Mouse_Move ev;
596
597         ecore_imf_evas_event_mouse_move_wrap(event_info, &ev);
598         if (ecore_imf_context_filter_event(sd->imf_context,
599                                            ECORE_IMF_EVENT_MOUSE_MOVE,
600                                            (Ecore_IMF_Event *) &ev))
601           return;
602      }
603 #endif
604
605    if (sd->selection_dragging)
606      {
607         evas_object_geometry_get(sd->editable_object, &ox, &oy, NULL, NULL);
608         pos = e_editable_pos_get_from_coords(sd->editable_object,
609                                              event->cur.canvas.x - ox,
610                                              event->cur.canvas.y - oy);
611         e_editable_cursor_pos_set(sd->editable_object, pos);
612 #ifdef HAVE_ECORE_IMF
613         if (sd->imf_context)
614           {
615              ecore_imf_context_reset(sd->imf_context);
616              ecore_imf_context_cursor_position_set(sd->imf_context,
617                                                    pos);
618           }
619 #endif
620      }
621 }
622
623 /* Called when the the "selection_notify" event is emitted */
624 static Eina_Bool
625 _e_entry_x_selection_notify_handler(void *data, int type __UNUSED__, void *event)
626 {
627    Evas_Object *entry;
628    E_Entry_Smart_Data *sd;
629    Ecore_X_Event_Selection_Notify *ev;
630    Evas_Object *editable;
631    int cursor_pos, selection_pos;
632    int start_pos, end_pos;
633    int selecting;
634    int changed = 0;
635    
636    if ((!(entry = data)) || (!(sd = evas_object_smart_data_get(entry))))
637      return 1;
638    if (!sd->focused)
639      return 1;
640    
641    editable = sd->editable_object;
642    cursor_pos = e_editable_cursor_pos_get(editable);
643    selection_pos = e_editable_selection_pos_get(editable);
644    start_pos = (cursor_pos <= selection_pos) ? cursor_pos : selection_pos;
645    end_pos = (cursor_pos >= selection_pos) ? cursor_pos : selection_pos;
646    selecting = (start_pos != end_pos);
647    
648    ev = event;
649    if ((ev->selection == ECORE_X_SELECTION_CLIPBOARD) ||
650        (ev->selection == ECORE_X_SELECTION_PRIMARY))
651      {
652         if (strcmp(ev->target, ECORE_X_SELECTION_TARGET_UTF8_STRING) == 0)
653           {
654              Ecore_X_Selection_Data_Text *text_data;
655              
656              text_data = ev->data;
657              if (selecting && !_e_entry_emacs_keybindings)
658                changed |= e_editable_delete(editable, start_pos, end_pos);
659              changed |= e_editable_insert(editable, start_pos, text_data->text);
660           }
661      }
662    
663    if (changed)
664      evas_object_smart_callback_call(entry, "changed", NULL);
665    
666    return ECORE_CALLBACK_PASS_ON;
667 }
668
669 /* Updates the X selection with the selected text of the entry */
670 static void
671 _e_entry_x_selection_update(Evas_Object *entry)
672 {
673    E_Entry_Smart_Data *sd;
674    Evas_Object *editable;
675    E_Win *win;
676    int cursor_pos, selection_pos;
677    int start_pos, end_pos;
678    int selecting;
679    char *text;
680    
681    if ((!entry) || (!(sd = evas_object_smart_data_get(entry))))
682      return;
683    if (!(win = e_win_evas_object_win_get(entry)))
684      return;
685    
686    editable = sd->editable_object;
687    if (e_editable_password_get(editable)) return;
688
689    cursor_pos = e_editable_cursor_pos_get(editable);
690    selection_pos = e_editable_selection_pos_get(editable);
691    start_pos = (cursor_pos <= selection_pos) ? cursor_pos : selection_pos;
692    end_pos = (cursor_pos >= selection_pos) ? cursor_pos : selection_pos;
693    selecting = (start_pos != end_pos);
694   
695    if ((!selecting) ||
696        (!(text = e_editable_text_range_get(editable, start_pos, end_pos))))
697      return;
698
699    ecore_x_selection_primary_set(win->evas_win, text, strlen(text) + 1);
700    free(text);
701 }
702
703 /* Treats the "key down" event to mimick the behavior of Windows/Gtk2/Qt */
704 static void 
705 _e_entry_key_down_windows(Evas_Object *entry, Evas_Event_Key_Down *event)
706 {
707    E_Entry_Smart_Data *sd;
708    Evas_Object *editable;
709    int cursor_pos, selection_pos;
710    int start_pos, end_pos;
711    int selecting;
712    int changed = 0;
713    int selection_changed = 0;
714    char *range;
715    E_Win *win;
716    
717    if ((!entry) || (!(sd = evas_object_smart_data_get(entry))))
718      return;
719    if ((!event) || (!event->keyname))
720      return;
721
722    editable = sd->editable_object;
723    cursor_pos = e_editable_cursor_pos_get(editable);
724    selection_pos = e_editable_selection_pos_get(editable);
725    start_pos = (cursor_pos <= selection_pos) ? cursor_pos : selection_pos;
726    end_pos = (cursor_pos >= selection_pos) ? cursor_pos : selection_pos;
727    selecting = (start_pos != end_pos);
728    
729    /* Move the cursor/selection to the left */
730    if (strcmp(event->key, "Left") == 0)
731      {
732         if (evas_key_modifier_is_set(event->modifiers, "Shift"))
733           {
734              e_editable_cursor_move_left(editable);
735              selection_changed = 1;
736           }
737         else if (selecting)
738           {
739              if (cursor_pos < selection_pos)
740                e_editable_selection_pos_set(editable, cursor_pos);
741              else
742                e_editable_cursor_pos_set(editable, selection_pos);
743           }
744         else
745           {
746              e_editable_cursor_move_left(editable);
747              e_editable_selection_pos_set(editable,
748                                           e_editable_cursor_pos_get(editable));
749           }
750      }
751    /* Move the cursor/selection to the right */
752    else if (strcmp(event->key, "Right") == 0)
753      {
754         if (evas_key_modifier_is_set(event->modifiers, "Shift"))
755           {
756              e_editable_cursor_move_right(editable);
757              selection_changed = 1;
758           }
759         else if (selecting)
760           {
761              if (cursor_pos > selection_pos)
762                e_editable_selection_pos_set(editable, cursor_pos);
763              else
764                e_editable_cursor_pos_set(editable, selection_pos);
765           }
766         else
767           {
768              e_editable_cursor_move_right(editable);
769              e_editable_selection_pos_set(editable,
770                                           e_editable_cursor_pos_get(editable));
771           }
772      }
773    /* Move the cursor/selection to the start of the entry */
774    else if (strcmp(event->keyname, "Home") == 0)
775      {
776         e_editable_cursor_move_to_start(editable);
777         if (!evas_key_modifier_is_set(event->modifiers, "Shift"))
778           e_editable_selection_pos_set(editable,
779                                        e_editable_cursor_pos_get(editable));
780         else
781           selection_changed = 1;
782      }
783    /* Move the cursor/selection to the end of the entry */
784    else if (strcmp(event->keyname, "End") == 0)
785      {
786         e_editable_cursor_move_to_end(editable);
787         if (!evas_key_modifier_is_set(event->modifiers, "Shift"))
788           e_editable_selection_pos_set(editable,
789                                        e_editable_cursor_pos_get(editable));
790         else
791           selection_changed = 1;
792      }
793    /* Delete the previous character */
794    else if ((sd->enabled) && (strcmp(event->keyname, "BackSpace") == 0))
795      {
796         if (selecting)
797           changed = e_editable_delete(editable, start_pos, end_pos);
798         else
799           changed = e_editable_delete(editable, cursor_pos - 1, cursor_pos);
800      }
801    /* Delete the next character */
802    else if ((sd->enabled) && (strcmp(event->keyname, "Delete") == 0))
803      {
804         if (selecting)
805           changed = e_editable_delete(editable, start_pos, end_pos);
806         else
807           changed = e_editable_delete(editable, cursor_pos, cursor_pos + 1);
808      }
809    /* Ctrl + A,C,X,V */
810    else if (evas_key_modifier_is_set(event->modifiers, "Control"))
811      {
812         if (strcmp(event->keyname, "a") == 0)
813           {
814              e_editable_select_all(editable);
815              selection_changed = 1;
816           }
817         else if ((strcmp(event->keyname, "x") == 0) ||
818                  (strcmp(event->keyname, "c") == 0))
819           {
820              if (!e_editable_password_get(editable) && selecting)
821                {
822                  range = e_editable_text_range_get(editable, start_pos, end_pos);
823                  if (range)
824                    {
825                       if ((win = e_win_evas_object_win_get(entry)))
826                         ecore_x_selection_clipboard_set(win->evas_win,
827                                                         range,
828                                                         strlen(range) + 1);
829                       free(range);
830                    }
831                  if ((sd->enabled) && (strcmp(event->keyname, "x") == 0))
832                    changed = e_editable_delete(editable, start_pos, end_pos);
833                }
834            }
835         else if ((sd->enabled) && (strcmp(event->keyname, "v") == 0))
836           {
837              if ((win = e_win_evas_object_win_get(entry)))
838                ecore_x_selection_clipboard_request(win->evas_win,
839                                                    ECORE_X_SELECTION_TARGET_UTF8_STRING);
840           }
841      }
842    /* Otherwise, we insert the corresponding character */
843    else if ((event->string) && ((sd->enabled)) &&
844           ((strlen(event->string) != 1) || (event->string[0] >= 0x20)))
845      {
846         if (selecting)
847           changed |= e_editable_delete(editable, start_pos, end_pos);
848         changed |= e_editable_insert(editable, start_pos, event->string);
849      }
850
851 #ifdef HAVE_ECORE_IMF
852    if (sd->imf_context)
853      {
854         ecore_imf_context_reset(sd->imf_context);
855         ecore_imf_context_cursor_position_set(sd->imf_context,
856                                               e_editable_cursor_pos_get(editable));
857      }
858 #endif
859
860    if (changed)
861      evas_object_smart_callback_call(entry, "changed", NULL);
862    if (selection_changed)
863      _e_entry_x_selection_update(entry);
864 }
865
866 /* Treats the "key down" event to mimick the behavior of Emacs */
867 static void 
868 _e_entry_key_down_emacs(Evas_Object *entry, Evas_Event_Key_Down *event)
869 {
870    E_Entry_Smart_Data *sd;
871    Evas_Object *editable;
872    int cursor_pos, selection_pos;
873    int start_pos, end_pos;
874    int selecting;
875    int changed = 0;
876    int selection_changed = 0;
877    char *range;
878    E_Win *win;
879    
880    if ((!entry) || (!(sd = evas_object_smart_data_get(entry))))
881      return;
882    if ((!event) || (!event->keyname))
883      return;
884
885    editable = sd->editable_object;
886    cursor_pos = e_editable_cursor_pos_get(editable);
887    selection_pos = e_editable_selection_pos_get(editable);
888    start_pos = (cursor_pos <= selection_pos) ? cursor_pos : selection_pos;
889    end_pos = (cursor_pos >= selection_pos) ? cursor_pos : selection_pos;
890    selecting = (start_pos != end_pos);
891    
892    /* Move the cursor/selection to the left */
893    if ((strcmp(event->key, "Left") == 0) ||
894       ((evas_key_modifier_is_set(event->modifiers, "Control")) &&
895        (strcmp(event->key, "b") == 0)))
896      {
897         e_editable_cursor_move_left(editable);
898         if (sd->selection_mode)
899           selection_changed = 1;
900         else
901           e_editable_selection_pos_set(editable,
902                                        e_editable_cursor_pos_get(editable));
903      }
904    /* Move the cursor/selection to the right */
905    else if ((strcmp(event->key, "Right") == 0) ||
906       ((evas_key_modifier_is_set(event->modifiers, "Control")) &&
907        (strcmp(event->key, "f") == 0)))
908      {
909         e_editable_cursor_move_right(editable);
910         if (sd->selection_mode)
911           selection_changed = 1;
912         else
913           e_editable_selection_pos_set(editable,
914                                        e_editable_cursor_pos_get(editable));
915      }
916    /* Move the cursor/selection to the start of the entry */
917    else if ((strcmp(event->keyname, "Home") == 0) ||
918       ((evas_key_modifier_is_set(event->modifiers, "Control")) &&
919        (strcmp(event->key, "a") == 0)))
920      {
921         e_editable_cursor_move_to_start(editable);
922         if (sd->selection_mode)
923           selection_changed = 1;
924         else
925           e_editable_selection_pos_set(editable,
926                                        e_editable_cursor_pos_get(editable));
927      }
928    /* Move the cursor/selection to the end of the entry */
929    else if ((strcmp(event->keyname, "End") == 0) ||
930       ((evas_key_modifier_is_set(event->modifiers, "Control")) &&
931        (strcmp(event->key, "e") == 0)))
932      {
933         e_editable_cursor_move_to_end(editable);
934         if (sd->selection_mode)
935           selection_changed = 1;
936         else
937           e_editable_selection_pos_set(editable,
938                                        e_editable_cursor_pos_get(editable));
939      }
940    /* Delete the previous character */
941    else if ((sd->enabled) && (strcmp(event->keyname, "BackSpace") == 0))
942      changed = e_editable_delete(editable, cursor_pos - 1, cursor_pos);
943    /* Delete the next character */
944    else if ((sd->enabled) && 
945       ((evas_key_modifier_is_set(event->modifiers, "Control")) &&
946        (strcmp(event->key, "d") == 0)))
947      changed = e_editable_delete(editable, cursor_pos, cursor_pos + 1);
948    /* Delete until end of line */
949    else if ((sd->enabled) && 
950       ((evas_key_modifier_is_set(event->modifiers, "Control")) &&
951        (strcmp(event->key, "k") == 0)))
952      changed = e_editable_delete(editable, cursor_pos,
953                                  e_editable_text_length_get(editable));
954    /* Toggle the selection mode */
955    else if ((evas_key_modifier_is_set(event->modifiers, "Control")) &&
956        (strcmp(event->key, "space") == 0))
957      {
958         if (sd->selection_mode)
959           {
960              e_editable_selection_pos_set(editable, cursor_pos);
961              sd->selection_mode = 0;
962           }
963         else
964           sd->selection_mode = 1;
965      }
966    /* Cut/Copy */
967    else if ((evas_key_modifier_is_set(event->modifiers, "Control") ||
968              evas_key_modifier_is_set(event->modifiers, "Shift")) &&
969             (strcmp(event->key, "w") == 0))
970      {
971         if (!e_editable_password_get(editable) && selecting)
972           {
973              range = e_editable_text_range_get(editable, start_pos, end_pos);
974              if (range)
975                {
976                   if ((win = e_win_evas_object_win_get(entry)))
977                     ecore_x_selection_clipboard_set(win->evas_win,
978                                                     range,
979                                                     strlen(range) + 1);
980                   free(range);
981                }
982              if ((sd->enabled) && (evas_key_modifier_is_set(event->modifiers, "Control")))
983                {
984                   changed = e_editable_delete(editable, start_pos, end_pos);
985                   sd->selection_mode = 0;
986                }
987           }
988      }
989    /* Paste */
990    else if ((sd->enabled) && 
991             ((evas_key_modifier_is_set(event->modifiers, "Control")) &&
992              (strcmp(event->key, "y") == 0)))
993      {
994         if ((win = e_win_evas_object_win_get(entry)))
995           ecore_x_selection_clipboard_request(win->evas_win,
996                                               ECORE_X_SELECTION_TARGET_UTF8_STRING);
997      }
998    /* Otherwise, we insert the corresponding character */
999    else if ((event->string) &&
1000             ((strlen(event->string) != 1) ||
1001              (event->string[0] >= 0x20 && event->string[0] != 0x7f)))
1002      changed = e_editable_insert(editable, cursor_pos, event->string);
1003
1004 #ifdef HAVE_ECORE_IMF
1005    if (sd->imf_context)
1006      {
1007         ecore_imf_context_reset(sd->imf_context);
1008         ecore_imf_context_cursor_position_set(sd->imf_context,
1009                                               e_editable_cursor_pos_get(editable));
1010      }
1011 #endif
1012
1013    if (changed)
1014      evas_object_smart_callback_call(entry, "changed", NULL);
1015    if (selection_changed)
1016      _e_entry_x_selection_update(entry);
1017 }
1018
1019 /* Editable object's smart methods */
1020
1021 static void 
1022 _e_entry_smart_add(Evas_Object *object)
1023 {
1024    Evas *evas;
1025    E_Entry_Smart_Data *sd;
1026    Evas_Object *o;
1027    int cw, ch;
1028    const char *ctx_id;
1029 #ifdef HAVE_ECORE_IMF
1030    const Ecore_IMF_Context_Info *ctx_info;
1031 #endif
1032    
1033    if ((!object) || !(evas = evas_object_evas_get(object)))
1034      return;
1035
1036    sd = malloc(sizeof(E_Entry_Smart_Data));
1037    if (!sd) return;
1038    
1039    evas_object_smart_data_set(object, sd);
1040
1041 #ifdef HAVE_ECORE_IMF
1042    ctx_id = ecore_imf_context_default_id_get();
1043    if (ctx_id)
1044      {
1045         ctx_info = ecore_imf_context_info_by_id_get(ctx_id);
1046         if (!ctx_info->canvas_type ||
1047             strcmp(ctx_info->canvas_type, "evas") == 0)
1048           sd->imf_context = ecore_imf_context_add(ctx_id);
1049         else
1050           {
1051              ctx_id = ecore_imf_context_default_id_by_canvas_type_get("evas");
1052              if (ctx_id)
1053                sd->imf_context = ecore_imf_context_add(ctx_id);
1054              else
1055                sd->imf_context = NULL;
1056           }
1057      }
1058    else
1059      sd->imf_context = NULL;
1060
1061    if (sd->imf_context)
1062      {
1063         ecore_imf_context_client_window_set(sd->imf_context,
1064                                             (long *)ecore_evas_window_get(ecore_evas_ecore_evas_get(evas)));
1065         ecore_imf_context_client_canvas_set(sd->imf_context, evas);
1066         ecore_imf_context_retrieve_surrounding_callback_set(sd->imf_context,
1067                                                             _e_entry_cb_imf_retrieve_surrounding,
1068                                                             sd);
1069         sd->imf_ee_commit_handler = 
1070           ecore_event_handler_add(ECORE_IMF_EVENT_COMMIT,
1071                                   _e_entry_cb_imf_event_commit, object);
1072         sd->imf_ee_delete_handler = 
1073           ecore_event_handler_add(ECORE_IMF_EVENT_DELETE_SURROUNDING,
1074                                   _e_entry_cb_imf_event_delete_surrounding, sd);
1075      }
1076 #endif
1077
1078    sd->enabled = 1;
1079    sd->focused = 0;
1080    sd->selection_dragging = 0;
1081    sd->selection_mode = 0;
1082    sd->valign = 0.5;
1083    
1084    o = edje_object_add(evas);
1085    sd->entry_object = o;
1086    e_theme_edje_object_set(o, "base/theme/widgets", "e/widgets/entry");
1087    evas_object_smart_member_add(o, object);
1088    
1089    o = e_editable_add(evas);
1090    sd->editable_object = o;
1091    e_editable_theme_set(o, "base/theme/widgets", "e/widgets/entry");
1092    e_editable_cursor_hide(o);
1093    e_editable_char_size_get(o, &cw, &ch);
1094    edje_extern_object_min_size_set(o, cw, ch);
1095    edje_object_part_swallow(sd->entry_object, "e.swallow.text", o);
1096    edje_object_size_min_calc(sd->entry_object, &sd->min_width, &sd->height);
1097    evas_object_show(o);
1098    
1099    evas_object_event_callback_add(object, EVAS_CALLBACK_KEY_DOWN,
1100                                   _e_entry_key_down_cb, NULL);
1101    evas_object_event_callback_add(object, EVAS_CALLBACK_KEY_UP,
1102                                   _e_entry_key_up_cb, NULL);
1103    evas_object_event_callback_add(object, EVAS_CALLBACK_MOUSE_DOWN,
1104                                   _e_entry_mouse_down_cb, NULL);
1105    evas_object_event_callback_add(object, EVAS_CALLBACK_MOUSE_UP,
1106                                   _e_entry_mouse_up_cb, NULL);
1107    evas_object_event_callback_add(object, EVAS_CALLBACK_MOUSE_MOVE,
1108                                   _e_entry_mouse_move_cb, NULL);
1109    sd->selection_handler = ecore_event_handler_add(
1110                                        ECORE_X_EVENT_SELECTION_NOTIFY,
1111                                        _e_entry_x_selection_notify_handler,
1112                                        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         if (sd->imf_ee_commit_handler) 
1127           ecore_event_handler_del(sd->imf_ee_commit_handler);
1128         if (sd->imf_ee_delete_handler) 
1129           ecore_event_handler_del(sd->imf_ee_delete_handler);
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 #ifdef HAVE_ECORE_IMF
1363 static Eina_Bool 
1364 _e_entry_cb_imf_retrieve_surrounding(void *data, Ecore_IMF_Context *ctx __UNUSED__, char **text, int *cursor_pos)
1365 {
1366    E_Entry_Smart_Data *sd;
1367
1368    sd = data;
1369
1370    if (text)
1371      {
1372         const char *str;
1373
1374         str = e_editable_text_get(sd->editable_object);
1375         *text = str ? strdup(str) : strdup("");
1376      }
1377
1378    if (cursor_pos)
1379      *cursor_pos = e_editable_cursor_pos_get(sd->editable_object);
1380
1381    return EINA_TRUE;
1382 }
1383
1384 static Eina_Bool
1385 _e_entry_cb_imf_event_commit(void *data, int type __UNUSED__, void *event)
1386 {
1387    Evas_Object *entry;
1388    E_Entry_Smart_Data *sd;
1389    Ecore_IMF_Event_Commit *ev = event;
1390    Evas_Object *editable;
1391    int cursor_pos, selection_pos;
1392    int start_pos, end_pos;
1393    int selecting;
1394    int changed = 0;
1395
1396    if ((!(entry = data)) || (!(sd = evas_object_smart_data_get(entry))))
1397      return ECORE_CALLBACK_PASS_ON;
1398
1399    if (sd->imf_context != ev->ctx)
1400      return ECORE_CALLBACK_PASS_ON;
1401
1402    editable = sd->editable_object;
1403    cursor_pos = e_editable_cursor_pos_get(editable);
1404    selection_pos = e_editable_selection_pos_get(editable);
1405    start_pos = (cursor_pos <= selection_pos) ? cursor_pos : selection_pos;
1406    end_pos = (cursor_pos >= selection_pos) ? cursor_pos : selection_pos;
1407    selecting = (start_pos != end_pos);
1408
1409    if (selecting)
1410      changed |= e_editable_delete(editable, start_pos, end_pos);
1411    changed |= e_editable_insert(editable, start_pos, ev->str);
1412
1413    if (changed)
1414      evas_object_smart_callback_call(entry, "changed", NULL);
1415
1416    return ECORE_CALLBACK_DONE;
1417 }
1418
1419 static Eina_Bool
1420 _e_entry_cb_imf_event_delete_surrounding(void *data, int type __UNUSED__, void *event)
1421 {
1422    E_Entry_Smart_Data *sd;
1423    Ecore_IMF_Event_Delete_Surrounding *ev = event;
1424    Evas_Object *editable;
1425    int cursor_pos;
1426
1427    sd = data;
1428
1429    if (sd->imf_context != ev->ctx)
1430      return ECORE_CALLBACK_PASS_ON;
1431
1432    editable = sd->editable_object;
1433    cursor_pos = e_editable_cursor_pos_get(editable);
1434    e_editable_delete(editable,
1435                      cursor_pos + ev->offset,
1436                      cursor_pos + ev->offset + ev->n_chars);
1437
1438    return ECORE_CALLBACK_DONE;
1439 }
1440 #endif