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