Edje entry: Handle entry newline legacy mode better.
[framework/uifw/edje.git] / src / lib / edje_entry.c
1 #include "edje_private.h"
2
3 #ifdef HAVE_ECORE_IMF
4 static Eina_Bool _edje_entry_imf_retrieve_surrounding_cb(void *data, Ecore_IMF_Context *ctx, char **text, int *cursor_pos);
5 static Eina_Bool _edje_entry_imf_event_commit_cb(void *data, int type, void *event);
6 static Eina_Bool _edje_entry_imf_event_preedit_changed_cb(void *data, int type, void *event);
7 static Eina_Bool _edje_entry_imf_event_delete_surrounding_cb(void *data, int type, void *event);
8 #endif
9
10 typedef struct _Entry Entry;
11 typedef struct _Sel Sel;
12 typedef struct _Anchor Anchor;
13
14 static void _edje_entry_imf_cursor_info_set(Entry *en);
15 static void _edje_entry_imf_context_reset(Entry *en);
16
17 struct _Entry
18 {
19    Edje_Real_Part *rp;
20    Evas_Object *cursor_bg;
21    Evas_Object *cursor_fg;
22    Evas_Textblock_Cursor *cursor;
23    Evas_Textblock_Cursor *sel_start, *sel_end;
24    Evas_Textblock_Cursor *cursor_user, *cursor_user_extra;
25    Evas_Textblock_Cursor *preedit_start, *preedit_end;
26    Ecore_Timer *pw_timer;
27    Eina_List *sel;
28    Eina_List *anchors;
29    Eina_List *anchorlist;
30    Eina_List *itemlist;
31    char *selection;
32    Eina_Bool selecting : 1;
33    Eina_Bool have_selection : 1;
34    Eina_Bool select_allow : 1;
35    Eina_Bool select_mod_start : 1;
36    Eina_Bool select_mod_end : 1;
37    Eina_Bool had_sel : 1;
38
39 #ifdef HAVE_ECORE_IMF
40    Eina_Bool have_preedit : 1;
41    Ecore_IMF_Context *imf_context;
42
43    Ecore_Event_Handler *imf_ee_handler_commit;
44    Ecore_Event_Handler *imf_ee_handler_delete;
45    Ecore_Event_Handler *imf_ee_handler_changed;
46 #endif
47 };
48
49 struct _Sel
50 {
51    Evas_Textblock_Rectangle rect;
52    Evas_Object *obj_fg, *obj_bg, *obj, *sobj;
53 };
54
55 struct _Anchor
56 {
57    Entry *en;
58    char *name;
59    Evas_Textblock_Cursor *start, *end;
60    Eina_List *sel;
61    Eina_Bool item : 1;
62 };
63
64 #ifdef HAVE_ECORE_IMF
65 static void
66 _preedit_clear(Entry *en)
67 {
68    if (en->preedit_start)
69      {
70         evas_textblock_cursor_free(en->preedit_start);
71         en->preedit_start = NULL;
72      }
73
74    if (en->preedit_end)
75      {
76         evas_textblock_cursor_free(en->preedit_end);
77         en->preedit_end = NULL;
78      }
79
80    en->have_preedit = EINA_FALSE;
81 }
82
83 static void
84 _preedit_del(Entry *en)
85 {
86    if (!en || !en->have_preedit) return;
87    if (!en->preedit_start || !en->preedit_end) return;
88    if (!evas_textblock_cursor_compare(en->preedit_start, en->preedit_end)) return;
89
90    /* delete the preedit characters */
91    evas_textblock_cursor_range_delete(en->preedit_start, en->preedit_end);
92 }
93
94 static void
95 _edje_entry_focus_in_cb(void *data, Evas_Object *o __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
96 {
97    Edje_Real_Part *rp;
98    Entry *en;
99
100    rp = data;
101    if (!rp || !rp->entry_data || !rp->edje || !rp->edje->obj) return;
102
103    en = rp->entry_data;
104    if (!en || !en->imf_context) return;
105
106    if (evas_object_focus_get(rp->edje->obj))
107      {
108         ecore_imf_context_reset(en->imf_context);
109         ecore_imf_context_focus_in(en->imf_context);
110         _edje_entry_imf_cursor_info_set(en);
111      }
112 }
113
114 static void
115 _edje_entry_focus_out_cb(void *data, Evas_Object *o __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
116 {
117    Edje_Real_Part *rp;
118    Entry *en;
119
120    rp = data;
121    if (!rp || !rp->entry_data) return;
122
123    en = rp->entry_data;
124    if (!en || !en->imf_context) return;
125
126    ecore_imf_context_reset(en->imf_context);
127    _edje_entry_imf_cursor_info_set(en);
128    ecore_imf_context_focus_out(en->imf_context);
129 }
130 #endif
131
132 static void
133 _edje_focus_in_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
134 {
135    Edje *ed = data;
136 #ifdef HAVE_ECORE_IMF
137    Edje_Real_Part *rp;
138    Entry *en;
139 #endif
140
141    _edje_emit(ed, "focus,in", "");
142 #ifdef HAVE_ECORE_IMF
143    rp = ed->focused_part;
144    if (!rp) return;
145
146    en = rp->entry_data;
147    if ((!en) || (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK) ||
148        (rp->part->entry_mode < EDJE_ENTRY_EDIT_MODE_EDITABLE))
149      return;
150
151    if (!en->imf_context) return;
152
153    ecore_imf_context_reset(en->imf_context);
154    ecore_imf_context_focus_in(en->imf_context);
155    _edje_entry_imf_cursor_info_set(en);
156 #endif
157 }
158
159 static void
160 _edje_focus_out_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
161 {
162    Edje *ed = data;
163 #ifdef HAVE_ECORE_IMF
164    Edje_Real_Part *rp = ed->focused_part;
165    Entry *en;
166 #endif
167
168    _edje_emit(ed, "focus,out", "");
169
170 #ifdef HAVE_ECORE_IMF
171    if (!rp) return;
172    en = rp->entry_data;
173    if ((!en) || (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK) ||
174        (rp->part->entry_mode < EDJE_ENTRY_EDIT_MODE_EDITABLE))
175      return;
176
177    if (!en->imf_context) return;
178
179    ecore_imf_context_reset(en->imf_context);
180    _edje_entry_imf_cursor_info_set(en);
181    ecore_imf_context_focus_out(en->imf_context);
182 #endif
183 }
184
185 static void
186 _text_filter_text_prepend(Entry *en, Evas_Textblock_Cursor *c, const char *text)
187 {
188    char *text2;
189    Edje_Text_Insert_Filter_Callback *cb;
190    Eina_List *l;
191
192    text2 = strdup(text);
193    EINA_LIST_FOREACH(en->rp->edje->text_insert_filter_callbacks, l, cb)
194      {
195         if (!strcmp(cb->part, en->rp->part->name))
196           {
197              cb->func(cb->data, en->rp->edje->obj, cb->part, EDJE_TEXT_FILTER_TEXT, &text2);
198              if (!text2) break;
199           }
200      }
201    if (text2)
202      {
203         evas_textblock_cursor_text_prepend(c, text2);
204         free(text2);
205      }
206 }
207
208 static void
209 _text_filter_format_prepend(Entry *en, Evas_Textblock_Cursor *c, const char *text)
210 {
211    char *text2;
212    Edje_Text_Insert_Filter_Callback *cb;
213    Eina_List *l;
214
215    text2 = strdup(text);
216    EINA_LIST_FOREACH(en->rp->edje->text_insert_filter_callbacks, l, cb)
217      {
218         if (!strcmp(cb->part, en->rp->part->name))
219           {
220              cb->func(cb->data, en->rp->edje->obj, cb->part, EDJE_TEXT_FILTER_FORMAT, &text2);
221              if (!text2) break;
222           }
223      }
224    if (text2)
225      {
226         evas_textblock_cursor_format_prepend(c, text2);
227         free(text2);
228      }
229 }
230
231 static void
232 _text_filter_markup_prepend(Entry *en, Evas_Textblock_Cursor *c, const char *text)
233 {
234    char *text2;
235    Edje_Text_Insert_Filter_Callback *cb;
236    Eina_List *l;
237
238    text2 = strdup(text);
239    EINA_LIST_FOREACH(en->rp->edje->text_insert_filter_callbacks, l, cb)
240      {
241         if (!strcmp(cb->part, en->rp->part->name))
242           {
243              cb->func(cb->data, en->rp->edje->obj, cb->part, EDJE_TEXT_FILTER_MARKUP, &text2);
244              if (!text2) break;
245           }
246      }
247    if (text2)
248      {
249         evas_object_textblock_text_markup_prepend(c, text2);
250         free(text2);
251      }
252 }
253
254 static void
255 _curs_update_from_curs(Evas_Textblock_Cursor *c, Evas_Object *o __UNUSED__, Entry *en, Evas_Coord *cx, Evas_Coord *cy)
256 {
257    Evas_Coord cw, ch;
258    Evas_Textblock_Cursor_Type cur_type;
259    if (c != en->cursor) return;
260    switch (en->rp->part->cursor_mode)
261      {
262       case EDJE_ENTRY_CURSOR_MODE_BEFORE:
263          cur_type = EVAS_TEXTBLOCK_CURSOR_BEFORE;
264          break;
265       case EDJE_ENTRY_CURSOR_MODE_UNDER:
266          /* no break for a resaon */
267       default:
268          cur_type = EVAS_TEXTBLOCK_CURSOR_UNDER;
269      }
270    evas_textblock_cursor_geometry_get(c, cx, cy, &cw, &ch, NULL, cur_type);
271    *cx += (cw / 2);
272    *cy += (ch / 2);
273 }
274
275 static int
276 _curs_line_last_get(Evas_Textblock_Cursor *c __UNUSED__, Evas_Object *o, Entry *en __UNUSED__)
277 {
278    Evas_Textblock_Cursor *cc;
279    int ln;
280
281    cc = evas_object_textblock_cursor_new(o);
282    evas_textblock_cursor_paragraph_last(cc);
283    ln = evas_textblock_cursor_line_geometry_get(cc, NULL, NULL, NULL, NULL);
284    evas_textblock_cursor_free(cc);
285    return ln;
286 }
287
288 static void
289 _curs_lin_start(Evas_Textblock_Cursor *c, Evas_Object *o __UNUSED__,
290                 Entry *en __UNUSED__)
291 {
292    evas_textblock_cursor_line_char_first(c);
293 }
294
295 static void
296 _curs_lin_end(Evas_Textblock_Cursor *c, Evas_Object *o __UNUSED__,
297               Entry *en __UNUSED__)
298 {
299    evas_textblock_cursor_line_char_last(c);
300 }
301
302 static void
303 _curs_start(Evas_Textblock_Cursor *c, Evas_Object *o __UNUSED__,
304             Entry *en __UNUSED__)
305 {
306    evas_textblock_cursor_paragraph_first(c);
307 }
308
309 static void
310 _curs_end(Evas_Textblock_Cursor *c, Evas_Object *o __UNUSED__, Entry *en __UNUSED__)
311 {
312    evas_textblock_cursor_paragraph_last(c);
313 }
314
315 static void
316 _curs_jump_line(Evas_Textblock_Cursor *c, Evas_Object *o, Entry *en, int ln)
317 {
318    Evas_Coord cx, cy;
319    Evas_Coord lx, ly, lw, lh;
320    int last = _curs_line_last_get(c, o, en);
321
322    if (ln < 0) ln = 0;
323    else
324      {
325         if (ln > last) ln = last;
326      }
327
328    _curs_update_from_curs(c, o, en, &cx, &cy);
329
330    if (!evas_object_textblock_line_number_geometry_get(o, ln, &lx, &ly, &lw, &lh))
331      return;
332    if (evas_textblock_cursor_char_coord_set(c, cx, ly + (lh / 2)))
333      return;
334    evas_textblock_cursor_line_set(c, ln);
335    if (cx < (lx + (lw / 2)))
336      {
337         if (ln == last) _curs_end(c, o, en);
338         _curs_lin_start(c, o, en);
339      }
340    else
341      {
342         if (ln == last)
343           _curs_end(c, o, en);
344         else
345           _curs_lin_end(c, o, en);
346      }
347 }
348
349 static void
350 _curs_jump_line_by(Evas_Textblock_Cursor *c, Evas_Object *o, Entry *en, int by)
351 {
352    int ln;
353
354    ln = evas_textblock_cursor_line_geometry_get(c, NULL, NULL, NULL, NULL) + by;
355    _curs_jump_line(c, o, en, ln);
356 }
357
358 static void
359 _curs_up(Evas_Textblock_Cursor *c, Evas_Object *o, Entry *en)
360 {
361    _curs_jump_line_by(c, o, en, -1);
362 }
363
364 static void
365 _curs_down(Evas_Textblock_Cursor *c, Evas_Object *o, Entry *en)
366 {
367    _curs_jump_line_by(c, o, en, 1);
368 }
369
370 static void
371 _sel_start(Evas_Textblock_Cursor *c, Evas_Object *o, Entry *en)
372 {
373    if (en->sel_start) return;
374    en->sel_start = evas_object_textblock_cursor_new(o);
375    evas_textblock_cursor_copy(c, en->sel_start);
376    en->sel_end = evas_object_textblock_cursor_new(o);
377    evas_textblock_cursor_copy(c, en->sel_end);
378
379    en->have_selection = EINA_FALSE;
380    if (en->selection)
381      {
382         free(en->selection);
383         en->selection = NULL;
384      }
385 }
386
387 static void
388 _sel_enable(Evas_Textblock_Cursor *c __UNUSED__, Evas_Object *o __UNUSED__, Entry *en)
389 {
390    if (en->have_selection) return;
391    en->have_selection = EINA_TRUE;
392    if (en->selection)
393      {
394         free(en->selection);
395         en->selection = NULL;
396      }
397    _edje_emit(en->rp->edje, "selection,start", en->rp->part->name);
398 }
399
400 static void
401 _sel_extend(Evas_Textblock_Cursor *c, Evas_Object *o, Entry *en)
402 {
403    if (!en->sel_end) return;
404    _sel_enable(c, o, en);
405    if (!evas_textblock_cursor_compare(c, en->sel_end)) return;
406    evas_textblock_cursor_copy(c, en->sel_end);
407    if (en->selection)
408      {
409         free(en->selection);
410         en->selection = NULL;
411      }
412    _edje_emit(en->rp->edje, "selection,changed", en->rp->part->name);
413    _edje_entry_imf_context_reset(en);
414 }
415
416 static void
417 _sel_preextend(Evas_Textblock_Cursor *c, Evas_Object *o, Entry *en)
418 {
419    if (!en->sel_end) return;
420    _sel_enable(c, o, en);
421    if (!evas_textblock_cursor_compare(c, en->sel_start)) return;
422    evas_textblock_cursor_copy(c, en->sel_start);
423    if (en->selection)
424      {
425         free(en->selection);
426         en->selection = NULL;
427      }
428    _edje_emit(en->rp->edje, "selection,changed", en->rp->part->name);
429    _edje_entry_imf_context_reset(en);
430 }
431
432 static void
433 _sel_clear(Evas_Textblock_Cursor *c __UNUSED__, Evas_Object *o __UNUSED__, Entry *en)
434 {
435    en->had_sel = EINA_FALSE;
436    if (en->sel_start)
437      {
438         evas_textblock_cursor_free(en->sel_start);
439         evas_textblock_cursor_free(en->sel_end);
440         en->sel_start = NULL;
441         en->sel_end = NULL;
442      }
443    if (en->selection)
444      {
445         free(en->selection);
446         en->selection = NULL;
447      }
448    while (en->sel)
449      {
450         Sel *sel;
451
452         sel = en->sel->data;
453         if (sel->obj_bg) evas_object_del(sel->obj_bg);
454         if (sel->obj_fg) evas_object_del(sel->obj_fg);
455         free(sel);
456         en->sel = eina_list_remove_list(en->sel, en->sel);
457      }
458    if (en->have_selection)
459      {
460         en->have_selection = EINA_FALSE;
461         _edje_emit(en->rp->edje, "selection,cleared", en->rp->part->name);
462      }
463 }
464
465 static void
466 _sel_update(Evas_Textblock_Cursor *c __UNUSED__, Evas_Object *o, Entry *en)
467 {
468    Eina_List *range = NULL, *l;
469    Sel *sel;
470    Evas_Coord x, y, w, h;
471    Evas_Object *smart, *clip;
472
473    smart = evas_object_smart_parent_get(o);
474    clip = evas_object_clip_get(o);
475    if (en->sel_start)
476      range = evas_textblock_cursor_range_geometry_get(en->sel_start, en->sel_end);
477    else
478      return;
479    if (eina_list_count(range) != eina_list_count(en->sel))
480      {
481         while (en->sel)
482           {
483              sel = en->sel->data;
484              if (sel->obj_bg) evas_object_del(sel->obj_bg);
485              if (sel->obj_fg) evas_object_del(sel->obj_fg);
486              free(sel);
487              en->sel = eina_list_remove_list(en->sel, en->sel);
488           }
489         if (en->have_selection)
490           {
491              for (l = range; l; l = eina_list_next(l))
492                {
493                   Evas_Object *ob;
494
495                   sel = calloc(1, sizeof(Sel));
496                   en->sel = eina_list_append(en->sel, sel);
497                   ob = edje_object_add(en->rp->edje->base.evas);
498                   edje_object_file_set(ob, en->rp->edje->path, en->rp->part->source);
499                   evas_object_smart_member_add(ob, smart);
500                   evas_object_stack_below(ob, o);
501                   evas_object_clip_set(ob, clip);
502                   evas_object_pass_events_set(ob, EINA_TRUE);
503                   evas_object_show(ob);
504                   sel->obj_bg = ob;
505                   _edje_subobj_register(en->rp->edje, sel->obj_bg);
506
507                   ob = edje_object_add(en->rp->edje->base.evas);
508                   edje_object_file_set(ob, en->rp->edje->path, en->rp->part->source2);
509                   evas_object_smart_member_add(ob, smart);
510                   evas_object_stack_above(ob, o);
511                   evas_object_clip_set(ob, clip);
512                   evas_object_pass_events_set(ob, EINA_TRUE);
513                   evas_object_show(ob);
514                   sel->obj_fg = ob;
515                   _edje_subobj_register(en->rp->edje, sel->obj_fg);
516                }
517           }
518      }
519    x = y = w = h = -1;
520    evas_object_geometry_get(o, &x, &y, &w, &h);
521    if (en->have_selection)
522      {
523         EINA_LIST_FOREACH(en->sel, l, sel)
524           {
525              Evas_Textblock_Rectangle *r;
526
527              r = range->data;
528              if (sel->obj_bg)
529                {
530                   evas_object_move(sel->obj_bg, x + r->x, y + r->y);
531                   evas_object_resize(sel->obj_bg, r->w, r->h);
532                }
533              if (sel->obj_fg)
534                {
535                   evas_object_move(sel->obj_fg, x + r->x, y + r->y);
536                   evas_object_resize(sel->obj_fg, r->w, r->h);
537                }
538              *(&(sel->rect)) = *r;
539              range = eina_list_remove_list(range, range);
540              free(r);
541           }
542      }
543    else
544      {
545         while (range)
546           {
547              free(range->data);
548              range = eina_list_remove_list(range, range);
549           }
550      }
551 }
552
553 static void
554 _edje_anchor_mouse_down_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
555 {
556    Anchor *an = data;
557    Evas_Event_Mouse_Down *ev = event_info;
558    Edje_Real_Part *rp = an->en->rp;
559    char *buf, *n;
560    size_t len;
561    int ignored;
562    Entry *en;
563
564    en = rp->entry_data;
565    if ((rp->part->select_mode == EDJE_ENTRY_SELECTION_MODE_EXPLICIT) &&
566        (en->select_allow))
567      return;
568    ignored = rp->part->ignore_flags & ev->event_flags;
569    if ((!ev->event_flags) || (!ignored))
570      {
571         n = an->name;
572         if (!n) n = "";
573         len = 200 + strlen(n);
574         buf = alloca(len);
575         if (ev->flags & EVAS_BUTTON_TRIPLE_CLICK)
576           snprintf(buf, len, "anchor,mouse,down,%i,%s,triple", ev->button, n);
577         else if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK)
578           snprintf(buf, len, "anchor,mouse,down,%i,%s,double", ev->button, n);
579         else
580           snprintf(buf, len, "anchor,mouse,down,%i,%s", ev->button, n);
581         _edje_emit(rp->edje, buf, rp->part->name);
582      }
583 }
584
585 static void
586 _edje_anchor_mouse_up_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
587 {
588    Anchor *an = data;
589    Evas_Event_Mouse_Up *ev = event_info;
590    Edje_Real_Part *rp = an->en->rp;
591    char *buf, *n;
592    size_t len;
593    int ignored;
594    Entry *en;
595
596    en = rp->entry_data;
597    ignored = rp->part->ignore_flags & ev->event_flags;
598    if ((rp->part->select_mode == EDJE_ENTRY_SELECTION_MODE_EXPLICIT) &&
599        (en->select_allow))
600      return;
601    n = an->name;
602    if (!n) n = "";
603    len = 200 + strlen(n);
604    buf = alloca(len);
605    if ((!ev->event_flags) || (!ignored))
606      {
607         snprintf(buf, len, "anchor,mouse,up,%i,%s", ev->button, n);
608         _edje_emit(rp->edje, buf, rp->part->name);
609      }
610    if ((rp->still_in) && (rp->clicked_button == ev->button) && (!ignored))
611      {
612         snprintf(buf, len, "anchor,mouse,clicked,%i,%s", ev->button, n);
613         _edje_emit(rp->edje, buf, rp->part->name);
614      }
615 }
616
617 static void
618 _edje_anchor_mouse_move_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
619 {
620    Anchor *an = data;
621    Evas_Event_Mouse_Move *ev = event_info;
622    Edje_Real_Part *rp = an->en->rp;
623    char *buf, *n;
624    size_t len;
625    int ignored;
626    Entry *en;
627
628    en = rp->entry_data;
629    if ((rp->part->select_mode == EDJE_ENTRY_SELECTION_MODE_EXPLICIT) &&
630        (en->select_allow))
631      return;
632    ignored = rp->part->ignore_flags & ev->event_flags;
633    if ((!ev->event_flags) || (!ignored))
634      {
635         n = an->name;
636         if (!n) n = "";
637         len = 200 + strlen(n);
638         buf = alloca(len);
639         snprintf(buf, len, "anchor,mouse,move,%s", n);
640         _edje_emit(rp->edje, buf, rp->part->name);
641      }
642 }
643
644 static void
645 _edje_anchor_mouse_in_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
646 {
647    Anchor *an = data;
648    Evas_Event_Mouse_In *ev = event_info;
649    Edje_Real_Part *rp = an->en->rp;
650    char *buf, *n;
651    size_t len;
652    int ignored;
653
654    ignored = rp->part->ignore_flags & ev->event_flags;
655    if ((!ev->event_flags) || (!ignored))
656      {
657         n = an->name;
658         if (!n) n = "";
659         len = 200 + strlen(n);
660         buf = alloca(len);
661         snprintf(buf, len, "anchor,mouse,in,%s", n);
662         _edje_emit(rp->edje, buf, rp->part->name);
663      }
664 }
665
666 static void
667 _edje_anchor_mouse_out_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
668 {
669    Anchor *an = data;
670    Evas_Event_Mouse_Out *ev = event_info;
671    Edje_Real_Part *rp = an->en->rp;
672    char *buf, *n;
673    size_t len;
674    int ignored;
675
676    ignored = rp->part->ignore_flags & ev->event_flags;
677    if ((!ev->event_flags) || (!ignored))
678      {
679         n = an->name;
680         if (!n) n = "";
681         len = 200 + strlen(n);
682         buf = alloca(len);
683         snprintf(buf, len, "anchor,mouse,out,%s", n);
684         _edje_emit(rp->edje, buf, rp->part->name);
685      }
686 }
687
688 static void
689 _anchors_update(Evas_Textblock_Cursor *c __UNUSED__, Evas_Object *o, Entry *en)
690 {
691    Eina_List *l, *ll, *range = NULL;
692    Evas_Coord x, y, w, h;
693    Evas_Object *smart, *clip;
694    Sel *sel;
695    Anchor *an;
696
697    smart = evas_object_smart_parent_get(o);
698    clip = evas_object_clip_get(o);
699    x = y = w = h = -1;
700    evas_object_geometry_get(o, &x, &y, &w, &h);
701    EINA_LIST_FOREACH(en->anchors, l, an)
702      {
703         // for item anchors
704         if (an->item)
705           {
706              Evas_Object *ob;
707
708              if (!an->sel)
709                {
710                   while (an->sel)
711                     {
712                        sel = an->sel->data;
713                        if (sel->obj_bg) evas_object_del(sel->obj_bg);
714                        if (sel->obj_fg) evas_object_del(sel->obj_fg);
715                        if (sel->obj) evas_object_del(sel->obj);
716                        free(sel);
717                        an->sel = eina_list_remove_list(an->sel, an->sel);
718                     }
719
720                   sel = calloc(1, sizeof(Sel));
721                   an->sel = eina_list_append(an->sel, sel);
722
723                   if (en->rp->edje->item_provider.func)
724                     {
725                        ob = en->rp->edje->item_provider.func
726                          (en->rp->edje->item_provider.data, smart, 
727                              en->rp->part->name, an->name);
728                        evas_object_smart_member_add(ob, smart);
729                        evas_object_stack_above(ob, o);
730                        evas_object_clip_set(ob, clip);
731                        evas_object_pass_events_set(ob, EINA_TRUE);
732                        evas_object_show(ob);
733                        sel->obj = ob;
734                     }
735                }
736           }
737         // for link anchors
738         else
739           {
740              range = 
741                evas_textblock_cursor_range_geometry_get(an->start, an->end);
742              if (eina_list_count(range) != eina_list_count(an->sel))
743                {
744                   while (an->sel)
745                     {
746                        sel = an->sel->data;
747                        if (sel->obj_bg) evas_object_del(sel->obj_bg);
748                        if (sel->obj_fg) evas_object_del(sel->obj_fg);
749                        if (sel->obj) evas_object_del(sel->obj);
750                        free(sel);
751                        an->sel = eina_list_remove_list(an->sel, an->sel);
752                     }
753                   for (ll = range; ll; ll = eina_list_next(ll))
754                     {
755                        Evas_Object *ob;
756
757                        sel = calloc(1, sizeof(Sel));
758                        an->sel = eina_list_append(an->sel, sel);
759                        ob = edje_object_add(en->rp->edje->base.evas);
760                        edje_object_file_set(ob, en->rp->edje->path, en->rp->part->source5);
761                        evas_object_smart_member_add(ob, smart);
762                        evas_object_stack_below(ob, o);
763                        evas_object_clip_set(ob, clip);
764                        evas_object_pass_events_set(ob, EINA_TRUE);
765                        evas_object_show(ob);
766                        sel->obj_bg = ob;
767                        _edje_subobj_register(en->rp->edje, sel->obj_bg);
768
769                        ob = edje_object_add(en->rp->edje->base.evas);
770                        edje_object_file_set(ob, en->rp->edje->path, en->rp->part->source6);
771                        evas_object_smart_member_add(ob, smart);
772                        evas_object_stack_above(ob, o);
773                        evas_object_clip_set(ob, clip);
774                        evas_object_pass_events_set(ob, EINA_TRUE);
775                        evas_object_show(ob);
776                        sel->obj_fg = ob;
777                        _edje_subobj_register(en->rp->edje, sel->obj_fg);
778
779                        ob = evas_object_rectangle_add(en->rp->edje->base.evas);
780                        evas_object_color_set(ob, 0, 0, 0, 0);
781                        evas_object_smart_member_add(ob, smart);
782                        evas_object_stack_above(ob, o);
783                        evas_object_clip_set(ob, clip);
784                        evas_object_repeat_events_set(ob, EINA_TRUE);
785                        evas_object_event_callback_add(ob, EVAS_CALLBACK_MOUSE_DOWN, _edje_anchor_mouse_down_cb, an);
786                        evas_object_event_callback_add(ob, EVAS_CALLBACK_MOUSE_UP, _edje_anchor_mouse_up_cb, an);
787                        evas_object_event_callback_add(ob, EVAS_CALLBACK_MOUSE_MOVE, _edje_anchor_mouse_move_cb, an);
788                        evas_object_event_callback_add(ob, EVAS_CALLBACK_MOUSE_IN, _edje_anchor_mouse_in_cb, an);
789                        evas_object_event_callback_add(ob, EVAS_CALLBACK_MOUSE_OUT, _edje_anchor_mouse_out_cb, an);
790                        evas_object_show(ob);
791                        sel->obj = ob;
792                     }
793                }
794           }
795         EINA_LIST_FOREACH(an->sel, ll, sel)
796           {
797              if (an->item)
798                {
799                   Evas_Coord cx, cy, cw, ch;
800
801                   if (!evas_textblock_cursor_format_item_geometry_get
802                       (an->start, &cx, &cy, &cw, &ch))
803                     continue;
804                   evas_object_move(sel->obj, x + cx, y + cy);
805                   evas_object_resize(sel->obj, cw, ch);
806                }
807              else
808                {
809                   Evas_Textblock_Rectangle *r;
810
811                   r = range->data;
812                   *(&(sel->rect)) = *r;
813                   if (sel->obj_bg)
814                     {
815                        evas_object_move(sel->obj_bg, x + r->x, y + r->y);
816                        evas_object_resize(sel->obj_bg, r->w, r->h);
817                     }
818                   if (sel->obj_fg)
819                     {
820                        evas_object_move(sel->obj_fg, x + r->x, y + r->y);
821                        evas_object_resize(sel->obj_fg, r->w, r->h);
822                     }
823                   if (sel->obj)
824                     {
825                        evas_object_move(sel->obj, x + r->x, y + r->y);
826                        evas_object_resize(sel->obj, r->w, r->h);
827                     }
828                   range = eina_list_remove_list(range, range);
829                   free(r);
830                }
831           }
832      }
833 }
834
835 static void
836 _anchors_clear(Evas_Textblock_Cursor *c __UNUSED__, Evas_Object *o __UNUSED__, Entry *en)
837 {
838    while (en->anchorlist)
839      {
840         free(en->anchorlist->data);
841         en->anchorlist = eina_list_remove_list(en->anchorlist, en->anchorlist);
842      }
843    while (en->itemlist)
844      {
845         free(en->itemlist->data);
846         en->itemlist = eina_list_remove_list(en->itemlist, en->itemlist);
847      }
848    while (en->anchors)
849      {
850         Anchor *an = en->anchors->data;
851
852         evas_textblock_cursor_free(an->start);
853         evas_textblock_cursor_free(an->end);
854         while (an->sel)
855           {
856              Sel *sel = an->sel->data;
857              if (sel->obj_bg) evas_object_del(sel->obj_bg);
858              if (sel->obj_fg) evas_object_del(sel->obj_fg);
859              if (sel->obj) evas_object_del(sel->obj);
860              free(sel);
861              an->sel = eina_list_remove_list(an->sel, an->sel);
862           }
863         free(an->name);
864         free(an);
865         en->anchors = eina_list_remove_list(en->anchors, en->anchors);
866      }
867 }
868
869 static void
870 _anchors_get(Evas_Textblock_Cursor *c, Evas_Object *o, Entry *en)
871 {
872    const Eina_List *anchors_a, *anchors_item;
873    Anchor *an = NULL;
874    _anchors_clear(c, o, en);
875
876    anchors_a = evas_textblock_node_format_list_get(o, "a");
877    anchors_item = evas_textblock_node_format_list_get(o, "item");
878
879    if (anchors_a)
880      {
881         const Evas_Object_Textblock_Node_Format *node;
882         const Eina_List *itr;
883         EINA_LIST_FOREACH(anchors_a, itr, node)
884           {
885              const char *s = evas_textblock_node_format_text_get(node);
886              char *p;
887              an = calloc(1, sizeof(Anchor));
888              if (!an)
889                 break;
890
891              an->en = en;
892              p = strstr(s, "href=");
893              if (p)
894                {
895                   an->name = strdup(p + 5);
896                }
897              en->anchors = eina_list_append(en->anchors, an);
898              an->start = evas_object_textblock_cursor_new(o);
899              an->end = evas_object_textblock_cursor_new(o);
900              evas_textblock_cursor_at_format_set(an->start, node);
901              evas_textblock_cursor_copy(an->start, an->end);
902
903              /* Close the anchor, if the anchor was without text,
904               * free it as well */
905              node = evas_textblock_node_format_next_get(node);
906              for (; node; node = evas_textblock_node_format_next_get(node))
907                {
908                   s = evas_textblock_node_format_text_get(node);
909                   if ((!strcmp(s, "- a")) || (!strcmp(s, "-a")))
910                      break;
911                }
912
913              if (node)
914                {
915                   evas_textblock_cursor_at_format_set(an->end, node);
916                }
917              else if (!evas_textblock_cursor_compare(an->start, an->end))
918                {
919                   if (an->name) free(an->name);
920                   evas_textblock_cursor_free(an->start);
921                   evas_textblock_cursor_free(an->end);
922                   en->anchors = eina_list_remove(en->anchors, an);
923                   free(an);
924                }
925              an = NULL;
926           }
927      }
928
929    if (anchors_item)
930      {
931         const Evas_Object_Textblock_Node_Format *node;
932         const Eina_List *itr;
933         EINA_LIST_FOREACH(anchors_item, itr, node)
934           {
935              const char *s = evas_textblock_node_format_text_get(node);
936              char *p;
937              an = calloc(1, sizeof(Anchor));
938              if (!an)
939                 break;
940
941              an->en = en;
942              an->item = 1;
943              p = strstr(s, "href=");
944              if (p)
945                {
946                   an->name = strdup(p + 5);
947                }
948              en->anchors = eina_list_append(en->anchors, an);
949              an->start = evas_object_textblock_cursor_new(o);
950              an->end = evas_object_textblock_cursor_new(o);
951              evas_textblock_cursor_at_format_set(an->start, node);
952              evas_textblock_cursor_copy(an->start, an->end);
953              /* Although needed in textblock, don't bother with finding the end
954               * here cause it doesn't really matter. */
955           }
956      }
957 }
958
959 static void
960 _free_entry_change_info(void *_info)
961 {
962    Edje_Entry_Change_Info *info = (Edje_Entry_Change_Info *) _info;
963    if (info->insert)
964      {
965         eina_stringshare_del(info->change.insert.content);
966      }
967    else
968      {
969         eina_stringshare_del(info->change.del.content);
970      }
971    free(info);
972 }
973
974 static void
975 _range_del_emit(Edje *ed, Evas_Textblock_Cursor *c __UNUSED__, Evas_Object *o __UNUSED__, Entry *en)
976 {
977    size_t start, end;
978    char *tmp;
979    Edje_Entry_Change_Info *info = calloc(1, sizeof(*info));
980    info->insert = EINA_FALSE;
981    start = evas_textblock_cursor_pos_get(en->sel_start);
982    end = evas_textblock_cursor_pos_get(en->sel_end);
983    info->change.del.start = start;
984    info->change.del.end = end;
985
986    tmp = evas_textblock_cursor_range_text_get(en->sel_start, en->sel_end, EVAS_TEXTBLOCK_TEXT_MARKUP);
987    info->change.del.content = eina_stringshare_add(tmp);
988    if (tmp) free(tmp);
989    evas_textblock_cursor_range_delete(en->sel_start, en->sel_end);
990    _edje_emit(ed, "entry,changed", en->rp->part->name);
991    _edje_emit_full(ed, "entry,changed,user", en->rp->part->name, info,
992                    _free_entry_change_info);
993 }
994
995 static void
996 _range_del(Evas_Textblock_Cursor *c __UNUSED__, Evas_Object *o __UNUSED__, Entry *en)
997 {
998    evas_textblock_cursor_range_delete(en->sel_start, en->sel_end);
999 }
1000
1001 static void
1002 _delete_emit(Edje *ed, Evas_Textblock_Cursor *c, Entry *en, size_t pos,
1003              Eina_Bool backspace)
1004 {
1005    if (!evas_textblock_cursor_char_next(c))
1006      {
1007         return;
1008      }
1009    evas_textblock_cursor_char_prev(c);
1010
1011    Edje_Entry_Change_Info *info = calloc(1, sizeof(*info));
1012    char *tmp = evas_textblock_cursor_content_get(c);
1013
1014    info->insert = EINA_FALSE;
1015    if (backspace)
1016      {
1017         info->change.del.start = pos - 1;
1018         info->change.del.end = pos;
1019      }
1020    else
1021      {
1022         info->change.del.start = pos + 1;
1023         info->change.del.end = pos;
1024      }
1025
1026    info->change.del.content = eina_stringshare_add(tmp);
1027    if (tmp) free(tmp);
1028
1029    evas_textblock_cursor_char_delete(c);
1030    _edje_emit(ed, "entry,changed", en->rp->part->name);
1031    _edje_emit_full(ed, "entry,changed,user", en->rp->part->name,
1032                    info, _free_entry_change_info);
1033 }
1034
1035 static void
1036 _edje_entry_hide_visible_password(Edje_Real_Part *rp)
1037 {
1038    const Evas_Object_Textblock_Node_Format *node;
1039    node = evas_textblock_node_format_first_get(rp->object);
1040    for (; node; node = evas_textblock_node_format_next_get(node))
1041      {
1042         const char *text = evas_textblock_node_format_text_get(node);
1043         if (text)
1044           {
1045              if (!strcmp(text, "+ password=off"))
1046                {
1047                   evas_textblock_node_format_remove_pair(rp->object,
1048                                                         (Evas_Object_Textblock_Node_Format *) node);
1049                   break;
1050                }
1051           }
1052      }
1053    _edje_entry_real_part_configure(rp);
1054    _edje_emit(rp->edje, "entry,changed", rp->part->name);
1055 }
1056
1057 static Eina_Bool
1058 _password_timer_cb(void *data)
1059 {
1060    Entry *en = (Entry *)data;
1061    _edje_entry_hide_visible_password(en->rp);
1062    en->pw_timer = NULL;
1063    return ECORE_CALLBACK_CANCEL;
1064 }
1065
1066 static void
1067 _edje_key_down_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
1068 {
1069    Edje *ed = data;
1070    Evas_Event_Key_Down *ev = event_info;
1071    Edje_Real_Part *rp = ed->focused_part;
1072    Entry *en;
1073    Eina_Bool control, alt, shift;
1074    Eina_Bool multiline;
1075    Eina_Bool cursor_changed;
1076    int old_cur_pos;
1077    if (!rp) return;
1078    en = rp->entry_data;
1079    if ((!en) || (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK) ||
1080        (rp->part->entry_mode < EDJE_ENTRY_EDIT_MODE_EDITABLE))
1081      return;
1082    if (!ev->key) return;
1083
1084 #ifdef HAVE_ECORE_IMF
1085    if (en->imf_context)
1086      {
1087         Ecore_IMF_Event_Key_Down ecore_ev;
1088         ecore_imf_evas_event_key_down_wrap(ev, &ecore_ev);
1089         if (ecore_imf_context_filter_event(en->imf_context,
1090                                            ECORE_IMF_EVENT_KEY_DOWN,
1091                                            (Ecore_IMF_Event *)&ecore_ev))
1092           return;
1093      }
1094 #endif
1095
1096    old_cur_pos = evas_textblock_cursor_pos_get(en->cursor);
1097
1098    control = evas_key_modifier_is_set(ev->modifiers, "Control");
1099    alt = evas_key_modifier_is_set(ev->modifiers, "Alt");
1100    shift = evas_key_modifier_is_set(ev->modifiers, "Shift");
1101    multiline = rp->part->multiline;
1102    cursor_changed = EINA_FALSE;
1103    if (!strcmp(ev->key, "Escape"))
1104      {
1105         // dead keys here. Escape for now (should emit these)
1106         _edje_emit(ed, "entry,key,escape", rp->part->name);
1107         ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1108      }
1109    else if (!strcmp(ev->key, "Up") || !strcmp(ev->key, "KP_Up"))
1110      {
1111         if (multiline)
1112           {
1113              if (en->select_allow)
1114                {
1115                   if (shift) _sel_start(en->cursor, rp->object, en);
1116                   else _sel_clear(en->cursor, rp->object, en);
1117                }
1118              _curs_up(en->cursor, rp->object, en);
1119              if (en->select_allow)
1120                {
1121                   if (shift) _sel_extend(en->cursor, rp->object, en);
1122                }
1123              ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1124           }
1125         _sel_clear(en->cursor, rp->object, en);
1126         _edje_emit(ed, "entry,key,up", rp->part->name);
1127         _edje_emit(rp->edje, "cursor,changed,manual", rp->part->name);
1128      }
1129    else if (!strcmp(ev->key, "Down") || !strcmp(ev->key, "KP_Down"))
1130      {
1131         if (multiline)
1132           {
1133              if (en->select_allow)
1134                {
1135                   if (shift) _sel_start(en->cursor, rp->object, en);
1136                   else _sel_clear(en->cursor, rp->object, en);
1137                }
1138              _curs_down(en->cursor, rp->object, en);
1139              if (en->select_allow)
1140                {
1141                   if (shift) _sel_extend(en->cursor, rp->object, en);
1142                }
1143              ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1144           }
1145         _sel_clear(en->cursor, rp->object, en);
1146         _edje_emit(ed, "entry,key,down", rp->part->name);
1147         _edje_emit(rp->edje, "cursor,changed,manual", rp->part->name);
1148      }
1149    else if (!strcmp(ev->key, "Left") || !strcmp(ev->key, "KP_Left"))
1150      {
1151         if (en->select_allow)
1152           {
1153              if (shift) _sel_start(en->cursor, rp->object, en);
1154              else _sel_clear(en->cursor, rp->object, en);
1155           }
1156         evas_textblock_cursor_char_prev(en->cursor);
1157         /* If control is pressed, go to the start of the word */
1158         if (control) evas_textblock_cursor_word_start(en->cursor);
1159         if (en->select_allow)
1160           {
1161              if (shift) _sel_extend(en->cursor, rp->object, en);
1162           }
1163         _sel_clear(en->cursor, rp->object, en);
1164         _edje_emit(ed, "entry,key,left", rp->part->name);
1165         _edje_emit(rp->edje, "cursor,changed,manual", rp->part->name);
1166         ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1167      }
1168    else if (!strcmp(ev->key, "Right") || !strcmp(ev->key, "KP_Right"))
1169      {
1170         if (en->select_allow)
1171           {
1172              if (shift) _sel_start(en->cursor, rp->object, en);
1173              else _sel_clear(en->cursor, rp->object, en);
1174           }
1175         /* If control is pressed, go to the start of the word */
1176         if (control) evas_textblock_cursor_word_end(en->cursor);
1177         evas_textblock_cursor_char_next(en->cursor);
1178         if (en->select_allow)
1179           {
1180              if (shift) _sel_extend(en->cursor, rp->object, en);
1181           }
1182         _sel_clear(en->cursor, rp->object, en);
1183         _edje_emit(ed, "entry,key,right", rp->part->name);
1184         _edje_emit(rp->edje, "cursor,changed,manual", rp->part->name);
1185         ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1186      }
1187    else if (!strcmp(ev->key, "BackSpace"))
1188      {
1189         if (control && !en->have_selection)
1190           {
1191              // del to start of previous word
1192              _sel_start(en->cursor, rp->object, en);
1193
1194              evas_textblock_cursor_char_prev(en->cursor);
1195              evas_textblock_cursor_word_start(en->cursor);
1196
1197              _sel_extend(en->cursor, rp->object, en);
1198
1199              _range_del_emit(ed, en->cursor, rp->object, en);
1200           }
1201         else if ((alt) && (shift))
1202           {
1203              // undo last action
1204           }
1205         else
1206           {
1207              if (en->have_selection)
1208                {
1209                   _range_del_emit(ed, en->cursor, rp->object, en);
1210                }
1211              else
1212                {
1213                   if (evas_textblock_cursor_char_prev(en->cursor))
1214                     {
1215                        _delete_emit(ed, en->cursor, en, old_cur_pos, EINA_TRUE);
1216                     }
1217                }
1218           }
1219         _sel_clear(en->cursor, rp->object, en);
1220         _anchors_get(en->cursor, rp->object, en);
1221         _edje_emit(ed, "entry,key,backspace", rp->part->name);
1222         ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1223      }
1224    else if (!strcmp(ev->key, "Delete") || !strcmp(ev->key, "KP_Delete"))
1225      {
1226         if (control)
1227           {
1228              // del to end of next word
1229              _sel_start(en->cursor, rp->object, en);
1230
1231              evas_textblock_cursor_word_end(en->cursor);
1232              evas_textblock_cursor_char_next(en->cursor);
1233
1234              _sel_extend(en->cursor, rp->object, en);
1235
1236              _range_del_emit(ed, en->cursor, rp->object, en);
1237           }
1238         else if (shift)
1239           {
1240              // cut
1241           }
1242         else
1243           {
1244              if (en->have_selection)
1245                {
1246                   _range_del_emit(ed, en->cursor, rp->object, en);
1247                }
1248              else
1249                {
1250                   _delete_emit(ed, en->cursor, en, old_cur_pos, EINA_FALSE);
1251                }
1252           }
1253         _sel_clear(en->cursor, rp->object, en);
1254         _anchors_get(en->cursor, rp->object, en);
1255         _edje_emit(ed, "entry,key,delete", rp->part->name);
1256         ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1257      }
1258    else if (!strcmp(ev->key, "Home") || !strcmp(ev->key, "KP_Home"))
1259      {
1260         if (en->select_allow)
1261           {
1262              if (shift) _sel_start(en->cursor, rp->object, en);
1263              else _sel_clear(en->cursor, rp->object, en);
1264           }
1265         if ((control) && (multiline))
1266           _curs_start(en->cursor, rp->object, en);
1267         else
1268           _curs_lin_start(en->cursor, rp->object, en);
1269         if (en->select_allow)
1270           {
1271              if (shift) _sel_extend(en->cursor, rp->object, en);
1272           }
1273         _edje_emit(ed, "entry,key,home", rp->part->name);
1274         ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1275      }
1276    else if (!strcmp(ev->key, "End") || !strcmp(ev->key, "KP_End"))
1277      {
1278         if (en->select_allow)
1279           {
1280              if (shift) _sel_start(en->cursor, rp->object, en);
1281              else _sel_clear(en->cursor, rp->object, en);
1282           }
1283         if ((control) && (multiline))
1284           _curs_end(en->cursor, rp->object, en);
1285         else
1286           _curs_lin_end(en->cursor, rp->object, en);
1287         if (en->select_allow)
1288           {
1289              if (shift) _sel_extend(en->cursor, rp->object, en);
1290           }
1291         _edje_emit(ed, "entry,key,end", rp->part->name);
1292         ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1293      }
1294    else if (!strcmp(ev->key, "Shift_L") || !strcmp(ev->key, "Shift_R"))
1295      {
1296         return;
1297      }
1298    else if ((control) && (!strcmp(ev->key, "v")))
1299      {
1300         _edje_emit(ed, "entry,paste,request", rp->part->name);
1301         _edje_emit(ed, "entry,paste,request,3", rp->part->name);
1302         ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1303      }
1304    else if ((control) && (!strcmp(ev->key, "a")))
1305      {
1306           _edje_emit(ed, "entry,selection,all,request", rp->part->name);
1307         ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1308      }
1309    else if ((control) && (!strcmp(ev->key, "A")))
1310      {
1311           _edje_emit(ed, "entry,selection,none,request", rp->part->name);
1312         ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1313      }
1314    else if ((control) && ((!strcmp(ev->key, "c") || (!strcmp(ev->key, "Insert")))))
1315      {
1316         _edje_emit(ed, "entry,copy,notify", rp->part->name);
1317         ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1318      }
1319    else if ((control) && ((!strcmp(ev->key, "x") || (!strcmp(ev->key, "m")))))
1320      {
1321         _edje_emit(ed, "entry,cut,notify", rp->part->name);
1322         ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1323      }
1324    else if ((control) && (!strcmp(ev->key, "z")))
1325      {
1326         if (shift)
1327           {
1328              // redo
1329              _edje_emit(ed, "entry,redo,request", rp->part->name);
1330           }
1331         else
1332           {
1333              // undo
1334              _edje_emit(ed, "entry,undo,request", rp->part->name);
1335           }
1336         ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1337      }
1338    else if ((control) && (!strcmp(ev->key, "y")))
1339      {
1340         // redo
1341         _edje_emit(ed, "entry,redo,request", rp->part->name);
1342         ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1343      }
1344    else if ((control) && (!strcmp(ev->key, "w")))
1345      {
1346         _sel_clear(en->cursor, rp->object, en);
1347         // select current word?
1348         ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1349      }
1350    else if (!strcmp(ev->key, "Tab"))
1351      {
1352         if (multiline)
1353           {
1354              if (shift)
1355                {
1356                   // remove a tab
1357                }
1358              else
1359                {
1360                   Edje_Entry_Change_Info *info = calloc(1, sizeof(*info));
1361                   info->insert = EINA_TRUE;
1362                   info->change.insert.plain_length = 1;
1363
1364                   if (en->have_selection)
1365                     {
1366                        _range_del_emit(ed, en->cursor, rp->object, en);
1367                        info->merge = EINA_TRUE;
1368                     }
1369                   _sel_clear(en->cursor, rp->object, en);
1370                   info->change.insert.pos =
1371                      evas_textblock_cursor_pos_get(en->cursor);
1372                   info->change.insert.content = eina_stringshare_add("<tab/>");
1373                   //yy
1374 //                  evas_textblock_cursor_format_prepend(en->cursor, "tab");
1375                   _text_filter_format_prepend(en, en->cursor, "tab");
1376                   _anchors_get(en->cursor, rp->object, en);
1377                   _edje_emit(ed, "entry,changed", rp->part->name);
1378                   _edje_emit_full(ed, "entry,changed,user", rp->part->name,
1379                                   info, _free_entry_change_info);
1380                }
1381              ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1382           }
1383         _edje_emit(ed, "entry,key,tab", rp->part->name);
1384      }
1385    else if ((!strcmp(ev->key, "ISO_Left_Tab")) && (multiline))
1386      {
1387         // remove a tab
1388         ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1389      }
1390    else if (!strcmp(ev->key, "Prior") || !strcmp(ev->key, "KP_Prior"))
1391      {
1392         if (en->select_allow)
1393           {
1394              if (shift) _sel_start(en->cursor, rp->object, en);
1395              else _sel_clear(en->cursor, rp->object, en);
1396           }
1397         _curs_jump_line_by(en->cursor, rp->object, en, -10);
1398         if (en->select_allow)
1399           {
1400              if (shift) _sel_extend(en->cursor, rp->object, en);
1401           }
1402         _sel_clear(en->cursor, rp->object, en);
1403         _edje_emit(ed, "entry,key,pgup", rp->part->name);
1404         ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1405      }
1406    else if (!strcmp(ev->key, "Next") || !strcmp(ev->key, "KP_Next"))
1407      {
1408         if (en->select_allow)
1409           {
1410              if (shift) _sel_start(en->cursor, rp->object, en);
1411              else _sel_clear(en->cursor, rp->object, en);
1412           }
1413         _curs_jump_line_by(en->cursor, rp->object, en, 10);
1414         if (en->select_allow)
1415           {
1416              if (shift) _sel_extend(en->cursor, rp->object, en);
1417           }
1418         _sel_clear(en->cursor, rp->object, en);
1419         _edje_emit(ed, "entry,key,pgdn", rp->part->name);
1420         ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1421      }
1422    else if ((!strcmp(ev->key, "Return")) || (!strcmp(ev->key, "KP_Enter")))
1423      {
1424         if (multiline)
1425           {
1426              Edje_Entry_Change_Info *info = calloc(1, sizeof(*info));
1427              info->insert = EINA_TRUE;
1428              info->change.insert.plain_length = 1;
1429              if (en->have_selection)
1430                {
1431                   _range_del_emit(ed, en->cursor, rp->object, en);
1432                   info->merge = EINA_TRUE;
1433                }
1434              _sel_clear(en->cursor, rp->object, en);
1435
1436              info->change.insert.pos =
1437                 evas_textblock_cursor_pos_get(en->cursor);
1438              if (shift ||
1439                  evas_object_textblock_legacy_newline_get(rp->object))
1440                {
1441                   //yy
1442 //                  evas_textblock_cursor_format_prepend(en->cursor, "br");
1443                   _text_filter_format_prepend(en, en->cursor, "br");
1444                   info->change.insert.content = eina_stringshare_add("<br/>");
1445                }
1446              else
1447                {
1448                   //yy
1449 //                  evas_textblock_cursor_format_prepend(en->cursor, "ps");
1450                   _text_filter_format_prepend(en, en->cursor, "ps");
1451                   info->change.insert.content = eina_stringshare_add("<ps/>");
1452                }
1453              _anchors_get(en->cursor, rp->object, en);
1454              _edje_emit(ed, "entry,changed", rp->part->name);
1455              _edje_emit_full(ed, "entry,changed,user", rp->part->name,
1456                              info, _free_entry_change_info);
1457              _edje_emit(ed, "cursor,changed", rp->part->name);
1458              cursor_changed = EINA_TRUE;
1459              ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1460           }
1461         _edje_emit(ed, "entry,key,enter", rp->part->name);
1462      }
1463    else
1464      {
1465         if (ev->string)
1466           {
1467              Edje_Entry_Change_Info *info = calloc(1, sizeof(*info));
1468              info->insert = EINA_TRUE;
1469              info->change.insert.plain_length = 1;
1470              info->change.insert.content = eina_stringshare_add(ev->string);
1471
1472              if (en->have_selection)
1473                {
1474                   _range_del_emit(ed, en->cursor, rp->object, en);
1475                   info->merge = EINA_TRUE;
1476                }
1477              _sel_clear(en->cursor, rp->object, en);
1478
1479              info->change.insert.pos =
1480                 evas_textblock_cursor_pos_get(en->cursor);
1481              // if PASSWORD_SHOW_LAST mode, appending text with password=off tag
1482              if ((rp->part->entry_mode == EDJE_ENTRY_EDIT_MODE_PASSWORD) &&
1483                  _edje_password_show_last)
1484                {
1485                   _edje_entry_hide_visible_password(en->rp);
1486                   _text_filter_format_prepend(en, en->cursor, "+ password=off");
1487                   _text_filter_text_prepend(en, en->cursor, ev->string);
1488                   _text_filter_format_prepend(en, en->cursor, "- password");
1489                   if (en->pw_timer)
1490                     {
1491                        ecore_timer_del(en->pw_timer);
1492                        en->pw_timer = NULL;
1493                     }
1494                   en->pw_timer = ecore_timer_add(_edje_password_show_last_timeout,
1495                                                  _password_timer_cb, en);
1496                }
1497              else
1498                _text_filter_text_prepend(en, en->cursor, ev->string);
1499              _anchors_get(en->cursor, rp->object, en);
1500              _edje_emit(ed, "entry,changed", rp->part->name);
1501              _edje_emit_full(ed, "entry,changed,user", rp->part->name,
1502                              info, _free_entry_change_info);
1503              _edje_emit(ed, "cursor,changed", rp->part->name);
1504              cursor_changed = EINA_TRUE;
1505              ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1506           }
1507      }
1508    if (!cursor_changed && (old_cur_pos != evas_textblock_cursor_pos_get(en->cursor)))
1509      _edje_emit(ed, "cursor,changed", rp->part->name);
1510
1511    _edje_entry_imf_context_reset(en);
1512    _edje_entry_imf_cursor_info_set(en);
1513    _edje_entry_real_part_configure(rp);
1514 }
1515
1516 static void
1517 _edje_key_up_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
1518 {
1519    Edje *ed = data;
1520    Edje_Real_Part *rp = ed->focused_part;
1521    Entry *en;
1522
1523    if (!rp) return;
1524    en = rp->entry_data;
1525    if ((!en) || (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK) ||
1526        (rp->part->entry_mode < EDJE_ENTRY_EDIT_MODE_EDITABLE))
1527      return;
1528
1529 #ifdef HAVE_ECORE_IMF
1530    if (en->imf_context)
1531      {
1532         Evas_Event_Key_Up *ev = event_info;
1533         Ecore_IMF_Event_Key_Up ecore_ev;
1534
1535         ecore_imf_evas_event_key_up_wrap(ev, &ecore_ev);
1536         if (ecore_imf_context_filter_event(en->imf_context,
1537                                            ECORE_IMF_EVENT_KEY_UP,
1538                                            (Ecore_IMF_Event *)&ecore_ev))
1539           return;
1540      }
1541 #else
1542    (void) event_info;
1543 #endif
1544 }
1545
1546 static void
1547 _edje_part_move_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
1548 {
1549    Edje_Real_Part *rp = data;
1550    Entry *en;
1551    if (!rp) return;
1552    en = rp->entry_data;
1553    if (!en) return;
1554    _edje_entry_imf_cursor_info_set(en);
1555 }
1556
1557 static void
1558 _edje_part_mouse_down_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
1559 {
1560    Evas_Coord cx, cy;
1561    Edje_Real_Part *rp = data;
1562    Evas_Event_Mouse_Down *ev = event_info;
1563    Entry *en;
1564    Evas_Coord x, y, w, h;
1565    //   Eina_Bool multiline;
1566    Evas_Textblock_Cursor *tc;
1567    Eina_Bool dosel = EINA_FALSE;
1568    if (!rp) return;
1569    if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
1570    en = rp->entry_data;
1571    if ((!en) || (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK) ||
1572        (rp->part->entry_mode < EDJE_ENTRY_EDIT_MODE_SELECTABLE))
1573      return;
1574    if ((ev->button != 1) && (ev->button != 2)) return;
1575
1576 #ifdef HAVE_ECORE_IMF
1577    if (en->imf_context)
1578      {
1579         Ecore_IMF_Event_Mouse_Down ecore_ev;
1580         ecore_imf_evas_event_mouse_down_wrap(ev, &ecore_ev);
1581         if (ecore_imf_context_filter_event(en->imf_context,
1582                                            ECORE_IMF_EVENT_MOUSE_DOWN,
1583                                            (Ecore_IMF_Event *)&ecore_ev))
1584           return;
1585      }
1586 #endif
1587
1588    en->select_mod_start = EINA_FALSE;
1589    en->select_mod_end = EINA_FALSE;
1590    if (rp->part->select_mode == EDJE_ENTRY_SELECTION_MODE_DEFAULT)
1591      dosel = EINA_TRUE;
1592    else if (rp->part->select_mode == EDJE_ENTRY_SELECTION_MODE_EXPLICIT)
1593      {
1594         if (en->select_allow) dosel = EINA_TRUE;
1595      }
1596    if (ev->button == 2) dosel = EINA_FALSE;
1597    if (dosel)
1598      {
1599         // double click -> select word
1600         // triple click -> select line
1601      }
1602    tc = evas_object_textblock_cursor_new(rp->object);
1603    evas_textblock_cursor_copy(en->cursor, tc);
1604    //   multiline = rp->part->multiline;
1605    evas_object_geometry_get(rp->object, &x, &y, &w, &h);
1606    cx = ev->canvas.x - x;
1607    cy = ev->canvas.y - y;
1608    if (!evas_textblock_cursor_char_coord_set(en->cursor, cx, cy))
1609      {
1610         Evas_Coord lx, ly, lw, lh;
1611         int line;
1612
1613         line = evas_textblock_cursor_line_coord_set(en->cursor, cy);
1614         if (line == -1)
1615           {
1616              if (rp->part->multiline)
1617                _curs_end(en->cursor, rp->object, en);
1618              else
1619                {
1620                   evas_textblock_cursor_paragraph_first(en->cursor);
1621                   evas_textblock_cursor_line_geometry_get(en->cursor, &lx, &ly, &lw, &lh);
1622                   if (!evas_textblock_cursor_char_coord_set(en->cursor, cx, ly + (lh / 2)))
1623                     _curs_end(en->cursor, rp->object, en);
1624                }
1625           }
1626         else
1627           {
1628              int lnum;
1629
1630              lnum = evas_textblock_cursor_line_geometry_get(en->cursor, &lx, &ly, &lw, &lh);
1631              if (lnum < 0)
1632                {
1633                   _curs_lin_start(en->cursor, rp->object, en);
1634                }
1635              else
1636                {
1637                   if (cx <= lx)
1638                     _curs_lin_start(en->cursor, rp->object, en);
1639                   else
1640                     _curs_lin_end(en->cursor, rp->object, en);
1641                }
1642           }
1643      }
1644    if (dosel)
1645      {
1646         if ((en->have_selection) &&
1647             (rp->part->select_mode == EDJE_ENTRY_SELECTION_MODE_EXPLICIT))
1648           {
1649              Eina_List *first, *last;
1650              FLOAT_T sc;
1651
1652              first = en->sel;
1653              last = eina_list_last(en->sel);
1654              if (first && last)
1655                {
1656                   Evas_Textblock_Rectangle *r1, *r2;
1657                   Evas_Coord d, d1, d2;
1658
1659                   r1 = first->data;
1660                   r2 = last->data;
1661                   d = r1->x - cx;
1662                   d1 = d * d;
1663                   d = (r1->y + (r1->h / 2)) - cy;
1664                   d1 += d * d;
1665                   d = r2->x + r2->w - 1 - cx;
1666                   d2 = d * d;
1667                   d = (r2->y + (r2->h / 2)) - cy;
1668                   d2 += d * d;
1669                   sc = rp->edje->scale;
1670                   if (sc == ZERO) sc = _edje_scale;
1671                   d = (Evas_Coord)MUL(FROM_INT(20), sc); // FIXME: maxing number!
1672                   d = d * d;
1673                   if (d1 < d2)
1674                     {
1675                        if (d1 <= d)
1676                          {
1677                             en->select_mod_start = EINA_TRUE;
1678                             en->selecting = EINA_TRUE;
1679                          }
1680                     }
1681                   else
1682                     {
1683                        if (d2 <= d)
1684                          {
1685                             en->select_mod_end = EINA_TRUE;
1686                             en->selecting = EINA_TRUE;
1687                          }
1688                     }
1689                }
1690           }
1691         else
1692           {
1693              en->selecting = EINA_TRUE;
1694              _sel_clear(en->cursor, rp->object, en);
1695              if (en->select_allow)
1696                {
1697                   _sel_start(en->cursor, rp->object, en);
1698                }
1699           }
1700      }
1701    if (evas_textblock_cursor_compare(tc, en->cursor))
1702      {
1703         _edje_emit(rp->edje, "cursor,changed", rp->part->name);
1704         _edje_emit(rp->edje, "cursor,changed,manual", rp->part->name);
1705      }
1706    evas_textblock_cursor_free(tc);
1707    
1708    _edje_entry_imf_context_reset(en);
1709    _edje_entry_imf_cursor_info_set(en);
1710
1711    _edje_entry_real_part_configure(rp);
1712    if (ev->button == 2)
1713      {
1714         _edje_emit(rp->edje, "entry,paste,request", rp->part->name);
1715         _edje_emit(rp->edje, "entry,paste,request,1", rp->part->name);
1716      }
1717 }
1718
1719 static void
1720 _edje_part_mouse_up_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
1721 {
1722    Evas_Coord cx, cy;
1723    Edje_Real_Part *rp = data;
1724    Evas_Event_Mouse_Up *ev = event_info;
1725    Entry *en;
1726    Evas_Coord x, y, w, h;
1727    Evas_Textblock_Cursor *tc;
1728    if (ev->button != 1) return;
1729    if (!rp) return;
1730    if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
1731    en = rp->entry_data;
1732    if ((!en) || (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK) ||
1733        (rp->part->entry_mode < EDJE_ENTRY_EDIT_MODE_SELECTABLE))
1734      return;
1735
1736 #ifdef HAVE_ECORE_IMF
1737    if (en->imf_context)
1738      {
1739         Ecore_IMF_Event_Mouse_Up ecore_ev;
1740         ecore_imf_evas_event_mouse_up_wrap(ev, &ecore_ev);
1741         if (ecore_imf_context_filter_event(en->imf_context,
1742                                            ECORE_IMF_EVENT_MOUSE_UP,
1743                                            (Ecore_IMF_Event *)&ecore_ev))
1744           return;
1745      }
1746 #endif
1747
1748    tc = evas_object_textblock_cursor_new(rp->object);
1749    evas_textblock_cursor_copy(en->cursor, tc);
1750    evas_object_geometry_get(rp->object, &x, &y, &w, &h);
1751    cx = ev->canvas.x - x;
1752    cy = ev->canvas.y - y;
1753    if (!evas_textblock_cursor_char_coord_set(en->cursor, cx, cy))
1754      {
1755         Evas_Coord lx, ly, lw, lh;
1756         int line;
1757
1758         line = evas_textblock_cursor_line_coord_set(en->cursor, cy);
1759         if (line == -1)
1760           {
1761              if (rp->part->multiline)
1762                _curs_end(en->cursor, rp->object, en);
1763              else
1764                {
1765                   evas_textblock_cursor_paragraph_first(en->cursor);
1766                   evas_textblock_cursor_line_geometry_get(en->cursor, &lx, &ly, &lw, &lh);
1767                   if (!evas_textblock_cursor_char_coord_set(en->cursor, cx, ly + (lh / 2)))
1768                     _curs_end(en->cursor, rp->object, en);
1769                }
1770           }
1771         else
1772           {
1773              int lnum;
1774
1775              lnum = evas_textblock_cursor_line_geometry_get(en->cursor, &lx, &ly, &lw, &lh);
1776              if (lnum < 0)
1777                {
1778                   _curs_lin_start(en->cursor, rp->object, en);
1779                }
1780              else
1781                {
1782                   if (cx <= lx)
1783                     _curs_lin_start(en->cursor, rp->object, en);
1784                   else
1785                     _curs_lin_end(en->cursor, rp->object, en);
1786                }
1787           }
1788      }
1789    if (rp->part->select_mode == EDJE_ENTRY_SELECTION_MODE_EXPLICIT)
1790      {
1791         if (en->select_allow)
1792           {
1793              if (en->had_sel)
1794                {
1795                   if (en->select_mod_end)
1796                     _sel_extend(en->cursor, rp->object, en);
1797                   else if (en->select_mod_start)
1798                     _sel_preextend(en->cursor, rp->object, en);
1799                }
1800              else
1801                _sel_extend(en->cursor, rp->object, en);
1802              //evas_textblock_cursor_copy(en->cursor, en->sel_end);
1803           }
1804      }
1805    else
1806      evas_textblock_cursor_copy(en->cursor, en->sel_end);
1807    if (en->selecting)
1808      {
1809         if (en->have_selection)
1810           en->had_sel = EINA_TRUE;
1811         en->selecting = EINA_FALSE;
1812      }
1813    if (evas_textblock_cursor_compare(tc, en->cursor))
1814      {
1815         _edje_emit(rp->edje, "cursor,changed", rp->part->name);
1816         _edje_emit(rp->edje, "cursor,changed,manual", rp->part->name);
1817      }
1818    evas_textblock_cursor_free(tc);
1819
1820    _edje_entry_imf_context_reset(en);
1821    _edje_entry_imf_cursor_info_set(en);
1822    _edje_entry_real_part_configure(rp);
1823 }
1824
1825 static void
1826 _edje_part_mouse_move_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
1827 {
1828    Evas_Coord cx, cy;
1829    Edje_Real_Part *rp = data;
1830    Evas_Event_Mouse_Move *ev = event_info;
1831    Entry *en;
1832    Evas_Coord x, y, w, h;
1833    Evas_Textblock_Cursor *tc;
1834    if (!rp) return;
1835    en = rp->entry_data;
1836    if ((!en) || (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK) ||
1837        (rp->part->entry_mode < EDJE_ENTRY_EDIT_MODE_SELECTABLE))
1838      return;
1839
1840 #ifdef HAVE_ECORE_IMF
1841    if (en->imf_context)
1842      {
1843         Ecore_IMF_Event_Mouse_Move ecore_ev;
1844         ecore_imf_evas_event_mouse_move_wrap(ev, &ecore_ev);
1845         if (ecore_imf_context_filter_event(en->imf_context,
1846                                            ECORE_IMF_EVENT_MOUSE_MOVE,
1847                                            (Ecore_IMF_Event *)&ecore_ev))
1848           return;
1849      }
1850 #endif
1851
1852    if (en->selecting)
1853      {
1854         tc = evas_object_textblock_cursor_new(rp->object);
1855         evas_textblock_cursor_copy(en->cursor, tc);
1856         evas_object_geometry_get(rp->object, &x, &y, &w, &h);
1857         cx = ev->cur.canvas.x - x;
1858         cy = ev->cur.canvas.y - y;
1859         if (!evas_textblock_cursor_char_coord_set(en->cursor, cx, cy))
1860           {
1861              Evas_Coord lx, ly, lw, lh;
1862
1863              if (evas_textblock_cursor_line_coord_set(en->cursor, cy) < 0)
1864                {
1865                   if (rp->part->multiline)
1866                     _curs_end(en->cursor, rp->object, en);
1867                   else
1868                     {
1869                        evas_textblock_cursor_paragraph_first(en->cursor);
1870                        evas_textblock_cursor_line_geometry_get(en->cursor, &lx, &ly, &lw, &lh);
1871                        if (!evas_textblock_cursor_char_coord_set(en->cursor, cx, ly + (lh / 2)))
1872                          _curs_end(en->cursor, rp->object, en);
1873                     }
1874                }
1875              else
1876                {
1877                   evas_textblock_cursor_line_geometry_get(en->cursor, &lx, &ly, &lw, &lh);
1878                   if (cx <= lx)
1879                     _curs_lin_start(en->cursor, rp->object, en);
1880                   else
1881                     _curs_lin_end(en->cursor, rp->object, en);
1882                }
1883           }
1884         if (rp->part->select_mode == EDJE_ENTRY_SELECTION_MODE_EXPLICIT)
1885           {
1886              if (en->select_allow)
1887                {
1888                   if (en->had_sel)
1889                     {
1890                        if (en->select_mod_end)
1891                          _sel_extend(en->cursor, rp->object, en);
1892                        else if (en->select_mod_start)
1893                          _sel_preextend(en->cursor, rp->object, en);
1894                     }
1895                   else
1896                     _sel_extend(en->cursor, rp->object, en);
1897                }
1898           }
1899         else
1900           {
1901              _sel_extend(en->cursor, rp->object, en);
1902           }
1903         if (en->select_allow)
1904           {
1905              if (evas_textblock_cursor_compare(en->sel_start, en->sel_end) != 0)
1906                _sel_enable(en->cursor, rp->object, en);
1907              if (en->have_selection)
1908                _sel_update(en->cursor, rp->object, en);
1909           }
1910         if (evas_textblock_cursor_compare(tc, en->cursor))
1911           {
1912              _edje_emit(rp->edje, "cursor,changed", rp->part->name);
1913              _edje_emit(rp->edje, "cursor,changed,manual", rp->part->name);
1914           }
1915         evas_textblock_cursor_free(tc);
1916
1917         _edje_entry_imf_context_reset(en);
1918         _edje_entry_imf_cursor_info_set(en);
1919
1920         _edje_entry_real_part_configure(rp);
1921      }
1922 }
1923
1924 static void
1925 _evas_focus_in_cb(void *data, Evas *e, __UNUSED__ void *event_info)
1926 {
1927    Edje *ed = (Edje *)data;
1928
1929    if (evas_focus_get(e) == ed->obj)
1930      {
1931         _edje_focus_in_cb(data, NULL, NULL, NULL);
1932      }
1933 }
1934
1935 static void
1936 _evas_focus_out_cb(void *data, Evas *e, __UNUSED__ void *event_info)
1937 {
1938    Edje *ed = (Edje *)data;
1939
1940    if (evas_focus_get(e) == ed->obj)
1941      {
1942         _edje_focus_out_cb(data, NULL, NULL, NULL);
1943      }
1944 }
1945
1946 /***************************************************************/
1947 void
1948 _edje_entry_init(Edje *ed)
1949 {
1950    if (!ed->has_entries)
1951      return;
1952    if (ed->entries_inited)
1953      return;
1954    ed->entries_inited = EINA_TRUE;
1955
1956    evas_object_event_callback_add(ed->obj, EVAS_CALLBACK_FOCUS_IN, _edje_focus_in_cb, ed);
1957    evas_object_event_callback_add(ed->obj, EVAS_CALLBACK_FOCUS_OUT, _edje_focus_out_cb, ed);
1958    evas_object_event_callback_add(ed->obj, EVAS_CALLBACK_KEY_DOWN, _edje_key_down_cb, ed);
1959    evas_object_event_callback_add(ed->obj, EVAS_CALLBACK_KEY_UP, _edje_key_up_cb, ed);
1960    evas_event_callback_add(ed->base.evas, EVAS_CALLBACK_CANVAS_FOCUS_IN, _evas_focus_in_cb, ed);
1961    evas_event_callback_add(ed->base.evas, EVAS_CALLBACK_CANVAS_FOCUS_OUT, _evas_focus_out_cb, ed);
1962 }
1963
1964 void
1965 _edje_entry_shutdown(Edje *ed)
1966 {
1967    if (!ed->has_entries)
1968      return;
1969    if (!ed->entries_inited)
1970      return;
1971    ed->entries_inited = EINA_FALSE;
1972
1973    evas_object_event_callback_del(ed->obj, EVAS_CALLBACK_FOCUS_IN, _edje_focus_in_cb);
1974    evas_object_event_callback_del(ed->obj, EVAS_CALLBACK_FOCUS_OUT, _edje_focus_out_cb);
1975    evas_object_event_callback_del(ed->obj, EVAS_CALLBACK_KEY_DOWN, _edje_key_down_cb);
1976    evas_object_event_callback_del(ed->obj, EVAS_CALLBACK_KEY_UP, _edje_key_up_cb);
1977    if (evas_event_callback_del_full(ed->base.evas, EVAS_CALLBACK_CANVAS_FOCUS_IN, _evas_focus_in_cb, ed) != ed)
1978      ERR("could not unregister EVAS_CALLBACK_FOCUS_IN");
1979    if (evas_event_callback_del_full(ed->base.evas, EVAS_CALLBACK_CANVAS_FOCUS_OUT, _evas_focus_out_cb, ed) != ed)
1980      ERR("could not unregister EVAS_CALLBACK_FOCUS_OUT");
1981 }
1982
1983 void
1984 _edje_entry_real_part_init(Edje_Real_Part *rp)
1985 {
1986    Entry *en;
1987 #ifdef HAVE_ECORE_IMF
1988    const char *ctx_id;
1989    const Ecore_IMF_Context_Info *ctx_info;
1990 #endif
1991
1992    en = calloc(1, sizeof(Entry));
1993    if (!en) return;
1994    rp->entry_data = en;
1995    en->rp = rp;
1996
1997    evas_object_event_callback_add(rp->object, EVAS_CALLBACK_MOVE, _edje_part_move_cb, rp);
1998
1999    evas_object_event_callback_add(rp->object, EVAS_CALLBACK_MOUSE_DOWN, _edje_part_mouse_down_cb, rp);
2000    evas_object_event_callback_add(rp->object, EVAS_CALLBACK_MOUSE_UP, _edje_part_mouse_up_cb, rp);
2001    evas_object_event_callback_add(rp->object, EVAS_CALLBACK_MOUSE_MOVE, _edje_part_mouse_move_cb, rp);
2002
2003    if (rp->part->select_mode == EDJE_ENTRY_SELECTION_MODE_DEFAULT)
2004      en->select_allow = EINA_TRUE;
2005
2006    if (rp->part->entry_mode == EDJE_ENTRY_EDIT_MODE_PASSWORD)
2007      {
2008         Edje_Part_Description_Text *txt;
2009
2010         txt = (Edje_Part_Description_Text *)rp->chosen_description;
2011
2012         en->select_allow = EINA_FALSE;
2013         if (txt && edje_string_get(&txt->text.repch))
2014           evas_object_textblock_replace_char_set(rp->object, edje_string_get(&txt->text.repch));
2015         else
2016           evas_object_textblock_replace_char_set(rp->object, "*");
2017      }
2018
2019    en->cursor_bg = edje_object_add(rp->edje->base.evas);
2020    edje_object_file_set(en->cursor_bg, rp->edje->path, rp->part->source3);
2021    evas_object_smart_member_add(en->cursor_bg, rp->edje->obj);
2022    evas_object_stack_below(en->cursor_bg, rp->object);
2023    evas_object_clip_set(en->cursor_bg, evas_object_clip_get(rp->object));
2024    evas_object_pass_events_set(en->cursor_bg, EINA_TRUE);
2025    _edje_subobj_register(en->rp->edje, en->cursor_bg);
2026
2027    en->cursor_fg = edje_object_add(rp->edje->base.evas);
2028    edje_object_file_set(en->cursor_fg, rp->edje->path, rp->part->source4);
2029    evas_object_smart_member_add(en->cursor_fg, rp->edje->obj);
2030    evas_object_stack_above(en->cursor_fg, rp->object);
2031    evas_object_clip_set(en->cursor_fg, evas_object_clip_get(rp->object));
2032    evas_object_pass_events_set(en->cursor_fg, EINA_TRUE);
2033    _edje_subobj_register(en->rp->edje, en->cursor_fg);
2034
2035    evas_object_textblock_legacy_newline_set(rp->object, EINA_TRUE);
2036
2037    if (rp->part->entry_mode >= EDJE_ENTRY_EDIT_MODE_EDITABLE)
2038      {
2039         evas_object_show(en->cursor_bg);
2040         evas_object_show(en->cursor_fg);
2041 #ifdef HAVE_ECORE_IMF
2042         ecore_imf_init();
2043
2044         edje_object_signal_callback_add(rp->edje->obj, "focus,part,in", rp->part->name, _edje_entry_focus_in_cb, rp);
2045         edje_object_signal_callback_add(rp->edje->obj, "focus,part,out", rp->part->name, _edje_entry_focus_out_cb, rp);
2046
2047         ctx_id = ecore_imf_context_default_id_get();
2048         if (ctx_id)
2049           {
2050              ctx_info = ecore_imf_context_info_by_id_get(ctx_id);
2051              if (!ctx_info->canvas_type ||
2052                  strcmp(ctx_info->canvas_type, "evas") == 0)
2053                {
2054                   en->imf_context = ecore_imf_context_add(ctx_id);
2055                }
2056              else
2057                {
2058                   ctx_id = ecore_imf_context_default_id_by_canvas_type_get("evas");
2059                   if (ctx_id)
2060                     {
2061                        en->imf_context = ecore_imf_context_add(ctx_id);
2062                     }
2063                }
2064           }
2065         else
2066           en->imf_context = NULL;
2067
2068         if (!en->imf_context) goto done;
2069
2070         ecore_imf_context_client_window_set
2071            (en->imf_context, 
2072                (void *)ecore_evas_window_get
2073                (ecore_evas_ecore_evas_get(rp->edje->base.evas)));
2074         ecore_imf_context_client_canvas_set(en->imf_context, rp->edje->base.evas);
2075
2076         ecore_imf_context_retrieve_surrounding_callback_set(en->imf_context,
2077                                                             _edje_entry_imf_retrieve_surrounding_cb, rp->edje);
2078         en->imf_ee_handler_commit = ecore_event_handler_add(ECORE_IMF_EVENT_COMMIT, _edje_entry_imf_event_commit_cb, rp->edje);
2079         en->imf_ee_handler_delete = ecore_event_handler_add(ECORE_IMF_EVENT_DELETE_SURROUNDING, _edje_entry_imf_event_delete_surrounding_cb, rp->edje);
2080         en->imf_ee_handler_changed = ecore_event_handler_add(ECORE_IMF_EVENT_PREEDIT_CHANGED, _edje_entry_imf_event_preedit_changed_cb, rp->edje);
2081         ecore_imf_context_input_mode_set(en->imf_context,
2082                                          rp->part->entry_mode == EDJE_ENTRY_EDIT_MODE_PASSWORD ?
2083                                          ECORE_IMF_INPUT_MODE_INVISIBLE : ECORE_IMF_INPUT_MODE_FULL);
2084 #endif
2085      }
2086 #ifdef HAVE_ECORE_IMF
2087 done:
2088 #endif
2089    en->cursor = (Evas_Textblock_Cursor *)evas_object_textblock_cursor_get(rp->object);
2090 }
2091
2092 void
2093 _edje_entry_real_part_shutdown(Edje_Real_Part *rp)
2094 {
2095    Entry *en = rp->entry_data;
2096    if (!en) return;
2097    rp->entry_data = NULL;
2098    _sel_clear(en->cursor, rp->object, en);
2099    _anchors_clear(en->cursor, rp->object, en);
2100 #ifdef HAVE_ECORE_IMF
2101    _preedit_clear(en);
2102 #endif
2103    evas_object_del(en->cursor_bg);
2104    evas_object_del(en->cursor_fg);
2105
2106    if (en->pw_timer)
2107      {
2108         ecore_timer_del(en->pw_timer);
2109         en->pw_timer = NULL;
2110      }
2111
2112 #ifdef HAVE_ECORE_IMF
2113    if (rp->part->entry_mode >= EDJE_ENTRY_EDIT_MODE_EDITABLE)
2114      {
2115         if (en->imf_context)
2116           {
2117              if (en->imf_ee_handler_commit)
2118                {
2119                   ecore_event_handler_del(en->imf_ee_handler_commit);
2120                   en->imf_ee_handler_commit = NULL;
2121                }
2122
2123              if (en->imf_ee_handler_delete)
2124                {
2125                   ecore_event_handler_del(en->imf_ee_handler_delete);
2126                   en->imf_ee_handler_delete = NULL;
2127                }
2128
2129              if (en->imf_ee_handler_changed)
2130                {
2131                   ecore_event_handler_del(en->imf_ee_handler_changed);
2132                   en->imf_ee_handler_changed = NULL;
2133                }
2134
2135              ecore_imf_context_del(en->imf_context);
2136              en->imf_context = NULL;
2137           }
2138
2139         edje_object_signal_callback_del(rp->edje->obj, "focus,part,in", rp->part->name, _edje_entry_focus_in_cb);
2140         edje_object_signal_callback_del(rp->edje->obj, "focus,part,out", rp->part->name, _edje_entry_focus_out_cb);
2141         ecore_imf_shutdown();
2142      }
2143 #endif
2144
2145    free(en);
2146 }
2147
2148 void
2149 _edje_entry_real_part_configure(Edje_Real_Part *rp)
2150 {
2151    Evas_Coord x, y, w, h, xx, yy, ww, hh;
2152    Entry *en = rp->entry_data;
2153    Evas_Textblock_Cursor_Type cur_type;
2154    if (!en) return;
2155    switch (rp->part->cursor_mode)
2156      {
2157       case EDJE_ENTRY_CURSOR_MODE_BEFORE:
2158          cur_type = EVAS_TEXTBLOCK_CURSOR_BEFORE;
2159          break;
2160       case EDJE_ENTRY_CURSOR_MODE_UNDER:
2161          /* no break for a resaon */
2162       default:
2163          cur_type = EVAS_TEXTBLOCK_CURSOR_UNDER;
2164      }
2165
2166    _sel_update(en->cursor, rp->object, en);
2167    _anchors_update(en->cursor, rp->object, en);
2168    x = y = w = h = -1;
2169    xx = yy = ww = hh = -1;
2170    evas_object_geometry_get(rp->object, &x, &y, &w, &h);
2171    evas_textblock_cursor_geometry_get(en->cursor, &xx, &yy, &ww, &hh, NULL, cur_type);
2172    if (ww < 1) ww = 1;
2173    if (hh < 1) hh = 1;
2174    if (en->cursor_bg)
2175      {
2176         evas_object_move(en->cursor_bg, x + xx, y + yy);
2177         evas_object_resize(en->cursor_bg, ww, hh);
2178      }
2179    if (en->cursor_fg)
2180      {
2181         evas_object_move(en->cursor_fg, x + xx, y + yy);
2182         evas_object_resize(en->cursor_fg, ww, hh);
2183      }
2184 }
2185
2186 const char *
2187 _edje_entry_selection_get(Edje_Real_Part *rp)
2188 {
2189    Entry *en = rp->entry_data;
2190    if (!en) return NULL;
2191    // get selection - convert to markup
2192    if ((!en->selection) && (en->have_selection))
2193      en->selection = evas_textblock_cursor_range_text_get
2194         (en->sel_start, en->sel_end, EVAS_TEXTBLOCK_TEXT_MARKUP);
2195    return en->selection;
2196 }
2197
2198 const char *
2199 _edje_entry_text_get(Edje_Real_Part *rp)
2200 {
2201    Entry *en = rp->entry_data;
2202    if (!en) return NULL;
2203    // get text - convert to markup
2204    return evas_object_textblock_text_markup_get(rp->object);
2205 }
2206
2207 void
2208 _edje_entry_text_markup_set(Edje_Real_Part *rp, const char *text)
2209 {
2210    Entry *en = rp->entry_data;
2211    if (!en) return;
2212
2213    // set text as markup
2214    _sel_clear(en->cursor, rp->object, en);
2215    evas_object_textblock_text_markup_set(rp->object, text);
2216    _edje_entry_set_cursor_start(rp);
2217
2218    _anchors_get(en->cursor, rp->object, en);
2219    _edje_emit(rp->edje, "entry,changed", rp->part->name);
2220    _edje_entry_imf_cursor_info_set(en);
2221 #if 0
2222    /* Don't emit cursor changed cause it didn't. It's just init to 0. */
2223    _edje_emit(rp->edje, "cursor,changed", rp->part->name);
2224 #endif
2225 }
2226
2227 void
2228 _edje_entry_text_markup_append(Edje_Real_Part *rp, const char *text)
2229 {
2230    Entry *en = rp->entry_data;
2231    Evas_Textblock_Cursor *end_cur;
2232    if (!en) return;
2233    end_cur = evas_object_textblock_cursor_new(rp->object);
2234    evas_textblock_cursor_paragraph_last(end_cur);
2235
2236    _text_filter_markup_prepend(en, end_cur, text);
2237    evas_textblock_cursor_free(end_cur);
2238
2239    /* We are updating according to the real cursor on purpose */
2240    _anchors_get(en->cursor, rp->object, en);
2241    _edje_emit(rp->edje, "entry,changed", rp->part->name);
2242
2243    _edje_entry_real_part_configure(rp);
2244 }
2245
2246 void
2247 _edje_entry_text_markup_insert(Edje_Real_Part *rp, const char *text)
2248 {
2249    Entry *en = rp->entry_data;
2250    if (!en) return;
2251    // prepend markup @ cursor pos
2252    if (en->have_selection)
2253      _range_del(en->cursor, rp->object, en);
2254    _sel_clear(en->cursor, rp->object, en);
2255    //xx
2256 //   evas_object_textblock_text_markup_prepend(en->cursor, text);
2257    _text_filter_markup_prepend(en, en->cursor, text);
2258    _anchors_get(en->cursor, rp->object, en);
2259    _edje_emit(rp->edje, "entry,changed", rp->part->name);
2260    _edje_emit(rp->edje, "cursor,changed", rp->part->name);
2261
2262    _edje_entry_imf_context_reset(en);
2263    _edje_entry_imf_cursor_info_set(en);
2264    
2265    _edje_entry_real_part_configure(rp);
2266 }
2267
2268 void
2269 _edje_entry_set_cursor_start(Edje_Real_Part *rp)
2270 {
2271    Entry *en = rp->entry_data;
2272    if (!en) return;
2273    _curs_start(en->cursor, rp->object, en);
2274
2275    _edje_entry_imf_cursor_info_set(en);
2276 }
2277
2278 void
2279 _edje_entry_set_cursor_end(Edje_Real_Part *rp)
2280 {
2281    Entry *en = rp->entry_data;
2282    if (!en) return;
2283    _curs_end(en->cursor, rp->object, en);
2284
2285    _edje_entry_imf_cursor_info_set(en);
2286 }
2287
2288 void
2289 _edje_entry_select_none(Edje_Real_Part *rp)
2290 {
2291    Entry *en = rp->entry_data;
2292    if (!en) return;
2293    _sel_clear(en->cursor, rp->object, en);
2294 }
2295
2296 void
2297 _edje_entry_select_all(Edje_Real_Part *rp)
2298 {
2299    Entry *en = rp->entry_data;
2300    if (!en) return;
2301    _sel_clear(en->cursor, rp->object, en);
2302    _curs_start(en->cursor, rp->object, en);
2303    _sel_enable(en->cursor, rp->object, en);
2304    _sel_start(en->cursor, rp->object, en);
2305    _curs_end(en->cursor, rp->object, en);
2306    _sel_extend(en->cursor, rp->object, en);
2307
2308    _edje_entry_imf_context_reset(en);
2309    _edje_entry_imf_cursor_info_set(en);
2310    _edje_entry_real_part_configure(rp);
2311 }
2312
2313 void
2314 _edje_entry_select_begin(Edje_Real_Part *rp)
2315 {
2316    Entry *en = rp->entry_data;
2317    if (!en) return;
2318    _sel_clear(en->cursor, rp->object, en);
2319    _sel_enable(en->cursor, rp->object, en);
2320    _sel_start(en->cursor, rp->object, en);
2321    _sel_extend(en->cursor, rp->object, en);
2322
2323    _edje_entry_imf_context_reset(en);
2324    _edje_entry_imf_cursor_info_set(en);
2325
2326    _edje_entry_real_part_configure(rp);
2327 }
2328
2329 void
2330 _edje_entry_select_extend(Edje_Real_Part *rp)
2331 {
2332    Entry *en = rp->entry_data;
2333    if (!en) return;
2334    _sel_extend(en->cursor, rp->object, en);
2335
2336    _edje_entry_imf_context_reset(en);
2337    _edje_entry_imf_cursor_info_set(en);
2338
2339    _edje_entry_real_part_configure(rp);
2340 }
2341
2342 const Eina_List *
2343 _edje_entry_anchor_geometry_get(Edje_Real_Part *rp, const char *anchor)
2344 {
2345    Entry *en = rp->entry_data;
2346    Eina_List *l;
2347    Anchor *an;
2348
2349    if (!en) return NULL;
2350    EINA_LIST_FOREACH(en->anchors, l, an)
2351      {
2352         if (an->item) continue;
2353         if (!strcmp(anchor, an->name))
2354           return an->sel;
2355      }
2356    return NULL;
2357 }
2358
2359 const Eina_List *
2360 _edje_entry_anchors_list(Edje_Real_Part *rp)
2361 {
2362    Entry *en = rp->entry_data;
2363    Eina_List *l, *anchors = NULL;
2364    Anchor *an;
2365
2366    if (!en) return NULL;
2367    if (!en->anchorlist)
2368      {
2369         EINA_LIST_FOREACH(en->anchors, l, an)
2370           {
2371              const char *n = an->name;
2372              if (an->item) continue;
2373              if (!n) n = "";
2374              anchors = eina_list_append(anchors, strdup(n));
2375           }
2376         en->anchorlist = anchors;
2377      }
2378    return en->anchorlist;
2379 }
2380
2381 Eina_Bool
2382 _edje_entry_item_geometry_get(Edje_Real_Part *rp, const char *item, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch)
2383 {
2384    Entry *en = rp->entry_data;
2385    Eina_List *l;
2386    Anchor *an;
2387
2388    if (!en) return EINA_FALSE;
2389    EINA_LIST_FOREACH(en->anchors, l, an)
2390      {
2391         if (an->item) continue;
2392         if (!strcmp(item, an->name))
2393           {
2394              evas_textblock_cursor_format_item_geometry_get(an->start, cx, cy, cw, ch);
2395              return EINA_TRUE;
2396           }
2397      }
2398    return EINA_FALSE;
2399 }
2400
2401 const Eina_List *
2402 _edje_entry_items_list(Edje_Real_Part *rp)
2403 {
2404    Entry *en = rp->entry_data;
2405    Eina_List *l, *items = NULL;
2406    Anchor *an;
2407
2408    if (!en) return NULL;
2409    if (!en->itemlist)
2410      {
2411         EINA_LIST_FOREACH(en->anchors, l, an)
2412           {
2413              const char *n = an->name;
2414              if (an->item) continue;
2415              if (!n) n = "";
2416              items = eina_list_append(items, strdup(n));
2417           }
2418         en->itemlist = items;
2419      }
2420    return en->itemlist;
2421 }
2422
2423 void
2424 _edje_entry_cursor_geometry_get(Edje_Real_Part *rp, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch)
2425 {
2426    Evas_Coord x, y, w, h, xx, yy, ww, hh;
2427    Entry *en = rp->entry_data;
2428    Evas_Textblock_Cursor_Type cur_type;
2429    if (!en) return;
2430    switch (rp->part->cursor_mode)
2431      {
2432       case EDJE_ENTRY_CURSOR_MODE_BEFORE:
2433          cur_type = EVAS_TEXTBLOCK_CURSOR_BEFORE;
2434          break;
2435       case EDJE_ENTRY_CURSOR_MODE_UNDER:
2436          /* no break for a resaon */
2437       default:
2438          cur_type = EVAS_TEXTBLOCK_CURSOR_UNDER;
2439      }
2440
2441    x = y = w = h = -1;
2442    xx = yy = ww = hh = -1;
2443    evas_object_geometry_get(rp->object, &x, &y, &w, &h);
2444    evas_textblock_cursor_geometry_get(en->cursor, &xx, &yy, &ww, &hh, NULL, cur_type);
2445    if (ww < 1) ww = 1;
2446    if (rp->part->cursor_mode == EDJE_ENTRY_CURSOR_MODE_BEFORE)
2447      edje_object_size_min_restricted_calc(en->cursor_fg, &ww, NULL, ww, 0);
2448    if (hh < 1) hh = 1;
2449    if (cx) *cx = x + xx;
2450    if (cy) *cy = y + yy;
2451    if (cw) *cw = ww;
2452    if (ch) *ch = hh;
2453 }
2454
2455 void
2456 _edje_entry_select_allow_set(Edje_Real_Part *rp, Eina_Bool allow)
2457 {
2458    Entry *en = rp->entry_data;
2459    if (rp->part->select_mode == EDJE_ENTRY_SELECTION_MODE_DEFAULT)
2460      return;
2461    en->select_allow = allow;
2462 }
2463
2464 Eina_Bool
2465 _edje_entry_select_allow_get(const Edje_Real_Part *rp)
2466 {
2467    const Entry *en = rp->entry_data;
2468    return en->select_allow;
2469 }
2470
2471 void
2472 _edje_entry_select_abort(Edje_Real_Part *rp)
2473 {
2474    Entry *en = rp->entry_data;
2475    if (en->selecting)
2476      {
2477         en->selecting = EINA_FALSE;
2478
2479         _edje_entry_imf_context_reset(en);
2480         _edje_entry_imf_cursor_info_set(en);
2481         _edje_entry_real_part_configure(rp);
2482      }
2483 }
2484
2485 void
2486 _edje_entry_autocapital_type_set(Edje_Real_Part *rp, Edje_Text_Autocapital_Type autocapital_type)
2487 {
2488    Entry *en = rp->entry_data;
2489    if (!en) return;
2490
2491    if (rp->part->entry_mode == EDJE_ENTRY_EDIT_MODE_PASSWORD)
2492      autocapital_type = EDJE_TEXT_AUTOCAPITAL_TYPE_NONE;
2493
2494 #ifdef HAVE_ECORE_IMF
2495    if (en->imf_context)
2496      ecore_imf_context_autocapital_type_set(en->imf_context, autocapital_type);
2497 #endif
2498 }
2499
2500 Edje_Text_Autocapital_Type
2501 _edje_entry_autocapital_type_get(Edje_Real_Part *rp)
2502 {
2503    Entry *en = rp->entry_data;
2504    if (!en) return EDJE_TEXT_AUTOCAPITAL_TYPE_NONE;
2505
2506 #ifdef HAVE_ECORE_IMF
2507    if (en->imf_context)
2508      return ecore_imf_context_autocapital_type_get(en->imf_context);
2509 #endif
2510
2511    return EDJE_TEXT_AUTOCAPITAL_TYPE_NONE;
2512 }
2513
2514 void
2515 _edje_entry_input_panel_enabled_set(Edje_Real_Part *rp, Eina_Bool enabled)
2516 {
2517    Entry *en = rp->entry_data;
2518
2519    if (!en) return;
2520 #ifdef HAVE_ECORE_IMF
2521    if (en->imf_context)
2522      ecore_imf_context_input_panel_enabled_set(en->imf_context, enabled);
2523 #else
2524    (void) enabled;
2525 #endif
2526 }
2527
2528 Eina_Bool
2529 _edje_entry_input_panel_enabled_get(Edje_Real_Part *rp)
2530 {
2531    Entry *en = rp->entry_data;
2532    if (!en) return EINA_FALSE;
2533 #ifdef HAVE_ECORE_IMF
2534    if (en->imf_context)
2535      return ecore_imf_context_input_panel_enabled_get(en->imf_context);
2536 #endif
2537
2538    return EINA_FALSE;
2539 }
2540
2541 static Evas_Textblock_Cursor *
2542 _cursor_get(Edje_Real_Part *rp, Edje_Cursor cur)
2543 {
2544    Entry *en = rp->entry_data;
2545    if (!en) return NULL;
2546
2547    switch (cur)
2548      {
2549       case EDJE_CURSOR_MAIN:
2550          return en->cursor;
2551       case EDJE_CURSOR_SELECTION_BEGIN:
2552          return en->sel_start;
2553       case EDJE_CURSOR_SELECTION_END:
2554          return en->sel_end;
2555       case EDJE_CURSOR_PREEDIT_START:
2556          if (!en->preedit_start)
2557            en->preedit_start = evas_object_textblock_cursor_new(rp->object);
2558          return en->preedit_start;
2559       case EDJE_CURSOR_PREEDIT_END:
2560          if (!en->preedit_end)
2561            en->preedit_end = evas_object_textblock_cursor_new(rp->object);
2562          return en->preedit_end;
2563       case EDJE_CURSOR_USER:
2564          if (!en->cursor_user)
2565            en->cursor_user = evas_object_textblock_cursor_new(rp->object);
2566          return en->cursor_user;
2567       case EDJE_CURSOR_USER_EXTRA:
2568          if (!en->cursor_user_extra)
2569            en->cursor_user_extra = evas_object_textblock_cursor_new(rp->object);
2570          return en->cursor_user_extra;
2571       default:
2572          break;
2573      }
2574    return NULL;
2575 }
2576
2577 Eina_Bool
2578 _edje_entry_cursor_next(Edje_Real_Part *rp, Edje_Cursor cur)
2579 {
2580    Entry *en = rp->entry_data;
2581    Evas_Textblock_Cursor *c = _cursor_get(rp, cur);
2582    if (!c) return EINA_FALSE;
2583    if (!evas_textblock_cursor_char_next(c))
2584      {
2585         return EINA_FALSE;
2586      }
2587    _sel_update(c, rp->object, rp->entry_data);
2588
2589    _edje_entry_imf_context_reset(en);
2590    _edje_entry_imf_cursor_info_set(en);
2591
2592    _edje_emit(rp->edje, "cursor,changed", rp->part->name);
2593    _edje_entry_real_part_configure(rp);
2594    return EINA_TRUE;
2595 }
2596
2597 Eina_Bool
2598 _edje_entry_cursor_prev(Edje_Real_Part *rp, Edje_Cursor cur)
2599 {
2600    Entry *en = rp->entry_data;
2601    Evas_Textblock_Cursor *c = _cursor_get(rp, cur);
2602    if (!c) return EINA_FALSE;
2603    if (!evas_textblock_cursor_char_prev(c))
2604      {
2605         if (evas_textblock_cursor_paragraph_prev(c)) goto ok;
2606         else return EINA_FALSE;
2607      }
2608 ok:
2609    _sel_update(c, rp->object, rp->entry_data);
2610
2611    _edje_entry_imf_context_reset(en);
2612    _edje_entry_imf_cursor_info_set(en);
2613
2614    _edje_emit(rp->edje, "cursor,changed", rp->part->name);
2615    _edje_entry_real_part_configure(rp);
2616    return EINA_TRUE;
2617 }
2618
2619 Eina_Bool
2620 _edje_entry_cursor_up(Edje_Real_Part *rp, Edje_Cursor cur)
2621 {
2622    Entry *en = rp->entry_data;
2623    Evas_Textblock_Cursor *c = _cursor_get(rp, cur);
2624    Evas_Coord lx, ly, lw, lh, cx, cy, cw, ch;
2625    int ln;
2626    if (!c) return EINA_FALSE;
2627    ln = evas_textblock_cursor_line_geometry_get(c, NULL, NULL, NULL, NULL);
2628    ln--;
2629    if (ln < 0) return EINA_FALSE;
2630    if (!evas_object_textblock_line_number_geometry_get(rp->object, ln,
2631                                                        &lx, &ly, &lw, &lh))
2632      return EINA_FALSE;
2633    evas_textblock_cursor_char_geometry_get(c, &cx, &cy, &cw, &ch);
2634    if (!evas_textblock_cursor_char_coord_set(c, cx, ly + (lh / 2)))
2635      {
2636         if (cx < (lx + (lw / 2)))
2637           evas_textblock_cursor_line_char_last(c);
2638         else
2639           evas_textblock_cursor_line_char_last(c);
2640      }
2641    _sel_update(c, rp->object, rp->entry_data);
2642
2643    _edje_entry_imf_context_reset(en);
2644    _edje_entry_imf_cursor_info_set(en);
2645
2646    _edje_emit(rp->edje, "cursor,changed", rp->part->name);
2647    _edje_entry_real_part_configure(rp);
2648    return EINA_TRUE;
2649 }
2650
2651 Eina_Bool
2652 _edje_entry_cursor_down(Edje_Real_Part *rp, Edje_Cursor cur)
2653 {
2654    Entry *en = rp->entry_data;
2655    Evas_Textblock_Cursor *c = _cursor_get(rp, cur);
2656    Evas_Coord lx, ly, lw, lh, cx, cy, cw, ch;
2657    int ln;
2658    if (!c) return EINA_FALSE;
2659    ln = evas_textblock_cursor_line_geometry_get(c, NULL, NULL, NULL, NULL);
2660    ln++;
2661    if (!evas_object_textblock_line_number_geometry_get(rp->object, ln,
2662                                                        &lx, &ly, &lw, &lh))
2663      return EINA_FALSE;
2664    evas_textblock_cursor_char_geometry_get(c, &cx, &cy, &cw, &ch);
2665    if (!evas_textblock_cursor_char_coord_set(c, cx, ly + (lh / 2)))
2666      {
2667         if (cx < (lx + (lw / 2)))
2668           evas_textblock_cursor_line_char_last(c);
2669         else
2670           evas_textblock_cursor_line_char_last(c);
2671      }
2672    _sel_update(c, rp->object, rp->entry_data);
2673
2674    _edje_entry_imf_context_reset(en);
2675    _edje_entry_imf_cursor_info_set(en);
2676    _edje_emit(rp->edje, "cursor,changed", rp->part->name);
2677    _edje_entry_real_part_configure(rp);
2678    return EINA_TRUE;
2679 }
2680
2681 void
2682 _edje_entry_cursor_begin(Edje_Real_Part *rp, Edje_Cursor cur)
2683 {
2684    Entry *en = rp->entry_data;
2685    Evas_Textblock_Cursor *c = _cursor_get(rp, cur);
2686    if (!c) return;
2687    evas_textblock_cursor_paragraph_first(c);
2688    _sel_update(c, rp->object, rp->entry_data);
2689
2690    _edje_entry_imf_context_reset(en);
2691    _edje_entry_imf_cursor_info_set(en);
2692    _edje_emit(rp->edje, "cursor,changed", rp->part->name);
2693    _edje_entry_real_part_configure(rp);
2694 }
2695
2696 void
2697 _edje_entry_cursor_end(Edje_Real_Part *rp, Edje_Cursor cur)
2698 {
2699    Entry *en = rp->entry_data;
2700    Evas_Textblock_Cursor *c = _cursor_get(rp, cur);
2701    if (!c) return;
2702    _curs_end(c, rp->object, rp->entry_data);
2703    _sel_update(c, rp->object, rp->entry_data);
2704
2705    _edje_entry_imf_context_reset(en);
2706    _edje_entry_imf_cursor_info_set(en);
2707
2708    _edje_emit(rp->edje, "cursor,changed", rp->part->name);
2709    _edje_entry_real_part_configure(rp);
2710 }
2711
2712 void
2713 _edje_entry_cursor_copy(Edje_Real_Part *rp, Edje_Cursor cur, Edje_Cursor dst)
2714 {
2715    Entry *en = rp->entry_data;
2716    Evas_Textblock_Cursor *c;
2717    Evas_Textblock_Cursor *d;
2718
2719    c = _cursor_get(rp, cur);
2720    if (!c) return;
2721    d = _cursor_get(rp, dst);
2722    if (!d) return;
2723    evas_textblock_cursor_copy(c, d);
2724    _sel_update(c, rp->object, rp->entry_data);
2725
2726    _edje_entry_imf_context_reset(en);
2727    _edje_entry_imf_cursor_info_set(en);
2728    _edje_emit(rp->edje, "cursor,changed", rp->part->name);
2729    _edje_entry_real_part_configure(rp);
2730 }
2731
2732 void
2733 _edje_entry_cursor_line_begin(Edje_Real_Part *rp, Edje_Cursor cur)
2734 {
2735    Entry *en = rp->entry_data;
2736    Evas_Textblock_Cursor *c = _cursor_get(rp, cur);
2737    if (!c) return;
2738    evas_textblock_cursor_line_char_first(c);
2739    _sel_update(c, rp->object, rp->entry_data);
2740
2741    _edje_entry_imf_context_reset(en);
2742    _edje_entry_imf_cursor_info_set(en);
2743
2744    _edje_emit(rp->edje, "cursor,changed", rp->part->name);
2745    _edje_entry_real_part_configure(rp);
2746 }
2747
2748 void
2749 _edje_entry_cursor_line_end(Edje_Real_Part *rp, Edje_Cursor cur)
2750 {
2751    Entry *en = rp->entry_data;
2752    Evas_Textblock_Cursor *c = _cursor_get(rp, cur);
2753    if (!c) return;
2754    evas_textblock_cursor_line_char_last(c);
2755    _sel_update(c, rp->object, rp->entry_data);
2756
2757    _edje_entry_imf_context_reset(en);
2758    _edje_entry_imf_cursor_info_set(en);
2759    _edje_emit(rp->edje, "cursor,changed", rp->part->name);
2760    _edje_entry_real_part_configure(rp);
2761 }
2762
2763 Eina_Bool
2764 _edje_entry_cursor_coord_set(Edje_Real_Part *rp, Edje_Cursor cur,
2765                              Evas_Coord x, Evas_Coord y)
2766 {
2767    Evas_Textblock_Cursor *c = _cursor_get(rp, cur);
2768    if (!c) return EINA_FALSE;
2769    return evas_textblock_cursor_char_coord_set(c, x, y);
2770 }
2771
2772 Eina_Bool
2773 _edje_entry_cursor_is_format_get(Edje_Real_Part *rp, Edje_Cursor cur)
2774 {
2775    Evas_Textblock_Cursor *c = _cursor_get(rp, cur);
2776    if (!c) return EINA_FALSE;
2777    if (evas_textblock_cursor_is_format(c)) return EINA_TRUE;
2778    return EINA_FALSE;
2779 }
2780
2781 Eina_Bool
2782 _edje_entry_cursor_is_visible_format_get(Edje_Real_Part *rp, Edje_Cursor cur)
2783 {
2784    Evas_Textblock_Cursor *c = _cursor_get(rp, cur);
2785    if (!c) return EINA_FALSE;
2786    return evas_textblock_cursor_format_is_visible_get(c);
2787 }
2788
2789 char *
2790 _edje_entry_cursor_content_get(Edje_Real_Part *rp, Edje_Cursor cur)
2791 {
2792    static char *s = NULL;
2793    Evas_Textblock_Cursor *c = _cursor_get(rp, cur);
2794
2795    if (!c) return NULL;
2796    if (s)
2797      {
2798         free(s);
2799         s = NULL;
2800      }
2801
2802    s = evas_textblock_cursor_content_get(c);
2803    return s;
2804 }
2805
2806 void
2807 _edje_entry_cursor_pos_set(Edje_Real_Part *rp, Edje_Cursor cur, int pos)
2808 {
2809    Entry *en = rp->entry_data;
2810    Evas_Textblock_Cursor *c = _cursor_get(rp, cur);
2811    if (!c) return;
2812    /* Abort if cursor position didn't really change */
2813    if (evas_textblock_cursor_pos_get(c) == pos)
2814       return;
2815
2816    evas_textblock_cursor_pos_set(c, pos);
2817    _sel_update(c, rp->object, rp->entry_data);
2818
2819    _edje_entry_imf_context_reset(en);
2820    _edje_entry_imf_cursor_info_set(en);
2821    _edje_emit(rp->edje, "cursor,changed", rp->part->name);
2822    _edje_entry_real_part_configure(rp);
2823 }
2824
2825 int
2826 _edje_entry_cursor_pos_get(Edje_Real_Part *rp, Edje_Cursor cur)
2827 {
2828    Evas_Textblock_Cursor *c = _cursor_get(rp, cur);
2829    if (!c) return 0;
2830    return evas_textblock_cursor_pos_get(c);
2831 }
2832
2833 void
2834 _edje_entry_input_panel_layout_set(Edje_Real_Part *rp, Edje_Input_Panel_Layout layout)
2835 {
2836    Entry *en = rp->entry_data;
2837    if (!en) return;
2838 #ifdef HAVE_ECORE_IMF
2839    if (en->imf_context)
2840      ecore_imf_context_input_panel_layout_set(en->imf_context, layout);
2841 #else
2842    (void) layout;
2843 #endif
2844 }
2845
2846 Edje_Input_Panel_Layout
2847 _edje_entry_input_panel_layout_get(Edje_Real_Part *rp)
2848 {
2849    Entry *en = rp->entry_data;
2850    if (!en) return EDJE_INPUT_PANEL_LAYOUT_INVALID;
2851 #ifdef HAVE_ECORE_IMF
2852    if (en->imf_context)
2853      return ecore_imf_context_input_panel_layout_get(en->imf_context);
2854 #endif
2855
2856    return EDJE_INPUT_PANEL_LAYOUT_INVALID;
2857 }
2858
2859 static void
2860 _edje_entry_imf_context_reset(Entry *en)
2861 {
2862 #ifdef HAVE_ECORE_IMF
2863    if (en->imf_context)
2864      ecore_imf_context_reset(en->imf_context);
2865 #else
2866    (void) en;
2867 #endif
2868 }
2869
2870 static void
2871 _edje_entry_imf_cursor_info_set(Entry *en)
2872 {
2873 #ifdef HAVE_ECORE_IMF
2874    Evas_Coord cx, cy, cw, ch;
2875    if (!en || !en->rp || !en->imf_context) return;
2876
2877    _edje_entry_cursor_geometry_get(en->rp, &cx, &cy, &cw, &ch);
2878
2879    ecore_imf_context_cursor_position_set(en->imf_context,
2880                                          evas_textblock_cursor_pos_get(en->cursor));
2881    ecore_imf_context_cursor_location_set(en->imf_context, cx, cy, cw, ch);
2882 #else
2883    (void) en;
2884 #endif
2885 }
2886
2887 #ifdef HAVE_ECORE_IMF
2888 static Eina_Bool
2889 _edje_entry_imf_retrieve_surrounding_cb(void *data, Ecore_IMF_Context *ctx __UNUSED__, char **text, int *cursor_pos)
2890 {
2891    Edje *ed = data;
2892    Edje_Real_Part *rp = ed->focused_part;
2893    Entry *en;
2894    const char *str;
2895
2896    if (!rp) return EINA_FALSE;
2897    en = rp->entry_data;
2898    if ((!en) || (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK) ||
2899        (rp->part->entry_mode < EDJE_ENTRY_EDIT_MODE_SELECTABLE))
2900      return EINA_FALSE;
2901
2902    if (text)
2903      {
2904         str = _edje_entry_text_get(rp);
2905         *text = str ? strdup(str) : strdup("");
2906      }
2907
2908    if (cursor_pos)
2909      *cursor_pos = evas_textblock_cursor_pos_get(en->cursor);
2910
2911    return EINA_TRUE;
2912 }
2913
2914 static Eina_Bool
2915 _edje_entry_imf_event_commit_cb(void *data, int type __UNUSED__, void *event)
2916 {
2917    Edje *ed = data;
2918    Edje_Real_Part *rp = ed->focused_part;
2919    Entry *en;
2920    Ecore_IMF_Event_Commit *ev = event;
2921    Evas_Textblock_Cursor *tc;
2922    Eina_Bool cursor_move = EINA_FALSE;
2923    int start_pos;
2924
2925    if ((!rp) || (!ev) || (!ev->str)) return ECORE_CALLBACK_PASS_ON;
2926
2927    en = rp->entry_data;
2928    if ((!en) || (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK) ||
2929        (rp->part->entry_mode < EDJE_ENTRY_EDIT_MODE_SELECTABLE))
2930      return ECORE_CALLBACK_PASS_ON;
2931
2932    if (!en->imf_context) return ECORE_CALLBACK_PASS_ON;
2933    if (en->imf_context != ev->ctx) return ECORE_CALLBACK_PASS_ON;
2934
2935    if (en->have_selection)
2936      {
2937         if (strcmp(ev->str, ""))
2938           {
2939              /* delete selected characters */
2940              _range_del_emit(ed, en->cursor, rp->object, en);
2941              _sel_clear(en->cursor, rp->object, en);
2942           }
2943      }
2944
2945    tc = evas_object_textblock_cursor_new(rp->object);
2946
2947    /* calculate the cursor position to insert commit string */
2948    if (en->preedit_start)
2949      evas_textblock_cursor_copy(en->preedit_start, tc);
2950    else
2951      evas_textblock_cursor_copy(en->cursor, tc);
2952
2953    start_pos = evas_textblock_cursor_pos_get(tc);
2954
2955
2956 #ifdef HAVE_ECORE_IMF
2957    /* delete preedit characters */
2958    _preedit_del(en);
2959    _preedit_clear(en);
2960 #endif
2961
2962    if (evas_textblock_cursor_compare(en->cursor, tc))
2963      cursor_move = EINA_TRUE;
2964    if ((rp->part->entry_mode == EDJE_ENTRY_EDIT_MODE_PASSWORD) &&
2965        _edje_password_show_last)
2966      _edje_entry_hide_visible_password(en->rp);
2967    if ((rp->part->entry_mode == EDJE_ENTRY_EDIT_MODE_PASSWORD) &&
2968        _edje_password_show_last && (!en->preedit_start))
2969      {
2970         _text_filter_format_prepend(en, tc, "+ password=off");
2971         _text_filter_text_prepend(en, tc, ev->str);
2972         _text_filter_format_prepend(en, tc, "- password");
2973         if (en->pw_timer)
2974           {
2975              ecore_timer_del(en->pw_timer);
2976              en->pw_timer = NULL;
2977           }
2978         en->pw_timer = ecore_timer_add(_edje_password_show_last_timeout,
2979                                        _password_timer_cb, en);
2980      }
2981    else
2982      _text_filter_text_prepend(en, tc, ev->str);
2983
2984    if (!cursor_move)
2985      {
2986         /* move cursor to the end of commit string */
2987         evas_textblock_cursor_copy(tc, en->cursor);
2988      }
2989
2990    evas_textblock_cursor_free(tc);
2991
2992    _edje_entry_imf_cursor_info_set(en);
2993    _anchors_get(en->cursor, rp->object, en);
2994    _edje_emit(rp->edje, "entry,changed", rp->part->name);
2995
2996      {
2997         Edje_Entry_Change_Info *info = calloc(1, sizeof(*info));
2998         info->insert = EINA_TRUE;
2999         info->change.insert.pos = start_pos;
3000         info->change.insert.content = eina_stringshare_add(ev->str);
3001         info->change.insert.plain_length =
3002            eina_unicode_utf8_get_len(info->change.insert.content);
3003         _edje_emit_full(ed, "entry,changed,user", rp->part->name,
3004                         info, _free_entry_change_info);
3005         _edje_emit(ed, "cursor,changed", rp->part->name);
3006      }
3007
3008    return ECORE_CALLBACK_DONE;
3009 }
3010
3011 static Eina_Bool
3012 _edje_entry_imf_event_preedit_changed_cb(void *data, int type __UNUSED__, void *event)
3013 {
3014    Edje *ed = data;
3015    Edje_Real_Part *rp = ed->focused_part;
3016    Entry *en;
3017    Ecore_IMF_Event_Preedit_Changed *ev = event;
3018    int cursor_pos;
3019    int preedit_start_pos, preedit_end_pos;
3020    char *preedit_string;
3021    int i;
3022    Eina_Bool preedit_end_state = EINA_FALSE;
3023    Eina_List *attrs = NULL, *l = NULL;
3024    Ecore_IMF_Preedit_Attr *attr;
3025    Eina_Strbuf *buf;
3026
3027    if ((!rp) || (!ev)) return ECORE_CALLBACK_PASS_ON;
3028
3029    en = rp->entry_data;
3030    if ((!en) || (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK) ||
3031        (rp->part->entry_mode < EDJE_ENTRY_EDIT_MODE_SELECTABLE))
3032      return ECORE_CALLBACK_PASS_ON;
3033
3034    if (!en->imf_context) return ECORE_CALLBACK_PASS_ON;
3035
3036    if (en->imf_context != ev->ctx) return ECORE_CALLBACK_PASS_ON;
3037
3038    ecore_imf_context_preedit_string_with_attributes_get(en->imf_context,
3039                                                         &preedit_string,
3040                                                         &attrs, &cursor_pos);
3041    if (!preedit_string) return ECORE_CALLBACK_PASS_ON;
3042
3043    if (!strcmp(preedit_string, ""))
3044      preedit_end_state = EINA_TRUE;
3045
3046    if (en->have_selection && !preedit_end_state)
3047      {
3048         /* delete selected characters */
3049         _range_del_emit(ed, en->cursor, rp->object, en);
3050         _sel_clear(en->cursor, rp->object, en);
3051      }
3052
3053    /* delete preedit characters */
3054    _preedit_del(en);
3055
3056    preedit_start_pos = evas_textblock_cursor_pos_get(en->cursor);
3057
3058    /* insert preedit character(s) */
3059    if (strlen(preedit_string) > 0)
3060      {
3061         buf = eina_strbuf_new();
3062         if (attrs)
3063           {
3064              EINA_LIST_FOREACH(attrs, l, attr)
3065                {
3066                   if (attr->preedit_type == ECORE_IMF_PREEDIT_TYPE_SUB1)
3067                     {
3068                        eina_strbuf_append(buf, "<preedit>");
3069                        eina_strbuf_append_n(buf, preedit_string + attr->start_index,
3070                                             attr->end_index - attr->start_index);
3071                        eina_strbuf_append(buf, "</preedit>");
3072                     }
3073
3074                   else if (attr->preedit_type == ECORE_IMF_PREEDIT_TYPE_SUB2 ||
3075                            attr->preedit_type == ECORE_IMF_PREEDIT_TYPE_SUB3)
3076                     {
3077                        eina_strbuf_append(buf, "<preedit_sel>");
3078                        eina_strbuf_append_n(buf, preedit_string + attr->start_index,
3079                                             attr->end_index - attr->start_index);
3080                        eina_strbuf_append(buf, "</preedit_sel>");
3081                     }
3082                }
3083           }
3084         if ((rp->part->entry_mode == EDJE_ENTRY_EDIT_MODE_PASSWORD) &&
3085             _edje_password_show_last)
3086           {
3087              _edje_entry_hide_visible_password(en->rp);
3088              _text_filter_format_prepend(en, en->cursor, "+ password=off");
3089              _text_filter_markup_prepend(en, en->cursor, eina_strbuf_string_get(buf));
3090              _text_filter_format_prepend(en, en->cursor, "- password");
3091              if (en->pw_timer)
3092                {
3093                   ecore_timer_del(en->pw_timer);
3094                   en->pw_timer = NULL;
3095                }
3096              en->pw_timer = ecore_timer_add(_edje_password_show_last_timeout,
3097                                             _password_timer_cb, en);
3098           }
3099         else
3100           {
3101              _text_filter_markup_prepend(en, en->cursor, eina_strbuf_string_get(buf));
3102           }
3103         eina_strbuf_free(buf);
3104      }
3105
3106    if (!preedit_end_state)
3107      {
3108         /* set preedit start cursor */
3109         if (!en->preedit_start)
3110           en->preedit_start = evas_object_textblock_cursor_new(rp->object);
3111         evas_textblock_cursor_copy(en->cursor, en->preedit_start);
3112
3113         /* set preedit end cursor */
3114         if (!en->preedit_end)
3115           en->preedit_end = evas_object_textblock_cursor_new(rp->object);
3116         evas_textblock_cursor_copy(en->cursor, en->preedit_end);
3117
3118         preedit_end_pos = evas_textblock_cursor_pos_get(en->cursor);
3119
3120         for (i = 0; i < (preedit_end_pos - preedit_start_pos); i++)
3121           {
3122              evas_textblock_cursor_char_prev(en->preedit_start);
3123           }
3124
3125         en->have_preedit = EINA_TRUE;
3126
3127         /* set cursor position */
3128         evas_textblock_cursor_pos_set(en->cursor, preedit_start_pos + cursor_pos);
3129      }
3130
3131    _edje_entry_imf_cursor_info_set(en);
3132    _anchors_get(en->cursor, rp->object, en);
3133    _edje_emit(rp->edje, "preedit,changed", rp->part->name);
3134    _edje_emit(ed, "cursor,changed", rp->part->name);
3135
3136    /* delete attribute list */
3137    if (attrs)
3138      {
3139         EINA_LIST_FREE(attrs, attr) free(attr);
3140      }
3141
3142    free(preedit_string);
3143
3144    return ECORE_CALLBACK_DONE;
3145 }
3146
3147 static Eina_Bool
3148 _edje_entry_imf_event_delete_surrounding_cb(void *data, int type __UNUSED__, void *event)
3149 {
3150    Edje *ed = data;
3151    Edje_Real_Part *rp = ed->focused_part;
3152    Entry *en;
3153    Ecore_IMF_Event_Delete_Surrounding *ev = event;
3154    Evas_Textblock_Cursor *del_start, *del_end;
3155    int cursor_pos;
3156
3157    if ((!rp) || (!ev)) return ECORE_CALLBACK_PASS_ON;
3158    en = rp->entry_data;
3159    if ((!en) || (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK) ||
3160        (rp->part->entry_mode < EDJE_ENTRY_EDIT_MODE_SELECTABLE))
3161      return ECORE_CALLBACK_PASS_ON;
3162
3163    if (!en->imf_context) return ECORE_CALLBACK_PASS_ON;
3164    if (en->imf_context != ev->ctx) return ECORE_CALLBACK_PASS_ON;
3165
3166    cursor_pos = evas_textblock_cursor_pos_get(en->cursor);
3167
3168    del_start = evas_object_textblock_cursor_new(en->rp->object);
3169    evas_textblock_cursor_pos_set(del_start, cursor_pos + ev->offset);
3170
3171    del_end = evas_object_textblock_cursor_new(en->rp->object);
3172    evas_textblock_cursor_pos_set(del_end, cursor_pos + ev->offset + ev->n_chars);
3173
3174    evas_textblock_cursor_range_delete(del_start, del_end);
3175
3176    evas_textblock_cursor_free(del_start);
3177    evas_textblock_cursor_free(del_end);
3178
3179    return ECORE_CALLBACK_DONE;
3180 }
3181 #endif
3182
3183 /* vim:set ts=8 sw=3 sts=3 expandtab cino=>5n-2f0^-2{2(0W1st0 :*/