merge with master
[framework/uifw/edje.git] / src / lib / edje_entry.c
1 #include "edje_private.h"
2 #include <ctype.h>
3
4 #ifdef HAVE_ECORE_IMF
5 static Eina_Bool _edje_entry_imf_retrieve_surrounding_cb(void *data, Ecore_IMF_Context *ctx, char **text, int *cursor_pos);
6 static void      _edje_entry_imf_event_commit_cb(void *data, Ecore_IMF_Context *ctx, void *event_info);
7 static void      _edje_entry_imf_event_preedit_changed_cb(void *data, Ecore_IMF_Context *ctx, void *event_info);
8 static void      _edje_entry_imf_event_delete_surrounding_cb(void *data, Ecore_IMF_Context *ctx, void *event);
9 #endif
10
11 // TIZEN ONLY - START
12 static void _edje_entry_top_handler_mouse_down_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info);
13 static void _edje_entry_top_handler_mouse_move_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info);
14 static void _edje_entry_top_handler_mouse_up_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info);
15
16 static void _edje_entry_bottom_handler_mouse_down_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info);
17 static void _edje_entry_bottom_handler_mouse_move_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info);
18 static void _edje_entry_bottom_handler_mouse_up_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info);
19 // TIZEN ONLY - END
20
21 typedef struct _Entry Entry;
22 typedef struct _Sel Sel;
23 typedef struct _Anchor Anchor;
24
25 // TIZEN ONLY - START
26 typedef enum _Entry_Long_Press_State
27 {
28    _ENTRY_LONG_PRESSING,
29    _ENTRY_LONG_PRESSED,
30    _ENTRY_LONG_PRESS_RELEASED
31 } Entry_Long_Press_State;
32 // TIZEN ONLY - END
33
34 static void _edje_entry_imf_cursor_location_set(Entry *en);
35 static void _edje_entry_imf_cursor_info_set(Entry *en);
36
37 struct _Entry
38 {
39    Edje_Real_Part *rp;
40    Evas_Coord ox, oy; // TIZEN ONLY
41    Evas_Coord sx, sy; // TIZEN ONLY
42    Evas_Coord rx, ry; // TIZEN ONLY
43    Evas_Coord dx, dy; // TIZEN ONLY
44    Evas_Coord_Rectangle layout_region; // TIZEN ONLY
45    Evas_Coord_Rectangle viewport_region; // TIZEN ONLY
46    Evas_Object *cursor_bg;
47    Evas_Object *cursor_fg;
48    Evas_Object *block_handler_top; // TIZEN ONLY
49    Evas_Object *block_handler_btm; // TIZEN ONLY
50    Evas_Textblock_Cursor *cursor;
51    Evas_Textblock_Cursor *sel_start, *sel_end;
52    Evas_Textblock_Cursor *cursor_user, *cursor_user_extra;
53    Evas_Textblock_Cursor *preedit_start, *preedit_end;
54    Ecore_Timer *pw_timer;
55    Eina_List *sel;
56    Eina_List *anchors;
57    Eina_List *anchorlist;
58    Eina_List *itemlist;
59    Eina_List *seq;
60    char *selection;
61    Edje_Input_Panel_Lang input_panel_lang;
62    Eina_Bool composing : 1;
63    Eina_Bool selecting : 1;
64    Eina_Bool have_selection : 1;
65    Eina_Bool select_allow : 1;
66    Eina_Bool select_mod_start : 1;
67    Eina_Bool select_mod_end : 1;
68    Eina_Bool double_clicked : 1; // TIZEN ONLY
69    Eina_Bool had_sel : 1;
70    Eina_Bool input_panel_enable : 1;
71    Eina_Bool prediction_allow : 1;
72    Eina_Bool copy_paste_disabled : 1;
73    // TIZEN ONLY(130129) : Currently, for freezing cursor movement.
74    Eina_Bool freeze : 1;
75    //
76    int select_dragging_state;
77
78 #ifdef HAVE_ECORE_IMF
79    Eina_Bool have_preedit : 1;
80    Eina_Bool commit_cancel : 1; // For skipping useless commit
81    Ecore_IMF_Context *imf_context;
82 #endif
83
84    Ecore_Timer *longpress_timer; // TIZEN ONLY
85    Entry_Long_Press_State long_press_state; // TIZEN ONLY
86 };
87
88 struct _Sel
89 {
90    Evas_Textblock_Rectangle rect;
91    Evas_Object *obj_fg, *obj_bg, *obj, *sobj;
92 };
93
94 struct _Anchor
95 {
96    Entry *en;
97    char *name;
98    Evas_Textblock_Cursor *start, *end;
99    Eina_List *sel;
100    Eina_Bool item : 1;
101 };
102
103 #ifdef HAVE_ECORE_IMF
104 static void
105 _preedit_clear(Entry *en)
106 {
107    if (en->preedit_start)
108      {
109         evas_textblock_cursor_free(en->preedit_start);
110         en->preedit_start = NULL;
111      }
112
113    if (en->preedit_end)
114      {
115         evas_textblock_cursor_free(en->preedit_end);
116         en->preedit_end = NULL;
117      }
118
119    en->have_preedit = EINA_FALSE;
120 }
121
122 static void
123 _preedit_del(Entry *en)
124 {
125    if (!en || !en->have_preedit) return;
126    if (!en->preedit_start || !en->preedit_end) return;
127    if (!evas_textblock_cursor_compare(en->preedit_start, en->preedit_end)) return;
128
129    /* delete the preedit characters */
130    evas_textblock_cursor_range_delete(en->preedit_start, en->preedit_end);
131 }
132
133 static void
134 _edje_entry_focus_in_cb(void *data, Evas_Object *o __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
135 {
136    Edje_Real_Part *rp;
137    Entry *en;
138
139    rp = data;
140    if ((rp->type != EDJE_RP_TYPE_TEXT) ||
141        (!rp->typedata.text)) return;
142    if (!rp || !rp->typedata.text->entry_data || !rp->edje || !rp->edje->obj) return;
143
144    en = rp->typedata.text->entry_data;
145    if (!en || !en->imf_context) return;
146
147    if (evas_object_focus_get(rp->edje->obj))
148      {
149         // TIZEN ONLY - START
150         if ((!en->block_handler_top) && (!en->block_handler_btm) &&
151             (en->rp->part->select_mode == EDJE_ENTRY_SELECTION_MODE_BLOCK_HANDLE))
152           {
153              const char *bh_position;
154              Evas_Object *ob;
155
156              ob = edje_object_add(en->rp->edje->base.evas);
157              edje_object_file_set(ob, en->rp->edje->path, en->rp->part->source2);
158              bh_position = edje_object_data_get(ob, "position");
159              if ((!bh_position) || (bh_position[0] == 0)) bh_position = "BOTH";
160
161              if ((!strcmp(bh_position, "BOTTOM")) || (!strcmp(bh_position, "BOTH")))
162                {
163                   evas_object_layer_set(ob, EVAS_LAYER_MAX - 2);
164                   en->block_handler_btm = ob;
165                   en->rp->edje->subobjs = eina_list_append(en->rp->edje->subobjs, en->block_handler_btm);
166                   evas_object_event_callback_add(ob, EVAS_CALLBACK_MOUSE_DOWN, _edje_entry_bottom_handler_mouse_down_cb, en->rp);
167                   evas_object_event_callback_add(ob, EVAS_CALLBACK_MOUSE_UP, _edje_entry_bottom_handler_mouse_up_cb, en->rp);
168                   evas_object_event_callback_add(ob, EVAS_CALLBACK_MOUSE_MOVE, _edje_entry_bottom_handler_mouse_move_cb, en->rp);
169                }
170              else
171                if (ob) evas_object_del(ob);
172
173              if ((!strcmp(bh_position, "TOP")) || (!strcmp(bh_position, "BOTH")))
174                {
175                   ob = edje_object_add(en->rp->edje->base.evas);
176                   edje_object_file_set(ob, en->rp->edje->path, en->rp->part->source3);
177                   evas_object_layer_set(ob, EVAS_LAYER_MAX - 2);
178                   en->block_handler_top = ob;
179                   en->rp->edje->subobjs = eina_list_append(en->rp->edje->subobjs, en->block_handler_top);
180                   evas_object_event_callback_add(ob, EVAS_CALLBACK_MOUSE_DOWN, _edje_entry_top_handler_mouse_down_cb, en->rp);
181                   evas_object_event_callback_add(ob, EVAS_CALLBACK_MOUSE_UP, _edje_entry_top_handler_mouse_up_cb, en->rp);
182                   evas_object_event_callback_add(ob, EVAS_CALLBACK_MOUSE_MOVE, _edje_entry_top_handler_mouse_move_cb, en->rp);
183                }
184           }
185         if (en->block_handler_top)
186           edje_object_signal_emit(en->block_handler_top, "edje,focus,in", "edje");
187         if (en->block_handler_btm)
188           edje_object_signal_emit(en->block_handler_btm, "edje,focus,in", "edje");
189         // TIZEN ONLY - END
190
191         ecore_imf_context_reset(en->imf_context);
192         ecore_imf_context_focus_in(en->imf_context);
193         _edje_entry_imf_cursor_info_set(en);
194      }
195 }
196
197 static void
198 _edje_entry_focus_out_cb(void *data, Evas_Object *o __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
199 {
200    Edje_Real_Part *rp;
201    Entry *en;
202
203    rp = data;
204    if ((rp->type != EDJE_RP_TYPE_TEXT) ||
205        (!rp->typedata.text)) return;
206    if (!rp || !rp->typedata.text->entry_data) return;
207
208    en = rp->typedata.text->entry_data;
209    if (!en || !en->imf_context) return;
210
211    // TIZEN ONLY - START
212    if (en->block_handler_top)
213      edje_object_signal_emit(en->block_handler_top, "edje,focus,out", "edje");
214    if (en->block_handler_btm)
215      edje_object_signal_emit(en->block_handler_btm, "edje,focus,out", "edje");
216    // TIZEN ONLY - END
217
218    ecore_imf_context_reset(en->imf_context);
219    ecore_imf_context_focus_out(en->imf_context);
220 }
221 #endif
222
223 static void
224 _edje_focus_in_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
225 {
226    Edje *ed = data;
227 #ifdef HAVE_ECORE_IMF
228    Edje_Real_Part *rp;
229    Entry *en;
230 #endif
231
232    _edje_emit(ed, "focus,in", "");
233
234    rp = ed->focused_part;
235    if (!rp) return;
236
237    if ((rp->type != EDJE_RP_TYPE_TEXT) ||
238        (!rp->typedata.text)) return;
239    en = rp->typedata.text->entry_data;
240    if ((!en) || (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK) ||
241        (rp->part->entry_mode < EDJE_ENTRY_EDIT_MODE_SELECTABLE))   //  TIZEN ONLY
242      return;
243
244    // TIZEN ONLY - START
245    if ((!en->block_handler_top) && (!en->block_handler_btm) &&
246       (en->rp->part->select_mode == EDJE_ENTRY_SELECTION_MODE_BLOCK_HANDLE))
247      {
248         const char *bh_position;
249         Evas_Object *ob;
250
251         ob = edje_object_add(en->rp->edje->base.evas);
252         edje_object_file_set(ob, en->rp->edje->path, en->rp->part->source2);
253         bh_position = edje_object_data_get(ob, "position");
254         if ((!bh_position) || (bh_position[0] == 0)) bh_position = "BOTH";
255
256         if ((!strcmp(bh_position, "BOTTOM")) || (!strcmp(bh_position, "BOTH")))
257           {
258              evas_object_layer_set(ob, EVAS_LAYER_MAX - 2);
259              en->block_handler_btm = ob;
260              en->rp->edje->subobjs = eina_list_append(en->rp->edje->subobjs, en->block_handler_btm);
261              evas_object_event_callback_add(ob, EVAS_CALLBACK_MOUSE_DOWN, _edje_entry_bottom_handler_mouse_down_cb, en->rp);
262              evas_object_event_callback_add(ob, EVAS_CALLBACK_MOUSE_UP, _edje_entry_bottom_handler_mouse_up_cb, en->rp);
263              evas_object_event_callback_add(ob, EVAS_CALLBACK_MOUSE_MOVE, _edje_entry_bottom_handler_mouse_move_cb, en->rp);
264           }
265         else
266           if (ob) evas_object_del(ob);
267
268         if ((!strcmp(bh_position, "TOP")) || (!strcmp(bh_position, "BOTH")))
269           {
270              ob = edje_object_add(en->rp->edje->base.evas);
271              edje_object_file_set(ob, en->rp->edje->path, en->rp->part->source3);
272              evas_object_layer_set(ob, EVAS_LAYER_MAX - 2);
273              en->block_handler_top = ob;
274              en->rp->edje->subobjs = eina_list_append(en->rp->edje->subobjs, en->block_handler_top);
275              evas_object_event_callback_add(ob, EVAS_CALLBACK_MOUSE_DOWN, _edje_entry_top_handler_mouse_down_cb, en->rp);
276              evas_object_event_callback_add(ob, EVAS_CALLBACK_MOUSE_UP, _edje_entry_top_handler_mouse_up_cb, en->rp);
277              evas_object_event_callback_add(ob, EVAS_CALLBACK_MOUSE_MOVE, _edje_entry_top_handler_mouse_move_cb, en->rp);
278           }
279      }
280    if (en->block_handler_top)
281      edje_object_signal_emit(en->block_handler_top, "edje,focus,in", "edje");
282    if (en->block_handler_btm)
283      edje_object_signal_emit(en->block_handler_btm, "edje,focus,in", "edje");
284
285    if (rp->part->entry_mode < EDJE_ENTRY_EDIT_MODE_EDITABLE) return;
286    // TIZEN ONLY - END
287
288 #ifdef HAVE_ECORE_IMF
289    if (!en->imf_context) return;
290
291    ecore_imf_context_reset(en->imf_context);
292    ecore_imf_context_focus_in(en->imf_context);
293    _edje_entry_imf_cursor_info_set(en);
294 #endif
295 }
296
297 static void
298 _edje_focus_out_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
299 {
300    Edje *ed = data;
301 #ifdef HAVE_ECORE_IMF
302    Edje_Real_Part *rp = ed->focused_part;
303    Entry *en;
304 #endif
305
306    _edje_emit(ed, "focus,out", "");
307
308 #ifdef HAVE_ECORE_IMF
309    if (!rp) return;
310    if ((rp->type != EDJE_RP_TYPE_TEXT) ||
311        (!rp->typedata.text)) return;
312    en = rp->typedata.text->entry_data;
313    if ((!en) || (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK) ||
314        (rp->part->entry_mode < EDJE_ENTRY_EDIT_MODE_SELECTABLE))  // TIZEN ONLY
315      return;
316
317    // TIZEN ONLY - START
318    if (en->block_handler_top)
319      edje_object_signal_emit(en->block_handler_top, "edje,focus,out", "edje");
320    if (en->block_handler_btm)
321      edje_object_signal_emit(en->block_handler_btm, "edje,focus,out", "edje");
322
323    if (rp->part->entry_mode < EDJE_ENTRY_EDIT_MODE_EDITABLE) return;
324    // TIZEN ONLY - END
325
326    if (!en->imf_context) return;
327
328    ecore_imf_context_reset(en->imf_context);
329    ecore_imf_context_focus_out(en->imf_context);
330 #endif
331 }
332
333 static void
334 _text_filter_markup_prepend_internal(Entry *en, Evas_Textblock_Cursor *c, char *text)
335 {
336    Edje_Markup_Filter_Callback *cb;
337    Eina_List *l;
338
339    EINA_LIST_FOREACH(en->rp->edje->markup_filter_callbacks, l, cb)
340      {
341         if (!strcmp(cb->part, en->rp->part->name))
342           {
343              cb->func(cb->data, en->rp->edje->obj, cb->part, &text);
344              if (!text) break;
345           }
346      }
347 #ifdef HAVE_ECORE_IMF
348    // For skipping useless commit
349    if (en->have_preedit && (!text || !strcmp(text, "")))
350       en->commit_cancel = EINA_TRUE;
351 #endif
352    if (text)
353      {
354         evas_object_textblock_text_markup_prepend(c, text);
355         free(text);
356      }
357 }
358
359 static void
360 _text_filter_text_prepend(Entry *en, Evas_Textblock_Cursor *c, const char *text)
361 {
362    char *text2;
363    Edje_Text_Insert_Filter_Callback *cb;
364    Eina_List *l;
365
366    text2 = strdup(text);
367    EINA_LIST_FOREACH(en->rp->edje->text_insert_filter_callbacks, l, cb)
368      {
369         if (!strcmp(cb->part, en->rp->part->name))
370           {
371              cb->func(cb->data, en->rp->edje->obj, cb->part, EDJE_TEXT_FILTER_TEXT, &text2);
372              if (!text2) break;
373           }
374      }
375    if (text2)
376      {
377         char *markup_text;
378         markup_text = evas_textblock_text_utf8_to_markup(NULL, text2);
379         free(text2);
380         if (markup_text)
381           _text_filter_markup_prepend_internal(en, c, markup_text);
382      }
383 }
384
385 static void
386 _text_filter_format_prepend(Entry *en, Evas_Textblock_Cursor *c, const char *text)
387 {
388    char *text2;
389    Edje_Text_Insert_Filter_Callback *cb;
390    Eina_List *l;
391
392    text2 = strdup(text);
393    EINA_LIST_FOREACH(en->rp->edje->text_insert_filter_callbacks, l, cb)
394      {
395         if (!strcmp(cb->part, en->rp->part->name))
396           {
397              cb->func(cb->data, en->rp->edje->obj, cb->part, EDJE_TEXT_FILTER_FORMAT, &text2);
398              if (!text2) break;
399           }
400      }
401    if (text2)
402      {
403         char *s, *markup_text;
404
405         s = text2;
406         if (*s == '+')
407           {
408              s++;
409              while (*s == ' ') s++;
410              if (!s)
411                {
412                   free(text2);
413                   return;
414                }
415              markup_text = (char*) malloc(strlen(s) + 3);
416              if (markup_text)
417                {
418                   *(markup_text) = '<';
419                   strncpy((markup_text + 1), s, strlen(s));
420                   *(markup_text + strlen(s) + 1) = '>';
421                   *(markup_text + strlen(s) + 2) = '\0';
422                }
423           }
424         else if (s[0] == '-')
425           {
426              s++;
427              while (*s == ' ') s++;
428              if (!s)
429                {
430                   free(text2);
431                   return;
432                }
433              markup_text = (char*) malloc(strlen(s) + 4);
434              if (markup_text)
435                {
436                   *(markup_text) = '<';
437                   *(markup_text + 1) = '/';
438                   strncpy((markup_text + 2), s, strlen(s));
439                   *(markup_text + strlen(s) + 2) = '>';
440                   *(markup_text + strlen(s) + 3) = '\0';
441                }
442           }
443         else
444           {
445              markup_text = (char*) malloc(strlen(s) + 4);
446              if (markup_text)
447                {
448                   *(markup_text) = '<';
449                   strncpy((markup_text + 1), s, strlen(s));
450                   *(markup_text + strlen(s) + 1) = '/';
451                   *(markup_text + strlen(s) + 2) = '>';
452                   *(markup_text + strlen(s) + 3) = '\0';
453                }
454           }
455         free(text2);
456         if (markup_text)
457           _text_filter_markup_prepend_internal(en, c, markup_text);
458      }
459 }
460
461 static void
462 _text_filter_markup_prepend(Entry *en, Evas_Textblock_Cursor *c, const char *text)
463 {
464    char *text2;
465    Edje_Text_Insert_Filter_Callback *cb;
466    Eina_List *l;
467
468    text2 = strdup(text);
469    EINA_LIST_FOREACH(en->rp->edje->text_insert_filter_callbacks, l, cb)
470      {
471         if (!strcmp(cb->part, en->rp->part->name))
472           {
473              cb->func(cb->data, en->rp->edje->obj, cb->part, EDJE_TEXT_FILTER_MARKUP, &text2);
474              if (!text2) break;
475           }
476      }
477    if (text2)
478      _text_filter_markup_prepend_internal(en, c, text2);
479 }
480
481 static void
482 _curs_update_from_curs(Evas_Textblock_Cursor *c, Evas_Object *o __UNUSED__, Entry *en, Evas_Coord *cx, Evas_Coord *cy)
483 {
484    Evas_Coord cw, ch;
485    Evas_Textblock_Cursor_Type cur_type;
486    if (c != en->cursor) return;
487    switch (en->rp->part->cursor_mode)
488      {
489       case EDJE_ENTRY_CURSOR_MODE_BEFORE:
490          cur_type = EVAS_TEXTBLOCK_CURSOR_BEFORE;
491          break;
492       case EDJE_ENTRY_CURSOR_MODE_UNDER:
493          /* no break for a resaon */
494       default:
495          cur_type = EVAS_TEXTBLOCK_CURSOR_UNDER;
496      }
497    evas_textblock_cursor_geometry_get(c, cx, cy, &cw, &ch, NULL, cur_type);
498    *cx += (cw / 2);
499    *cy += (ch / 2);
500 }
501
502 static int
503 _curs_line_last_get(Evas_Textblock_Cursor *c __UNUSED__, Evas_Object *o, Entry *en __UNUSED__)
504 {
505    Evas_Textblock_Cursor *cc;
506    int ln;
507
508    cc = evas_object_textblock_cursor_new(o);
509    evas_textblock_cursor_paragraph_last(cc);
510    ln = evas_textblock_cursor_line_geometry_get(cc, NULL, NULL, NULL, NULL);
511    evas_textblock_cursor_free(cc);
512    return ln;
513 }
514
515 static void
516 _curs_lin_start(Evas_Textblock_Cursor *c, Evas_Object *o __UNUSED__,
517                 Entry *en __UNUSED__)
518 {
519    evas_textblock_cursor_line_char_first(c);
520 }
521
522 static void
523 _curs_lin_end(Evas_Textblock_Cursor *c, Evas_Object *o __UNUSED__,
524               Entry *en __UNUSED__)
525 {
526    evas_textblock_cursor_line_char_last(c);
527 }
528
529 static void
530 _curs_start(Evas_Textblock_Cursor *c, Evas_Object *o __UNUSED__,
531             Entry *en __UNUSED__)
532 {
533    evas_textblock_cursor_paragraph_first(c);
534 }
535
536 static void
537 _curs_end(Evas_Textblock_Cursor *c, Evas_Object *o __UNUSED__, Entry *en __UNUSED__)
538 {
539    evas_textblock_cursor_paragraph_last(c);
540 }
541
542 static void
543 _curs_jump_line(Evas_Textblock_Cursor *c, Evas_Object *o, Entry *en, int ln)
544 {
545    Evas_Coord cx, cy;
546    Evas_Coord lx, ly, lw, lh;
547    int last = _curs_line_last_get(c, o, en);
548
549    if (ln < 0) ln = 0;
550    else
551      {
552         if (ln > last) ln = last;
553      }
554
555    _curs_update_from_curs(c, o, en, &cx, &cy);
556
557    if (!evas_object_textblock_line_number_geometry_get(o, ln, &lx, &ly, &lw, &lh))
558      return;
559    if (evas_textblock_cursor_char_coord_set(c, cx, ly + (lh / 2)))
560      return;
561    evas_textblock_cursor_line_set(c, ln);
562    if (cx < (lx + (lw / 2)))
563      {
564         if (ln == last) _curs_end(c, o, en);
565         _curs_lin_start(c, o, en);
566      }
567    else
568      {
569         if (ln == last)
570           _curs_end(c, o, en);
571         else
572           _curs_lin_end(c, o, en);
573      }
574 }
575
576 static void
577 _curs_jump_line_by(Evas_Textblock_Cursor *c, Evas_Object *o, Entry *en, int by)
578 {
579    int ln;
580
581    ln = evas_textblock_cursor_line_geometry_get(c, NULL, NULL, NULL, NULL) + by;
582    _curs_jump_line(c, o, en, ln);
583 }
584
585 static void
586 _curs_up(Evas_Textblock_Cursor *c, Evas_Object *o, Entry *en)
587 {
588    _curs_jump_line_by(c, o, en, -1);
589 }
590
591 static void
592 _curs_down(Evas_Textblock_Cursor *c, Evas_Object *o, Entry *en)
593 {
594    _curs_jump_line_by(c, o, en, 1);
595 }
596
597 static void
598 _sel_start(Evas_Textblock_Cursor *c, Evas_Object *o, Entry *en)
599 {
600    if (en->sel_start) return;
601    en->sel_start = evas_object_textblock_cursor_new(o);
602    evas_textblock_cursor_copy(c, en->sel_start);
603    en->sel_end = evas_object_textblock_cursor_new(o);
604    evas_textblock_cursor_copy(c, en->sel_end);
605
606    en->have_selection = EINA_FALSE;
607    if (en->selection)
608      {
609         free(en->selection);
610         en->selection = NULL;
611      }
612 }
613
614 static void
615 _sel_enable(Evas_Textblock_Cursor *c __UNUSED__, Evas_Object *o __UNUSED__, Entry *en)
616 {
617    if (en->have_selection) return;
618    en->have_selection = EINA_TRUE;
619    if (en->selection)
620      {
621         free(en->selection);
622         en->selection = NULL;
623      }
624    _edje_emit(en->rp->edje, "selection,start", en->rp->part->name);
625 }
626
627 static void
628 _sel_extend(Evas_Textblock_Cursor *c, Evas_Object *o, Entry *en)
629 {
630    if (!en->sel_end) return;
631    _edje_entry_imf_context_reset(en->rp);
632    _sel_enable(c, o, en);
633    if (!evas_textblock_cursor_compare(c, en->sel_end)) return;
634
635    // TIZEN ONLY - START
636    if (en->rp->part->select_mode == EDJE_ENTRY_SELECTION_MODE_BLOCK_HANDLE)
637      {
638         /* Do NOT allow sel_end to pass sel_start while extending */
639         if (evas_textblock_cursor_compare(c, en->sel_start) <= 0)
640           evas_textblock_cursor_pos_set(c, evas_textblock_cursor_pos_get(en->sel_start) + 1);
641      }
642    // TIZEN ONLY - END
643
644    evas_textblock_cursor_copy(c, en->sel_end);
645
646    _edje_entry_imf_cursor_info_set(en);
647
648    if (en->selection)
649      {
650         free(en->selection);
651         en->selection = NULL;
652      }
653    _edje_emit(en->rp->edje, "selection,changed", en->rp->part->name);
654 }
655
656 static void
657 _sel_preextend(Evas_Textblock_Cursor *c, Evas_Object *o, Entry *en)
658 {
659    if (!en->sel_end) return;
660    _edje_entry_imf_context_reset(en->rp);
661    _sel_enable(c, o, en);
662    if (!evas_textblock_cursor_compare(c, en->sel_start)) return;
663
664    // TIZEN ONLY - START
665    if (en->rp->part->select_mode == EDJE_ENTRY_SELECTION_MODE_BLOCK_HANDLE)
666      {
667         /* Do NOT allow sel_start to pass sel_end while pre-extending */
668         if (evas_textblock_cursor_compare(c, en->sel_end) >= 0)
669           evas_textblock_cursor_pos_set(c, evas_textblock_cursor_pos_get(en->sel_end) - 1);
670      }
671    // TIZEN ONLY - END
672
673    evas_textblock_cursor_copy(c, en->sel_start);
674
675    _edje_entry_imf_cursor_info_set(en);
676
677    if (en->selection)
678      {
679         free(en->selection);
680         en->selection = NULL;
681      }
682    _edje_emit(en->rp->edje, "selection,changed", en->rp->part->name);
683 }
684
685 static void
686 _sel_clear(Evas_Textblock_Cursor *c __UNUSED__, Evas_Object *o __UNUSED__, Entry *en)
687 {
688    en->had_sel = EINA_FALSE;
689    if (en->sel_start)
690      {
691         evas_textblock_cursor_free(en->sel_start);
692         evas_textblock_cursor_free(en->sel_end);
693         en->sel_start = NULL;
694         en->sel_end = NULL;
695      }
696    if (en->selection)
697      {
698         free(en->selection);
699         en->selection = NULL;
700      }
701    while (en->sel)
702      {
703         Sel *sel;
704
705         sel = en->sel->data;
706         if (sel->obj_bg) evas_object_del(sel->obj_bg);
707         if (sel->obj_fg) evas_object_del(sel->obj_fg);
708
709         // TIZEN ONLY - START
710         if (en->rp->part->select_mode == EDJE_ENTRY_SELECTION_MODE_BLOCK_HANDLE)
711           {
712              evas_object_hide(en->block_handler_top);
713              evas_object_hide(en->block_handler_btm);
714           }
715         // TIZEN ONLY - END
716         free(sel);
717         en->sel = eina_list_remove_list(en->sel, en->sel);
718      }
719    if (en->have_selection)
720      {
721         en->have_selection = EINA_FALSE;
722         evas_object_show(en->cursor_fg);
723         _edje_emit(en->rp->edje, "selection,cleared", en->rp->part->name);
724      }
725 }
726
727 static void
728 _sel_update(Evas_Textblock_Cursor *c __UNUSED__, Evas_Object *o, Entry *en)
729 {
730    Eina_List *range = NULL, *l;
731    Sel *sel;
732    Evas_Coord x, y, w, h;
733    Evas_Object *smart, *clip;
734
735    smart = evas_object_smart_parent_get(o);
736    clip = evas_object_clip_get(o);
737    if (en->sel_start)
738      {
739         range = evas_textblock_cursor_range_geometry_get(en->sel_start, en->sel_end);
740         if (!range) return;
741      }
742    else
743      return;
744    if (eina_list_count(range) != eina_list_count(en->sel))
745      {
746         while (en->sel)
747           {
748              sel = en->sel->data;
749              if (sel->obj_bg) evas_object_del(sel->obj_bg);
750              if (sel->obj_fg) evas_object_del(sel->obj_fg);
751              free(sel);
752              en->sel = eina_list_remove_list(en->sel, en->sel);
753           }
754         if (en->have_selection)
755           {
756              for (l = range; l; l = eina_list_next(l))
757                {
758                   Evas_Object *ob;
759
760                   sel = calloc(1, sizeof(Sel));
761                   en->sel = eina_list_append(en->sel, sel);
762                   ob = edje_object_add(en->rp->edje->base.evas);
763                   edje_object_file_set(ob, en->rp->edje->path, en->rp->part->source);
764                   evas_object_smart_member_add(ob, smart);
765                   evas_object_stack_below(ob, o);
766                   evas_object_clip_set(ob, clip);
767                   evas_object_pass_events_set(ob, EINA_TRUE);
768                   evas_object_show(ob);
769                   sel->obj_bg = ob;
770                   _edje_subobj_register(en->rp->edje, sel->obj_bg);
771
772                   ob = edje_object_add(en->rp->edje->base.evas);
773                   if (en->rp->part->select_mode == EDJE_ENTRY_SELECTION_MODE_BLOCK_HANDLE)
774                      edje_object_file_set(ob, en->rp->edje->path, en->rp->part->source6);
775                   else
776                      edje_object_file_set(ob, en->rp->edje->path, en->rp->part->source2);
777                   evas_object_smart_member_add(ob, smart);
778                   evas_object_stack_above(ob, o);
779                   evas_object_clip_set(ob, clip);
780                   evas_object_pass_events_set(ob, EINA_TRUE);
781                   evas_object_show(ob);
782                   sel->obj_fg = ob;
783                   _edje_subobj_register(en->rp->edje, sel->obj_fg);
784                }
785           }
786      }
787    x = y = w = h = -1;
788    evas_object_geometry_get(o, &x, &y, &w, &h);
789    if (en->have_selection)
790      {
791         // TIZEN ONLY - START
792         int list_cnt, list_idx;
793
794         list_cnt = eina_list_count(en->sel);
795         list_idx = 0;
796         evas_object_hide(en->cursor_fg);
797         evas_object_hide(en->cursor_bg);
798         // TIZEN ONLY - END
799
800         EINA_LIST_FOREACH(en->sel, l, sel)
801           {
802              Evas_Textblock_Rectangle *r;
803              list_idx++; // TIZEN ONLY
804
805              r = range->data;
806              if (sel->obj_bg)
807                {
808                   evas_object_move(sel->obj_bg, x + r->x, y + r->y);
809                   evas_object_resize(sel->obj_bg, r->w, r->h);
810                }
811              if (sel->obj_fg)
812                {
813                   evas_object_move(sel->obj_fg, x + r->x, y + r->y);
814                   evas_object_resize(sel->obj_fg, r->w, r->h);
815                }
816              // TIZEN ONLY - START
817              if (en->rp->part->select_mode == EDJE_ENTRY_SELECTION_MODE_BLOCK_HANDLE)
818                {
819                   if (list_idx == 1)
820                     {
821                        Evas_Coord nx, ny, handler_height = 0;
822                        const char *bh_position = edje_object_data_get(en->block_handler_top, "position");
823
824                        edje_object_part_geometry_get(en->block_handler_top, "handle", NULL, NULL, NULL, &handler_height);
825
826                        if (bh_position && !strcmp(bh_position, "BOTTOM"))
827                          {
828                             nx = x + r->x;
829                             ny = y + r->y + r->h;
830                          }
831                        else
832                          {
833                             nx = x + r->x;
834                             ny = y + r->y;
835                          }
836                        evas_object_hide(en->block_handler_top);
837                        evas_object_move(en->block_handler_top, nx, ny);
838
839                        // if viewport region is not set, show handlers
840                        if (en->viewport_region.x == -1 && en->viewport_region.y == -1 &&
841                            en->viewport_region.w == -1 && en->viewport_region.h == -1)
842                          {
843                             edje_object_signal_emit(en->block_handler_top, "elm,state,bottom", "elm");
844                             evas_object_show(en->block_handler_top);
845                          }
846                        else
847                          {
848                             if ((en->viewport_region.w > 0 && en->viewport_region.h > 0) &&
849                                 (nx >= en->viewport_region.x) && (nx <= (en->viewport_region.x + en->viewport_region.w)) &&
850                                 (ny >= en->viewport_region.y) && (ny <= (en->viewport_region.y + en->viewport_region.h)))
851                               {
852                                  if (en->layout_region.w != -1 && en->layout_region.h != -1 &&
853                                      ((ny + handler_height) > (en->layout_region.y + en->layout_region.h)))
854                                    edje_object_signal_emit(en->block_handler_top, "elm,state,top", "elm");
855                                  else
856                                    edje_object_signal_emit(en->block_handler_top, "elm,state,bottom", "elm");
857
858                                  evas_object_show(en->block_handler_top);
859                               }
860                          }
861                     }
862                   if (list_idx == list_cnt)
863                     {
864                        Evas_Coord nx, ny, handler_height = 0;
865
866                        edje_object_part_geometry_get(en->block_handler_btm, "handle", NULL, NULL, NULL, &handler_height);
867
868                        nx = x + r->x + r->w;
869                        ny = y + r->y + r->h;
870
871                        evas_object_hide(en->block_handler_btm);
872                        evas_object_move(en->block_handler_btm, nx, ny);
873
874                        // if viewport region is not set, show handlers
875                        if (en->viewport_region.x == -1 && en->viewport_region.y == -1 &&
876                            en->viewport_region.w == -1 && en->viewport_region.h == -1)
877                          {
878                             edje_object_signal_emit(en->block_handler_btm, "elm,state,bottom", "elm");
879                             evas_object_show(en->block_handler_btm);
880                          }
881                        else
882                          {
883                             if ((en->viewport_region.w > 0 && en->viewport_region.h > 0) &&
884                                 (nx >= en->viewport_region.x) && (nx <= (en->viewport_region.x + en->viewport_region.w)) &&
885                                 (ny >= en->viewport_region.y) && (ny <= (en->viewport_region.y + en->viewport_region.h)))
886                               {
887                                  if (en->layout_region.w != -1 && en->layout_region.h != -1 &&
888                                      ((ny + handler_height) > (en->layout_region.y + en->layout_region.h)))
889                                    edje_object_signal_emit(en->block_handler_btm, "elm,state,top", "elm");
890                                  else
891                                    edje_object_signal_emit(en->block_handler_btm, "elm,state,bottom", "elm");
892
893                                  evas_object_show(en->block_handler_btm);
894                               }
895                          }
896                     }
897                }
898              // TIZEN ONLY - END
899              *(&(sel->rect)) = *r;
900              range = eina_list_remove_list(range, range);
901              free(r);
902           }
903      }
904    else
905      {
906         while (range)
907           {
908              free(range->data);
909              range = eina_list_remove_list(range, range);
910           }
911      }
912 }
913
914 static void
915 _edje_anchor_mouse_down_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
916 {
917    Anchor *an = data;
918    Evas_Event_Mouse_Down *ev = event_info;
919    Edje_Real_Part *rp = an->en->rp;
920    char *buf, *n;
921    size_t len;
922    int ignored;
923    Entry *en;
924
925    if ((rp->type != EDJE_RP_TYPE_TEXT) ||
926        (!rp->typedata.text)) return;
927    en = rp->typedata.text->entry_data;
928    if (((rp->part->select_mode == EDJE_ENTRY_SELECTION_MODE_EXPLICIT) ||
929         (rp->part->select_mode == EDJE_ENTRY_SELECTION_MODE_BLOCK_HANDLE)) &&
930        (en->select_allow))
931      return;
932    ignored = rp->part->ignore_flags & ev->event_flags;
933    if ((!ev->event_flags) || (!ignored))
934      {
935         n = an->name;
936         if (!n) n = "";
937         len = 200 + strlen(n);
938         buf = alloca(len);
939         if (ev->flags & EVAS_BUTTON_TRIPLE_CLICK)
940           snprintf(buf, len, "anchor,mouse,down,%i,%s,triple", ev->button, n);
941         else if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK)
942           snprintf(buf, len, "anchor,mouse,down,%i,%s,double", ev->button, n);
943         else
944           snprintf(buf, len, "anchor,mouse,down,%i,%s", ev->button, n);
945         _edje_emit(rp->edje, buf, rp->part->name);
946      }
947 }
948
949 static void
950 _edje_anchor_mouse_up_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
951 {
952    Anchor *an = data;
953    Evas_Event_Mouse_Up *ev = event_info;
954    Edje_Real_Part *rp = an->en->rp;
955    char *buf, *n;
956    size_t len;
957    int ignored;
958    Entry *en;
959
960    if ((rp->type != EDJE_RP_TYPE_TEXT) ||
961        (!rp->typedata.text)) return;
962    en = rp->typedata.text->entry_data;
963    ignored = rp->part->ignore_flags & ev->event_flags;
964    if (((rp->part->select_mode == EDJE_ENTRY_SELECTION_MODE_EXPLICIT) ||
965         (rp->part->select_mode == EDJE_ENTRY_SELECTION_MODE_BLOCK_HANDLE)) &&
966        (en->select_allow))
967      return;
968    n = an->name;
969    if (!n) n = "";
970    len = 200 + strlen(n);
971    buf = alloca(len);
972    if ((!ev->event_flags) || (!ignored))
973      {
974         snprintf(buf, len, "anchor,mouse,up,%i,%s", ev->button, n);
975         _edje_emit(rp->edje, buf, rp->part->name);
976      }
977    if ((rp->still_in) && (rp->clicked_button == ev->button) && (!ignored))
978      {
979         snprintf(buf, len, "anchor,mouse,clicked,%i,%s", ev->button, n);
980         _edje_emit(rp->edje, buf, rp->part->name);
981      }
982 }
983
984 static void
985 _edje_anchor_mouse_move_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
986 {
987    Anchor *an = data;
988    Evas_Event_Mouse_Move *ev = event_info;
989    Edje_Real_Part *rp = an->en->rp;
990    char *buf, *n;
991    size_t len;
992    int ignored;
993    Entry *en;
994
995    if ((rp->type != EDJE_RP_TYPE_TEXT) ||
996        (!rp->typedata.text)) return;
997    en = rp->typedata.text->entry_data;
998    if (((rp->part->select_mode == EDJE_ENTRY_SELECTION_MODE_EXPLICIT) ||
999         (rp->part->select_mode == EDJE_ENTRY_SELECTION_MODE_BLOCK_HANDLE)) &&
1000        (en->select_allow))
1001      return;
1002    ignored = rp->part->ignore_flags & ev->event_flags;
1003    if ((!ev->event_flags) || (!ignored))
1004      {
1005         n = an->name;
1006         if (!n) n = "";
1007         len = 200 + strlen(n);
1008         buf = alloca(len);
1009         snprintf(buf, len, "anchor,mouse,move,%s", n);
1010         _edje_emit(rp->edje, buf, rp->part->name);
1011      }
1012 }
1013
1014 static void
1015 _edje_anchor_mouse_in_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
1016 {
1017    Anchor *an = data;
1018    Evas_Event_Mouse_In *ev = event_info;
1019    Edje_Real_Part *rp = an->en->rp;
1020    char *buf, *n;
1021    size_t len;
1022    int ignored;
1023
1024    ignored = rp->part->ignore_flags & ev->event_flags;
1025    if ((!ev->event_flags) || (!ignored))
1026      {
1027         n = an->name;
1028         if (!n) n = "";
1029         len = 200 + strlen(n);
1030         buf = alloca(len);
1031         snprintf(buf, len, "anchor,mouse,in,%s", n);
1032         _edje_emit(rp->edje, buf, rp->part->name);
1033      }
1034 }
1035
1036 static void
1037 _edje_anchor_mouse_out_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
1038 {
1039    Anchor *an = data;
1040    Evas_Event_Mouse_Out *ev = event_info;
1041    Edje_Real_Part *rp = an->en->rp;
1042    char *buf, *n;
1043    size_t len;
1044    int ignored;
1045
1046    ignored = rp->part->ignore_flags & ev->event_flags;
1047    if ((!ev->event_flags) || (!ignored))
1048      {
1049         n = an->name;
1050         if (!n) n = "";
1051         len = 200 + strlen(n);
1052         buf = alloca(len);
1053         snprintf(buf, len, "anchor,mouse,out,%s", n);
1054         _edje_emit(rp->edje, buf, rp->part->name);
1055      }
1056 }
1057
1058 static void
1059 _anchors_update(Evas_Textblock_Cursor *c __UNUSED__, Evas_Object *o, Entry *en)
1060 {
1061    Eina_List *l, *ll, *range = NULL;
1062    Evas_Coord x, y, w, h;
1063    Evas_Object *smart, *clip;
1064    Sel *sel;
1065    Anchor *an;
1066
1067    smart = evas_object_smart_parent_get(o);
1068    clip = evas_object_clip_get(o);
1069    x = y = w = h = -1;
1070    evas_object_geometry_get(o, &x, &y, &w, &h);
1071    EINA_LIST_FOREACH(en->anchors, l, an)
1072      {
1073         // for item anchors
1074         if (an->item)
1075           {
1076              Evas_Object *ob;
1077
1078              if (!an->sel)
1079                {
1080                   while (an->sel)
1081                     {
1082                        sel = an->sel->data;
1083                        if (sel->obj_bg) evas_object_del(sel->obj_bg);
1084                        if (sel->obj_fg) evas_object_del(sel->obj_fg);
1085                        if (sel->obj) evas_object_del(sel->obj);
1086                        free(sel);
1087                        an->sel = eina_list_remove_list(an->sel, an->sel);
1088                     }
1089
1090                   sel = calloc(1, sizeof(Sel));
1091                   an->sel = eina_list_append(an->sel, sel);
1092
1093                   if (en->rp->edje->item_provider.func)
1094                     {
1095                        ob = en->rp->edje->item_provider.func
1096                          (en->rp->edje->item_provider.data, smart,
1097                              en->rp->part->name, an->name);
1098                        evas_object_smart_member_add(ob, smart);
1099                        evas_object_stack_above(ob, o);
1100                        evas_object_clip_set(ob, clip);
1101                        evas_object_pass_events_set(ob, EINA_TRUE);
1102                        evas_object_show(ob);
1103                        sel->obj = ob;
1104                     }
1105                }
1106           }
1107         // for link anchors
1108         else
1109           {
1110              range =
1111                evas_textblock_cursor_range_geometry_get(an->start, an->end);
1112              if (eina_list_count(range) != eina_list_count(an->sel))
1113                {
1114                   while (an->sel)
1115                     {
1116                        sel = an->sel->data;
1117                        if (sel->obj_bg) evas_object_del(sel->obj_bg);
1118                        if (sel->obj_fg) evas_object_del(sel->obj_fg);
1119                        if (sel->obj) evas_object_del(sel->obj);
1120                        free(sel);
1121                        an->sel = eina_list_remove_list(an->sel, an->sel);
1122                     }
1123                   for (ll = range; ll; ll = eina_list_next(ll))
1124                     {
1125                        Evas_Object *ob;
1126
1127                        sel = calloc(1, sizeof(Sel));
1128                        an->sel = eina_list_append(an->sel, sel);
1129                        ob = edje_object_add(en->rp->edje->base.evas);
1130                        edje_object_file_set(ob, en->rp->edje->path, en->rp->part->source5);
1131                        evas_object_smart_member_add(ob, smart);
1132                        evas_object_stack_below(ob, o);
1133                        evas_object_clip_set(ob, clip);
1134                        evas_object_pass_events_set(ob, EINA_TRUE);
1135                        evas_object_show(ob);
1136                        sel->obj_bg = ob;
1137                        _edje_subobj_register(en->rp->edje, sel->obj_bg);
1138
1139                        ob = edje_object_add(en->rp->edje->base.evas);
1140                        edje_object_file_set(ob, en->rp->edje->path, en->rp->part->source6);
1141                        evas_object_smart_member_add(ob, smart);
1142                        evas_object_stack_above(ob, o);
1143                        evas_object_clip_set(ob, clip);
1144                        evas_object_pass_events_set(ob, EINA_TRUE);
1145                        evas_object_show(ob);
1146                        sel->obj_fg = ob;
1147                        _edje_subobj_register(en->rp->edje, sel->obj_fg);
1148
1149                        ob = evas_object_rectangle_add(en->rp->edje->base.evas);
1150                        evas_object_color_set(ob, 0, 0, 0, 0);
1151                        evas_object_smart_member_add(ob, smart);
1152                        evas_object_stack_above(ob, o);
1153                        evas_object_clip_set(ob, clip);
1154                        evas_object_repeat_events_set(ob, EINA_TRUE);
1155                        evas_object_event_callback_add(ob, EVAS_CALLBACK_MOUSE_DOWN, _edje_anchor_mouse_down_cb, an);
1156                        evas_object_event_callback_add(ob, EVAS_CALLBACK_MOUSE_UP, _edje_anchor_mouse_up_cb, an);
1157                        evas_object_event_callback_add(ob, EVAS_CALLBACK_MOUSE_MOVE, _edje_anchor_mouse_move_cb, an);
1158                        evas_object_event_callback_add(ob, EVAS_CALLBACK_MOUSE_IN, _edje_anchor_mouse_in_cb, an);
1159                        evas_object_event_callback_add(ob, EVAS_CALLBACK_MOUSE_OUT, _edje_anchor_mouse_out_cb, an);
1160                        evas_object_show(ob);
1161                        sel->obj = ob;
1162                     }
1163                }
1164           }
1165         EINA_LIST_FOREACH(an->sel, ll, sel)
1166           {
1167              if (an->item)
1168                {
1169                   Evas_Coord cx, cy, cw, ch;
1170
1171                   if (!evas_textblock_cursor_format_item_geometry_get
1172                       (an->start, &cx, &cy, &cw, &ch))
1173                     continue;
1174                   evas_object_move(sel->obj, x + cx, y + cy);
1175                   evas_object_resize(sel->obj, cw, ch);
1176                }
1177              else
1178                {
1179                   Evas_Textblock_Rectangle *r;
1180
1181                   r = range->data;
1182                   *(&(sel->rect)) = *r;
1183                   if (sel->obj_bg)
1184                     {
1185                        evas_object_move(sel->obj_bg, x + r->x, y + r->y);
1186                        evas_object_resize(sel->obj_bg, r->w, r->h);
1187                     }
1188                   if (sel->obj_fg)
1189                     {
1190                        evas_object_move(sel->obj_fg, x + r->x, y + r->y);
1191                        evas_object_resize(sel->obj_fg, r->w, r->h);
1192                     }
1193                   if (sel->obj)
1194                     {
1195                        evas_object_move(sel->obj, x + r->x, y + r->y);
1196                        evas_object_resize(sel->obj, r->w, r->h);
1197                     }
1198                   range = eina_list_remove_list(range, range);
1199                   free(r);
1200                }
1201           }
1202      }
1203 }
1204
1205 static void
1206 _anchors_clear(Evas_Textblock_Cursor *c __UNUSED__, Evas_Object *o __UNUSED__, Entry *en)
1207 {
1208    while (en->anchorlist)
1209      {
1210         free(en->anchorlist->data);
1211         en->anchorlist = eina_list_remove_list(en->anchorlist, en->anchorlist);
1212      }
1213    while (en->itemlist)
1214      {
1215         free(en->itemlist->data);
1216         en->itemlist = eina_list_remove_list(en->itemlist, en->itemlist);
1217      }
1218    while (en->anchors)
1219      {
1220         Anchor *an = en->anchors->data;
1221
1222         evas_textblock_cursor_free(an->start);
1223         evas_textblock_cursor_free(an->end);
1224         while (an->sel)
1225           {
1226              Sel *sel = an->sel->data;
1227              if (sel->obj_bg) evas_object_del(sel->obj_bg);
1228              if (sel->obj_fg) evas_object_del(sel->obj_fg);
1229              if (sel->obj) evas_object_del(sel->obj);
1230              free(sel);
1231              an->sel = eina_list_remove_list(an->sel, an->sel);
1232           }
1233         free(an->name);
1234         free(an);
1235         en->anchors = eina_list_remove_list(en->anchors, en->anchors);
1236      }
1237 }
1238
1239 static void
1240 _anchors_get(Evas_Textblock_Cursor *c, Evas_Object *o, Entry *en)
1241 {
1242    const Eina_List *anchors_a, *anchors_item;
1243    Anchor *an = NULL;
1244    _anchors_clear(c, o, en);
1245
1246    anchors_a = evas_textblock_node_format_list_get(o, "a");
1247    anchors_item = evas_textblock_node_format_list_get(o, "item");
1248
1249    if (anchors_a)
1250      {
1251         const Evas_Object_Textblock_Node_Format *node;
1252         const Eina_List *itr;
1253         EINA_LIST_FOREACH(anchors_a, itr, node)
1254           {
1255              const char *s = evas_textblock_node_format_text_get(node);
1256              char *p;
1257              an = calloc(1, sizeof(Anchor));
1258              if (!an)
1259                break;
1260
1261              an->en = en;
1262              p = strstr(s, "href=");
1263              if (p)
1264                {
1265                   an->name = strdup(p + 5);
1266                }
1267              en->anchors = eina_list_append(en->anchors, an);
1268              an->start = evas_object_textblock_cursor_new(o);
1269              an->end = evas_object_textblock_cursor_new(o);
1270              evas_textblock_cursor_at_format_set(an->start, node);
1271              evas_textblock_cursor_copy(an->start, an->end);
1272
1273              /* Close the anchor, if the anchor was without text,
1274               * free it as well */
1275              node = evas_textblock_node_format_next_get(node);
1276              for (; node; node = evas_textblock_node_format_next_get(node))
1277                {
1278                   s = evas_textblock_node_format_text_get(node);
1279                   if ((!strcmp(s, "- a")) || (!strcmp(s, "-a")))
1280                     break;
1281                }
1282
1283              if (node)
1284                {
1285                   evas_textblock_cursor_at_format_set(an->end, node);
1286                }
1287              else if (!evas_textblock_cursor_compare(an->start, an->end))
1288                {
1289                   if (an->name) free(an->name);
1290                   evas_textblock_cursor_free(an->start);
1291                   evas_textblock_cursor_free(an->end);
1292                   en->anchors = eina_list_remove(en->anchors, an);
1293                   free(an);
1294                }
1295              an = NULL;
1296           }
1297      }
1298
1299    if (anchors_item)
1300      {
1301         const Evas_Object_Textblock_Node_Format *node;
1302         const Eina_List *itr;
1303         EINA_LIST_FOREACH(anchors_item, itr, node)
1304           {
1305              const char *s = evas_textblock_node_format_text_get(node);
1306              char *p;
1307              an = calloc(1, sizeof(Anchor));
1308              if (!an)
1309                break;
1310
1311              an->en = en;
1312              an->item = 1;
1313              p = strstr(s, "href=");
1314              if (p)
1315                {
1316                   an->name = strdup(p + 5);
1317                }
1318              en->anchors = eina_list_append(en->anchors, an);
1319              an->start = evas_object_textblock_cursor_new(o);
1320              an->end = evas_object_textblock_cursor_new(o);
1321              evas_textblock_cursor_at_format_set(an->start, node);
1322              evas_textblock_cursor_copy(an->start, an->end);
1323              /* Although needed in textblock, don't bother with finding the end
1324               * here cause it doesn't really matter. */
1325           }
1326      }
1327 }
1328
1329 static void
1330 _free_entry_change_info(void *_info)
1331 {
1332    Edje_Entry_Change_Info *info = (Edje_Entry_Change_Info *) _info;
1333    if (info->insert)
1334      {
1335         eina_stringshare_del(info->change.insert.content);
1336      }
1337    else
1338      {
1339         eina_stringshare_del(info->change.del.content);
1340      }
1341    free(info);
1342 }
1343
1344 static void
1345 _range_del_emit(Edje *ed, Evas_Textblock_Cursor *c __UNUSED__, Evas_Object *o __UNUSED__, Entry *en)
1346 {
1347    size_t start, end;
1348    char *tmp;
1349    Edje_Entry_Change_Info *info;
1350
1351    start = evas_textblock_cursor_pos_get(en->sel_start);
1352    end = evas_textblock_cursor_pos_get(en->sel_end);
1353    if (start == end)
1354       goto noop;
1355
1356    info = calloc(1, sizeof(*info));
1357    info->insert = EINA_FALSE;
1358    info->change.del.start = start;
1359    info->change.del.end = end;
1360
1361    tmp = evas_textblock_cursor_range_text_get(en->sel_start, en->sel_end, EVAS_TEXTBLOCK_TEXT_MARKUP);
1362    info->change.del.content = eina_stringshare_add(tmp);
1363    if (tmp) free(tmp);
1364    evas_textblock_cursor_range_delete(en->sel_start, en->sel_end);
1365    _edje_emit(ed, "entry,changed", en->rp->part->name);
1366    _edje_emit_full(ed, "entry,changed,user", en->rp->part->name, info,
1367                    _free_entry_change_info);
1368 noop:
1369    _sel_clear(en->cursor, en->rp->object, en);
1370 }
1371
1372 static void
1373 _range_del(Evas_Textblock_Cursor *c __UNUSED__, Evas_Object *o __UNUSED__, Entry *en)
1374 {
1375    evas_textblock_cursor_range_delete(en->sel_start, en->sel_end);
1376    _sel_clear(en->cursor, en->rp->object, en);
1377 }
1378
1379 static void
1380 _delete_emit(Edje *ed, Evas_Textblock_Cursor *c, Entry *en, size_t pos,
1381              Eina_Bool backspace)
1382 {
1383    if (!evas_textblock_cursor_char_next(c))
1384      {
1385         return;
1386      }
1387    evas_textblock_cursor_char_prev(c);
1388
1389    Edje_Entry_Change_Info *info = calloc(1, sizeof(*info));
1390    char *tmp = evas_textblock_cursor_content_get(c);
1391
1392    info->insert = EINA_FALSE;
1393    if (backspace)
1394      {
1395         info->change.del.start = pos - 1;
1396         info->change.del.end = pos;
1397      }
1398    else
1399      {
1400         info->change.del.start = pos + 1;
1401         info->change.del.end = pos;
1402      }
1403
1404    info->change.del.content = eina_stringshare_add(tmp);
1405    if (tmp) free(tmp);
1406
1407    evas_textblock_cursor_char_delete(c);
1408    _edje_emit(ed, "entry,changed", en->rp->part->name);
1409    _edje_emit_full(ed, "entry,changed,user", en->rp->part->name,
1410                    info, _free_entry_change_info);
1411 }
1412
1413 static void
1414 _edje_entry_hide_visible_password(Edje_Real_Part *rp)
1415 {
1416    const Evas_Object_Textblock_Node_Format *node;
1417    node = evas_textblock_node_format_first_get(rp->object);
1418    for (; node; node = evas_textblock_node_format_next_get(node))
1419      {
1420         const char *text = evas_textblock_node_format_text_get(node);
1421         if (text)
1422           {
1423              if (!strcmp(text, "+ password=off"))
1424                {
1425                   evas_textblock_node_format_remove_pair(rp->object,
1426                                                          (Evas_Object_Textblock_Node_Format *) node);
1427                   break;
1428                }
1429           }
1430      }
1431    _edje_entry_real_part_configure(rp);
1432    _edje_emit(rp->edje, "entry,changed", rp->part->name);
1433 }
1434
1435 static Eina_Bool
1436 _password_timer_cb(void *data)
1437 {
1438    Entry *en = (Entry *)data;
1439    _edje_entry_hide_visible_password(en->rp);
1440    en->pw_timer = NULL;
1441    return ECORE_CALLBACK_CANCEL;
1442 }
1443
1444 static Eina_Bool
1445 _is_modifier(const char *key)
1446 {
1447    if ((!strncmp(key, "Shift", 5)) ||
1448        (!strncmp(key, "Control", 7)) ||
1449        (!strncmp(key, "Alt", 3)) ||
1450        (!strncmp(key, "Meta", 4)) ||
1451        (!strncmp(key, "Super", 5)) ||
1452        (!strncmp(key, "Hyper", 5)) ||
1453        (!strcmp(key, "Scroll_Lock")) ||
1454        (!strcmp(key, "Num_Lock")) ||
1455        (!strcmp(key, "Caps_Lock")))
1456      return EINA_TRUE;
1457    return EINA_FALSE;
1458 }
1459
1460 static void
1461 _compose_seq_reset(Entry *en)
1462 {
1463    char *str;
1464    
1465    EINA_LIST_FREE(en->seq, str) eina_stringshare_del(str);
1466    en->composing = EINA_FALSE;
1467 }
1468
1469 static void
1470 _edje_key_down_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
1471 {
1472    Edje *ed = data;
1473    Evas_Event_Key_Down *ev = event_info;
1474    Edje_Real_Part *rp = ed->focused_part;
1475    Entry *en;
1476    Eina_Bool control, alt, shift;
1477    Eina_Bool multiline;
1478    Eina_Bool cursor_changed;
1479    int old_cur_pos;
1480    if (!rp) return;
1481    if ((rp->type != EDJE_RP_TYPE_TEXT) ||
1482        (!rp->typedata.text)) return;
1483    en = rp->typedata.text->entry_data;
1484    if ((!en) || (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK) ||
1485        (rp->part->entry_mode < EDJE_ENTRY_EDIT_MODE_EDITABLE))
1486      return;
1487    if (!ev->keyname) return;
1488
1489 #ifdef HAVE_ECORE_IMF
1490    if (en->imf_context)
1491      {
1492         Ecore_IMF_Event_Key_Down ecore_ev;
1493         Eina_Bool filter_ret;
1494         ecore_imf_evas_event_key_down_wrap(ev, &ecore_ev);
1495         if (!en->composing)
1496           {
1497              filter_ret = ecore_imf_context_filter_event(en->imf_context,
1498                                                          ECORE_IMF_EVENT_KEY_DOWN,
1499                                                          (Ecore_IMF_Event *)&ecore_ev);
1500
1501              if (en->have_preedit)
1502                {
1503                   if (!strcmp(ev->keyname, "Down") ||
1504                       (!strcmp(ev->keyname, "KP_Down") && !ev->string) ||
1505                       !strcmp(ev->keyname, "Up") ||
1506                       (!strcmp(ev->keyname, "KP_Up") && !ev->string) ||
1507                       !strcmp(ev->keyname, "Next") ||
1508                       (!strcmp(ev->keyname, "KP_Next") && !ev->string) ||
1509                       !strcmp(ev->keyname, "Prior") ||
1510                       (!strcmp(ev->keyname, "KP_Prior") && !ev->string) ||
1511                       !strcmp(ev->keyname, "Home") ||
1512                       (!strcmp(ev->keyname, "KP_Home") && !ev->string) ||
1513                       !strcmp(ev->keyname, "End") ||
1514                       (!strcmp(ev->keyname, "KP_End") && !ev->string))
1515                     ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1516                }
1517
1518              if (filter_ret)
1519                return;
1520           }
1521      }
1522 #endif
1523
1524    if ((!strcmp(ev->keyname, "Escape")) ||
1525        (!strcmp(ev->keyname, "Return")) || (!strcmp(ev->keyname, "KP_Enter")))
1526      _edje_entry_imf_context_reset(rp);
1527
1528    old_cur_pos = evas_textblock_cursor_pos_get(en->cursor);
1529
1530    control = evas_key_modifier_is_set(ev->modifiers, "Control");
1531    alt = evas_key_modifier_is_set(ev->modifiers, "Alt");
1532    shift = evas_key_modifier_is_set(ev->modifiers, "Shift");
1533    multiline = rp->part->multiline;
1534    cursor_changed = EINA_FALSE;
1535    if (!strcmp(ev->keyname, "Escape"))
1536      {
1537         _compose_seq_reset(en);
1538         // dead keys here. Escape for now (should emit these)
1539         _edje_emit(ed, "entry,key,escape", rp->part->name);
1540         ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1541      }
1542    else if (!strcmp(ev->keyname, "Up") ||
1543             (!strcmp(ev->keyname, "KP_Up") && !ev->string))
1544      {
1545         _compose_seq_reset(en);
1546         if (multiline)
1547           {
1548              if (en->select_allow)
1549                {
1550                   if (shift) _sel_start(en->cursor, rp->object, en);
1551                   else _sel_clear(en->cursor, rp->object, en);
1552                }
1553              _curs_up(en->cursor, rp->object, en);
1554              if (en->select_allow)
1555                {
1556                   if (shift) _sel_extend(en->cursor, rp->object, en);
1557                   else _sel_clear(en->cursor, rp->object, en);
1558                }
1559              ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1560           }
1561         _edje_emit(ed, "entry,key,up", rp->part->name);
1562         _edje_emit(rp->edje, "cursor,changed,manual", rp->part->name);
1563      }
1564    else if (!strcmp(ev->keyname, "Down") ||
1565             (!strcmp(ev->keyname, "KP_Down") && !ev->string))
1566      {
1567         _compose_seq_reset(en);
1568         if (multiline)
1569           {
1570              if (en->select_allow)
1571                {
1572                   if (shift) _sel_start(en->cursor, rp->object, en);
1573                   else _sel_clear(en->cursor, rp->object, en);
1574                }
1575              _curs_down(en->cursor, rp->object, en);
1576              if (en->select_allow)
1577                {
1578                   if (shift) _sel_extend(en->cursor, rp->object, en);
1579                   else _sel_clear(en->cursor, rp->object, en);
1580                }
1581              ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1582           }
1583         _edje_emit(ed, "entry,key,down", rp->part->name);
1584         _edje_emit(rp->edje, "cursor,changed,manual", rp->part->name);
1585      }
1586    else if (!strcmp(ev->keyname, "Left") ||
1587             (!strcmp(ev->keyname, "KP_Left") && !ev->string))
1588      {
1589         _compose_seq_reset(en);
1590         if (en->select_allow)
1591           {
1592              if (shift) _sel_start(en->cursor, rp->object, en);
1593              else _sel_clear(en->cursor, rp->object, en);
1594           }
1595         evas_textblock_cursor_char_prev(en->cursor);
1596         /* If control is pressed, go to the start of the word */
1597         if (control) evas_textblock_cursor_word_start(en->cursor);
1598         if (en->select_allow)
1599           {
1600              if (shift) _sel_extend(en->cursor, rp->object, en);
1601              else _sel_clear(en->cursor, rp->object, en);
1602           }
1603         _edje_emit(ed, "entry,key,left", rp->part->name);
1604         _edje_emit(rp->edje, "cursor,changed,manual", rp->part->name);
1605         ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1606      }
1607    else if (!strcmp(ev->keyname, "Right") ||
1608             (!strcmp(ev->keyname, "KP_Right") && !ev->string))
1609      {
1610         _compose_seq_reset(en);
1611         if (en->select_allow)
1612           {
1613              if (shift) _sel_start(en->cursor, rp->object, en);
1614              else _sel_clear(en->cursor, rp->object, en);
1615           }
1616         /* If control is pressed, go to the end of the word */
1617         if (control) evas_textblock_cursor_word_end(en->cursor);
1618         evas_textblock_cursor_char_next(en->cursor);
1619         if (en->select_allow)
1620           {
1621              if (shift) _sel_extend(en->cursor, rp->object, en);
1622              else _sel_clear(en->cursor, rp->object, en);
1623           }
1624         _edje_emit(ed, "entry,key,right", rp->part->name);
1625         _edje_emit(rp->edje, "cursor,changed,manual", rp->part->name);
1626         ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1627      }
1628    else if (!strcmp(ev->keyname, "BackSpace"))
1629      {
1630         _compose_seq_reset(en);
1631         if (control && !en->have_selection)
1632           {
1633              // del to start of previous word
1634              _sel_start(en->cursor, rp->object, en);
1635
1636              evas_textblock_cursor_char_prev(en->cursor);
1637              evas_textblock_cursor_word_start(en->cursor);
1638
1639              _sel_preextend(en->cursor, rp->object, en);
1640
1641              _range_del_emit(ed, en->cursor, rp->object, en);
1642           }
1643         else if ((alt) && (shift))
1644           {
1645              // undo last action
1646           }
1647         else
1648           {
1649              if (en->have_selection)
1650                {
1651                   _range_del_emit(ed, en->cursor, rp->object, en);
1652                }
1653              else
1654                {
1655                   if (evas_textblock_cursor_char_prev(en->cursor))
1656                     {
1657                        _delete_emit(ed, en->cursor, en, old_cur_pos, EINA_TRUE);
1658                     }
1659                }
1660           }
1661         _sel_clear(en->cursor, rp->object, en);
1662         _anchors_get(en->cursor, rp->object, en);
1663         _edje_emit(ed, "entry,key,backspace", rp->part->name);
1664         ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1665      }
1666    else if (!strcmp(ev->keyname, "Delete") ||
1667             (!strcmp(ev->keyname, "KP_Delete") && !ev->string))
1668      {
1669         _compose_seq_reset(en);
1670         if (control)
1671           {
1672              // del to end of next word
1673              _sel_start(en->cursor, rp->object, en);
1674
1675              evas_textblock_cursor_word_end(en->cursor);
1676              evas_textblock_cursor_char_next(en->cursor);
1677
1678              _sel_extend(en->cursor, rp->object, en);
1679
1680              _range_del_emit(ed, en->cursor, rp->object, en);
1681           }
1682         else if (shift)
1683           {
1684              // cut
1685           }
1686         else
1687           {
1688              if (en->have_selection)
1689                {
1690                   _range_del_emit(ed, en->cursor, rp->object, en);
1691                }
1692              else
1693                {
1694                   _delete_emit(ed, en->cursor, en, old_cur_pos, EINA_FALSE);
1695                }
1696           }
1697         _sel_clear(en->cursor, rp->object, en);
1698         _anchors_get(en->cursor, rp->object, en);
1699         _edje_emit(ed, "entry,key,delete", rp->part->name);
1700         ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1701      }
1702    else if (!strcmp(ev->keyname, "Home") ||
1703             ((!strcmp(ev->keyname, "KP_Home")) && !ev->string))
1704      {
1705         _compose_seq_reset(en);
1706         if (en->select_allow)
1707           {
1708              if (shift) _sel_start(en->cursor, rp->object, en);
1709              else _sel_clear(en->cursor, rp->object, en);
1710           }
1711         if ((control) && (multiline))
1712           _curs_start(en->cursor, rp->object, en);
1713         else
1714           _curs_lin_start(en->cursor, rp->object, en);
1715         if (en->select_allow)
1716           {
1717              if (shift) _sel_extend(en->cursor, rp->object, en);
1718           }
1719         _edje_emit(ed, "entry,key,home", rp->part->name);
1720         ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1721      }
1722    else if (!strcmp(ev->keyname, "End") ||
1723             ((!strcmp(ev->keyname, "KP_End")) && !ev->string))
1724      {
1725         _compose_seq_reset(en);
1726         if (en->select_allow)
1727           {
1728              if (shift) _sel_start(en->cursor, rp->object, en);
1729              else _sel_clear(en->cursor, rp->object, en);
1730           }
1731         if ((control) && (multiline))
1732           _curs_end(en->cursor, rp->object, en);
1733         else
1734           _curs_lin_end(en->cursor, rp->object, en);
1735         if (en->select_allow)
1736           {
1737              if (shift) _sel_extend(en->cursor, rp->object, en);
1738           }
1739         _edje_emit(ed, "entry,key,end", rp->part->name);
1740         ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1741      }
1742    else if ((control) && (!shift) && (!strcmp(ev->keyname, "v")))
1743      {
1744         _compose_seq_reset(en);
1745         _edje_emit(ed, "entry,paste,request", rp->part->name);
1746         _edje_emit(ed, "entry,paste,request,3", rp->part->name);
1747         ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1748      }
1749    else if ((control) && (!strcmp(ev->keyname, "a")))
1750      {
1751         _compose_seq_reset(en);
1752         if (shift)
1753           {
1754              _edje_emit(ed, "entry,selection,none,request", rp->part->name);
1755              ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1756           }
1757         else
1758           {
1759              _edje_emit(ed, "entry,selection,all,request", rp->part->name);
1760              ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1761           }
1762      }
1763    else if ((control) && (((!shift) && !strcmp(ev->keyname, "c")) || !strcmp(ev->keyname, "Insert")))
1764      {
1765         _compose_seq_reset(en);
1766         _edje_emit(ed, "entry,copy,notify", rp->part->name);
1767         ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1768      }
1769    else if ((control) && (!shift) && ((!strcmp(ev->keyname, "x") || (!strcmp(ev->keyname, "m")))))
1770      {
1771         _compose_seq_reset(en);
1772         _edje_emit(ed, "entry,cut,notify", rp->part->name);
1773         ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1774      }
1775    else if ((control) && (!strcmp(ev->keyname, "z")))
1776      {
1777         _compose_seq_reset(en);
1778         if (shift)
1779           {
1780              // redo
1781              _edje_emit(ed, "entry,redo,request", rp->part->name);
1782           }
1783         else
1784           {
1785              // undo
1786              _edje_emit(ed, "entry,undo,request", rp->part->name);
1787           }
1788         ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1789      }
1790    else if ((control) && (!shift) && (!strcmp(ev->keyname, "y")))
1791      {
1792         _compose_seq_reset(en);
1793         // redo
1794         _edje_emit(ed, "entry,redo,request", rp->part->name);
1795         ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1796      }
1797    else if ((control) && (!shift) && (!strcmp(ev->keyname, "w")))
1798      {
1799         _compose_seq_reset(en);
1800         _sel_clear(en->cursor, rp->object, en);
1801         // select current word?
1802         ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1803      }
1804    else if (!strcmp(ev->keyname, "Tab"))
1805      {
1806         _compose_seq_reset(en);
1807         if (multiline)
1808           {
1809              if (shift)
1810                {
1811                   // remove a tab
1812                }
1813              else
1814                {
1815                   Edje_Entry_Change_Info *info = calloc(1, sizeof(*info));
1816                   info->insert = EINA_TRUE;
1817                   info->change.insert.plain_length = 1;
1818
1819                   if (en->have_selection)
1820                     {
1821                        _range_del_emit(ed, en->cursor, rp->object, en);
1822                        info->merge = EINA_TRUE;
1823                     }
1824                   info->change.insert.pos =
1825                      evas_textblock_cursor_pos_get(en->cursor);
1826                   info->change.insert.content = eina_stringshare_add("<tab/>");
1827                   //yy
1828 //                  evas_textblock_cursor_format_prepend(en->cursor, "tab");
1829                   _text_filter_format_prepend(en, en->cursor, "tab");
1830                   _anchors_get(en->cursor, rp->object, en);
1831                   _edje_emit(ed, "entry,changed", rp->part->name);
1832                   _edje_emit_full(ed, "entry,changed,user", rp->part->name,
1833                                   info, _free_entry_change_info);
1834                }
1835              ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1836           }
1837         _edje_emit(ed, "entry,key,tab", rp->part->name);
1838      }
1839    else if ((!strcmp(ev->keyname, "ISO_Left_Tab")) && (multiline))
1840      {
1841         _compose_seq_reset(en);
1842         // remove a tab
1843         ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1844      }
1845    else if (!strcmp(ev->keyname, "Prior") ||
1846             (!strcmp(ev->keyname, "KP_Prior") && !ev->string))
1847      {
1848         _compose_seq_reset(en);
1849         if (en->select_allow)
1850           {
1851              if (shift) _sel_start(en->cursor, rp->object, en);
1852              else _sel_clear(en->cursor, rp->object, en);
1853           }
1854         _curs_jump_line_by(en->cursor, rp->object, en, -10);
1855         if (en->select_allow)
1856           {
1857              if (shift) _sel_extend(en->cursor, rp->object, en);
1858              else _sel_clear(en->cursor, rp->object, en);
1859           }
1860         _edje_emit(ed, "entry,key,pgup", rp->part->name);
1861         ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1862      }
1863    else if (!strcmp(ev->keyname, "Next") ||
1864             (!strcmp(ev->keyname, "KP_Next") && !ev->string))
1865      {
1866         _compose_seq_reset(en);
1867         if (en->select_allow)
1868           {
1869              if (shift) _sel_start(en->cursor, rp->object, en);
1870              else _sel_clear(en->cursor, rp->object, en);
1871           }
1872         _curs_jump_line_by(en->cursor, rp->object, en, 10);
1873         if (en->select_allow)
1874           {
1875              if (shift) _sel_extend(en->cursor, rp->object, en);
1876              else _sel_clear(en->cursor, rp->object, en);
1877           }
1878         _edje_emit(ed, "entry,key,pgdn", rp->part->name);
1879         ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1880      }
1881    else if ((!strcmp(ev->keyname, "Return")) || (!strcmp(ev->keyname, "KP_Enter")))
1882      {
1883         _compose_seq_reset(en);
1884         if (multiline)
1885           {
1886              Edje_Entry_Change_Info *info = calloc(1, sizeof(*info));
1887              info->insert = EINA_TRUE;
1888              info->change.insert.plain_length = 1;
1889              if (en->have_selection)
1890                {
1891                   _range_del_emit(ed, en->cursor, rp->object, en);
1892                   info->merge = EINA_TRUE;
1893                }
1894
1895              info->change.insert.pos =
1896                 evas_textblock_cursor_pos_get(en->cursor);
1897              if (shift ||
1898                  evas_object_textblock_legacy_newline_get(rp->object))
1899                {
1900                   //yy
1901 //                  evas_textblock_cursor_format_prepend(en->cursor, "br");
1902                   _text_filter_format_prepend(en, en->cursor, "br");
1903                   info->change.insert.content = eina_stringshare_add("<br/>");
1904                }
1905              else
1906                {
1907                   //yy
1908 //                  evas_textblock_cursor_format_prepend(en->cursor, "ps");
1909                   _text_filter_format_prepend(en, en->cursor, "ps");
1910                   info->change.insert.content = eina_stringshare_add("<ps/>");
1911                }
1912              _anchors_get(en->cursor, rp->object, en);
1913              _edje_emit(ed, "entry,changed", rp->part->name);
1914              _edje_emit_full(ed, "entry,changed,user", rp->part->name,
1915                              info, _free_entry_change_info);
1916              _edje_emit(ed, "cursor,changed", rp->part->name);
1917              cursor_changed = EINA_TRUE;
1918              ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1919           }
1920         _edje_emit(ed, "entry,key,enter", rp->part->name);
1921      }
1922    else
1923      {
1924         char *compres = NULL, *string = (char *)ev->string;
1925         Eina_Bool free_string = EINA_FALSE;
1926         Ecore_Compose_State state;
1927         
1928         if (!en->composing)
1929           {
1930              _compose_seq_reset(en);
1931              en->seq = eina_list_append(en->seq, eina_stringshare_add(ev->key));
1932              state = ecore_compose_get(en->seq, &compres);
1933              if (state == ECORE_COMPOSE_MIDDLE) en->composing = EINA_TRUE;
1934              else en->composing = EINA_FALSE;
1935              if (!en->composing) _compose_seq_reset(en);
1936              else goto end;
1937           }
1938         else
1939           {
1940              if (_is_modifier(ev->key)) goto end;
1941              en->seq = eina_list_append(en->seq, eina_stringshare_add(ev->key));
1942              state = ecore_compose_get(en->seq, &compres);
1943              if (state == ECORE_COMPOSE_NONE) _compose_seq_reset(en);
1944              else if (state == ECORE_COMPOSE_DONE)
1945                {
1946                   _compose_seq_reset(en);
1947                   if (compres)
1948                     {
1949                        string = compres;
1950                        free_string = EINA_TRUE;
1951                     }
1952                }
1953              else goto end;
1954           }
1955         if (string)
1956           {
1957              Edje_Entry_Change_Info *info = calloc(1, sizeof(*info));
1958              info->insert = EINA_TRUE;
1959              info->change.insert.plain_length = 1;
1960              info->change.insert.content = eina_stringshare_add(string);
1961
1962              if (en->have_selection)
1963                {
1964                   _range_del_emit(ed, en->cursor, rp->object, en);
1965                   info->merge = EINA_TRUE;
1966                }
1967
1968              info->change.insert.pos =
1969                 evas_textblock_cursor_pos_get(en->cursor);
1970              // if PASSWORD_SHOW_LAST mode, appending text with password=off tag
1971              if ((rp->part->entry_mode == EDJE_ENTRY_EDIT_MODE_PASSWORD) &&
1972                  _edje_password_show_last)
1973                {
1974                   _edje_entry_hide_visible_password(en->rp);
1975                   _text_filter_format_prepend(en, en->cursor, "+ password=off");
1976                   _text_filter_text_prepend(en, en->cursor, string);
1977                   _text_filter_format_prepend(en, en->cursor, "- password");
1978                   if (en->pw_timer)
1979                     {
1980                        ecore_timer_del(en->pw_timer);
1981                        en->pw_timer = NULL;
1982                     }
1983                   en->pw_timer = ecore_timer_add(TO_DOUBLE(_edje_password_show_last_timeout),
1984                                                  _password_timer_cb, en);
1985                }
1986              else
1987                _text_filter_text_prepend(en, en->cursor, string);
1988              _anchors_get(en->cursor, rp->object, en);
1989              _edje_emit(ed, "entry,changed", rp->part->name);
1990              _edje_emit_full(ed, "entry,changed,user", rp->part->name,
1991                              info, _free_entry_change_info);
1992              _edje_emit(ed, "cursor,changed", rp->part->name);
1993              cursor_changed = EINA_TRUE;
1994              ev->event_flags |= EVAS_EVENT_FLAG_ON_HOLD;
1995           }
1996         if (free_string) free(string);
1997      }
1998 end:
1999    if (!cursor_changed && (old_cur_pos != evas_textblock_cursor_pos_get(en->cursor)))
2000      _edje_emit(ed, "cursor,changed", rp->part->name);
2001
2002    _edje_entry_imf_cursor_info_set(en);
2003    _edje_entry_real_part_configure(rp);
2004 }
2005
2006 static void
2007 _edje_key_up_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
2008 {
2009    Edje *ed = data;
2010    Edje_Real_Part *rp = ed->focused_part;
2011    Entry *en;
2012
2013    if (!rp) return;
2014    if ((rp->type != EDJE_RP_TYPE_TEXT) ||
2015        (!rp->typedata.text)) return;
2016    en = rp->typedata.text->entry_data;
2017    if ((!en) || (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK) ||
2018        (rp->part->entry_mode < EDJE_ENTRY_EDIT_MODE_EDITABLE))
2019      return;
2020
2021 #ifdef HAVE_ECORE_IMF
2022    if (en->imf_context)
2023      {
2024         Evas_Event_Key_Up *ev = event_info;
2025         Ecore_IMF_Event_Key_Up ecore_ev;
2026
2027         ecore_imf_evas_event_key_up_wrap(ev, &ecore_ev);
2028         if (ecore_imf_context_filter_event(en->imf_context,
2029                                            ECORE_IMF_EVENT_KEY_UP,
2030                                            (Ecore_IMF_Event *)&ecore_ev))
2031           return;
2032      }
2033 #else
2034    (void) event_info;
2035 #endif
2036 }
2037
2038 // TIZEN ONLY - START
2039 static Eina_Bool
2040 _edje_entry_select_word(Edje_Real_Part *rp)
2041 {
2042    Entry *en;
2043    if (!rp) return EINA_FALSE;
2044    if ((rp->type != EDJE_RP_TYPE_TEXT) ||
2045        (!rp->typedata.text)) return EINA_FALSE;
2046
2047    en = rp->typedata.text->entry_data;
2048    if (!en) return EINA_FALSE;
2049
2050    if (en->cursor_fg) evas_object_hide(en->cursor_fg);
2051    if (en->cursor_bg) evas_object_hide(en->cursor_bg);
2052
2053    evas_textblock_cursor_word_start(en->cursor);
2054
2055    if (evas_textblock_cursor_eol_get(en->cursor))
2056      {
2057         evas_textblock_cursor_char_prev(en->cursor);
2058         evas_textblock_cursor_word_start(en->cursor);
2059      }
2060
2061    _sel_clear(en->cursor, rp->object, en);
2062    _sel_enable(en->cursor, rp->object, en);
2063    _sel_start(en->cursor, rp->object, en);
2064
2065    evas_textblock_cursor_word_end(en->cursor);
2066    evas_textblock_cursor_char_next(en->cursor);
2067
2068    _sel_extend(en->cursor, rp->object, en);
2069    _edje_entry_real_part_configure(rp);
2070
2071    en->select_allow = EINA_TRUE;
2072    en->had_sel = EINA_TRUE;
2073    en->selecting = EINA_FALSE;
2074
2075    return EINA_TRUE;
2076 }
2077
2078 static void
2079 _edje_entry_mouse_double_clicked(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
2080 {
2081    Edje_Real_Part *rp = data;
2082    Entry *en;
2083    if (!rp) return;
2084    if ((rp->type != EDJE_RP_TYPE_TEXT) ||
2085        (!rp->typedata.text)) return;
2086
2087    en = rp->typedata.text->entry_data;
2088
2089    if (!en) return;
2090    en->double_clicked = EINA_TRUE;
2091
2092    if (en->copy_paste_disabled) return;
2093
2094    _edje_entry_select_word(rp);
2095    _edje_emit(en->rp->edje, "selection,end", en->rp->part->name);
2096 }
2097
2098 static Eina_Bool
2099 _long_press(void *data)
2100 {
2101    Edje_Real_Part *rp = data;
2102    Entry *en;
2103    if (!rp) return ECORE_CALLBACK_CANCEL;
2104    if ((rp->type != EDJE_RP_TYPE_TEXT) ||
2105        (!rp->typedata.text)) return ECORE_CALLBACK_CANCEL;
2106
2107    en = rp->typedata.text->entry_data;
2108    if (!en) return ECORE_CALLBACK_CANCEL;
2109
2110    if (en->longpress_timer)
2111      {
2112         ecore_timer_del(en->longpress_timer);
2113         en->longpress_timer = NULL;
2114      }
2115
2116    en->long_press_state = _ENTRY_LONG_PRESSED;
2117    en->longpress_timer = NULL;
2118
2119    _edje_emit(en->rp->edje, "long,pressed", en->rp->part->name);
2120    return ECORE_CALLBACK_CANCEL;
2121 }
2122 // TIZEN ONLY - END
2123
2124 static void
2125 _edje_part_move_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
2126 {
2127    Edje_Real_Part *rp = data;
2128    Entry *en;
2129    if (!rp) return;
2130    if ((rp->type != EDJE_RP_TYPE_TEXT) ||
2131        (!rp->typedata.text)) return;
2132    en = rp->typedata.text->entry_data;
2133    if (!en) return;
2134    _edje_entry_imf_cursor_location_set(en);
2135 }
2136
2137 static void
2138 _edje_part_mouse_down_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
2139 {
2140    Evas_Coord cx, cy;
2141    Edje_Real_Part *rp = data;
2142    Evas_Event_Mouse_Down *ev = event_info;
2143    Entry *en;
2144    Evas_Coord x, y, w, h;
2145    //   Eina_Bool multiline;
2146    Evas_Textblock_Cursor *tc = NULL;
2147    Eina_Bool dosel = EINA_FALSE;
2148    Eina_Bool shift;
2149    if (!rp) return;
2150    if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
2151    if ((rp->type != EDJE_RP_TYPE_TEXT) ||
2152        (!rp->typedata.text)) return;
2153    en = rp->typedata.text->entry_data;
2154    en->double_clicked = EINA_FALSE;
2155    en->long_press_state = _ENTRY_LONG_PRESSING;
2156    if ((!en) || (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK) ||
2157        (rp->part->entry_mode < EDJE_ENTRY_EDIT_MODE_SELECTABLE))
2158      return;
2159    if ((ev->button != 1) && (ev->button != 2)) return;
2160
2161    // TIZEN ONLY - START
2162    en->dx = ev->canvas.x;
2163    en->dy = ev->canvas.y;
2164    // TIZEN ONLY - END
2165
2166 #ifdef HAVE_ECORE_IMF
2167    if (en->imf_context)
2168      {
2169         Ecore_IMF_Event_Mouse_Down ecore_ev;
2170         ecore_imf_evas_event_mouse_down_wrap(ev, &ecore_ev);
2171         if (ecore_imf_context_filter_event(en->imf_context,
2172                                            ECORE_IMF_EVENT_MOUSE_DOWN,
2173                                            (Ecore_IMF_Event *)&ecore_ev))
2174           return;
2175      }
2176 #endif
2177
2178    _edje_entry_imf_context_reset(rp);
2179
2180    shift = evas_key_modifier_is_set(ev->modifiers, "Shift");
2181    en->select_mod_start = EINA_FALSE;
2182    en->select_mod_end = EINA_FALSE;
2183    if (rp->part->select_mode == EDJE_ENTRY_SELECTION_MODE_DEFAULT)
2184       dosel = EINA_TRUE;
2185    else if ((rp->part->select_mode == EDJE_ENTRY_SELECTION_MODE_EXPLICIT) ||
2186             (rp->part->select_mode == EDJE_ENTRY_SELECTION_MODE_BLOCK_HANDLE))
2187      {
2188         if (en->select_allow) dosel = EINA_TRUE;
2189      }
2190    if (ev->button == 2) dosel = EINA_FALSE;
2191    if (dosel)
2192      {
2193         evas_object_geometry_get(rp->object, &x, &y, &w, &h);
2194         cx = ev->canvas.x - x;
2195         cy = ev->canvas.y - y;
2196         if (ev->flags & EVAS_BUTTON_TRIPLE_CLICK)
2197           {
2198              if (shift)
2199                {
2200                   tc = evas_object_textblock_cursor_new(rp->object);
2201                   evas_textblock_cursor_copy(en->cursor, tc);
2202                   if (evas_textblock_cursor_compare(en->cursor, en->sel_start) < 0)
2203                     evas_textblock_cursor_line_char_first(en->cursor);
2204                   else
2205                     evas_textblock_cursor_line_char_last(en->cursor);
2206                   _sel_extend(en->cursor, rp->object, en);
2207                }
2208              else
2209                {
2210                   en->have_selection = EINA_FALSE;
2211                   en->selecting = EINA_FALSE;
2212                   _sel_clear(en->cursor, rp->object, en);
2213                   tc = evas_object_textblock_cursor_new(rp->object);
2214                   evas_textblock_cursor_copy(en->cursor, tc);
2215                   evas_textblock_cursor_line_char_first(en->cursor);
2216                   _sel_start(en->cursor, rp->object, en);
2217                   evas_textblock_cursor_line_char_last(en->cursor);
2218                   _sel_extend(en->cursor, rp->object, en);
2219                }
2220              goto end;
2221           }
2222         else if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK)
2223           {
2224              if (shift)
2225                {
2226                   tc = evas_object_textblock_cursor_new(rp->object);
2227                   evas_textblock_cursor_copy(en->cursor, tc);
2228                   if (evas_textblock_cursor_compare(en->cursor, en->sel_start) < 0)
2229                     evas_textblock_cursor_word_start(en->cursor);
2230                   else
2231                     {
2232                        evas_textblock_cursor_word_end(en->cursor);
2233                        evas_textblock_cursor_char_next(en->cursor);
2234                     }
2235                   _sel_extend(en->cursor, rp->object, en);
2236                }
2237              else
2238                {
2239                   en->have_selection = EINA_FALSE;
2240                   en->selecting = EINA_FALSE;
2241                   _sel_clear(en->cursor, rp->object, en);
2242                   tc = evas_object_textblock_cursor_new(rp->object);
2243                   evas_textblock_cursor_copy(en->cursor, tc);
2244                   evas_textblock_cursor_word_start(en->cursor);
2245                   _sel_start(en->cursor, rp->object, en);
2246                   evas_textblock_cursor_word_end(en->cursor);
2247                   evas_textblock_cursor_char_next(en->cursor);
2248                   _sel_extend(en->cursor, rp->object, en);
2249                }
2250              goto end;
2251           }
2252      }
2253    tc = evas_object_textblock_cursor_new(rp->object);
2254    evas_textblock_cursor_copy(en->cursor, tc);
2255    //   multiline = rp->part->multiline;
2256    evas_object_geometry_get(rp->object, &x, &y, &w, &h);
2257    cx = ev->canvas.x - x;
2258    cy = ev->canvas.y - y;
2259    if (en->rp->part->select_mode == EDJE_ENTRY_SELECTION_MODE_BLOCK_HANDLE)
2260      {
2261         evas_textblock_cursor_char_coord_set(en->cursor, cx, cy);
2262      }
2263    else
2264      {
2265         if (!evas_textblock_cursor_char_coord_set(en->cursor, cx, cy))
2266           {
2267              Evas_Coord lx, ly, lw, lh;
2268              int line;
2269
2270              line = evas_textblock_cursor_line_coord_set(en->cursor, cy);
2271              if (line == -1)
2272                {
2273                   if (rp->part->multiline)
2274                      _curs_end(en->cursor, rp->object, en);
2275                   else
2276                     {
2277                        evas_textblock_cursor_paragraph_first(en->cursor);
2278                        evas_textblock_cursor_line_geometry_get(en->cursor, &lx, &ly, &lw, &lh);
2279                        if (!evas_textblock_cursor_char_coord_set(en->cursor, cx, ly + (lh / 2)))
2280                           _curs_end(en->cursor, rp->object, en);
2281                     }
2282                }
2283              else
2284                {
2285                   int lnum;
2286
2287                   lnum = evas_textblock_cursor_line_geometry_get(en->cursor, &lx, &ly, &lw, &lh);
2288                   if (lnum < 0)
2289                     {
2290                        _curs_lin_start(en->cursor, rp->object, en);
2291                     }
2292                   else
2293                     {
2294                        if (cx <= lx)
2295                           _curs_lin_start(en->cursor, rp->object, en);
2296                        else
2297                           _curs_lin_end(en->cursor, rp->object, en);
2298                     }
2299                }
2300           }
2301      }
2302    if (dosel)
2303      {
2304         if ((en->have_selection) &&
2305             (rp->part->select_mode == EDJE_ENTRY_SELECTION_MODE_EXPLICIT))
2306           {
2307              if (shift)
2308                _sel_extend(en->cursor, rp->object, en);
2309              else
2310                {
2311                   Eina_List *first, *last;
2312                   FLOAT_T sc;
2313
2314                   first = en->sel;
2315                   last = eina_list_last(en->sel);
2316                   if (first && last)
2317                     {
2318                        Evas_Textblock_Rectangle *r1, *r2;
2319                        Evas_Coord d, d1, d2;
2320                        
2321                        r1 = first->data;
2322                        r2 = last->data;
2323                        d = r1->x - cx;
2324                        d1 = d * d;
2325                        d = (r1->y + (r1->h / 2)) - cy;
2326                        d1 += d * d;
2327                        d = r2->x + r2->w - 1 - cx;
2328                        d2 = d * d;
2329                        d = (r2->y + (r2->h / 2)) - cy;
2330                        d2 += d * d;
2331                        sc = rp->edje->scale;
2332                        if (sc == ZERO) sc = _edje_scale;
2333                        d = (Evas_Coord)MUL(FROM_INT(20), sc); // FIXME: maxing number!
2334                        d = d * d;
2335                        if (d1 < d2)
2336                          {
2337                             if (d1 <= d)
2338                               {
2339                                  en->select_mod_start = EINA_TRUE;
2340                                  en->selecting = EINA_TRUE;
2341                               }
2342                          }
2343                        else
2344                          {
2345                             if (d2 <= d)
2346                               {
2347                                  en->select_mod_end = EINA_TRUE;
2348                                  en->selecting = EINA_TRUE;
2349                               }
2350                          }
2351                     }
2352                }
2353           }
2354         else
2355           {
2356              if ((en->have_selection) && (shift))
2357                _sel_extend(en->cursor, rp->object, en);
2358              else
2359                {
2360                   en->selecting = EINA_TRUE;
2361                   _sel_clear(en->cursor, rp->object, en);
2362                   if (en->select_allow)
2363                     {
2364                        _sel_start(en->cursor, rp->object, en);
2365                     }
2366                }
2367           }
2368      }
2369  end:
2370    if (evas_textblock_cursor_compare(tc, en->cursor))
2371      {
2372         _edje_emit(rp->edje, "cursor,changed", rp->part->name);
2373         _edje_emit(rp->edje, "cursor,changed,manual", rp->part->name);
2374      }
2375    evas_textblock_cursor_free(tc);
2376
2377    // TIZEN ONLY - START
2378    if (en->rp->part->select_mode == EDJE_ENTRY_SELECTION_MODE_BLOCK_HANDLE)
2379      {
2380         if (en->longpress_timer) ecore_timer_del(en->longpress_timer);
2381         en->longpress_timer = ecore_timer_add(1.0, _long_press, data);
2382      } // TIZEN ONLY - END
2383    else
2384       _edje_entry_real_part_configure(rp);
2385    if (ev->button == 2)
2386      {
2387         _edje_emit(rp->edje, "entry,paste,request", rp->part->name);
2388         _edje_emit(rp->edje, "entry,paste,request,1", rp->part->name);
2389      }
2390 }
2391
2392 static void
2393 _edje_part_mouse_up_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
2394 {
2395    Evas_Coord cx, cy;
2396    Edje_Real_Part *rp = data;
2397    Evas_Event_Mouse_Up *ev = event_info;
2398    Entry *en;
2399    Evas_Coord x, y, w, h;
2400    Evas_Textblock_Cursor *tc;
2401    if (ev->button != 1) return;
2402    if (!rp) return;
2403    //if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return; //TIZEN ONLY
2404    //if (ev->flags & EVAS_BUTTON_TRIPLE_CLICK) return; // TIZEN ONLY
2405    //if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK) return; // TIZEN ONLY
2406    if ((rp->type != EDJE_RP_TYPE_TEXT) ||
2407        (!rp->typedata.text)) return;
2408    en = rp->typedata.text->entry_data;
2409    if ((!en) || (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK) ||
2410        (rp->part->entry_mode < EDJE_ENTRY_EDIT_MODE_SELECTABLE))
2411      return;
2412
2413    // TIZEN ONLY - START
2414    if (en->longpress_timer)
2415      {
2416         ecore_timer_del(en->longpress_timer);
2417         en->longpress_timer = NULL;
2418      }
2419
2420    if (en->double_clicked) return;
2421    if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD)
2422      {
2423         _edje_entry_imf_cursor_info_set(en);
2424         return;
2425      }
2426
2427    if (ev->flags & EVAS_BUTTON_TRIPLE_CLICK) return;
2428    if (ev->flags & EVAS_BUTTON_DOUBLE_CLICK) return;
2429
2430    if (en->long_press_state == _ENTRY_LONG_PRESSED)
2431      {
2432         en->long_press_state = _ENTRY_LONG_PRESS_RELEASED;
2433         _edje_entry_imf_cursor_info_set(en);
2434         return;
2435      }
2436    en->long_press_state = _ENTRY_LONG_PRESS_RELEASED;
2437    // TIZEN ONLY - END
2438
2439 #ifdef HAVE_ECORE_IMF
2440    if (en->imf_context)
2441      {
2442         Ecore_IMF_Event_Mouse_Up ecore_ev;
2443         ecore_imf_evas_event_mouse_up_wrap(ev, &ecore_ev);
2444         if (ecore_imf_context_filter_event(en->imf_context,
2445                                            ECORE_IMF_EVENT_MOUSE_UP,
2446                                            (Ecore_IMF_Event *)&ecore_ev))
2447           return;
2448      }
2449 #endif
2450
2451    tc = evas_object_textblock_cursor_new(rp->object);
2452    evas_textblock_cursor_copy(en->cursor, tc);
2453    evas_object_geometry_get(rp->object, &x, &y, &w, &h);
2454    cx = ev->canvas.x - x;
2455    cy = ev->canvas.y - y;
2456    if (!evas_textblock_cursor_char_coord_set(en->cursor, cx, cy))
2457      {
2458         Evas_Coord lx, ly, lw, lh;
2459         int line;
2460
2461         line = evas_textblock_cursor_line_coord_set(en->cursor, cy);
2462         if (line == -1)
2463           {
2464              if (rp->part->multiline)
2465                _curs_end(en->cursor, rp->object, en);
2466              else
2467                {
2468                   evas_textblock_cursor_paragraph_first(en->cursor);
2469                   evas_textblock_cursor_line_geometry_get(en->cursor, &lx, &ly, &lw, &lh);
2470                   if (!evas_textblock_cursor_char_coord_set(en->cursor, cx, ly + (lh / 2)))
2471                     _curs_end(en->cursor, rp->object, en);
2472                }
2473           }
2474         else
2475           {
2476              int lnum;
2477
2478              lnum = evas_textblock_cursor_line_geometry_get(en->cursor, &lx, &ly, &lw, &lh);
2479              if (lnum < 0)
2480                {
2481                   _curs_lin_start(en->cursor, rp->object, en);
2482                }
2483              else
2484                {
2485                   if (cx <= lx)
2486                     _curs_lin_start(en->cursor, rp->object, en);
2487                   else
2488                     _curs_lin_end(en->cursor, rp->object, en);
2489                }
2490           }
2491      }
2492    if (rp->part->select_mode != EDJE_ENTRY_SELECTION_MODE_BLOCK_HANDLE)
2493      {
2494        if ((rp->part->select_mode == EDJE_ENTRY_SELECTION_MODE_EXPLICIT))
2495          {
2496            if (en->select_allow)
2497              {
2498                if (en->had_sel)
2499                  {
2500                    if (en->select_mod_end)
2501                      _sel_extend(en->cursor, rp->object, en);
2502                    else if (en->select_mod_start)
2503                      _sel_preextend(en->cursor, rp->object, en);
2504                  }
2505                else
2506                  _sel_extend(en->cursor, rp->object, en);
2507                //evas_textblock_cursor_copy(en->cursor, en->sel_end);
2508              }
2509          }
2510        else
2511          evas_textblock_cursor_copy(en->cursor, en->sel_end);
2512
2513        if (en->selecting)
2514          {
2515            if (en->have_selection)
2516              en->had_sel = EINA_TRUE;
2517            en->selecting = EINA_FALSE;
2518          }
2519      }
2520
2521    if (evas_textblock_cursor_compare(tc, en->cursor))
2522      {
2523         _edje_emit(rp->edje, "cursor,changed", rp->part->name);
2524         _edje_emit(rp->edje, "cursor,changed,manual", rp->part->name);
2525      }
2526
2527    _edje_entry_imf_cursor_info_set(en);
2528
2529    evas_textblock_cursor_free(tc);
2530
2531    _edje_entry_real_part_configure(rp);
2532 }
2533
2534 static void
2535 _edje_part_mouse_move_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
2536 {
2537    Evas_Coord cx, cy;
2538    Edje_Real_Part *rp = data;
2539    Evas_Event_Mouse_Move *ev = event_info;
2540    Entry *en;
2541    Evas_Coord x, y, w, h;
2542    Evas_Textblock_Cursor *tc;
2543    if (!rp) return;
2544    if ((rp->type != EDJE_RP_TYPE_TEXT) ||
2545        (!rp->typedata.text)) return;
2546    en = rp->typedata.text->entry_data;
2547    if ((!en) || (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK) ||
2548        (rp->part->entry_mode < EDJE_ENTRY_EDIT_MODE_SELECTABLE))
2549      return;
2550
2551 #ifdef HAVE_ECORE_IMF
2552    if (en->imf_context)
2553      {
2554         Ecore_IMF_Event_Mouse_Move ecore_ev;
2555         ecore_imf_evas_event_mouse_move_wrap(ev, &ecore_ev);
2556         if (ecore_imf_context_filter_event(en->imf_context,
2557                                            ECORE_IMF_EVENT_MOUSE_MOVE,
2558                                            (Ecore_IMF_Event *)&ecore_ev))
2559           return;
2560      }
2561 #endif
2562
2563    // TIZEN ONLY - START
2564    if (rp->part->select_mode == EDJE_ENTRY_SELECTION_MODE_BLOCK_HANDLE)
2565      {
2566         _edje_entry_real_part_configure(rp);
2567
2568         if (en->long_press_state == _ENTRY_LONG_PRESSING)
2569           {
2570              Evas_Coord dx, dy;
2571
2572              dx = en->dx - ev->cur.canvas.x;
2573              dy = en->dy - ev->cur.canvas.y;
2574
2575              /* FIXME: Magic number 40 is used to ignore finger move while detecting long press.              */
2576              /*        This should be replaced with the constant or variable relevant to the elm_finger_size. */
2577              if (((dx*dx) + (dy*dy)) > (40*40))
2578                {
2579                   en->long_press_state = _ENTRY_LONG_PRESS_RELEASED;
2580                   if (en->longpress_timer)
2581                     {
2582                        ecore_timer_del(en->longpress_timer);
2583                        en->longpress_timer = NULL;
2584                     }
2585                }
2586           }
2587         else if (en->long_press_state == _ENTRY_LONG_PRESSED)
2588           {
2589              Evas_Coord flx, fly, flh;
2590              Evas_Coord cnx, cny;
2591
2592              tc = evas_object_textblock_cursor_new(rp->object);
2593              evas_textblock_cursor_copy(en->cursor, tc);
2594              evas_object_geometry_get(rp->object, &x, &y, &w, &h);
2595
2596              cx = ev->cur.canvas.x - x;
2597              cy = ev->cur.canvas.y - y;
2598              evas_textblock_cursor_char_coord_set(en->cursor, cx, cy);
2599
2600              /* handle the special cases in which pressed position is above the first line or below the last line  */
2601              evas_object_textblock_line_number_geometry_get(rp->object, 0, &flx, &fly, NULL, &flh);
2602              evas_textblock_cursor_line_geometry_get(en->cursor, &cnx, &cny, NULL, NULL);
2603              if ((cnx == flx) && (cny == fly))
2604                {
2605                   /* cursor is in the first line */
2606                   evas_textblock_cursor_char_coord_set(en->cursor, cx, fly + flh / 2);
2607                }
2608              else
2609                {
2610                   Evas_Textblock_Cursor *lc;
2611                   Evas_Coord llx, lly, llh;
2612
2613                   lc = evas_object_textblock_cursor_new(rp->object);
2614                   evas_textblock_cursor_copy(en->cursor, lc);
2615                   evas_textblock_cursor_paragraph_last(lc);
2616                   evas_textblock_cursor_line_geometry_get(lc, &llx, &lly, NULL, &llh);
2617                   if ((cnx == llx) && (cny == lly))
2618                     {
2619                        /* cursor is in the last line */
2620                        evas_textblock_cursor_char_coord_set(en->cursor, cx, lly + llh / 2);
2621                     }
2622                   evas_textblock_cursor_free(lc);
2623                }
2624
2625              if (evas_textblock_cursor_compare(tc, en->cursor))
2626                {
2627                   _edje_emit(rp->edje, "cursor,changed", rp->part->name);
2628                }
2629              evas_textblock_cursor_free(tc);
2630
2631              _edje_emit(en->rp->edje, "magnifier,changed", en->rp->part->name);
2632           }
2633      } // TIZEN ONLY - END
2634    else
2635      {
2636         if (en->selecting)
2637           {
2638              tc = evas_object_textblock_cursor_new(rp->object);
2639              evas_textblock_cursor_copy(en->cursor, tc);
2640              evas_object_geometry_get(rp->object, &x, &y, &w, &h);
2641              cx = ev->cur.canvas.x - x;
2642              cy = ev->cur.canvas.y - y;
2643              if (!evas_textblock_cursor_char_coord_set(en->cursor, cx, cy))
2644                {
2645                   Evas_Coord lx, ly, lw, lh;
2646
2647                   if (evas_textblock_cursor_line_coord_set(en->cursor, cy) < 0)
2648                     {
2649                        if (rp->part->multiline)
2650                          _curs_end(en->cursor, rp->object, en);
2651                        else
2652                          {
2653                             evas_textblock_cursor_paragraph_first(en->cursor);
2654                             evas_textblock_cursor_line_geometry_get(en->cursor, &lx, &ly, &lw, &lh);
2655                             if (!evas_textblock_cursor_char_coord_set(en->cursor, cx, ly + (lh / 2)))
2656                               _curs_end(en->cursor, rp->object, en);
2657                          }
2658                     }
2659                   else
2660                     {
2661                        evas_textblock_cursor_line_geometry_get(en->cursor, &lx, &ly, &lw, &lh);
2662                        if (cx <= lx)
2663                          _curs_lin_start(en->cursor, rp->object, en);
2664                        else
2665                          _curs_lin_end(en->cursor, rp->object, en);
2666                     }
2667                }
2668
2669              if ((rp->part->select_mode == EDJE_ENTRY_SELECTION_MODE_EXPLICIT) ||
2670                  (rp->part->select_mode == EDJE_ENTRY_SELECTION_MODE_BLOCK_HANDLE))
2671                {
2672                   if (en->select_allow)
2673                     {
2674                        if (en->had_sel)
2675                          {
2676                             if (en->select_mod_end)
2677                               _sel_extend(en->cursor, rp->object, en);
2678                             else if (en->select_mod_start)
2679                               _sel_preextend(en->cursor, rp->object, en);
2680                          }
2681                        else
2682                          _sel_extend(en->cursor, rp->object, en);
2683                     }
2684                }
2685              else
2686                {
2687                   _sel_extend(en->cursor, rp->object, en);
2688                }
2689              if (en->select_allow)
2690                {
2691                   if (evas_textblock_cursor_compare(en->sel_start, en->sel_end) != 0)
2692                     _sel_enable(en->cursor, rp->object, en);
2693                   if (en->have_selection)
2694                     _sel_update(en->cursor, rp->object, en);
2695                }
2696              if (evas_textblock_cursor_compare(tc, en->cursor))
2697                {
2698                   _edje_emit(rp->edje, "cursor,changed", rp->part->name);
2699                   _edje_emit(rp->edje, "cursor,changed,manual", rp->part->name);
2700                }
2701              evas_textblock_cursor_free(tc);
2702
2703              _edje_entry_real_part_configure(rp);
2704           }
2705      }
2706 }
2707
2708 // TIZEN ONLY - START
2709 static void
2710 _edje_entry_top_handler_mouse_down_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
2711 {
2712    Evas_Event_Mouse_Down *ev = event_info;
2713    Evas_Coord ox, oy, ow, oh;
2714    Evas_Coord lx, ly, lw, lh;
2715    Edje_Real_Part *rp = data;
2716    Entry *en = rp->typedata.text->entry_data;
2717
2718    if (ev->button != 1) return;
2719
2720    en->rx = en->sx = ev->canvas.x;
2721    en->ry = en->sy = ev->canvas.y;
2722
2723    evas_object_geometry_get(obj, &ox, &oy, NULL, NULL);
2724    edje_object_size_min_calc(obj, &ow, &oh);
2725    evas_textblock_cursor_line_geometry_get(en->cursor, &lx, &ly, &lw, &lh);
2726
2727    en->ox = ox + ow/2 - en->rx;
2728    //en->oy = oy + oh - en->ry + lh/2;
2729    en->oy = oy + oh - en->ry - lh/2;
2730
2731    en->select_mod_start = EINA_TRUE;
2732    en->selecting = EINA_TRUE;
2733
2734    _edje_emit(en->rp->edje, "handler,move,start", en->rp->part->name);
2735 }
2736
2737 static void
2738 _edje_entry_top_handler_mouse_up_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
2739 {
2740    Edje_Real_Part *rp = data;
2741    Entry *en = rp->typedata.text->entry_data;
2742
2743    _edje_emit(en->rp->edje, "handler,move,end", en->rp->part->name);
2744 }
2745
2746 static void
2747 _edje_entry_top_handler_mouse_move_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
2748 {
2749    Evas_Event_Mouse_Move *ev = event_info;
2750    Edje_Real_Part *rp = data;
2751    Entry *en = rp->typedata.text->entry_data;
2752    Evas_Coord x, y, tx, ty, tw, th;
2753    Evas_Coord cx, cy;
2754    Evas_Coord lh;
2755    Evas_Textblock_Cursor_Type cur_type;
2756    Evas_Coord sx, sy;
2757
2758    if (ev->buttons != 1) return;
2759
2760    x = ev->cur.canvas.x;
2761    y = ev->cur.canvas.y;
2762
2763    en->rx += (x - en->sx);
2764    en->ry += (y - en->sy);
2765    en->sx = ev->cur.canvas.x;
2766    en->sy = ev->cur.canvas.y;
2767
2768    evas_object_geometry_get(rp->object, &tx, &ty, NULL, NULL);
2769    evas_object_textblock_size_formatted_get(rp->object, &tw, &th);
2770
2771    cx = en->rx + en->ox - tx;
2772    cy = en->ry + en->oy - ty;
2773
2774    evas_textblock_cursor_line_geometry_get(en->cursor, NULL, NULL, NULL, &lh);
2775    if (cx <= 0) cx = 1;
2776    if (cy <= 0) cy = lh / 2;
2777    if (cy > th) cy = th - 1;
2778
2779    switch (rp->part->cursor_mode)
2780      {
2781       case EDJE_ENTRY_CURSOR_MODE_BEFORE:
2782          cur_type = EVAS_TEXTBLOCK_CURSOR_BEFORE;
2783          break;
2784       case EDJE_ENTRY_CURSOR_MODE_UNDER:
2785       default:
2786          cur_type = EVAS_TEXTBLOCK_CURSOR_UNDER;
2787      }
2788
2789    evas_textblock_cursor_geometry_get(en->sel_end, &sx, &sy, NULL, NULL, NULL, cur_type);
2790
2791    evas_textblock_cursor_char_coord_set(en->cursor, cx, cy);
2792
2793    //moving in allowed space
2794    if (evas_textblock_cursor_compare(en->cursor, en->sel_end) >= 0)
2795      {
2796         if (cx >= sx)
2797            evas_textblock_cursor_pos_set(en->cursor, evas_textblock_cursor_pos_get(en->sel_end) - 1);
2798         else
2799           {
2800              if (!evas_textblock_cursor_char_coord_set(en->cursor, cx, sy + 1))
2801                 evas_textblock_cursor_line_char_first(en->cursor);
2802           }
2803      }
2804
2805    if (en->select_allow)
2806      {
2807         if (en->had_sel)
2808           {
2809              if (en->select_mod_start)
2810                _sel_preextend(en->cursor, rp->object, en);
2811           }
2812      }
2813    _edje_entry_real_part_configure(rp);
2814    _edje_emit(en->rp->edje, "handler,moving", en->rp->part->name);
2815 }
2816
2817 static void
2818 _edje_entry_bottom_handler_mouse_down_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
2819 {
2820    Evas_Event_Mouse_Down *ev = event_info;
2821    Evas_Coord ox, oy, ow, oh;
2822    Evas_Coord lx, ly, lw, lh;
2823    Edje_Real_Part *rp = data;
2824    Entry *en = rp->typedata.text->entry_data;
2825
2826    if (ev->button != 1) return;
2827
2828    en->rx = en->sx = ev->canvas.x;
2829    en->ry = en->sy = ev->canvas.y;
2830
2831    evas_object_geometry_get(obj, &ox, &oy, NULL, NULL);
2832    edje_object_size_min_calc(obj, &ow, &oh);
2833    evas_textblock_cursor_line_geometry_get(en->cursor, &lx, &ly, &lw, &lh);
2834
2835    en->ox = ox + ow/2 - en->rx;
2836    en->oy = oy - en->ry - lh/2;
2837
2838    en->select_mod_end = EINA_TRUE;
2839    en->selecting = EINA_TRUE;
2840
2841    _edje_emit(en->rp->edje, "handler,move,start", en->rp->part->name);
2842 }
2843
2844 static void
2845 _edje_entry_bottom_handler_mouse_up_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
2846 {
2847    Edje_Real_Part *rp = data;
2848    Entry *en = rp->typedata.text->entry_data;
2849
2850    _edje_emit(en->rp->edje, "handler,move,end", en->rp->part->name);
2851 }
2852
2853 static void
2854 _edje_entry_bottom_handler_mouse_move_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
2855 {
2856    Evas_Event_Mouse_Move *ev = event_info;
2857    Edje_Real_Part *rp = data;
2858    Entry *en = rp->typedata.text->entry_data;
2859    Evas_Coord x, y, tx, ty, tw, th;
2860    Evas_Coord cx, cy;
2861    Evas_Textblock_Cursor_Type cur_type;
2862    Evas_Coord sx, sy;
2863    Evas_Coord ox, oy, hx;
2864
2865    if (ev->buttons != 1) return;
2866
2867    x = ev->cur.canvas.x;
2868    y = ev->cur.canvas.y;
2869
2870    en->rx += (x - en->sx);
2871    en->ry += (y - en->sy);
2872    en->sx = ev->cur.canvas.x;
2873    en->sy = ev->cur.canvas.y;
2874
2875    evas_object_geometry_get(rp->object, &tx, &ty, NULL, NULL);
2876    evas_object_textblock_size_formatted_get(rp->object, &tw, &th);
2877
2878    cx = en->rx + en->ox - tx;
2879    cy = en->ry + en->oy - ty;
2880
2881    if (cx < 0) cx = 0;
2882    if (cy < 0) cy = 0;
2883    if (cy > th) cy = th - 1;
2884
2885    switch (rp->part->cursor_mode)
2886      {
2887       case EDJE_ENTRY_CURSOR_MODE_BEFORE:
2888          cur_type = EVAS_TEXTBLOCK_CURSOR_BEFORE;
2889          break;
2890       case EDJE_ENTRY_CURSOR_MODE_UNDER:
2891       default:
2892          cur_type = EVAS_TEXTBLOCK_CURSOR_UNDER;
2893      }
2894
2895    evas_textblock_cursor_geometry_get(en->sel_start, &sx, &sy, NULL, NULL, NULL, cur_type);
2896    evas_textblock_cursor_char_coord_set(en->cursor, cx, cy);
2897
2898    //avoid hiding the first char
2899    if (evas_textblock_cursor_compare(en->cursor, en->sel_start) == 0)
2900      {
2901         evas_object_geometry_get(rp->object, &ox, &oy, NULL, NULL);
2902         evas_object_geometry_get(en->block_handler_top, &hx, NULL, NULL, NULL);
2903         if (hx < en->viewport_region.x)
2904            evas_object_move(rp->object, ox + en->viewport_region.x - hx, oy);
2905      }
2906
2907    //moving in allowed space
2908    if (evas_textblock_cursor_compare(en->cursor, en->sel_start) <= 0)
2909      {
2910         if (cx <= sx)
2911            evas_textblock_cursor_pos_set(en->cursor, evas_textblock_cursor_pos_get(en->sel_start) + 1);
2912         else
2913           {
2914              if (!evas_textblock_cursor_char_coord_set(en->cursor, cx, sy + 1))
2915                 evas_textblock_cursor_line_char_last(en->cursor);
2916           }
2917      }
2918
2919    if (en->select_allow)
2920      {
2921         if (en->had_sel)
2922           {
2923              if (en->select_mod_end)
2924                _sel_extend(en->cursor, rp->object, en);
2925           }
2926      }
2927    _edje_entry_real_part_configure(rp);
2928    _edje_emit(en->rp->edje, "handler,moving", en->rp->part->name);
2929 }
2930 // TIZEN ONLY - END
2931
2932 static void
2933 _evas_focus_in_cb(void *data, Evas *e, __UNUSED__ void *event_info)
2934 {
2935    Edje *ed = (Edje *)data;
2936
2937    if (evas_focus_get(e) == ed->obj)
2938      {
2939         _edje_focus_in_cb(data, NULL, NULL, NULL);
2940      }
2941 }
2942
2943 static void
2944 _evas_focus_out_cb(void *data, Evas *e, __UNUSED__ void *event_info)
2945 {
2946    Edje *ed = (Edje *)data;
2947
2948    if (evas_focus_get(e) == ed->obj)
2949      {
2950         _edje_focus_out_cb(data, NULL, NULL, NULL);
2951      }
2952 }
2953
2954 /***************************************************************/
2955 void
2956 _edje_entry_init(Edje *ed)
2957 {
2958    if (!ed->has_entries)
2959      return;
2960    if (ed->entries_inited)
2961      return;
2962    ed->entries_inited = EINA_TRUE;
2963
2964    evas_object_event_callback_add(ed->obj, EVAS_CALLBACK_FOCUS_IN, _edje_focus_in_cb, ed);
2965    evas_object_event_callback_add(ed->obj, EVAS_CALLBACK_FOCUS_OUT, _edje_focus_out_cb, ed);
2966    evas_object_event_callback_add(ed->obj, EVAS_CALLBACK_KEY_DOWN, _edje_key_down_cb, ed);
2967    evas_object_event_callback_add(ed->obj, EVAS_CALLBACK_KEY_UP, _edje_key_up_cb, ed);
2968    evas_event_callback_add(ed->base.evas, EVAS_CALLBACK_CANVAS_FOCUS_IN, _evas_focus_in_cb, ed);
2969    evas_event_callback_add(ed->base.evas, EVAS_CALLBACK_CANVAS_FOCUS_OUT, _evas_focus_out_cb, ed);
2970 }
2971
2972 void
2973 _edje_entry_shutdown(Edje *ed)
2974 {
2975    if (!ed->has_entries)
2976      return;
2977    if (!ed->entries_inited)
2978      return;
2979    ed->entries_inited = EINA_FALSE;
2980
2981    evas_object_event_callback_del(ed->obj, EVAS_CALLBACK_FOCUS_IN, _edje_focus_in_cb);
2982    evas_object_event_callback_del(ed->obj, EVAS_CALLBACK_FOCUS_OUT, _edje_focus_out_cb);
2983    evas_object_event_callback_del(ed->obj, EVAS_CALLBACK_KEY_DOWN, _edje_key_down_cb);
2984    evas_object_event_callback_del(ed->obj, EVAS_CALLBACK_KEY_UP, _edje_key_up_cb);
2985    if (evas_event_callback_del_full(ed->base.evas, EVAS_CALLBACK_CANVAS_FOCUS_IN, _evas_focus_in_cb, ed) != ed)
2986      ERR("could not unregister EVAS_CALLBACK_FOCUS_IN");
2987    if (evas_event_callback_del_full(ed->base.evas, EVAS_CALLBACK_CANVAS_FOCUS_OUT, _evas_focus_out_cb, ed) != ed)
2988      ERR("could not unregister EVAS_CALLBACK_FOCUS_OUT");
2989 }
2990
2991 void
2992 _edje_entry_real_part_init(Edje_Real_Part *rp)
2993 {
2994    Entry *en;
2995 #ifdef HAVE_ECORE_IMF
2996    const char *ctx_id;
2997    const Ecore_IMF_Context_Info *ctx_info;
2998 #endif
2999
3000    if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3001        (!rp->typedata.text)) return;
3002    en = calloc(1, sizeof(Entry));
3003    if (!en) return;
3004    rp->typedata.text->entry_data = en;
3005    en->rp = rp;
3006
3007    evas_object_event_callback_add(rp->object, EVAS_CALLBACK_MOVE, _edje_part_move_cb, rp);
3008
3009    evas_object_event_callback_add(rp->object, EVAS_CALLBACK_MOUSE_DOWN, _edje_part_mouse_down_cb, rp);
3010    evas_object_event_callback_add(rp->object, EVAS_CALLBACK_MOUSE_UP, _edje_part_mouse_up_cb, rp);
3011    evas_object_event_callback_add(rp->object, EVAS_CALLBACK_MOUSE_MOVE, _edje_part_mouse_move_cb, rp);
3012
3013    if (rp->part->select_mode == EDJE_ENTRY_SELECTION_MODE_DEFAULT)
3014      en->select_allow = EINA_TRUE;
3015
3016    if (rp->part->entry_mode == EDJE_ENTRY_EDIT_MODE_PASSWORD)
3017      {
3018         Edje_Part_Description_Text *txt;
3019
3020         txt = (Edje_Part_Description_Text *)rp->chosen_description;
3021
3022         en->select_allow = EINA_FALSE;
3023         if (txt && edje_string_get(&txt->text.repch))
3024           evas_object_textblock_replace_char_set(rp->object, edje_string_get(&txt->text.repch));
3025         else
3026           evas_object_textblock_replace_char_set(rp->object, "*");
3027      }
3028
3029    en->cursor_bg = edje_object_add(rp->edje->base.evas);
3030    if (rp->part->select_mode == EDJE_ENTRY_SELECTION_MODE_BLOCK_HANDLE)
3031      edje_object_file_set(en->cursor_bg, rp->edje->path, rp->part->source6);
3032    else
3033      edje_object_file_set(en->cursor_bg, rp->edje->path, rp->part->source3);
3034    evas_object_smart_member_add(en->cursor_bg, rp->edje->obj);
3035    evas_object_stack_below(en->cursor_bg, rp->object);
3036    evas_object_clip_set(en->cursor_bg, evas_object_clip_get(rp->object));
3037    evas_object_pass_events_set(en->cursor_bg, EINA_TRUE);
3038    _edje_subobj_register(en->rp->edje, en->cursor_bg);
3039
3040    en->cursor_fg = edje_object_add(rp->edje->base.evas);
3041    edje_object_file_set(en->cursor_fg, rp->edje->path, rp->part->source4);
3042    evas_object_smart_member_add(en->cursor_fg, rp->edje->obj);
3043    evas_object_stack_above(en->cursor_fg, rp->object);
3044    evas_object_clip_set(en->cursor_fg, evas_object_clip_get(rp->object));
3045    evas_object_pass_events_set(en->cursor_fg, EINA_TRUE);
3046    _edje_subobj_register(en->rp->edje, en->cursor_fg);
3047
3048    evas_object_textblock_legacy_newline_set(rp->object, EINA_TRUE);
3049
3050    if (rp->part->entry_mode >= EDJE_ENTRY_EDIT_MODE_EDITABLE)
3051      {
3052         evas_object_show(en->cursor_bg);
3053         evas_object_show(en->cursor_fg);
3054         en->input_panel_enable = EINA_TRUE;
3055
3056 #ifdef HAVE_ECORE_IMF
3057         ecore_imf_init();
3058
3059         en->commit_cancel = EINA_FALSE;
3060
3061         edje_object_signal_callback_add(rp->edje->obj, "focus,part,in", rp->part->name, _edje_entry_focus_in_cb, rp);
3062         edje_object_signal_callback_add(rp->edje->obj, "focus,part,out", rp->part->name, _edje_entry_focus_out_cb, rp);
3063
3064         ctx_id = ecore_imf_context_default_id_get();
3065         if (ctx_id)
3066           {
3067              ctx_info = ecore_imf_context_info_by_id_get(ctx_id);
3068              if (!ctx_info->canvas_type ||
3069                  strcmp(ctx_info->canvas_type, "evas") == 0)
3070                {
3071                   en->imf_context = ecore_imf_context_add(ctx_id);
3072                }
3073              else
3074                {
3075                   ctx_id = ecore_imf_context_default_id_by_canvas_type_get("evas");
3076                   if (ctx_id)
3077                     {
3078                        en->imf_context = ecore_imf_context_add(ctx_id);
3079                     }
3080                }
3081           }
3082         else
3083           en->imf_context = NULL;
3084
3085         if (!en->imf_context) goto done;
3086
3087         ecore_imf_context_client_window_set
3088            (en->imf_context,
3089                (void *)ecore_evas_window_get
3090                (ecore_evas_ecore_evas_get(rp->edje->base.evas)));
3091         ecore_imf_context_client_canvas_set(en->imf_context, rp->edje->base.evas);
3092
3093         ecore_imf_context_retrieve_surrounding_callback_set(en->imf_context,
3094                                                             _edje_entry_imf_retrieve_surrounding_cb, rp->edje);
3095         ecore_imf_context_event_callback_add(en->imf_context, ECORE_IMF_CALLBACK_COMMIT, _edje_entry_imf_event_commit_cb, rp->edje);
3096         ecore_imf_context_event_callback_add(en->imf_context, ECORE_IMF_CALLBACK_DELETE_SURROUNDING, _edje_entry_imf_event_delete_surrounding_cb, rp->edje);
3097         ecore_imf_context_event_callback_add(en->imf_context, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, _edje_entry_imf_event_preedit_changed_cb, rp->edje);
3098         ecore_imf_context_input_mode_set(en->imf_context,
3099                                          rp->part->entry_mode == EDJE_ENTRY_EDIT_MODE_PASSWORD ?
3100                                          ECORE_IMF_INPUT_MODE_INVISIBLE : ECORE_IMF_INPUT_MODE_FULL);
3101
3102         if (rp->part->entry_mode == EDJE_ENTRY_EDIT_MODE_PASSWORD)
3103           ecore_imf_context_input_panel_language_set(en->imf_context, ECORE_IMF_INPUT_PANEL_LANG_ALPHABET);
3104 #endif
3105      }
3106 #ifdef HAVE_ECORE_IMF
3107 done:
3108 #endif
3109    en->cursor = (Evas_Textblock_Cursor *)evas_object_textblock_cursor_get(rp->object);
3110
3111    // TIZEN ONLY - START
3112    edje_object_signal_callback_add(rp->edje->obj, "mouse,down,1,double", rp->part->name, _edje_entry_mouse_double_clicked, rp);
3113    // TIZEN ONLY - END
3114 }
3115
3116 void
3117 _edje_entry_real_part_shutdown(Edje_Real_Part *rp)
3118 {
3119    Entry *en;
3120    
3121    if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3122        (!rp->typedata.text)) return;
3123    en = rp->typedata.text->entry_data;
3124    if (!en) return;
3125    rp->typedata.text->entry_data = NULL;
3126    _sel_clear(en->cursor, rp->object, en);
3127    _anchors_clear(en->cursor, rp->object, en);
3128 #ifdef HAVE_ECORE_IMF
3129    _preedit_clear(en);
3130 #endif
3131    // TIZEN ONLY - START
3132    rp->edje->subobjs = eina_list_remove(rp->edje->subobjs, en->cursor_bg);
3133    rp->edje->subobjs = eina_list_remove(rp->edje->subobjs, en->cursor_fg);
3134    rp->edje->subobjs = eina_list_remove(rp->edje->subobjs, en->block_handler_top);
3135    rp->edje->subobjs = eina_list_remove(rp->edje->subobjs, en->block_handler_btm);
3136    // TIZEN ONLY - END
3137    evas_object_del(en->cursor_bg);
3138    evas_object_del(en->cursor_fg);
3139
3140    // TIZEN ONLY - START
3141    if (en->block_handler_top)
3142      {
3143         evas_object_del(en->block_handler_top);
3144         en->block_handler_top = NULL;
3145      }
3146    if (en->block_handler_btm)
3147      {
3148         evas_object_del(en->block_handler_btm);
3149         en->block_handler_btm = NULL;
3150      }
3151
3152    if (en->longpress_timer)
3153      {
3154         ecore_timer_del(en->longpress_timer);
3155         en->longpress_timer = NULL;
3156      }
3157    // TIZEN ONLY - END
3158
3159    if (en->pw_timer)
3160      {
3161         ecore_timer_del(en->pw_timer);
3162         en->pw_timer = NULL;
3163      }
3164
3165 #ifdef HAVE_ECORE_IMF
3166    if (rp->part->entry_mode >= EDJE_ENTRY_EDIT_MODE_EDITABLE)
3167      {
3168         if (en->imf_context)
3169           {
3170              ecore_imf_context_event_callback_del(en->imf_context, ECORE_IMF_CALLBACK_COMMIT, _edje_entry_imf_event_commit_cb);
3171              ecore_imf_context_event_callback_del(en->imf_context, ECORE_IMF_CALLBACK_DELETE_SURROUNDING, _edje_entry_imf_event_delete_surrounding_cb);
3172              ecore_imf_context_event_callback_del(en->imf_context, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, _edje_entry_imf_event_preedit_changed_cb);
3173
3174              ecore_imf_context_del(en->imf_context);
3175              en->imf_context = NULL;
3176           }
3177
3178         edje_object_signal_callback_del(rp->edje->obj, "focus,part,in", rp->part->name, _edje_entry_focus_in_cb);
3179         edje_object_signal_callback_del(rp->edje->obj, "focus,part,out", rp->part->name, _edje_entry_focus_out_cb);
3180         ecore_imf_shutdown();
3181      }
3182 #endif
3183    _compose_seq_reset(en);
3184    
3185    free(en);
3186 }
3187
3188 void
3189 _edje_entry_real_part_configure(Edje_Real_Part *rp)
3190 {
3191    Evas_Coord x, y, w, h, xx, yy, ww, hh;
3192    Entry *en;
3193    Evas_Textblock_Cursor_Type cur_type;
3194    
3195    if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3196        (!rp->typedata.text)) return;
3197    en = rp->typedata.text->entry_data;
3198    if (!en) return;
3199    switch (rp->part->cursor_mode)
3200      {
3201       case EDJE_ENTRY_CURSOR_MODE_BEFORE:
3202          cur_type = EVAS_TEXTBLOCK_CURSOR_BEFORE;
3203          break;
3204       case EDJE_ENTRY_CURSOR_MODE_UNDER:
3205          /* no break for a resaon */
3206       default:
3207          cur_type = EVAS_TEXTBLOCK_CURSOR_UNDER;
3208      }
3209
3210    _sel_update(en->cursor, rp->object, en);
3211    _anchors_update(en->cursor, rp->object, en);
3212    x = y = w = h = -1;
3213    xx = yy = ww = hh = -1;
3214    evas_object_geometry_get(rp->object, &x, &y, &w, &h);
3215    evas_textblock_cursor_geometry_get(en->cursor, &xx, &yy, &ww, &hh, NULL, cur_type);
3216    if (ww < 1) ww = 1;
3217    if (hh < 1) hh = 1;
3218    if (en->cursor_bg)
3219      {
3220         evas_object_move(en->cursor_bg, x + xx, y + yy);
3221         evas_object_resize(en->cursor_bg, ww, hh);
3222      }
3223    if (en->cursor_fg)
3224      {
3225         evas_object_move(en->cursor_fg, x + xx, y + yy);
3226         evas_object_resize(en->cursor_fg, ww, hh);
3227      }
3228 }
3229
3230 const char *
3231 _edje_entry_selection_get(Edje_Real_Part *rp)
3232 {
3233    Entry *en;
3234    
3235    if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3236        (!rp->typedata.text)) return NULL;
3237    en = rp->typedata.text->entry_data;
3238    if (!en) return NULL;
3239    // get selection - convert to markup
3240    if ((!en->selection) && (en->have_selection))
3241      en->selection = evas_textblock_cursor_range_text_get
3242         (en->sel_start, en->sel_end, EVAS_TEXTBLOCK_TEXT_MARKUP);
3243    return en->selection;
3244 }
3245
3246 const char *
3247 _edje_entry_text_get(Edje_Real_Part *rp)
3248 {
3249    Entry *en;
3250    
3251    if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3252        (!rp->typedata.text)) return NULL;
3253    en = rp->typedata.text->entry_data;
3254    if (!en) return NULL;
3255    // get text - convert to markup
3256    return evas_object_textblock_text_markup_get(rp->object);
3257 }
3258
3259 void
3260 _edje_entry_text_markup_set(Edje_Real_Part *rp, const char *text)
3261 {
3262    Entry *en;
3263    
3264    if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3265        (!rp->typedata.text)) return;
3266    en = rp->typedata.text->entry_data;
3267    if (!en) return;
3268    _edje_entry_imf_context_reset(rp);
3269    // set text as markup
3270    _sel_clear(en->cursor, rp->object, en);
3271    evas_object_textblock_text_markup_set(rp->object, text);
3272    _edje_entry_set_cursor_start(rp);
3273
3274    _anchors_get(en->cursor, rp->object, en);
3275    _edje_emit(rp->edje, "entry,changed", rp->part->name);
3276
3277    // TIZEN ONLY(130129) : Currently, for freezing cursor movement.
3278    if (!en->freeze)
3279      {
3280         _edje_entry_imf_cursor_info_set(en);
3281         _edje_entry_real_part_configure(rp);
3282      }
3283    //
3284
3285 #if 0
3286    /* Don't emit cursor changed cause it didn't. It's just init to 0. */
3287    _edje_emit(rp->edje, "cursor,changed", rp->part->name);
3288 #endif
3289 }
3290
3291 void
3292 _edje_entry_text_markup_append(Edje_Real_Part *rp, const char *text)
3293 {
3294    Entry *en;
3295    
3296    if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3297        (!rp->typedata.text)) return;
3298    en = rp->typedata.text->entry_data;
3299    Evas_Textblock_Cursor *end_cur;
3300    if (!en) return;
3301    end_cur = evas_object_textblock_cursor_new(rp->object);
3302    evas_textblock_cursor_paragraph_last(end_cur);
3303
3304    _text_filter_markup_prepend(en, end_cur, text);
3305    evas_textblock_cursor_free(end_cur);
3306
3307    /* We are updating according to the real cursor on purpose */
3308    _anchors_get(en->cursor, rp->object, en);
3309    _edje_emit(rp->edje, "entry,changed", rp->part->name);
3310
3311    _edje_entry_real_part_configure(rp);
3312 }
3313
3314 void
3315 _edje_entry_text_markup_insert(Edje_Real_Part *rp, const char *text)
3316 {
3317    Entry *en;
3318    
3319    if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3320        (!rp->typedata.text)) return;
3321    en = rp->typedata.text->entry_data;
3322    if (!en) return;
3323    _edje_entry_imf_context_reset(rp);
3324
3325    // prepend markup @ cursor pos
3326    if (en->have_selection)
3327      _range_del(en->cursor, rp->object, en);
3328    //xx
3329 //   evas_object_textblock_text_markup_prepend(en->cursor, text);
3330    _text_filter_markup_prepend(en, en->cursor, text);
3331    _anchors_get(en->cursor, rp->object, en);
3332    _edje_emit(rp->edje, "entry,changed", rp->part->name);
3333    _edje_emit(rp->edje, "cursor,changed", rp->part->name);
3334
3335    _edje_entry_imf_cursor_info_set(en);
3336    _edje_entry_real_part_configure(rp);
3337 }
3338
3339 void
3340 _edje_entry_set_cursor_start(Edje_Real_Part *rp)
3341 {
3342    Entry *en;
3343    
3344    if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3345        (!rp->typedata.text)) return;
3346    en = rp->typedata.text->entry_data;
3347    if (!en) return;
3348    _curs_start(en->cursor, rp->object, en);
3349
3350    // TIZEN ONLY(130129) : Currently, for freezing cursor movement.
3351    if (!en->freeze)
3352       _edje_entry_imf_cursor_info_set(en);
3353 }
3354
3355 void
3356 _edje_entry_set_cursor_end(Edje_Real_Part *rp)
3357 {
3358    Entry *en;
3359    
3360    if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3361        (!rp->typedata.text)) return;
3362    en = rp->typedata.text->entry_data;
3363    if (!en) return;
3364    _curs_end(en->cursor, rp->object, en);
3365
3366    _edje_entry_imf_cursor_info_set(en);
3367 }
3368
3369 void
3370 _edje_entry_select_none(Edje_Real_Part *rp)
3371 {
3372    Entry *en;
3373    
3374    if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3375        (!rp->typedata.text)) return;
3376    en = rp->typedata.text->entry_data;
3377    if (!en) return;
3378    _sel_clear(en->cursor, rp->object, en);
3379 }
3380
3381 void
3382 _edje_entry_select_all(Edje_Real_Part *rp)
3383 {
3384    Entry *en;
3385    
3386    if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3387        (!rp->typedata.text)) return;
3388    en = rp->typedata.text->entry_data;
3389    if (!en) return;
3390
3391    _edje_entry_imf_context_reset(rp);
3392
3393    _sel_clear(en->cursor, rp->object, en);
3394    _curs_start(en->cursor, rp->object, en);
3395    _sel_enable(en->cursor, rp->object, en);
3396    _sel_start(en->cursor, rp->object, en);
3397    _curs_end(en->cursor, rp->object, en);
3398    _sel_extend(en->cursor, rp->object, en);
3399
3400    _edje_entry_real_part_configure(rp);
3401
3402    // TIZEN ONLY - START
3403    en->select_allow = EINA_TRUE;
3404    en->had_sel = EINA_TRUE;
3405
3406    _edje_emit(en->rp->edje, "selection,end", en->rp->part->name);
3407    // TIZEN ONLY - END
3408 }
3409
3410 void
3411 _edje_entry_select_begin(Edje_Real_Part *rp)
3412 {
3413    Entry *en;
3414    
3415    if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3416        (!rp->typedata.text)) return;
3417    en = rp->typedata.text->entry_data;
3418    if (!en) return;
3419
3420    _edje_entry_imf_context_reset(rp);
3421
3422    _sel_clear(en->cursor, rp->object, en);
3423    _sel_enable(en->cursor, rp->object, en);
3424    _sel_start(en->cursor, rp->object, en);
3425    _sel_extend(en->cursor, rp->object, en);
3426
3427    _edje_entry_real_part_configure(rp);
3428 }
3429
3430 void
3431 _edje_entry_select_extend(Edje_Real_Part *rp)
3432 {
3433    Entry *en;
3434    
3435    if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3436        (!rp->typedata.text)) return;
3437    en = rp->typedata.text->entry_data;
3438    if (!en) return;
3439    _edje_entry_imf_context_reset(rp);
3440    _sel_extend(en->cursor, rp->object, en);
3441
3442    _edje_entry_real_part_configure(rp);
3443 }
3444
3445 const Eina_List *
3446 _edje_entry_anchor_geometry_get(Edje_Real_Part *rp, const char *anchor)
3447 {
3448    Entry *en;
3449    Eina_List *l;
3450    Anchor *an;
3451
3452    if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3453        (!rp->typedata.text)) return NULL;
3454    en = rp->typedata.text->entry_data;
3455    if (!en) return NULL;
3456    EINA_LIST_FOREACH(en->anchors, l, an)
3457      {
3458         if (an->item) continue;
3459         if (!strcmp(anchor, an->name))
3460           return an->sel;
3461      }
3462    return NULL;
3463 }
3464
3465 const Eina_List *
3466 _edje_entry_anchors_list(Edje_Real_Part *rp)
3467 {
3468    Entry *en;
3469    Eina_List *l, *anchors = NULL;
3470    Anchor *an;
3471
3472    if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3473        (!rp->typedata.text)) return NULL;
3474    en = rp->typedata.text->entry_data;
3475    if (!en) return NULL;
3476    if (!en->anchorlist)
3477      {
3478         EINA_LIST_FOREACH(en->anchors, l, an)
3479           {
3480              const char *n = an->name;
3481              if (an->item) continue;
3482              if (!n) n = "";
3483              anchors = eina_list_append(anchors, strdup(n));
3484           }
3485         en->anchorlist = anchors;
3486      }
3487    return en->anchorlist;
3488 }
3489
3490 Eina_Bool
3491 _edje_entry_item_geometry_get(Edje_Real_Part *rp, const char *item, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch)
3492 {
3493    Entry *en;
3494    Eina_List *l;
3495    Anchor *an;
3496
3497    if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3498        (!rp->typedata.text)) return EINA_FALSE;
3499    en = rp->typedata.text->entry_data;
3500    if (!en) return EINA_FALSE;
3501    EINA_LIST_FOREACH(en->anchors, l, an)
3502      {
3503         if (an->item) continue;
3504         if (!strcmp(item, an->name))
3505           {
3506              evas_textblock_cursor_format_item_geometry_get(an->start, cx, cy, cw, ch);
3507              return EINA_TRUE;
3508           }
3509      }
3510    return EINA_FALSE;
3511 }
3512
3513 const Eina_List *
3514 _edje_entry_items_list(Edje_Real_Part *rp)
3515 {
3516    Entry *en;
3517    Eina_List *l, *items = NULL;
3518    Anchor *an;
3519
3520    if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3521        (!rp->typedata.text)) return NULL;
3522    en = rp->typedata.text->entry_data;
3523    if (!en) return NULL;
3524    if (!en->itemlist)
3525      {
3526         EINA_LIST_FOREACH(en->anchors, l, an)
3527           {
3528              const char *n = an->name;
3529              if (an->item) continue;
3530              if (!n) n = "";
3531              items = eina_list_append(items, strdup(n));
3532           }
3533         en->itemlist = items;
3534      }
3535    return en->itemlist;
3536 }
3537
3538 // TIZEN ONLY - START
3539 void
3540 _edje_entry_copy_paste_disabled_set(Edje_Real_Part *rp, Eina_Bool disabled)
3541 {
3542    Entry *en = rp->typedata.text->entry_data;
3543    if (!en) return;
3544
3545    en->copy_paste_disabled = disabled;
3546 }
3547
3548 void
3549 _edje_entry_layout_region_set(Edje_Real_Part *rp, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h)
3550 {
3551    Entry *en = rp->typedata.text->entry_data;
3552    if (!en) return;
3553
3554    en->layout_region.x = x;
3555    en->layout_region.y = y;
3556    en->layout_region.w = w;
3557    en->layout_region.h = h;
3558    _sel_update(en->cursor, rp->object, en);
3559 }
3560
3561 void
3562 _edje_entry_viewport_region_set(Edje_Real_Part *rp, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h)
3563 {
3564    Entry *en = rp->typedata.text->entry_data;
3565    if (!en) return;
3566
3567    en->viewport_region.x = x;
3568    en->viewport_region.y = y;
3569    en->viewport_region.w = w;
3570    en->viewport_region.h = h;
3571    _sel_update(en->cursor, rp->object, en);
3572 }
3573 // TIZEN ONLY - END
3574
3575 void
3576 _edje_entry_cursor_geometry_get(Edje_Real_Part *rp, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch)
3577 {
3578    Evas_Coord x, y, w, h, xx, yy, ww, hh;
3579    Entry *en;
3580    Evas_Textblock_Cursor_Type cur_type;
3581    
3582    if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3583        (!rp->typedata.text)) return;
3584    en = rp->typedata.text->entry_data;
3585    if (!en) return;
3586    switch (rp->part->cursor_mode)
3587      {
3588       case EDJE_ENTRY_CURSOR_MODE_BEFORE:
3589          cur_type = EVAS_TEXTBLOCK_CURSOR_BEFORE;
3590          break;
3591       case EDJE_ENTRY_CURSOR_MODE_UNDER:
3592          /* no break for a resaon */
3593       default:
3594          cur_type = EVAS_TEXTBLOCK_CURSOR_UNDER;
3595      }
3596
3597    x = y = w = h = -1;
3598    xx = yy = ww = hh = -1;
3599    evas_object_geometry_get(rp->object, &x, &y, &w, &h);
3600    evas_textblock_cursor_geometry_get(en->cursor, &xx, &yy, &ww, &hh, NULL, cur_type);
3601    if (ww < 1) ww = 1;
3602    if (rp->part->cursor_mode == EDJE_ENTRY_CURSOR_MODE_BEFORE)
3603      edje_object_size_min_restricted_calc(en->cursor_fg, &ww, NULL, ww, 0);
3604    if (hh < 1) hh = 1;
3605    if (cx) *cx = x + xx;
3606    if (cy) *cy = y + yy;
3607    if (cw) *cw = ww;
3608    if (ch) *ch = hh;
3609 }
3610
3611 void
3612 _edje_entry_user_insert(Edje_Real_Part *rp, const char *text)
3613 {
3614    Entry *en;
3615    Edje_Entry_Change_Info *info;
3616
3617    if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3618        (!rp->typedata.text)) return;
3619    en = rp->typedata.text->entry_data;
3620    if (!en) return;
3621    info = calloc(1, sizeof(*info));
3622    if (!info) return;
3623    info->insert = EINA_TRUE;
3624    info->change.insert.plain_length = 1;
3625    info->change.insert.content = eina_stringshare_add(text);
3626      {
3627         char *tmp;
3628         tmp = evas_textblock_text_markup_to_utf8(rp->object,
3629                                                  info->change.insert.content);
3630         info->change.insert.plain_length = eina_unicode_utf8_get_len(tmp);
3631         free(tmp);
3632      }
3633
3634    if (en->have_selection)
3635      {
3636         _range_del_emit(rp->edje, en->cursor, rp->object, en);
3637         info->merge = EINA_TRUE;
3638      }
3639    info->change.insert.pos = evas_textblock_cursor_pos_get(en->cursor);
3640    _text_filter_markup_prepend(en, en->cursor, text);
3641    _anchors_get(en->cursor, rp->object, en);
3642    _edje_emit(rp->edje, "entry,changed", rp->part->name);
3643    _edje_emit_full(rp->edje, "entry,changed,user", rp->part->name,
3644                    info, _free_entry_change_info);
3645    _edje_emit(rp->edje, "cursor,changed", rp->part->name);
3646
3647    _edje_entry_imf_cursor_info_set(en);
3648    _edje_entry_real_part_configure(rp);
3649 }
3650
3651 void
3652 _edje_entry_select_allow_set(Edje_Real_Part *rp, Eina_Bool allow)
3653 {
3654    Entry *en;
3655    
3656    if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3657        (!rp->typedata.text)) return;
3658    en = rp->typedata.text->entry_data;
3659    if (!en) return;
3660    if (rp->part->select_mode == EDJE_ENTRY_SELECTION_MODE_DEFAULT)
3661      return;
3662    en->select_allow = allow;
3663
3664    // TIZEN ONLY - START
3665    if ((allow) && (rp->part->select_mode == EDJE_ENTRY_SELECTION_MODE_BLOCK_HANDLE))
3666      {
3667         if (!_edje_entry_select_word(rp)) return;
3668         _edje_emit(en->rp->edje, "selection,end", en->rp->part->name);
3669      }
3670    // TIZEN ONLY - END
3671 }
3672
3673 Eina_Bool
3674 _edje_entry_select_allow_get(const Edje_Real_Part *rp)
3675 {
3676    Entry *en;
3677    
3678    if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3679        (!rp->typedata.text)) return EINA_FALSE;
3680    en = rp->typedata.text->entry_data;
3681    if (!en) return EINA_FALSE;
3682    return en->select_allow;
3683 }
3684
3685 void
3686 _edje_entry_select_abort(Edje_Real_Part *rp)
3687 {
3688    Entry *en;
3689    
3690    if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3691        (!rp->typedata.text)) return;
3692    en = rp->typedata.text->entry_data;
3693    if (!en) return;
3694    if (en->selecting)
3695      {
3696         en->selecting = EINA_FALSE;
3697
3698         _edje_entry_imf_context_reset(rp);
3699         _edje_entry_imf_cursor_info_set(en);
3700         _edje_entry_real_part_configure(rp);
3701      }
3702 }
3703
3704 void *
3705 _edje_entry_imf_context_get(Edje_Real_Part *rp)
3706 {
3707    Entry *en;
3708    
3709    if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3710        (!rp->typedata.text)) return NULL;
3711    en = rp->typedata.text->entry_data;
3712    if (!en) return NULL;
3713
3714 #ifdef HAVE_ECORE_IMF
3715    return en->imf_context;
3716 #else
3717    return NULL;
3718 #endif
3719 }
3720
3721 void
3722 _edje_entry_autocapital_type_set(Edje_Real_Part *rp, Edje_Text_Autocapital_Type autocapital_type)
3723 {
3724    Entry *en;
3725    
3726    if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3727        (!rp->typedata.text)) return;
3728    en = rp->typedata.text->entry_data;
3729    if (!en) return;
3730
3731    if (rp->part->entry_mode == EDJE_ENTRY_EDIT_MODE_PASSWORD)
3732      autocapital_type = EDJE_TEXT_AUTOCAPITAL_TYPE_NONE;
3733
3734 #ifdef HAVE_ECORE_IMF
3735    if (en->imf_context)
3736      ecore_imf_context_autocapital_type_set(en->imf_context, autocapital_type);
3737 #endif
3738 }
3739
3740 Edje_Text_Autocapital_Type
3741 _edje_entry_autocapital_type_get(Edje_Real_Part *rp)
3742 {
3743    Entry *en;
3744    
3745    if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3746        (!rp->typedata.text)) return EDJE_TEXT_AUTOCAPITAL_TYPE_NONE;
3747    en = rp->typedata.text->entry_data;
3748    if (!en) return EDJE_TEXT_AUTOCAPITAL_TYPE_NONE;
3749
3750 #ifdef HAVE_ECORE_IMF
3751    if (en->imf_context)
3752      return ecore_imf_context_autocapital_type_get(en->imf_context);
3753 #endif
3754
3755    return EDJE_TEXT_AUTOCAPITAL_TYPE_NONE;
3756 }
3757
3758 void
3759 _edje_entry_prediction_allow_set(Edje_Real_Part *rp, Eina_Bool prediction)
3760 {
3761    Entry *en;
3762    
3763    if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3764        (!rp->typedata.text)) return;
3765    en = rp->typedata.text->entry_data;
3766    if (!en) return;
3767    en->prediction_allow = prediction;
3768 #ifdef HAVE_ECORE_IMF
3769    if (en->imf_context)
3770      ecore_imf_context_prediction_allow_set(en->imf_context, prediction);
3771 #endif
3772 }
3773
3774 Eina_Bool
3775 _edje_entry_prediction_allow_get(Edje_Real_Part *rp)
3776 {
3777    Entry *en;
3778    
3779    if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3780        (!rp->typedata.text)) return EINA_FALSE;
3781    en = rp->typedata.text->entry_data;
3782    if (!en) return EINA_FALSE;
3783    return en->prediction_allow;
3784 }
3785
3786 void
3787 _edje_entry_input_panel_enabled_set(Edje_Real_Part *rp, Eina_Bool enabled)
3788 {
3789    Entry *en;
3790    
3791    if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3792        (!rp->typedata.text)) return;
3793    en = rp->typedata.text->entry_data;
3794    if (!en) return;
3795    en->input_panel_enable = enabled;
3796 #ifdef HAVE_ECORE_IMF
3797    if (en->imf_context)
3798      ecore_imf_context_input_panel_enabled_set(en->imf_context, enabled);
3799 #endif
3800 }
3801
3802 Eina_Bool
3803 _edje_entry_input_panel_enabled_get(Edje_Real_Part *rp)
3804 {
3805    Entry *en;
3806    
3807    if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3808        (!rp->typedata.text)) return EINA_FALSE;
3809    en = rp->typedata.text->entry_data;
3810    if (!en) return EINA_FALSE;
3811    return en->input_panel_enable;
3812 }
3813
3814 void
3815 _edje_entry_input_panel_show(Edje_Real_Part *rp)
3816 {
3817    Entry *en;
3818    
3819    if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3820        (!rp->typedata.text)) return;
3821    en = rp->typedata.text->entry_data;
3822    if (!en) return;
3823 #ifdef HAVE_ECORE_IMF
3824    if (en->imf_context)
3825      ecore_imf_context_input_panel_show(en->imf_context);
3826 #endif
3827 }
3828
3829 void
3830 _edje_entry_input_panel_hide(Edje_Real_Part *rp)
3831 {
3832    Entry *en;
3833    
3834    if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3835        (!rp->typedata.text)) return;
3836    en = rp->typedata.text->entry_data;
3837    if (!en) return;
3838 #ifdef HAVE_ECORE_IMF
3839    if (en->imf_context)
3840      ecore_imf_context_input_panel_hide(en->imf_context);
3841 #endif
3842 }
3843
3844 void
3845 _edje_entry_input_panel_language_set(Edje_Real_Part *rp, Edje_Input_Panel_Lang lang)
3846 {
3847    Entry *en;
3848    
3849    if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3850        (!rp->typedata.text)) return;
3851    en = rp->typedata.text->entry_data;
3852    if (!en) return;
3853    en->input_panel_lang = lang;
3854 #ifdef HAVE_ECORE_IMF
3855    if (en->imf_context)
3856      ecore_imf_context_input_panel_language_set(en->imf_context, lang);
3857 #endif
3858 }
3859
3860 Edje_Input_Panel_Lang
3861 _edje_entry_input_panel_language_get(Edje_Real_Part *rp)
3862 {
3863    Entry *en;
3864    
3865    if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3866        (!rp->typedata.text)) return EDJE_INPUT_PANEL_LANG_AUTOMATIC;
3867    en = rp->typedata.text->entry_data;
3868    if (!en) return EDJE_INPUT_PANEL_LANG_AUTOMATIC;
3869    return en->input_panel_lang;
3870 }
3871
3872 #ifdef HAVE_ECORE_IMF
3873 void
3874 _edje_entry_input_panel_imdata_set(Edje_Real_Part *rp, const void *data, int len)
3875 #else
3876 void
3877 _edje_entry_input_panel_imdata_set(Edje_Real_Part *rp, const void *data __UNUSED__, int len __UNUSED__)
3878 #endif
3879 {
3880    Entry *en;
3881    
3882    if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3883        (!rp->typedata.text)) return;
3884    en = rp->typedata.text->entry_data;
3885    if (!en) return;
3886 #ifdef HAVE_ECORE_IMF
3887    if (en->imf_context)
3888      ecore_imf_context_input_panel_imdata_set(en->imf_context, data, len);
3889 #endif
3890 }
3891
3892 #ifdef HAVE_ECORE_IMF
3893 void
3894 _edje_entry_input_panel_imdata_get(Edje_Real_Part *rp, void *data, int *len)
3895 #else
3896 void
3897 _edje_entry_input_panel_imdata_get(Edje_Real_Part *rp, void *data __UNUSED__, int *len __UNUSED__)
3898 #endif
3899 {
3900    Entry *en;
3901    
3902    if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3903        (!rp->typedata.text)) return;
3904    en = rp->typedata.text->entry_data;
3905    if (!en) return;
3906 #ifdef HAVE_ECORE_IMF
3907    if (en->imf_context)
3908      ecore_imf_context_input_panel_imdata_get(en->imf_context, data, len);
3909 #endif
3910 }
3911
3912 #ifdef HAVE_ECORE_IMF
3913 void
3914 _edje_entry_input_panel_return_key_type_set(Edje_Real_Part *rp, Edje_Input_Panel_Return_Key_Type return_key_type)
3915 #else
3916 void
3917 _edje_entry_input_panel_return_key_type_set(Edje_Real_Part *rp, Edje_Input_Panel_Return_Key_Type return_key_type __UNUSED__)
3918 #endif
3919 {
3920    Entry *en;
3921    
3922    if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3923        (!rp->typedata.text)) return;
3924    en = rp->typedata.text->entry_data;
3925    if (!en) return;
3926 #ifdef HAVE_ECORE_IMF
3927    if (en->imf_context)
3928      ecore_imf_context_input_panel_return_key_type_set(en->imf_context, return_key_type);
3929 #endif
3930 }
3931
3932 Edje_Input_Panel_Return_Key_Type
3933 _edje_entry_input_panel_return_key_type_get(Edje_Real_Part *rp)
3934 {
3935    Entry *en;
3936    
3937    if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3938        (!rp->typedata.text)) return EDJE_INPUT_PANEL_RETURN_KEY_TYPE_DEFAULT;
3939    en = rp->typedata.text->entry_data;
3940    if (!en) return EDJE_INPUT_PANEL_RETURN_KEY_TYPE_DEFAULT;
3941 #ifdef HAVE_ECORE_IMF
3942    if (en->imf_context)
3943      return ecore_imf_context_input_panel_return_key_type_get(en->imf_context);
3944 #endif
3945    return EDJE_INPUT_PANEL_RETURN_KEY_TYPE_DEFAULT;
3946 }
3947
3948 #ifdef HAVE_ECORE_IMF
3949 void
3950 _edje_entry_input_panel_return_key_disabled_set(Edje_Real_Part *rp, Eina_Bool disabled)
3951 #else
3952 void
3953 _edje_entry_input_panel_return_key_disabled_set(Edje_Real_Part *rp, Eina_Bool disabled __UNUSED__)
3954 #endif
3955 {
3956    Entry *en;
3957    
3958    if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3959        (!rp->typedata.text)) return;
3960    en = rp->typedata.text->entry_data;
3961    if (!en) return;
3962 #ifdef HAVE_ECORE_IMF
3963    if (en->imf_context)
3964      ecore_imf_context_input_panel_return_key_disabled_set(en->imf_context, disabled);
3965 #endif
3966 }
3967
3968 Eina_Bool
3969 _edje_entry_input_panel_return_key_disabled_get(Edje_Real_Part *rp)
3970 {
3971    Entry *en;
3972    
3973    if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3974        (!rp->typedata.text)) return EINA_FALSE;
3975    en = rp->typedata.text->entry_data;
3976    if (!en) return EINA_FALSE;
3977 #ifdef HAVE_ECORE_IMF
3978    if (en->imf_context)
3979      return ecore_imf_context_input_panel_return_key_disabled_get(en->imf_context);
3980 #endif
3981    return EINA_FALSE;
3982 }
3983
3984 static Evas_Textblock_Cursor *
3985 _cursor_get(Edje_Real_Part *rp, Edje_Cursor cur)
3986 {
3987    Entry *en;
3988    
3989    if ((rp->type != EDJE_RP_TYPE_TEXT) ||
3990        (!rp->typedata.text)) return NULL;
3991    en = rp->typedata.text->entry_data;
3992    if (!en) return NULL;
3993    switch (cur)
3994      {
3995       case EDJE_CURSOR_MAIN:
3996          return en->cursor;
3997       case EDJE_CURSOR_SELECTION_BEGIN:
3998          return en->sel_start;
3999       case EDJE_CURSOR_SELECTION_END:
4000          return en->sel_end;
4001       case EDJE_CURSOR_PREEDIT_START:
4002          if (!en->preedit_start)
4003            en->preedit_start = evas_object_textblock_cursor_new(rp->object);
4004          return en->preedit_start;
4005       case EDJE_CURSOR_PREEDIT_END:
4006          if (!en->preedit_end)
4007            en->preedit_end = evas_object_textblock_cursor_new(rp->object);
4008          return en->preedit_end;
4009       case EDJE_CURSOR_USER:
4010          if (!en->cursor_user)
4011            en->cursor_user = evas_object_textblock_cursor_new(rp->object);
4012          return en->cursor_user;
4013       case EDJE_CURSOR_USER_EXTRA:
4014          if (!en->cursor_user_extra)
4015            en->cursor_user_extra = evas_object_textblock_cursor_new(rp->object);
4016          return en->cursor_user_extra;
4017       default:
4018          break;
4019      }
4020    return NULL;
4021 }
4022
4023 Eina_Bool
4024 _edje_entry_cursor_next(Edje_Real_Part *rp, Edje_Cursor cur)
4025 {
4026    Entry *en;
4027    Evas_Textblock_Cursor *c = _cursor_get(rp, cur);
4028    
4029    if ((rp->type != EDJE_RP_TYPE_TEXT) ||
4030        (!rp->typedata.text)) return EINA_FALSE;
4031    en = rp->typedata.text->entry_data;
4032    if (!en) return EINA_FALSE;
4033    
4034    if (!c) return EINA_FALSE;
4035
4036    _edje_entry_imf_context_reset(rp);
4037
4038    if (!evas_textblock_cursor_char_next(c))
4039      {
4040         return EINA_FALSE;
4041      }
4042    _sel_update(c, rp->object, rp->typedata.text->entry_data);
4043    _edje_entry_imf_cursor_info_set(en);
4044
4045    _edje_emit(rp->edje, "cursor,changed", rp->part->name);
4046    _edje_entry_real_part_configure(rp);
4047    return EINA_TRUE;
4048 }
4049
4050 Eina_Bool
4051 _edje_entry_cursor_prev(Edje_Real_Part *rp, Edje_Cursor cur)
4052 {
4053    Entry *en;
4054    Evas_Textblock_Cursor *c = _cursor_get(rp, cur);
4055    
4056    if ((rp->type != EDJE_RP_TYPE_TEXT) ||
4057        (!rp->typedata.text)) return EINA_FALSE;
4058    en = rp->typedata.text->entry_data;
4059    if (!en) return EINA_FALSE;
4060    if (!c) return EINA_FALSE;
4061
4062    _edje_entry_imf_context_reset(rp);
4063
4064    if (!evas_textblock_cursor_char_prev(c))
4065      {
4066         if (evas_textblock_cursor_paragraph_prev(c)) goto ok;
4067         else return EINA_FALSE;
4068      }
4069 ok:
4070    _sel_update(c, rp->object, rp->typedata.text->entry_data);
4071
4072    _edje_entry_imf_cursor_info_set(en);
4073
4074    _edje_emit(rp->edje, "cursor,changed", rp->part->name);
4075    _edje_entry_real_part_configure(rp);
4076    return EINA_TRUE;
4077 }
4078
4079 Eina_Bool
4080 _edje_entry_cursor_up(Edje_Real_Part *rp, Edje_Cursor cur)
4081 {
4082    Entry *en;
4083    Evas_Textblock_Cursor *c = _cursor_get(rp, cur);
4084    Evas_Coord lx, ly, lw, lh, cx, cy, cw, ch;
4085    int ln;
4086    
4087    if ((rp->type != EDJE_RP_TYPE_TEXT) ||
4088        (!rp->typedata.text)) return EINA_FALSE;
4089    en = rp->typedata.text->entry_data;
4090    if (!en) return EINA_FALSE;
4091    if (!c) return EINA_FALSE;
4092
4093    _edje_entry_imf_context_reset(rp);
4094
4095    ln = evas_textblock_cursor_line_geometry_get(c, NULL, NULL, NULL, NULL);
4096    ln--;
4097    if (ln < 0) return EINA_FALSE;
4098    if (!evas_object_textblock_line_number_geometry_get(rp->object, ln,
4099                                                        &lx, &ly, &lw, &lh))
4100      return EINA_FALSE;
4101    evas_textblock_cursor_char_geometry_get(c, &cx, &cy, &cw, &ch);
4102    if (!evas_textblock_cursor_char_coord_set(c, cx, ly + (lh / 2)))
4103      {
4104         if (cx < (lx + (lw / 2)))
4105           evas_textblock_cursor_line_char_last(c);
4106         else
4107           evas_textblock_cursor_line_char_last(c);
4108      }
4109    _sel_update(c, rp->object, rp->typedata.text->entry_data);
4110
4111    _edje_entry_imf_cursor_info_set(en);
4112
4113    _edje_emit(rp->edje, "cursor,changed", rp->part->name);
4114    _edje_entry_real_part_configure(rp);
4115    return EINA_TRUE;
4116 }
4117
4118 Eina_Bool
4119 _edje_entry_cursor_down(Edje_Real_Part *rp, Edje_Cursor cur)
4120 {
4121    Entry *en;
4122    Evas_Textblock_Cursor *c = _cursor_get(rp, cur);
4123    Evas_Coord lx, ly, lw, lh, cx, cy, cw, ch;
4124    int ln;
4125
4126    if ((rp->type != EDJE_RP_TYPE_TEXT) ||
4127        (!rp->typedata.text)) return EINA_FALSE;
4128    en = rp->typedata.text->entry_data;
4129    if (!en) return EINA_FALSE;
4130    if (!c) return EINA_FALSE;
4131
4132    _edje_entry_imf_context_reset(rp);
4133
4134    ln = evas_textblock_cursor_line_geometry_get(c, NULL, NULL, NULL, NULL);
4135    ln++;
4136    if (!evas_object_textblock_line_number_geometry_get(rp->object, ln,
4137                                                        &lx, &ly, &lw, &lh))
4138      return EINA_FALSE;
4139    evas_textblock_cursor_char_geometry_get(c, &cx, &cy, &cw, &ch);
4140    if (!evas_textblock_cursor_char_coord_set(c, cx, ly + (lh / 2)))
4141      {
4142         if (cx < (lx + (lw / 2)))
4143           evas_textblock_cursor_line_char_last(c);
4144         else
4145           evas_textblock_cursor_line_char_last(c);
4146      }
4147    _sel_update(c, rp->object, rp->typedata.text->entry_data);
4148
4149    _edje_entry_imf_cursor_info_set(en);
4150    _edje_emit(rp->edje, "cursor,changed", rp->part->name);
4151    _edje_entry_real_part_configure(rp);
4152    return EINA_TRUE;
4153 }
4154
4155 void
4156 _edje_entry_cursor_begin(Edje_Real_Part *rp, Edje_Cursor cur)
4157 {
4158    Entry *en;
4159    Evas_Textblock_Cursor *c = _cursor_get(rp, cur);
4160    
4161    if ((rp->type != EDJE_RP_TYPE_TEXT) ||
4162        (!rp->typedata.text)) return;
4163    en = rp->typedata.text->entry_data;
4164    if (!en) return;
4165    if (!c) return;
4166
4167    _edje_entry_imf_context_reset(rp);
4168
4169    evas_textblock_cursor_paragraph_first(c);
4170    _sel_update(c, rp->object, rp->typedata.text->entry_data);
4171
4172    _edje_entry_imf_cursor_info_set(en);
4173    _edje_emit(rp->edje, "cursor,changed", rp->part->name);
4174    _edje_entry_real_part_configure(rp);
4175 }
4176
4177 void
4178 _edje_entry_cursor_end(Edje_Real_Part *rp, Edje_Cursor cur)
4179 {
4180    Entry *en;
4181    Evas_Textblock_Cursor *c = _cursor_get(rp, cur);
4182    
4183    if ((rp->type != EDJE_RP_TYPE_TEXT) ||
4184        (!rp->typedata.text)) return;
4185    en = rp->typedata.text->entry_data;
4186    if (!en) return;
4187    if (!c) return;
4188
4189    _edje_entry_imf_context_reset(rp);
4190
4191    _curs_end(c, rp->object, rp->typedata.text->entry_data);
4192    _sel_update(c, rp->object, rp->typedata.text->entry_data);
4193
4194    _edje_entry_imf_cursor_info_set(en);
4195
4196    _edje_emit(rp->edje, "cursor,changed", rp->part->name);
4197    _edje_entry_real_part_configure(rp);
4198 }
4199
4200 void
4201 _edje_entry_cursor_copy(Edje_Real_Part *rp, Edje_Cursor cur, Edje_Cursor dst)
4202 {
4203    Entry *en;
4204    Evas_Textblock_Cursor *c;
4205    Evas_Textblock_Cursor *d;
4206
4207    if ((rp->type != EDJE_RP_TYPE_TEXT) ||
4208        (!rp->typedata.text)) return;
4209    en = rp->typedata.text->entry_data;
4210    if (!en) return;
4211    c = _cursor_get(rp, cur);
4212    if (!c) return;
4213    d = _cursor_get(rp, dst);
4214    if (!d) return;
4215    evas_textblock_cursor_copy(c, d);
4216    _sel_update(c, rp->object, rp->typedata.text->entry_data);
4217
4218    _edje_entry_imf_context_reset(rp);
4219    _edje_entry_imf_cursor_info_set(en);
4220    _edje_emit(rp->edje, "cursor,changed", rp->part->name);
4221    _edje_entry_real_part_configure(rp);
4222 }
4223
4224 void
4225 _edje_entry_cursor_line_begin(Edje_Real_Part *rp, Edje_Cursor cur)
4226 {
4227    Entry *en;
4228    Evas_Textblock_Cursor *c = _cursor_get(rp, cur);
4229    
4230    if ((rp->type != EDJE_RP_TYPE_TEXT) ||
4231        (!rp->typedata.text)) return;
4232    en = rp->typedata.text->entry_data;
4233    if (!en) return;
4234    if (!c) return;
4235    _edje_entry_imf_context_reset(rp);
4236
4237    evas_textblock_cursor_line_char_first(c);
4238    _sel_update(c, rp->object, rp->typedata.text->entry_data);
4239
4240    _edje_entry_imf_cursor_info_set(en);
4241
4242    _edje_emit(rp->edje, "cursor,changed", rp->part->name);
4243    _edje_entry_real_part_configure(rp);
4244 }
4245
4246 void
4247 _edje_entry_cursor_line_end(Edje_Real_Part *rp, Edje_Cursor cur)
4248 {
4249    Entry *en;
4250    Evas_Textblock_Cursor *c = _cursor_get(rp, cur);
4251    
4252    if ((rp->type != EDJE_RP_TYPE_TEXT) ||
4253        (!rp->typedata.text)) return;
4254    en = rp->typedata.text->entry_data;
4255    if (!en) return;
4256    if (!c) return;
4257    _edje_entry_imf_context_reset(rp);
4258    evas_textblock_cursor_line_char_last(c);
4259    _sel_update(c, rp->object, rp->typedata.text->entry_data);
4260
4261    _edje_entry_imf_cursor_info_set(en);
4262    _edje_emit(rp->edje, "cursor,changed", rp->part->name);
4263    _edje_entry_real_part_configure(rp);
4264 }
4265
4266 Eina_Bool
4267 _edje_entry_cursor_coord_set(Edje_Real_Part *rp, Edje_Cursor cur,
4268                              Evas_Coord x, Evas_Coord y)
4269 {
4270    Evas_Textblock_Cursor *c = _cursor_get(rp, cur);
4271    if (!c) return EINA_FALSE;
4272    return evas_textblock_cursor_char_coord_set(c, x, y);
4273 }
4274
4275 Eina_Bool
4276 _edje_entry_cursor_is_format_get(Edje_Real_Part *rp, Edje_Cursor cur)
4277 {
4278    Evas_Textblock_Cursor *c = _cursor_get(rp, cur);
4279    if (!c) return EINA_FALSE;
4280    if (evas_textblock_cursor_is_format(c)) return EINA_TRUE;
4281    return EINA_FALSE;
4282 }
4283
4284 Eina_Bool
4285 _edje_entry_cursor_is_visible_format_get(Edje_Real_Part *rp, Edje_Cursor cur)
4286 {
4287    Evas_Textblock_Cursor *c = _cursor_get(rp, cur);
4288    if (!c) return EINA_FALSE;
4289    return evas_textblock_cursor_format_is_visible_get(c);
4290 }
4291
4292 char *
4293 _edje_entry_cursor_content_get(Edje_Real_Part *rp, Edje_Cursor cur)
4294 {
4295    static char *s = NULL;
4296    Evas_Textblock_Cursor *c = _cursor_get(rp, cur);
4297
4298    if (!c) return NULL;
4299    if (s)
4300      {
4301         free(s);
4302         s = NULL;
4303      }
4304
4305    s = evas_textblock_cursor_content_get(c);
4306    return s;
4307 }
4308
4309 void
4310 _edje_entry_cursor_pos_set(Edje_Real_Part *rp, Edje_Cursor cur, int pos)
4311 {
4312    Entry *en;
4313    Evas_Textblock_Cursor *c = _cursor_get(rp, cur);
4314    
4315    if ((rp->type != EDJE_RP_TYPE_TEXT) ||
4316        (!rp->typedata.text)) return;
4317    en = rp->typedata.text->entry_data;
4318    if (!en) return;
4319    if (!c) return;
4320    /* Abort if cursor position didn't really change */
4321    if (evas_textblock_cursor_pos_get(c) == pos)
4322      return;
4323
4324    _edje_entry_imf_context_reset(rp);
4325    evas_textblock_cursor_pos_set(c, pos);
4326    _sel_update(c, rp->object, rp->typedata.text->entry_data);
4327
4328    _edje_emit(rp->edje, "cursor,changed", rp->part->name);
4329    // TIZEN ONLY(130129) : Currently, for freezing cursor movement.
4330    if (!en->freeze)
4331      {
4332         _edje_entry_imf_cursor_info_set(en);
4333         _edje_entry_real_part_configure(rp);
4334      }
4335    //
4336 }
4337
4338 int
4339 _edje_entry_cursor_pos_get(Edje_Real_Part *rp, Edje_Cursor cur)
4340 {
4341    Evas_Textblock_Cursor *c = _cursor_get(rp, cur);
4342    if (!c) return 0;
4343    return evas_textblock_cursor_pos_get(c);
4344 }
4345
4346 // TIZEN ONLY - START
4347 Eina_Bool
4348 _edje_entry_selection_geometry_get(Edje_Real_Part *rp, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h)
4349 {
4350    Entry *en = rp->typedata.text->entry_data;
4351    if (!en || !en->have_selection || !en->sel)
4352      return EINA_FALSE;
4353
4354    Sel *sel;
4355    Eina_List *l;
4356    Evas_Textblock_Rectangle rect;
4357    Evas_Coord tx, ty, tw, th;
4358
4359    l = en->sel;
4360    if (!l) return EINA_FALSE;
4361    sel = eina_list_data_get(l);
4362    if (!sel) return EINA_FALSE;
4363    rect = sel->rect;
4364    ty = rect.y;
4365    tw = rect.w;
4366
4367    l = eina_list_last(en->sel);
4368    if (!l) return EINA_FALSE;
4369    sel = eina_list_data_get(l);
4370    if (!sel) return EINA_FALSE;
4371    rect = sel->rect;
4372
4373    tx = rect.x;
4374    th = rect.y - ty + rect.h;
4375
4376    EINA_LIST_FOREACH(en->sel, l, sel)
4377      {
4378         if (sel)
4379           {
4380              if (tw < sel->rect.w) tw = sel->rect.w;
4381              if (sel->rect.x < tx) tx = sel->rect.x;
4382           }
4383      }
4384
4385    Evas_Coord vx, vy;
4386    evas_object_geometry_get(rp->object, &vx, &vy, NULL, NULL);
4387    tx += vx;
4388    ty += vy;
4389
4390    if (x) *x = tx;
4391    if (y) *y = ty;
4392    if (w) *w = tw;
4393    if (h) *h = th;
4394
4395    return EINA_TRUE;
4396 }
4397 // TIZEN ONLY - END
4398
4399 void
4400 _edje_entry_input_panel_layout_set(Edje_Real_Part *rp, Edje_Input_Panel_Layout layout)
4401 {
4402    Entry *en;
4403    
4404    if ((rp->type != EDJE_RP_TYPE_TEXT) ||
4405        (!rp->typedata.text)) return;
4406    en = rp->typedata.text->entry_data;
4407    if (!en) return;
4408 #ifdef HAVE_ECORE_IMF
4409    if (en->imf_context)
4410      ecore_imf_context_input_panel_layout_set(en->imf_context, layout);
4411 #else
4412    (void) layout;
4413 #endif
4414 }
4415
4416 Edje_Input_Panel_Layout
4417 _edje_entry_input_panel_layout_get(Edje_Real_Part *rp)
4418 {
4419    Entry *en;
4420    
4421    if ((rp->type != EDJE_RP_TYPE_TEXT) ||
4422        (!rp->typedata.text)) return EDJE_INPUT_PANEL_LAYOUT_INVALID;
4423    en = rp->typedata.text->entry_data;
4424    if (!en) return EDJE_INPUT_PANEL_LAYOUT_INVALID;
4425 #ifdef HAVE_ECORE_IMF
4426    if (en->imf_context)
4427      return ecore_imf_context_input_panel_layout_get(en->imf_context);
4428 #endif
4429
4430    return EDJE_INPUT_PANEL_LAYOUT_INVALID;
4431 }
4432
4433 void
4434 _edje_entry_imf_context_reset(Edje_Real_Part *rp)
4435 {
4436    Entry *en;
4437    
4438    if ((rp->type != EDJE_RP_TYPE_TEXT) ||
4439        (!rp->typedata.text)) return;
4440    en = rp->typedata.text->entry_data;
4441    if (!en) return;
4442 #ifdef HAVE_ECORE_IMF
4443    if (en->imf_context)
4444      ecore_imf_context_reset(en->imf_context);
4445    if (en->commit_cancel)
4446       en->commit_cancel = EINA_FALSE;
4447 #endif
4448 }
4449
4450 static void
4451 _edje_entry_imf_cursor_location_set(Entry *en)
4452 {
4453 #ifdef HAVE_ECORE_IMF
4454    Evas_Coord cx, cy, cw, ch;
4455    if (!en || !en->rp || !en->imf_context) return;
4456
4457    _edje_entry_cursor_geometry_get(en->rp, &cx, &cy, &cw, &ch);
4458    ecore_imf_context_cursor_location_set(en->imf_context, cx, cy, cw, ch);
4459 #else
4460    (void) en;
4461 #endif
4462 }
4463
4464 static void
4465 _edje_entry_imf_cursor_info_set(Entry *en)
4466 {
4467    int cursor_pos;
4468
4469 #ifdef HAVE_ECORE_IMF
4470    if (!en || !en->rp || !en->imf_context) return;
4471
4472    if (en->have_selection)
4473      {
4474         if (evas_textblock_cursor_compare(en->sel_start, en->sel_end) < 0)
4475           cursor_pos = evas_textblock_cursor_pos_get(en->sel_start);
4476         else
4477           cursor_pos = evas_textblock_cursor_pos_get(en->sel_end);
4478      }
4479    else
4480      cursor_pos = evas_textblock_cursor_pos_get(en->cursor);
4481
4482    ecore_imf_context_cursor_position_set(en->imf_context, cursor_pos);
4483
4484    _edje_entry_imf_cursor_location_set(en);
4485 #else
4486    (void) en;
4487 #endif
4488 }
4489
4490 #ifdef HAVE_ECORE_IMF
4491 static Eina_Bool
4492 _edje_entry_imf_retrieve_surrounding_cb(void *data, Ecore_IMF_Context *ctx __UNUSED__, char **text, int *cursor_pos)
4493 {
4494    Edje *ed = data;
4495    Edje_Real_Part *rp = ed->focused_part;
4496    Entry *en = NULL;
4497    const char *str;
4498    char *plain_text;
4499
4500    if (!rp) return EINA_FALSE;
4501    if ((rp->type != EDJE_RP_TYPE_TEXT) ||
4502        (!rp->typedata.text)) return EINA_FALSE;
4503    else
4504      en = rp->typedata.text->entry_data;
4505    if ((!en) || (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK) ||
4506        (rp->part->entry_mode < EDJE_ENTRY_EDIT_MODE_SELECTABLE))
4507      return EINA_FALSE;
4508
4509    if (text)
4510      {
4511         str = _edje_entry_text_get(rp);
4512         if (str)
4513           plain_text = evas_textblock_text_markup_to_utf8(NULL, str);
4514         else
4515           plain_text = strdup("");
4516         *text = plain_text;
4517      }
4518
4519    if (cursor_pos)
4520      *cursor_pos = evas_textblock_cursor_pos_get(en->cursor);
4521
4522    return EINA_TRUE;
4523 }
4524
4525 static void
4526 _edje_entry_imf_event_commit_cb(void *data, Ecore_IMF_Context *ctx __UNUSED__, void *event_info)
4527 {
4528    Edje *ed = data;
4529    Edje_Real_Part *rp = ed->focused_part;
4530    Entry *en = NULL;
4531    char *commit_str = event_info;
4532    int start_pos;
4533
4534    if ((!rp)) return;
4535    if ((rp->type != EDJE_RP_TYPE_TEXT) ||
4536        (!rp->typedata.text)) return;
4537    else
4538      en = rp->typedata.text->entry_data;
4539    if ((!en) || (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK) ||
4540        (rp->part->entry_mode < EDJE_ENTRY_EDIT_MODE_SELECTABLE))
4541      return;
4542
4543    if (en->have_selection)
4544      {
4545         if (strcmp(commit_str, ""))
4546           {
4547              /* delete selected characters */
4548              _range_del_emit(ed, en->cursor, rp->object, en);
4549              _sel_clear(en->cursor, rp->object, en);
4550           }
4551      }
4552
4553    start_pos = evas_textblock_cursor_pos_get(en->cursor);
4554
4555    /* delete preedit characters */
4556    _preedit_del(en);
4557    _preedit_clear(en);
4558
4559    // Skipping commit process when it is useless
4560    if (en->commit_cancel)
4561      {
4562         en->commit_cancel = EINA_FALSE;
4563         return;
4564      }
4565
4566    if ((rp->part->entry_mode == EDJE_ENTRY_EDIT_MODE_PASSWORD) &&
4567        _edje_password_show_last)
4568      _edje_entry_hide_visible_password(en->rp);
4569    if ((rp->part->entry_mode == EDJE_ENTRY_EDIT_MODE_PASSWORD) &&
4570        _edje_password_show_last && (!en->preedit_start))
4571      {
4572         _text_filter_format_prepend(en, en->cursor, "+ password=off");
4573         _text_filter_text_prepend(en, en->cursor, commit_str);
4574         _text_filter_format_prepend(en, en->cursor, "- password");
4575
4576         if (en->pw_timer)
4577           {
4578              ecore_timer_del(en->pw_timer);
4579              en->pw_timer = NULL;
4580           }
4581         en->pw_timer = ecore_timer_add(TO_DOUBLE(_edje_password_show_last_timeout),
4582                                        _password_timer_cb, en);
4583      }
4584    else
4585      _text_filter_text_prepend(en, en->cursor, commit_str);
4586
4587
4588    _edje_entry_imf_cursor_info_set(en);
4589    _anchors_get(en->cursor, rp->object, en);
4590    _edje_emit(rp->edje, "entry,changed", rp->part->name);
4591
4592      {
4593         Edje_Entry_Change_Info *info = calloc(1, sizeof(*info));
4594         info->insert = EINA_TRUE;
4595         info->change.insert.pos = start_pos;
4596         info->change.insert.content = eina_stringshare_add(commit_str);
4597         info->change.insert.plain_length =
4598            eina_unicode_utf8_get_len(info->change.insert.content);
4599         _edje_emit_full(ed, "entry,changed,user", rp->part->name,
4600                         info, _free_entry_change_info);
4601         _edje_emit(ed, "cursor,changed", rp->part->name);
4602      }
4603
4604    _edje_entry_imf_cursor_info_set(en);
4605    _edje_entry_real_part_configure(rp);
4606 }
4607
4608 static void
4609 _edje_entry_imf_event_preedit_changed_cb(void *data, Ecore_IMF_Context *ctx __UNUSED__, void *event_info __UNUSED__)
4610 {
4611    Edje *ed = data;
4612    Edje_Real_Part *rp = ed->focused_part;
4613    Entry *en = NULL;
4614    int cursor_pos;
4615    int preedit_start_pos, preedit_end_pos;
4616    char *preedit_string;
4617    char *preedit_tag_index;
4618    char *pretag = NULL;
4619    char *markup_txt = NULL;
4620    char *tagname[] = {NULL, "preedit", "preedit_sel", "preedit_sel",
4621                       "preedit_sub1", "preedit_sub2", "preedit_sub3", "preedit_sub4"};
4622    int i;
4623    size_t preedit_type_size = sizeof(tagname) / sizeof(tagname[0]);
4624    Eina_Bool preedit_end_state = EINA_FALSE;
4625    Eina_List *attrs = NULL, *l = NULL;
4626    Ecore_IMF_Preedit_Attr *attr;
4627    Eina_Strbuf *buf;
4628    Eina_Strbuf *preedit_attr_str;
4629
4630    if ((!rp)) return;
4631
4632    if ((rp->type != EDJE_RP_TYPE_TEXT) ||
4633        (!rp->typedata.text)) return;
4634    else
4635      en = rp->typedata.text->entry_data;
4636    if ((!en) || (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK) ||
4637        (rp->part->entry_mode < EDJE_ENTRY_EDIT_MODE_SELECTABLE))
4638      return;
4639
4640    if (!en->imf_context) return;
4641
4642    ecore_imf_context_preedit_string_with_attributes_get(en->imf_context,
4643                                                         &preedit_string,
4644                                                         &attrs, &cursor_pos);
4645    if (!preedit_string) return;
4646
4647    if (!strcmp(preedit_string, ""))
4648      preedit_end_state = EINA_TRUE;
4649
4650    if (en->have_selection && !preedit_end_state)
4651      {
4652         /* delete selected characters */
4653         _range_del_emit(ed, en->cursor, rp->object, en);
4654      }
4655
4656    if (en->preedit_start && en->preedit_end)
4657      {
4658         /* extract the tag string */
4659         char *str = evas_textblock_cursor_range_text_get(en->preedit_start, en->preedit_end, EVAS_TEXTBLOCK_TEXT_MARKUP);
4660
4661         if (str)
4662           {
4663              preedit_tag_index = strstr(str, "<preedit");
4664
4665              if ((preedit_tag_index - str) > 0)
4666                {
4667                   pretag = calloc(1, sizeof(char)*(preedit_tag_index-str+1));
4668                   if (preedit_tag_index)
4669                     {
4670                        strncpy(pretag, str, preedit_tag_index-str);
4671                     }
4672                }
4673              free(str);
4674           }
4675      }
4676
4677    /* delete preedit characters */
4678    _preedit_del(en);
4679
4680    preedit_start_pos = evas_textblock_cursor_pos_get(en->cursor);
4681
4682    /* restore previous tag */
4683    if (pretag)
4684      {
4685         _text_filter_markup_prepend(en, en->cursor, pretag);
4686         free(pretag);
4687      }
4688
4689    /* insert preedit character(s) */
4690    if (strlen(preedit_string) > 0)
4691      {
4692         buf = eina_strbuf_new();
4693         if (attrs)
4694           {
4695              EINA_LIST_FOREACH(attrs, l, attr)
4696                {
4697                   if (attr->preedit_type <= preedit_type_size &&
4698                       tagname[attr->preedit_type])
4699                     {
4700                        preedit_attr_str = eina_strbuf_new();
4701                        if (preedit_attr_str)
4702                          {
4703                             eina_strbuf_append_n(preedit_attr_str, preedit_string + attr->start_index, attr->end_index - attr->start_index);
4704                             markup_txt = evas_textblock_text_utf8_to_markup(NULL, eina_strbuf_string_get(preedit_attr_str));
4705
4706                             if (markup_txt)
4707                               {
4708                                  eina_strbuf_append_printf(buf, "<%s>%s</%s>", tagname[attr->preedit_type], markup_txt, tagname[attr->preedit_type]);
4709                                  free(markup_txt);
4710                               }
4711                             eina_strbuf_free(preedit_attr_str);
4712                          }
4713                     }
4714                   else
4715                     eina_strbuf_append(buf, preedit_string);
4716                }
4717           }
4718         else
4719           {
4720              eina_strbuf_append(buf, preedit_string);
4721           }
4722
4723         // For skipping useless commit
4724         if (!preedit_end_state)
4725            en->have_preedit = EINA_TRUE;
4726
4727         if ((rp->part->entry_mode == EDJE_ENTRY_EDIT_MODE_PASSWORD) &&
4728             _edje_password_show_last)
4729           {
4730              _edje_entry_hide_visible_password(en->rp);
4731              _text_filter_format_prepend(en, en->cursor, "+ password=off");
4732              _text_filter_markup_prepend(en, en->cursor, eina_strbuf_string_get(buf));
4733              _text_filter_format_prepend(en, en->cursor, "- password");
4734              if (en->pw_timer)
4735                {
4736                   ecore_timer_del(en->pw_timer);
4737                   en->pw_timer = NULL;
4738                }
4739              en->pw_timer = ecore_timer_add(TO_DOUBLE(_edje_password_show_last_timeout),
4740                                             _password_timer_cb, en);
4741           }
4742         else
4743           {
4744              _text_filter_markup_prepend(en, en->cursor, eina_strbuf_string_get(buf));
4745           }
4746         eina_strbuf_free(buf);
4747      }
4748
4749    if (!preedit_end_state)
4750      {
4751         /* set preedit start cursor */
4752         if (!en->preedit_start)
4753           en->preedit_start = evas_object_textblock_cursor_new(rp->object);
4754         evas_textblock_cursor_copy(en->cursor, en->preedit_start);
4755
4756         /* set preedit end cursor */
4757         if (!en->preedit_end)
4758           en->preedit_end = evas_object_textblock_cursor_new(rp->object);
4759         evas_textblock_cursor_copy(en->cursor, en->preedit_end);
4760
4761         preedit_end_pos = evas_textblock_cursor_pos_get(en->cursor);
4762
4763         for (i = 0; i < (preedit_end_pos - preedit_start_pos); i++)
4764           {
4765              evas_textblock_cursor_char_prev(en->preedit_start);
4766           }
4767
4768         en->have_preedit = EINA_TRUE;
4769
4770         /* set cursor position */
4771         evas_textblock_cursor_pos_set(en->cursor, preedit_start_pos + cursor_pos);
4772      }
4773
4774    _edje_entry_imf_cursor_info_set(en);
4775    _anchors_get(en->cursor, rp->object, en);
4776    _edje_emit(rp->edje, "preedit,changed", rp->part->name);
4777    _edje_emit(ed, "cursor,changed", rp->part->name);
4778
4779    /* delete attribute list */
4780    if (attrs)
4781      {
4782         EINA_LIST_FREE(attrs, attr) free(attr);
4783      }
4784
4785    free(preedit_string);
4786 }
4787
4788 static void
4789 _edje_entry_imf_event_delete_surrounding_cb(void *data, Ecore_IMF_Context *ctx __UNUSED__, void *event_info)
4790 {
4791    Edje *ed = data;
4792    Edje_Real_Part *rp = ed->focused_part;
4793    Entry *en = NULL;
4794    Ecore_IMF_Event_Delete_Surrounding *ev = event_info;
4795    Evas_Textblock_Cursor *del_start, *del_end;
4796    int cursor_pos;
4797
4798    if ((!rp) || (!ev)) return;
4799    if ((rp->type != EDJE_RP_TYPE_TEXT) ||
4800        (!rp->typedata.text)) return;
4801    else
4802      en = rp->typedata.text->entry_data;
4803    if ((!en) || (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK) ||
4804        (rp->part->entry_mode < EDJE_ENTRY_EDIT_MODE_SELECTABLE))
4805      return;
4806
4807    cursor_pos = evas_textblock_cursor_pos_get(en->cursor);
4808
4809    del_start = evas_object_textblock_cursor_new(en->rp->object);
4810    evas_textblock_cursor_pos_set(del_start, cursor_pos + ev->offset);
4811
4812    del_end = evas_object_textblock_cursor_new(en->rp->object);
4813    evas_textblock_cursor_pos_set(del_end, cursor_pos + ev->offset + ev->n_chars);
4814
4815    evas_textblock_cursor_range_delete(del_start, del_end);
4816
4817    evas_textblock_cursor_free(del_start);
4818    evas_textblock_cursor_free(del_end);
4819 }
4820 #endif
4821
4822
4823 //////////////////////////////////////  TIZEN ONLY(130129)  : START //////////////////////////////////
4824 void _edje_entry_freeze(Edje_Real_Part *rp)
4825 {
4826    Entry *en = NULL;
4827
4828    if ((rp->type != EDJE_RP_TYPE_TEXT) ||
4829        (!rp->typedata.text)) return;
4830
4831    en = rp->typedata.text->entry_data;
4832    if (!en) return;
4833
4834    en->freeze = EINA_TRUE;
4835 }
4836
4837 void _edje_entry_thaw(Edje_Real_Part *rp)
4838 {
4839    Entry *en = NULL;
4840
4841    if ((rp->type != EDJE_RP_TYPE_TEXT) ||
4842        (!rp->typedata.text)) return;
4843
4844    en = rp->typedata.text->entry_data;
4845    if (!en) return;
4846
4847    en->freeze = EINA_FALSE;
4848
4849    _edje_entry_imf_cursor_info_set(en);
4850    _edje_entry_real_part_configure(rp);
4851 }
4852 ///////////////////////////////////////////  TIZEN ONLY : END   ////////////////////////////////////////
4853
4854 /* vim:set ts=8 sw=3 sts=3 expandtab cino=>5n-2f0^-2{2(0W1st0 :*/