Revise code to handle IME hide key
[platform/core/uifw/isf.git] / ism / extras / wayland_immodule / wayland_imcontext.c
1 /*
2  * Copyright © 2012, 2013 Intel Corporation
3  *
4  * Permission to use, copy, modify, distribute, and sell this software and
5  * its documentation for any purpose is hereby granted without fee, provided
6  * that the above copyright notice appear in all copies and that both that
7  * copyright notice and this permission notice appear in supporting
8  * documentation, and that the name of the copyright holders not be used in
9  * advertising or publicity pertaining to distribution of the software
10  * without specific, written prior permission.  The copyright holders make
11  * no representations about the suitability of this software for any
12  * purpose.  It is provided "as is" without express or implied warranty.
13  *
14  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
15  * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
16  * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
17  * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
18  * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
19  * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
20  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21  */
22
23 #include "scim_private.h"
24 #include <unistd.h>
25
26 #include <Ecore.h>
27 #include <Ecore_Evas.h>
28 #include <Ecore_Input.h>
29 #define EFL_BETA_API_SUPPORT
30 #include <Ecore_Wl2.h>
31 #include <dlog.h>
32 #include <wctype.h>
33 #include <app_common.h>
34 #ifdef HAVE_VCONF
35 #include <vconf.h>
36 #endif
37 #include <stdlib.h>
38 #include <string.h>
39 #include <sys/types.h>
40 #include <sys/socket.h>
41 #include <sys/un.h>
42 #include <sys/time.h>
43 #include <fcntl.h>
44
45 #include "isf_debug.h"
46 #include "wayland_imcontext.h"
47 #include "tizen_profile.h"
48 #include "isf_device_event.h"
49
50 #ifdef LOG_TAG
51 # undef LOG_TAG
52 #endif
53 #define LOG_TAG "IMMODULE"
54
55 #define IME_DEVICE_NAME "ime"
56
57 #define HIDE_TIMER_INTERVAL     0.05
58 #define WAIT_FOR_FILTER_DONE_SECOND 1.3
59
60 #define MOD_SHIFT_MASK      0x01
61 #define MOD_CAPS_MASK       0x02
62 #define MOD_CONTROL_MASK    0x04
63 #define MOD_ALT_MASK        0x08
64 #define MOD_NUM_MASK        0x100
65 #define MOD_Mod5_MASK       0x80
66
67 #define VCONFKEY_AUTOPERIOD_ALLOW_BOOL  "file/private/isf/autoperiod_allow"
68 #define VCONFKEY_AUTOCAPITAL_ALLOW_BOOL "file/private/isf/autocapital_allow"
69 #define SOCK_PATH "/run/.isf/scim-panel-socket"
70
71 typedef enum {
72     INPUT_LANG_URDU,
73     INPUT_LANG_HINDI,
74     INPUT_LANG_BENGALI_IN,
75     INPUT_LANG_BENGALI_BD,
76     INPUT_LANG_ASSAMESE,
77     INPUT_LANG_PUNJABI,
78     INPUT_LANG_NEPALI,
79     INPUT_LANG_ORIYA,
80     INPUT_LANG_MAITHILI,
81     INPUT_LANG_ARMENIAN,
82     INPUT_LANG_CN,
83     INPUT_LANG_CN_HK,
84     INPUT_LANG_CN_TW,
85     INPUT_LANG_JAPANESE,
86     INPUT_LANG_KHMER,
87     INPUT_LANG_KOREAN,
88     INPUT_LANG_BURMESE,
89     INPUT_LANG_OTHER,
90     INPUT_LANG_ASSAMESE_BN,
91     INPUT_LANG_BENGALI_AS,
92     INPUT_LANG_BODO,
93     INPUT_LANG_DOGRI,
94     INPUT_LANG_MANIPURI,
95     INPUT_LANG_MANIPURI_AS,
96     INPUT_LANG_MANIPURI_BN,
97     INPUT_LANG_KONKANI,
98     INPUT_LANG_SINDHI
99 } Input_Language;
100
101 const double DOUBLE_SPACE_INTERVAL = 1.0;
102
103 static Eina_Bool _clear_hide_timer();
104 static Ecore_Timer *_hide_timer  = NULL;
105
106 static const char *_ecore_imf_event_empty = "";
107
108 static Eina_Bool             will_hide = EINA_FALSE;
109 static Eina_Bool             ignore_hide = EINA_FALSE;
110
111 static Ecore_Event_Filter   *_ecore_event_filter_handler = NULL;
112 static Ecore_IMF_Context    *_focused_ctx                = NULL;
113 static Ecore_IMF_Context    *_show_req_ctx               = NULL;
114 static Ecore_IMF_Context    *_hide_req_ctx               = NULL;
115 static Ecore_IMF_Context    *_focus_req_ctx              = NULL;
116 static Ecore_IMF_Context    *_input_panel_ctx            = NULL;
117 static Eina_Bool             _focus_req_only             = EINA_TRUE;
118
119 static Eina_Rectangle        _keyboard_geometry = {0, 0, 0, 0};
120
121 static Ecore_IMF_Input_Panel_State _input_panel_state    = ECORE_IMF_INPUT_PANEL_STATE_HIDE;
122 static Ecore_Event_Handler *_win_focus_out_handler       = NULL;
123 static Ecore_Event_Handler *_conformant_change_handler   = NULL;
124
125 static Eina_Bool             _custom_conformant_event     = EINA_FALSE;
126 static Eina_Bool             _received_will_hide_event    = EINA_FALSE;
127 static Eina_Bool             _conformant_reset_done       = EINA_FALSE;
128 static Eina_Bool             _conformant_reset_started    = EINA_FALSE;
129 static Evas                 *_active_context_canvas       = NULL;
130 static unsigned int          _active_context_window_id    = 0;
131
132 static Ecore_Device         *_ime_device = NULL;
133
134 static double                space_key_time               = 0.0;
135 static Eina_Bool             autoperiod_allow             = EINA_FALSE;
136 static Eina_Bool             autocap_allow                = EINA_FALSE;
137 static Eina_Bool             hw_keyboard_mode             = EINA_FALSE;
138 static Eina_Bool             _preedit_cursor_changed      = EINA_FALSE;
139
140 static Input_Language        input_lang                   = INPUT_LANG_OTHER;
141 static Evas_Coord            g_scr_w = 0, g_scr_h = 0;
142
143 static void set_autocapital (Ecore_IMF_Context *ctx);
144
145 static Eina_Bool g_key_rate_checked = EINA_FALSE, g_focused = EINA_FALSE;
146 static double g_original_key_rate = 0.0, g_original_key_delay = 0.0, g_desired_key_rate = 0.0;
147 //
148
149 typedef struct __LanguageInfo {
150     const char *code;
151     Input_Language lang;
152     Eina_Unicode punc_code;
153 } LanguageInfo;
154
155 static LanguageInfo __language_infos [] = {
156     { "ur_PK",  INPUT_LANG_URDU,        0x06D4 },
157     { "hi_IN",  INPUT_LANG_HINDI,       0x0964 },
158     { "bn_IN",  INPUT_LANG_BENGALI_IN,  0x0964 },
159     { "bn_BD",  INPUT_LANG_BENGALI_BD,  0x0964 },
160     { "as_IN",  INPUT_LANG_ASSAMESE,    0x0964 },
161     { "pa_IN",  INPUT_LANG_PUNJABI,     0x0964 },
162     { "ne_NP",  INPUT_LANG_NEPALI,      0x0964 },
163     { "or_IN",  INPUT_LANG_ORIYA,       0x0964 },
164     { "mai_IN", INPUT_LANG_MAITHILI,    0x0964 },
165     { "hy_AM",  INPUT_LANG_ARMENIAN,    0x0589 },
166     { "zh_CN",  INPUT_LANG_CN,          0x3002 },
167     { "zh_HK",  INPUT_LANG_CN_HK,       0x3002 },
168     { "zh_TW",  INPUT_LANG_CN_TW,       0x3002 },
169     { "ja_JP",  INPUT_LANG_JAPANESE,    0x3002 },
170     { "km_KH",  INPUT_LANG_KHMER,       0x17D4 },
171     { "ko_KR",  INPUT_LANG_KOREAN,      0x002E },
172     { "asb_IN", INPUT_LANG_ASSAMESE_BN, 0x0964 },
173     { "bna_IN", INPUT_LANG_BENGALI_AS,  0x0964 },
174     { "brx_IN", INPUT_LANG_BODO,        0x0964 },
175     { "doi_IN", INPUT_LANG_DOGRI,       0x0964 },
176     { "mni_IN", INPUT_LANG_MANIPURI,    0xabeb },
177     { "mnia_IN",INPUT_LANG_MANIPURI_AS, 0x0964 },
178     { "mnib_IN",INPUT_LANG_MANIPURI_BN, 0x0964 },
179     { "kok_IN", INPUT_LANG_KONKANI,     0x0964 },
180     { "sd_IN",  INPUT_LANG_SINDHI,      0x0964 },
181 };
182
183 static const char *hide_keys [] = {
184     "Escape",
185     "XF86Back", // BACK_KEY
186     "XF86Stop"  // OLD_BACK_KEY
187 };
188
189 struct _WaylandIMContext
190 {
191     Ecore_IMF_Context *ctx;
192
193     struct wl_text_input_manager *text_input_manager;
194     struct wl_text_input *text_input;
195
196     Ecore_Wl2_Window *window;
197     Ecore_Wl2_Input  *input;
198     Evas            *canvas;
199
200     char *preedit_text;
201     char *preedit_commit;
202     char *language;
203     Eina_List *preedit_attrs;
204     int32_t preedit_cursor;
205
206     struct
207     {
208         Eina_List *attrs;
209         int32_t cursor;
210     } pending_preedit;
211
212     int32_t cursor_position;
213
214     struct
215     {
216         int x;
217         int y;
218         int width;
219         int height;
220     } cursor_location;
221
222     xkb_mod_mask_t control_mask;
223     xkb_mod_mask_t alt_mask;
224     xkb_mod_mask_t shift_mask;
225     xkb_mod_mask_t caps_mask;
226     xkb_mod_mask_t num_mask;
227
228     uint32_t serial;
229     uint32_t content_purpose;
230     uint32_t content_hint;
231     Ecore_IMF_Input_Panel_Layout input_panel_layout;
232
233     // TIZEN_ONLY(20150716): Support return key type
234     uint32_t return_key_type;
235
236     Eina_Bool return_key_disabled;
237
238     void *imdata;
239     uint32_t imdata_size;
240
241     uint32_t bidi_direction;
242
243     void *input_panel_data;
244     uint32_t input_panel_data_length;
245
246     struct
247     {
248         uint32_t serial;
249         uint32_t state;
250     } last_key_event_filter;
251     Eina_List *keysym_list;
252
253     uint32_t reset_serial;
254
255     Eina_Bool has_conformant;
256     char *prediction_hint;
257     char *mime_type;
258
259     struct
260     {
261         int x;
262         int y;
263     } input_panel_position;
264     //
265 };
266
267 typedef struct {
268     Ecore_IMF_Context *ctx;
269     WaylandIMContext *imcontext;
270 } Ecore_Imf_Wayland_Imcontext_Pair;
271 Eina_List *_ecore_imf_wayland_imcontext_pair_list = NULL;
272
273 static void _ecore_imf_wayland_imcontext_pair_add (Ecore_IMF_Context *ctx, WaylandIMContext *imcontext)
274 {
275     Ecore_Imf_Wayland_Imcontext_Pair *pair = malloc (sizeof (Ecore_Imf_Wayland_Imcontext_Pair));
276     if (pair) {
277         pair->ctx = ctx;
278         pair->imcontext = imcontext;
279
280         _ecore_imf_wayland_imcontext_pair_list = eina_list_append (_ecore_imf_wayland_imcontext_pair_list, pair);
281     }
282 }
283
284 static Ecore_Imf_Wayland_Imcontext_Pair* _ecore_imf_wayland_imcontext_pair_find (Ecore_IMF_Context *ctx)
285 {
286     Eina_List *l;
287     Ecore_Imf_Wayland_Imcontext_Pair *pair;
288     EINA_LIST_FOREACH (_ecore_imf_wayland_imcontext_pair_list, l, pair)
289         if (pair->ctx == ctx) {
290             return pair;
291         }
292     LOGE("The Ecore_Imf %p if not found in Ecore_IMF-WaylandIMContext pair list!!", ctx);
293     return NULL;
294 }
295
296 static void _ecore_imf_wayland_imcontext_pair_del (Ecore_IMF_Context *ctx)
297 {
298     Eina_List *l;
299     Eina_List *l_next;
300     Ecore_Imf_Wayland_Imcontext_Pair *pair;
301
302     EINA_LIST_FOREACH_SAFE (_ecore_imf_wayland_imcontext_pair_list, l, l_next, pair)
303         if (ctx == pair->ctx) {
304             free (pair);
305             _ecore_imf_wayland_imcontext_pair_list = eina_list_remove_list (_ecore_imf_wayland_imcontext_pair_list, l);
306         }
307 }
308
309 static void _ecore_imf_wayland_imcontext_pair_destroy ()
310 {
311     if (_ecore_imf_wayland_imcontext_pair_list) {
312         Ecore_Imf_Wayland_Imcontext_Pair *pair;
313         EINA_LIST_FREE (_ecore_imf_wayland_imcontext_pair_list, pair)
314             free (pair);
315         _ecore_imf_wayland_imcontext_pair_list = NULL;
316     }
317 }
318
319 static int _ecore_imf_wayland_imcontext_pair_log ()
320 {
321     char buffer[255] = { '\0' };
322     int count = 0;
323     Eina_List *l;
324     Ecore_Imf_Wayland_Imcontext_Pair *pair;
325     EINA_LIST_FOREACH(_ecore_imf_wayland_imcontext_pair_list, l, pair) {
326         if (pair) {
327             snprintf(buffer + strlen(buffer), 255 - strlen(buffer), "%s[%p/%p]", (count ? "," : ""), pair->ctx, pair->imcontext);
328         }
329         count++;
330     }
331     if (count == 0) {
332         LOGD("No Ecore_Imf / Wayland_Imcontext pair found");
333     } else {
334         LOGD("%d Pair(s) : %s", count, buffer);
335     }
336
337     return count;
338 }
339
340 // TIZEN_ONLY(20150708): Support back key
341 static void _input_panel_hide(Ecore_IMF_Context *ctx, Eina_Bool instant);
342 static Eina_Bool show_input_panel(Ecore_IMF_Context *ctx);
343
344 static void
345 reset_keyboard_geometry ()
346 {
347     Ecore_Wl2_Display *wl2_display = ecore_wl2_connected_display_get(NULL);
348     if (wl2_display && (g_scr_w == 0 || g_scr_h == 0)) {
349         ecore_wl2_sync();
350         ecore_wl2_display_screen_size_get(wl2_display, &g_scr_w, &g_scr_h);
351     }
352     _keyboard_geometry.x = 0;
353     _keyboard_geometry.y = g_scr_h;
354     _keyboard_geometry.w = 0;
355     _keyboard_geometry.h = 0;
356 }
357
358 static void
359 _device_info_free (void *data EINA_UNUSED, void *ev)
360 {
361     Ecore_Event_Device_Info *e;
362
363     e = ev;
364     eina_stringshare_del (e->name);
365     eina_stringshare_del (e->identifier);
366     eina_stringshare_del (e->seatname);
367
368     free (e);
369 }
370
371 void
372 _device_info_send (unsigned int window, Eina_Bool flag)
373 {
374     Ecore_Event_Device_Info *e;
375
376     if (!(e = calloc (1, sizeof (Ecore_Event_Device_Info)))) return;
377
378     e->name = eina_stringshare_ref (IME_DEVICE_NAME);
379     e->identifier = eina_stringshare_ref (IME_DEVICE_NAME);
380     e->seatname = eina_stringshare_ref (IME_DEVICE_NAME);
381     e->clas = ECORE_DEVICE_CLASS_KEYBOARD;
382     e->subclas = ECORE_DEVICE_SUBCLASS_VIRTUAL_KEYBOARD;
383     e->window = window;
384
385     if (flag)
386         ecore_event_add (ECORE_EVENT_DEVICE_ADD, e, _device_info_free, NULL);
387     else
388         ecore_event_add (ECORE_EVENT_DEVICE_DEL, e, _device_info_free, NULL);
389 }
390
391 static void
392 set_input_language (const char *input_lang_str)
393 {
394     unsigned int i;
395     input_lang = INPUT_LANG_OTHER;
396
397     for (i = 0; i < (sizeof (__language_infos) / sizeof (__language_infos[0])); i++) {
398         if (strcmp (input_lang_str, __language_infos[i].code) == 0) {
399             input_lang = __language_infos[i].lang;
400             break;
401         }
402     }
403 }
404
405 static void autoperiod_allow_changed_cb (keynode_t *key, void* data)
406 {
407     autoperiod_allow = vconf_keynode_get_bool (key);
408 }
409
410 static void autocapital_allow_changed_cb (keynode_t *key, void* data)
411 {
412     autocap_allow = vconf_keynode_get_bool (key);
413 }
414
415 static void input_language_changed_cb (keynode_t *key, void* data)
416 {
417     char *input_lang = vconf_keynode_get_str (key);
418     if (input_lang) {
419         set_input_language (input_lang);
420         LOGD("input lang : %s", input_lang);
421     }
422 }
423
424 static Eina_Bool
425 check_symbol (Eina_Unicode ucode, Eina_Unicode symbols[], int symbol_num)
426 {
427     int i;
428     for (i = 0; i < symbol_num; i++) {
429         // Check symbol
430         if (ucode == symbols[i])
431             return EINA_TRUE;
432     }
433
434     return EINA_FALSE;
435 }
436
437 static Eina_Bool
438 check_space_symbol (Eina_Unicode uchar)
439 {
440     Eina_Unicode space_symbols[] = {' ', 0x00A0 /* no-break space */, 0x3000 /* ideographic space */};
441     const int symbol_num = sizeof (space_symbols) / sizeof (space_symbols[0]);
442
443     return check_symbol (uchar, space_symbols, symbol_num);
444 }
445
446 static void
447 autoperiod_insert (Ecore_IMF_Context *ctx)
448 {
449     char *plain_str = NULL;
450     int cursor_pos = 0;
451     Eina_Unicode *ustr = NULL;
452     Ecore_IMF_Event_Delete_Surrounding ev;
453     char *fullstop_mark = NULL;
454     size_t ulen = 0;
455     int del_chars = 0;
456     WaylandIMContext *imcontext = NULL;
457
458     if (autoperiod_allow == EINA_FALSE)
459         return;
460
461     if (!ctx) return;
462
463     Ecore_IMF_Input_Panel_Layout layout = ecore_imf_context_input_panel_layout_get (ctx);
464     if (layout != ECORE_IMF_INPUT_PANEL_LAYOUT_NORMAL)
465         return;
466
467     if ((ecore_time_get () - space_key_time) > DOUBLE_SPACE_INTERVAL)
468         goto done;
469
470     imcontext = (WaylandIMContext *)ecore_imf_context_data_get (ctx);
471     if (!imcontext) return;
472
473     ecore_imf_context_surrounding_get (ctx, &plain_str, NULL);
474     if (!plain_str) goto done;
475
476     cursor_pos = imcontext->cursor_position;
477
478     // Convert string from UTF-8 to unicode
479     ustr = eina_unicode_utf8_to_unicode (plain_str, NULL);
480     if (!ustr) goto done;
481
482     ulen = eina_unicode_strlen (ustr);
483
484     if (cursor_pos < 2 || cursor_pos > (int)ulen) {
485         LOGD ("invalid range. cursor pos : %d, length : %zu", cursor_pos, ulen);
486         goto done;
487     }
488
489     if (check_space_symbol (ustr[cursor_pos-1])) {
490         // any character (except space & punctuation) + press space key twice in short time
491         if (!(iswpunct (ustr[cursor_pos-2]) || check_space_symbol (ustr[cursor_pos-2])) &&
492             iswprint(ustr[cursor_pos-2])) {
493             del_chars = 1;
494         }
495         // any character (except space & punctuation) + space + press space key twice in short time
496         else if (cursor_pos >= 3 &&
497                  check_space_symbol (ustr[cursor_pos-2]) &&
498                  !(iswpunct (ustr[cursor_pos-3]) || check_space_symbol (ustr[cursor_pos-3])) &&
499                  iswprint(ustr[cursor_pos-3])) {
500             del_chars = 2;
501         }
502
503         if (del_chars > 0) {
504             ev.ctx = ctx;
505             ev.n_chars = del_chars;
506             ev.offset = del_chars * -1;
507
508             ecore_imf_context_event_callback_call (ctx, ECORE_IMF_CALLBACK_DELETE_SURROUNDING, &ev);
509
510             if (input_lang == INPUT_LANG_OTHER) {
511                 fullstop_mark = strdup (".");
512             }
513             else {
514                 Eina_Unicode wbuf[2] = {0};
515                 wbuf[0] = __language_infos[input_lang].punc_code;
516
517                 fullstop_mark = eina_unicode_unicode_to_utf8 (wbuf, NULL);
518             }
519
520             ecore_imf_context_event_callback_call (ctx, ECORE_IMF_CALLBACK_COMMIT, (void *)fullstop_mark);
521
522             if (fullstop_mark) {
523                 free (fullstop_mark);
524                 fullstop_mark = NULL;
525             }
526         }
527     }
528
529 done:
530     if (plain_str) free (plain_str);
531     if (ustr) free (ustr);
532     space_key_time = ecore_time_get ();
533 }
534
535 static Eina_Bool
536 check_except_autocapital (Eina_Unicode *ustr, int cursor_pos)
537 {
538     const char *except_str[] = {"e.g.", "E.g."};
539     unsigned int i = 0, j = 0, len = 0;
540     for (i = 0; i < (sizeof (except_str) / sizeof (except_str[0])); i++) {
541         len = strlen (except_str[i]);
542         if (cursor_pos < (int)len)
543             continue;
544
545         for (j = len; j > 0; j--) {
546             if (ustr[cursor_pos-j] != except_str[i][len-j])
547                 break;
548         }
549
550         if (j == 0) return EINA_TRUE;
551     }
552
553     return EINA_FALSE;
554 }
555
556 static Eina_Bool
557 analyze_surrounding_text (Ecore_IMF_Context *ctx)
558 {
559     char *plain_str = NULL;
560     Eina_Unicode puncs[] = {'\n','.', '!', '?', 0x00BF /* ¿ */, 0x00A1 /* ¡ */,
561                             0x3002 /* 。 */, 0x06D4 /* Urdu */, 0x0964 /* Hindi */,
562                             0x0589 /* Armenian */, 0x17D4 /* Khmer */, 0x104A /* Myanmar */};
563     Eina_Unicode *ustr = NULL;
564     Eina_Bool ret = EINA_FALSE;
565     Eina_Bool detect_space = EINA_FALSE;
566     int cursor_pos = 0;
567     int i = 0;
568     const int punc_num = sizeof (puncs) / sizeof (puncs[0]);
569     WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get (ctx);
570     if (!imcontext) return EINA_FALSE;
571
572     switch (ecore_imf_context_autocapital_type_get (ctx)) {
573         case ECORE_IMF_AUTOCAPITAL_TYPE_NONE:
574             return EINA_FALSE;
575         case ECORE_IMF_AUTOCAPITAL_TYPE_ALLCHARACTER:
576             return EINA_TRUE;
577         default:
578             break;
579     }
580
581     if (imcontext->preedit_text && strcmp (imcontext->preedit_text, "") != 0)
582         return EINA_FALSE;
583
584     if (imcontext->cursor_position == 0)
585         return EINA_TRUE;
586
587     ecore_imf_context_surrounding_get (ctx, &plain_str, &cursor_pos);
588
589     if (!plain_str) goto done;
590
591     if (cursor_pos == 0) {
592         ret = EINA_TRUE;
593         goto done;
594     }
595
596     // Convert string from UTF-8 to unicode
597     ustr = eina_unicode_utf8_to_unicode (plain_str, NULL);
598     if (!ustr) goto done;
599
600     if (eina_unicode_strlen (ustr) < (size_t)cursor_pos) goto done;
601
602     if (cursor_pos >= 1) {
603         if (ecore_imf_context_autocapital_type_get (ctx) == ECORE_IMF_AUTOCAPITAL_TYPE_WORD) {
604             // Check space or no-break space
605             if (check_space_symbol (ustr[cursor_pos-1])) {
606                 ret = EINA_TRUE;
607                 goto done;
608             }
609         }
610
611         // Check paragraph separator <PS> or carriage return  <br>
612         if ((ustr[cursor_pos-1] == 0x2029) || (ustr[cursor_pos-1] == '\n')) {
613             ret = EINA_TRUE;
614             goto done;
615         }
616
617         for (i = cursor_pos; i > 0; i--) {
618             // Check space or no-break space
619             if (check_space_symbol (ustr[i-1])) {
620                 detect_space = EINA_TRUE;
621                 continue;
622             }
623
624             // Check punctuation and following the continuous space(s)
625             if (detect_space && check_symbol (ustr[i-1], puncs, punc_num)) {
626                 if (check_except_autocapital (ustr, i))
627                     ret = EINA_FALSE;
628                 else
629                     ret = EINA_TRUE;
630
631                 goto done;
632             } else {
633                 ret = EINA_FALSE;
634                 goto done;
635             }
636         }
637
638         if ((i == 0) && (detect_space == EINA_TRUE)) {
639             // continuous space(s) without any character
640             ret = EINA_TRUE;
641             goto done;
642         }
643     }
644
645 done:
646     if (ustr) free (ustr);
647     if (plain_str) free (plain_str);
648
649     return ret;
650 }
651
652 static void
653 set_autocapital (Ecore_IMF_Context *ctx)
654 {
655     Eina_Bool uppercase = EINA_FALSE;
656
657     WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get (ctx);
658     if (!imcontext || !imcontext->text_input || !imcontext->input) return;
659
660     if (hw_keyboard_mode) return;
661
662     if (ecore_imf_context_input_panel_layout_get (ctx) != ECORE_IMF_INPUT_PANEL_LAYOUT_NORMAL)
663         return;
664
665     // Check autocapital type
666     if (ecore_imf_context_input_panel_caps_lock_mode_get (ctx)) {
667         uppercase = EINA_TRUE;
668     } else {
669         if (autocap_allow == EINA_FALSE)
670             return;
671
672         uppercase = analyze_surrounding_text (ctx);
673     }
674
675     LOGD ("ctx : %p, auto capital : %d", ctx, uppercase);
676     wl_text_input_set_capital_mode (imcontext->text_input, uppercase);
677 }
678
679 static Ecore_IMF_Context *
680 get_using_ctx ()
681 {
682     return (_show_req_ctx ? _show_req_ctx : _focused_ctx);
683 }
684
685 static Eina_Bool
686 check_hide_key(const char *keyname)
687 {
688     if (!keyname) return EINA_FALSE;
689
690     unsigned int i = 0;
691     for (i = 0; i < (sizeof(hide_keys) / sizeof(hide_keys[0])); i++) {
692         if (strcmp(keyname, hide_keys[i]) == 0) {
693             return EINA_TRUE;
694         }
695     }
696
697     return EINA_FALSE;
698 }
699
700 static unsigned int
701 _ecore_key_modifiers_to_ecore_imf_locks(unsigned int modifiers)
702 {
703     unsigned int locks = 0;
704
705     if (modifiers & ECORE_EVENT_LOCK_SCROLL)
706         locks |= ECORE_IMF_KEYBOARD_LOCK_SCROLL;
707
708     if (modifiers & ECORE_EVENT_LOCK_CAPS)
709         locks |= ECORE_IMF_KEYBOARD_LOCK_CAPS;
710
711     if (modifiers & ECORE_EVENT_LOCK_NUM)
712         locks |= ECORE_IMF_KEYBOARD_LOCK_NUM;
713
714     return locks;
715 }
716
717 static unsigned int
718 _ecore_key_modifiers_to_ecore_imf_modifiers(unsigned int modifiers)
719 {
720    unsigned int mask = 0;
721
722     /**< "Control" is pressed */
723     if (modifiers & ECORE_EVENT_MODIFIER_CTRL)
724         mask |= ECORE_IMF_KEYBOARD_MODIFIER_CTRL;
725
726     /**< "Alt" is pressed */
727     if (modifiers & ECORE_EVENT_MODIFIER_ALT)
728         mask |=  ECORE_IMF_KEYBOARD_MODIFIER_ALT;
729
730     /**< "Shift" is pressed */
731     if (modifiers & ECORE_EVENT_MODIFIER_SHIFT)
732         mask |= ECORE_IMF_KEYBOARD_MODIFIER_SHIFT;
733
734     /**< "Win" (between "Ctrl" and "Alt") is pressed */
735     if (modifiers & ECORE_EVENT_MODIFIER_WIN)
736         mask |= ECORE_IMF_KEYBOARD_MODIFIER_WIN;
737
738     /**< "AltGr" is pressed */
739     if (modifiers & ECORE_EVENT_MODIFIER_ALTGR)
740         mask |= ECORE_IMF_KEYBOARD_MODIFIER_ALTGR;
741
742     return mask;
743 }
744
745 static void
746 _ecore_event_to_ecore_imf_key_down_event(Ecore_Event_Key *ecore_event, Ecore_IMF_Event_Key_Down *imf_event)
747 {
748     if (!ecore_event || !imf_event)
749         return;
750
751     imf_event->keyname = ecore_event->keyname ? ecore_event->keyname : _ecore_imf_event_empty;
752     imf_event->key = ecore_event->key ? ecore_event->key : _ecore_imf_event_empty;
753     imf_event->string = ecore_event->string ? ecore_event->string : _ecore_imf_event_empty;
754     imf_event->compose = ecore_event->compose ? ecore_event->compose : _ecore_imf_event_empty;
755     imf_event->timestamp = ecore_event->timestamp;
756
757     if (ecore_event->dev) {
758         imf_event->dev_name = ecore_device_name_get(ecore_event->dev) ? ecore_device_name_get(ecore_event->dev) : _ecore_imf_event_empty;
759         imf_event->dev_class = (Ecore_IMF_Device_Class)ecore_device_class_get(ecore_event->dev);
760         imf_event->dev_subclass = (Ecore_IMF_Device_Subclass)ecore_device_subclass_get(ecore_event->dev);
761     }
762     else {
763         imf_event->dev_name = _ecore_imf_event_empty;
764         imf_event->dev_class = ECORE_IMF_DEVICE_CLASS_NONE;
765         imf_event->dev_subclass = ECORE_IMF_DEVICE_SUBCLASS_NONE;
766     }
767
768     imf_event->modifiers = _ecore_key_modifiers_to_ecore_imf_modifiers(ecore_event->modifiers);
769     imf_event->locks = _ecore_key_modifiers_to_ecore_imf_locks(ecore_event->modifiers);
770 }
771
772 static void
773 _ecore_event_to_ecore_imf_key_up_event(Ecore_Event_Key *ecore_event, Ecore_IMF_Event_Key_Up *imf_event)
774 {
775     if (!ecore_event || !imf_event)
776         return;
777
778     imf_event->keyname = ecore_event->keyname ? ecore_event->keyname : _ecore_imf_event_empty;
779     imf_event->key = ecore_event->key ? ecore_event->key : _ecore_imf_event_empty;
780     imf_event->string = ecore_event->string ? ecore_event->string : _ecore_imf_event_empty;
781     imf_event->compose = ecore_event->compose ? ecore_event->compose : _ecore_imf_event_empty;
782     imf_event->timestamp = ecore_event->timestamp;
783
784     if (ecore_event->dev) {
785         imf_event->dev_name = ecore_device_name_get(ecore_event->dev) ? ecore_device_name_get(ecore_event->dev) : _ecore_imf_event_empty;
786         imf_event->dev_class = (Ecore_IMF_Device_Class)ecore_device_class_get(ecore_event->dev);
787         imf_event->dev_subclass = (Ecore_IMF_Device_Subclass)ecore_device_subclass_get(ecore_event->dev);
788     }
789     else {
790         imf_event->dev_name = _ecore_imf_event_empty;
791         imf_event->dev_class = ECORE_IMF_DEVICE_CLASS_NONE;
792         imf_event->dev_subclass = ECORE_IMF_DEVICE_SUBCLASS_NONE;
793     }
794
795     imf_event->modifiers = _ecore_key_modifiers_to_ecore_imf_modifiers(ecore_event->modifiers);
796     imf_event->locks = _ecore_key_modifiers_to_ecore_imf_locks(ecore_event->modifiers);
797 }
798
799 static Eina_Bool check_nograb_backkey()
800 {
801     char *nograb_backkey = getenv ("ISF_KEY_NOGRAB_BACKKEY");
802     if (nograb_backkey) {
803         if (atoi (nograb_backkey) != 0)
804             return EINA_TRUE; /* the event is kept */
805     }
806
807     return EINA_FALSE;
808 }
809
810 static Eina_Bool
811 key_down_filter_cb(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
812 {
813     Ecore_Event_Key *ev = (Ecore_Event_Key *)event;
814     if (!ev || !ev->keyname) return ECORE_CALLBACK_PASS_ON; /* the event is kept */
815
816     Ecore_IMF_Context *active_ctx = get_using_ctx ();
817
818     if (!active_ctx) return ECORE_CALLBACK_PASS_ON; /* the event is kept */
819
820     if (check_nograb_backkey()) return ECORE_CALLBACK_PASS_ON; /* the event is kept */
821
822     if ((_input_panel_state == ECORE_IMF_INPUT_PANEL_STATE_SHOW ||
823         _input_panel_state == ECORE_IMF_INPUT_PANEL_STATE_WILL_SHOW) &&
824         check_hide_key(ev->keyname)) {
825
826         if (ev->event_flags & ECORE_EVENT_FLAG_CANCEL) {
827             SECURE_LOGD ("%s key is cancelled.", ev->keyname);
828             return ECORE_CALLBACK_PASS_ON;
829         }
830
831         SECURE_LOGD ("%s key is pressed.", ev->keyname);
832
833         Ecore_IMF_Event_Key_Down imf_event;
834         Eina_Bool filter_ret = EINA_FALSE;
835
836         _ecore_event_to_ecore_imf_key_down_event(ev, &imf_event);
837
838         if (_focused_ctx)
839             filter_ret = ecore_imf_context_filter_event(_focused_ctx, ECORE_IMF_EVENT_KEY_DOWN, (Ecore_IMF_Event *)&imf_event);
840         else
841             LOGD("no focus");
842
843         SECURE_LOGD ("%s key is pressed. ret : %d", ev->keyname, filter_ret);
844         return ECORE_CALLBACK_DONE; /* the event is removed from the queue */
845     }
846     return ECORE_CALLBACK_PASS_ON; /* the event is kept */
847 }
848
849 static Eina_Bool
850 key_up_filter_cb(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
851 {
852     Ecore_Event_Key *ev = (Ecore_Event_Key *)event;
853     if (!ev || !ev->keyname) return ECORE_CALLBACK_PASS_ON; /* the event is kept */
854
855     Ecore_IMF_Context *active_ctx = get_using_ctx ();
856
857     if (!active_ctx) return ECORE_CALLBACK_PASS_ON; /* the event is kept */
858
859     if (check_nograb_backkey()) return ECORE_CALLBACK_PASS_ON; /* the event is kept */
860
861     if (_input_panel_state == ECORE_IMF_INPUT_PANEL_STATE_HIDE ||
862         !check_hide_key(ev->keyname))
863         return ECORE_CALLBACK_PASS_ON; /* the event is kept */
864
865     if (ev->event_flags & ECORE_EVENT_FLAG_CANCEL) {
866         SECURE_LOGD ("%s key is cancelled.", ev->keyname);
867         return ECORE_CALLBACK_PASS_ON;
868     }
869
870     SECURE_LOGD ("%s key is released.", ev->keyname);
871
872     Ecore_IMF_Event_Key_Up imf_event;
873     Eina_Bool filter_ret = EINA_FALSE;
874
875     _ecore_event_to_ecore_imf_key_up_event(ev, &imf_event);
876
877     if (_focused_ctx)
878         filter_ret = ecore_imf_context_filter_event(_focused_ctx, ECORE_IMF_EVENT_KEY_UP, (Ecore_IMF_Event *)&imf_event);
879     else
880         LOGD("no focus");
881
882     SECURE_LOGD ("%s key is released. ret : %d", ev->keyname, filter_ret);
883     if (filter_ret) {
884         return ECORE_CALLBACK_DONE; /* the event is removed from the queue */
885     }
886     else {
887         ecore_imf_context_reset(active_ctx);
888         _input_panel_hide(active_ctx, EINA_TRUE);
889         return ECORE_CALLBACK_DONE; /* the event is removed from the queue */
890     }
891 }
892
893 static Eina_Bool
894 rotary_event_cb(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
895 {
896     Ecore_Event_Detent_Rotate *ev = event;
897     if (!ev) return ECORE_CALLBACK_PASS_ON;
898
899     Ecore_IMF_Context *active_ctx = NULL;
900     if (_show_req_ctx)
901         active_ctx = _show_req_ctx;
902     else if (_focused_ctx)
903         active_ctx = _focused_ctx;
904
905     if (!active_ctx) return ECORE_CALLBACK_PASS_ON;
906
907     if (_input_panel_state == ECORE_IMF_INPUT_PANEL_STATE_HIDE)
908         return ECORE_CALLBACK_PASS_ON;
909
910     ecore_imf_context_reset(active_ctx);
911     WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(active_ctx);
912     if (imcontext && imcontext->input && imcontext->text_input) {
913         isf_device_type_e device_type = find_device_type_from_ecore_event(ECORE_EVENT_DETENT_ROTATE);
914         char *buffer = NULL;
915         size_t buflen = 0;
916
917         if (device_buffer_encode((const char*)(event), sizeof(Ecore_Event_Detent_Rotate), &buffer, &buflen) &&
918             buffer && buflen > 0) {
919             wl_text_input_process_input_device_event(imcontext->text_input,
920                 (unsigned int)device_type, buffer, buflen);
921         }
922         if (buffer) free(buffer);
923     }
924
925     return ECORE_CALLBACK_DONE;
926 }
927
928 static Eina_Bool
929 _ecore_event_filter_cb(void *data, void *loop_data EINA_UNUSED, int type, void *event)
930 {
931     if (type == ECORE_EVENT_KEY_DOWN) {
932         return key_down_filter_cb(data, type, event);
933     }
934     else if (type == ECORE_EVENT_KEY_UP) {
935         return key_up_filter_cb(data, type, event);
936     }
937     /* The IME needs to process Rotary event prior to client application */
938     else if (type == ECORE_EVENT_DETENT_ROTATE) {
939         return rotary_event_cb(data, type, event);
940     }
941
942     return ECORE_CALLBACK_PASS_ON;
943 }
944
945 static void
946 register_key_handler()
947 {
948     if (!_ecore_event_filter_handler)
949         _ecore_event_filter_handler = ecore_event_filter_add(NULL, _ecore_event_filter_cb, NULL, NULL);
950 }
951
952 static void
953 unregister_key_handler()
954 {
955     if (_ecore_event_filter_handler) {
956         ecore_event_filter_del(_ecore_event_filter_handler);
957         _ecore_event_filter_handler = NULL;
958     }
959
960     _clear_hide_timer();
961 }
962 //
963
964 static Eina_Bool
965 _clear_hide_timer()
966 {
967     if (_hide_timer) {
968         LOGD("Delete hide timer");
969         ecore_timer_del(_hide_timer);
970         _hide_timer = NULL;
971         return EINA_TRUE;
972     }
973
974     return EINA_FALSE;
975 }
976
977 static void _win_focus_out_handler_del ()
978 {
979     if (_win_focus_out_handler) {
980         ecore_event_handler_del (_win_focus_out_handler);
981         _win_focus_out_handler = NULL;
982     }
983 }
984
985 static void _conformant_change_handler_del()
986 {
987     if (_conformant_change_handler) {
988         ecore_event_handler_del(_conformant_change_handler);
989         _conformant_change_handler = NULL;
990     }
991 }
992
993 static void
994 _send_input_panel_hide_request(Ecore_IMF_Context *ctx)
995 {
996     if (!ctx) return;
997
998     // TIZEN_ONLY(20150708): Support back key
999     _hide_req_ctx = NULL;
1000     //
1001
1002     _win_focus_out_handler_del ();
1003
1004     WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
1005     if (imcontext && imcontext->text_input) {
1006         LOGD("Send IME hide request");
1007         wl_text_input_hide_input_panel(imcontext->text_input);
1008     } else {
1009         LOGD("creating temporary context for sending hide request");
1010         const char *ctx_id = ecore_imf_context_default_id_get();
1011         Ecore_IMF_Context *temp_context = ecore_imf_context_add(ctx_id);
1012         if (temp_context) {
1013             imcontext = (WaylandIMContext *)ecore_imf_context_data_get(temp_context);
1014             if (imcontext && imcontext->text_input) {
1015                 LOGD("Send IME hide request");
1016                 wl_text_input_hide_input_panel(imcontext->text_input);
1017             }
1018
1019             ecore_imf_context_del(temp_context);
1020         }
1021     }
1022 }
1023
1024 static void _conformant_area_free (void *data EINA_UNUSED, void *ev)
1025 {
1026     Ecore_Wl2_Event_Conformant_Change *e = ev;
1027     free(e);
1028     e = NULL;
1029 }
1030
1031 static void add_conformant_change_event(Ecore_Wl2_Window *window)
1032 {
1033     Ecore_Wl2_Event_Conformant_Change *ev;
1034     ev = calloc(1, sizeof(Ecore_Wl2_Event_Conformant_Change));
1035     if (ev) {
1036         ev->win = ecore_wl2_window_id_get(window);
1037         ev->part_type = 1;
1038         ev->state = 0;
1039         ecore_event_add(ECORE_WL2_EVENT_CONFORMANT_CHANGE, ev, _conformant_area_free, NULL);
1040     }
1041 }
1042
1043 static Eina_Rectangle _conformant_area_backup = { 0, 0, 0, 0 };
1044 static Eina_Bool reset_conformant_area(Ecore_IMF_Context *ctx)
1045 {
1046     Eina_Bool reset = EINA_FALSE;
1047     Eina_Bool has_conformant = EINA_FALSE;
1048     Ecore_Wl2_Window *window = NULL;
1049
1050     if (!ctx) return EINA_FALSE;
1051
1052     WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
1053     if (imcontext) {
1054         window = imcontext->window;
1055         has_conformant = imcontext->has_conformant;
1056     }
1057
1058     if (window) {
1059         int x = 0, y = 0, w = 0, h = 0;
1060         Eina_Bool result = ecore_wl2_window_keyboard_geometry_get(window, &x, &y, &w, &h);
1061
1062         if (result) {
1063             if (ecore_imf_context_client_canvas_get(ctx) && has_conformant && (w != 0 || h != 0)) {
1064                 reset = EINA_TRUE;
1065                 _conformant_area_backup.x = x;
1066                 _conformant_area_backup.y = y;
1067                 _conformant_area_backup.w = w;
1068                 _conformant_area_backup.h = h;
1069             }
1070         }
1071     }
1072     LOGD("reset %d", reset);
1073     if (reset) {
1074         ecore_wl2_window_keyboard_geometry_set(window, 0, 0, 0, 0);
1075
1076         add_conformant_change_event(window);
1077
1078         _conformant_reset_started = EINA_TRUE;
1079     }
1080
1081     return reset;
1082 }
1083
1084 static void restore_conformant_area(Ecore_IMF_Context *ctx)
1085 {
1086     Eina_Bool restore = EINA_FALSE;
1087     Eina_Bool has_conformant = EINA_FALSE;
1088     Ecore_Wl2_Window *window = NULL;
1089
1090     if (!ctx) return;
1091
1092     WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
1093     if (imcontext) {
1094         window = imcontext->window;
1095         has_conformant = imcontext->has_conformant;
1096     }
1097
1098     if (window) {
1099         int x = 0, y = 0, w = 0, h = 0;
1100         Eina_Bool result = ecore_wl2_window_keyboard_geometry_get(window, &x, &y, &w, &h);
1101
1102         if (result) {
1103             if (ecore_imf_context_client_canvas_get(ctx) && has_conformant && (w == 0 || h == 0)) {
1104                 restore = EINA_TRUE;
1105             }
1106         }
1107     }
1108     LOGD("restore %d", restore);
1109     if (restore) {
1110         ecore_wl2_window_keyboard_geometry_set(window,
1111             _conformant_area_backup.x, _conformant_area_backup.y,
1112             _conformant_area_backup.w, _conformant_area_backup.h);
1113
1114         add_conformant_change_event(window);
1115
1116        _conformant_reset_started = EINA_FALSE;
1117     }
1118 }
1119
1120 static void
1121 _send_will_hide_ack(WaylandIMContext *imcontext)
1122 {
1123     if (!imcontext) return;
1124     if (!(imcontext->text_input)) return;
1125
1126     const char *szWillHideAck = "WILL_HIDE_ACK";
1127     wl_text_input_set_input_panel_data(imcontext->text_input, szWillHideAck, strlen(szWillHideAck));
1128     _received_will_hide_event = EINA_FALSE;
1129 }
1130
1131 static Eina_Bool
1132 _hide_timer_handler(void *data)
1133 {
1134     LOGD("Start hide timer");
1135     Ecore_IMF_Context *ctx = (Ecore_IMF_Context *)data;
1136     _send_input_panel_hide_request(ctx);
1137
1138     if (!reset_conformant_area(ctx) && !_conformant_reset_started) {
1139         LOGD("No need to reset conformant, sending ACK right away");
1140         _send_will_hide_ack((WaylandIMContext *)ecore_imf_context_data_get(ctx));
1141     }
1142
1143     if (_TV)
1144         reset_keyboard_geometry();
1145
1146     _hide_timer = NULL;
1147     return ECORE_CALLBACK_CANCEL;
1148 }
1149
1150 static void
1151 _input_panel_hide_timer_start(void *data)
1152 {
1153     if (!_hide_timer) {
1154         LOGD("Add timer to hide input panel");
1155         _hide_timer = ecore_timer_add(HIDE_TIMER_INTERVAL, _hide_timer_handler, data);
1156     }
1157 }
1158
1159 static void
1160 _input_panel_hide(Ecore_IMF_Context *ctx, Eina_Bool instant)
1161 {
1162     LOGD ("ctx : %p", ctx);
1163
1164     if (!ctx) return;
1165
1166     will_hide = EINA_TRUE;
1167     _conformant_reset_started = EINA_FALSE;
1168
1169     if (instant || (_hide_timer && ecore_timer_pending_get(_hide_timer) <= 0.0)) {
1170         _clear_hide_timer();
1171         _send_input_panel_hide_request(ctx);
1172
1173         if (!reset_conformant_area(ctx) && !_conformant_reset_started) {
1174             LOGD("No need to reset conformant, sending ACK right away");
1175             _send_will_hide_ack((WaylandIMContext *)ecore_imf_context_data_get(ctx));
1176         }
1177
1178         if (_TV)
1179             reset_keyboard_geometry();
1180     } else {
1181         _input_panel_hide_timer_start(ctx);
1182         // TIZEN_ONLY(20150708): Support back key
1183         _hide_req_ctx = ctx;
1184         //
1185     }
1186 }
1187
1188 static unsigned int
1189 utf8_offset_to_characters(const char *str, int offset)
1190 {
1191     int index = 0;
1192     unsigned int i = 0;
1193
1194     for (; index < offset; i++) {
1195         if (eina_unicode_utf8_next_get(str, &index) == 0)
1196             break;
1197     }
1198
1199     return i;
1200 }
1201
1202 static void
1203 send_cursor_location(WaylandIMContext *imcontext)
1204 {
1205 #if ENABLE_SEND_CURSOR_LOCATION
1206     Ecore_Evas *ee = NULL;
1207     int canvas_x = 0, canvas_y = 0;
1208
1209     if (imcontext->canvas) {
1210         ee = ecore_evas_ecore_evas_get(imcontext->canvas);
1211         if (ee)
1212             ecore_evas_geometry_get(ee, &canvas_x, &canvas_y, NULL, NULL);
1213     }
1214
1215     if (imcontext->input && imcontext->text_input) {
1216         wl_text_input_set_cursor_rectangle(imcontext->text_input,
1217                 imcontext->cursor_location.x + canvas_x,
1218                 imcontext->cursor_location.y + canvas_y,
1219                 imcontext->cursor_location.width,
1220                 imcontext->cursor_location.height);
1221     }
1222 #endif
1223 }
1224
1225 static void
1226 update_state(WaylandIMContext *imcontext)
1227 {
1228     if (!imcontext->ctx)
1229         return;
1230
1231     send_cursor_location (imcontext);
1232
1233     if (imcontext->input && imcontext->text_input) {
1234         wl_text_input_commit_state(imcontext->text_input, ++imcontext->serial);
1235     }
1236 }
1237
1238 static Eina_Bool
1239 check_serial(WaylandIMContext *imcontext, uint32_t serial)
1240 {
1241     if (_TV)
1242         return EINA_TRUE;
1243     else {
1244         Ecore_IMF_Preedit_Attr *attr;
1245
1246         if ((imcontext->serial - serial) >
1247                 (imcontext->serial - imcontext->reset_serial)) {
1248             LOGD("outdated serial: %u, current: %u, reset: %u",
1249                     serial, imcontext->serial, imcontext->reset_serial);
1250
1251             imcontext->pending_preedit.cursor = 0;
1252
1253             if (imcontext->pending_preedit.attrs) {
1254                 EINA_LIST_FREE(imcontext->pending_preedit.attrs, attr) {
1255                     if (attr)
1256                         free(attr);
1257                 }
1258                 imcontext->pending_preedit.attrs = NULL;
1259             }
1260
1261             return EINA_FALSE;
1262         }
1263
1264         return EINA_TRUE;
1265     }
1266 }
1267
1268 static void
1269 clear_preedit_text(WaylandIMContext *imcontext)
1270 {
1271     Ecore_IMF_Preedit_Attr *attr = NULL;
1272
1273     imcontext->preedit_cursor = 0;
1274
1275     if (imcontext->preedit_text) {
1276         free(imcontext->preedit_text);
1277         imcontext->preedit_text = NULL;
1278     }
1279
1280     if (imcontext->preedit_attrs) {
1281         EINA_LIST_FREE(imcontext->preedit_attrs, attr) {
1282             if (attr)
1283                 free(attr);
1284         }
1285     }
1286
1287     imcontext->preedit_attrs = NULL;
1288 }
1289
1290 static void
1291 clear_preedit(WaylandIMContext *imcontext)
1292 {
1293     clear_preedit_text(imcontext);
1294
1295     if (imcontext->preedit_commit) {
1296         free(imcontext->preedit_commit);
1297         imcontext->preedit_commit = NULL;
1298     }
1299 }
1300
1301 static void
1302 text_input_commit_string(void                 *data,
1303                          struct wl_text_input *text_input EINA_UNUSED,
1304                          uint32_t              serial,
1305                          const char           *text)
1306 {
1307     WaylandIMContext *imcontext = (WaylandIMContext *)data;
1308     Eina_Bool old_preedit = EINA_FALSE;
1309
1310     SECURE_LOGD("ctx : %p, commit event (text: '%s', current pre-edit: '%s')",
1311                 imcontext->ctx,
1312                 text,
1313                 imcontext->preedit_text ? imcontext->preedit_text : "");
1314
1315     if (!imcontext->ctx)
1316         return;
1317
1318     old_preedit =
1319         imcontext->preedit_text && strlen(imcontext->preedit_text) > 0;
1320
1321     if (!check_serial(imcontext, serial))
1322         return;
1323
1324     if (old_preedit) {
1325         ecore_imf_context_event_callback_call(imcontext->ctx,
1326                 ECORE_IMF_CALLBACK_PREEDIT_END,
1327                 NULL);
1328     }
1329
1330     clear_preedit(imcontext);
1331
1332     if (!text)
1333         return;
1334
1335     Eina_Unicode *ustr = eina_unicode_utf8_to_unicode (text, NULL);
1336
1337     if (ustr) {
1338         if (eina_unicode_strcmp (ustr, L" ") == 0 ||
1339             eina_unicode_strcmp (ustr, L" ") == 0)
1340             autoperiod_insert (imcontext->ctx);
1341
1342         free(ustr);
1343     }
1344
1345     ecore_imf_context_event_callback_call(imcontext->ctx, ECORE_IMF_CALLBACK_COMMIT, (void *)text);
1346 }
1347
1348 static void
1349 commit_preedit(WaylandIMContext *imcontext)
1350 {
1351     if (!imcontext->preedit_commit)
1352         return;
1353
1354     if (!imcontext->ctx)
1355         return;
1356
1357     imcontext->pending_preedit.cursor = 0;
1358     clear_preedit_text(imcontext);
1359
1360     size_t commit_len = strlen(imcontext->preedit_commit);
1361
1362     if (commit_len == 0) {
1363         ecore_imf_context_event_callback_call(imcontext->ctx,
1364                 ECORE_IMF_CALLBACK_PREEDIT_START,
1365                 NULL);
1366
1367         ecore_imf_context_event_callback_call(imcontext->ctx,
1368                 ECORE_IMF_CALLBACK_PREEDIT_CHANGED,
1369                 NULL);
1370
1371         ecore_imf_context_event_callback_call(imcontext->ctx,
1372                 ECORE_IMF_CALLBACK_PREEDIT_END, NULL);
1373     }
1374
1375     if (commit_len > 0) {
1376         char *commit_str = NULL;
1377         commit_str = strdup(imcontext->preedit_commit);
1378         clear_preedit(imcontext);
1379         ecore_imf_context_event_callback_call(imcontext->ctx,
1380                 ECORE_IMF_CALLBACK_COMMIT,
1381                 (void *)commit_str);
1382         free(commit_str);
1383     }
1384 }
1385
1386 static Eina_Bool
1387 set_focus(Ecore_IMF_Context *ctx)
1388 {
1389     LOGD("ctx : %p", ctx);
1390     WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
1391     if (!imcontext) return EINA_FALSE;
1392
1393     if (!imcontext->window) {
1394         LOGW("window is not given");
1395         return EINA_FALSE;
1396     }
1397
1398     if (imcontext->canvas) {
1399         if (!evas_focus_state_get(imcontext->canvas)) {
1400             LOGW("ctx : %p, canvas does not have focus", ctx);
1401             return EINA_FALSE;
1402         }
1403     }
1404     else if (!ecore_wl2_window_activated_get(imcontext->window)) {
1405         LOGW("ctx : %p, window does not have focus", ctx);
1406         return EINA_FALSE;
1407     }
1408
1409     Ecore_Wl2_Input *input = ecore_wl2_window_input_get(imcontext->window);
1410     if (!input) {
1411         LOGW("ctx : %p, Can't get Wl_Input", ctx);
1412         return EINA_FALSE;
1413     }
1414
1415     struct wl_seat *seat = ecore_wl2_input_seat_get(input);
1416     if (!seat) {
1417         LOGW("ctx : %p, Can't get Wl_seat", ctx);
1418         return EINA_FALSE;
1419     }
1420
1421     imcontext->input = input;
1422     _focused_ctx = ctx;
1423
1424     wl_text_input_activate(imcontext->text_input, seat,
1425             ecore_wl2_window_surface_get(imcontext->window));
1426
1427     if (g_key_rate_checked == EINA_FALSE && g_desired_key_rate == 0.0) {
1428         char *key_rate = getenv ("ISF_KEY_REPEAT_RATE");
1429         if (key_rate) {
1430             g_desired_key_rate = atof (key_rate);
1431             if (g_desired_key_rate > 0.0) {
1432                 if (!ecore_wl2_input_keyboard_repeat_get (input, &g_original_key_rate, &g_original_key_delay)) {
1433                     LOGE ("ecore_wl2_input_keyboard_repeat_get failed");
1434                 }
1435                 else {
1436                     LOGD ("ecore_wl2_input_keyboard_repeat_get original rate=%f, delay=%f. Desired rate=%f",
1437                         g_original_key_rate, g_original_key_delay, g_desired_key_rate);
1438                 }
1439             }
1440         }
1441         g_key_rate_checked = EINA_TRUE;
1442     }
1443
1444     if (g_desired_key_rate > 0.0 && g_original_key_delay > 0.0 && !g_focused) {
1445         g_focused = EINA_TRUE;
1446         if (!ecore_wl2_input_keyboard_repeat_set (input, g_desired_key_rate, g_original_key_delay)) {
1447             LOGE ("ecore_wl2_input_keyboard_repeat_set failed");
1448         }
1449         else {
1450             LOGD ("ecore_wl2_input_keyboard_repeat_set(%f, %f)", g_desired_key_rate, g_original_key_delay);
1451         }
1452     }
1453
1454     return EINA_TRUE;
1455 }
1456
1457 static void
1458 set_focus_out(Ecore_IMF_Context *ctx)
1459 {
1460     char *surrounding = NULL;
1461     int cursor_pos = 0;
1462
1463     WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
1464     if (!imcontext || !imcontext->input) return;
1465
1466     if (ecore_imf_context_surrounding_get(ctx, &surrounding, &cursor_pos)) {
1467         if (surrounding) {
1468             wl_text_input_finalize_content(imcontext->text_input, surrounding, cursor_pos);
1469             free(surrounding);
1470         }
1471     }
1472
1473     // deactivate
1474     if (imcontext->text_input)
1475         wl_text_input_deactivate(imcontext->text_input,
1476                                  ecore_wl2_input_seat_get(imcontext->input));
1477
1478     if (ctx == _focused_ctx)
1479         _focused_ctx = NULL;
1480
1481     imcontext->input = NULL;
1482     _preedit_cursor_changed = EINA_FALSE;
1483
1484     if (g_desired_key_rate > 0.0 && g_focused) {
1485         g_focused = EINA_FALSE;
1486
1487         Ecore_Wl2_Input *input = ecore_wl2_window_input_get(imcontext->window);
1488         if (input) {
1489             if (!ecore_wl2_input_keyboard_repeat_set (input, g_original_key_rate, g_original_key_delay)) {
1490                 LOGE ("ecore_wl2_input_keyboard_repeat_set failed.");
1491             }
1492             else {
1493                 LOGD ("ecore_wl2_input_keyboard_repeat_set(%f, %f)", g_original_key_rate, g_original_key_delay);
1494             }
1495         }
1496         else {
1497             LOGW("ctx : %p, Can't get Wl_Input", ctx);
1498         }
1499     }
1500 }
1501
1502 // TIZEN_ONLY(20160217): ignore the duplicate show request
1503 static Eina_Bool _compare_context(Ecore_IMF_Context *ctx1, Ecore_IMF_Context *ctx2)
1504 {
1505     if (!ctx1 || !ctx2) return EINA_FALSE;
1506
1507     if ((ecore_imf_context_autocapital_type_get(ctx1) == ecore_imf_context_autocapital_type_get(ctx2)) &&
1508         (ecore_imf_context_input_panel_layout_get(ctx1) == ecore_imf_context_input_panel_layout_get(ctx2)) &&
1509         (ecore_imf_context_input_panel_layout_variation_get(ctx1) == ecore_imf_context_input_panel_layout_variation_get(ctx2)) &&
1510         (ecore_imf_context_input_panel_language_get(ctx1) == ecore_imf_context_input_panel_language_get(ctx2)) &&
1511         (ecore_imf_context_input_panel_return_key_type_get(ctx1) == ecore_imf_context_input_panel_return_key_type_get(ctx2)) &&
1512         (ecore_imf_context_input_panel_return_key_disabled_get(ctx1) == ecore_imf_context_input_panel_return_key_disabled_get(ctx2)) &&
1513         (ecore_imf_context_input_panel_caps_lock_mode_get(ctx1) == ecore_imf_context_input_panel_caps_lock_mode_get(ctx2)))
1514         return EINA_TRUE;
1515
1516     return EINA_FALSE;
1517 }
1518 //
1519
1520 static void send_get_hide_permission(WaylandIMContext *imcontext)
1521 {
1522     if (imcontext->text_input) {
1523         ignore_hide = EINA_FALSE;
1524         wl_text_input_get_hide_permission(imcontext->text_input);
1525     }
1526 }
1527
1528 static Eina_Bool _client_window_focus_out_cb(void *data, int ev_type, void *ev)
1529 {
1530     Ecore_Wl2_Event_Focus_Out *e = (Ecore_Wl2_Event_Focus_Out *)ev;
1531     Ecore_IMF_Context *ctx = (Ecore_IMF_Context *)data;
1532     if (!ctx || !e) return ECORE_CALLBACK_PASS_ON;
1533
1534     WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get (ctx);
1535     if (!imcontext || !imcontext->window) return ECORE_CALLBACK_PASS_ON;
1536
1537     unsigned int client_win_id = ecore_wl2_window_id_get (imcontext->window);
1538
1539     LOGD ("ctx : %p, client_window id : %#x, focus-out win : %#x", ctx, client_win_id, e->window);
1540
1541     if (client_win_id > 0) {
1542         if (e->window == client_win_id) {
1543             LOGD ("window focus out");
1544
1545             if (_focused_ctx == ctx) {
1546                 wayland_im_context_focus_out (ctx);
1547             }
1548
1549             if (_show_req_ctx == ctx) {
1550                 send_get_hide_permission(imcontext);
1551             }
1552         }
1553     }
1554     else {
1555         send_get_hide_permission(imcontext);
1556     }
1557
1558     return ECORE_CALLBACK_PASS_ON;
1559 }
1560
1561 static void send_will_hide_ack(Ecore_IMF_Context *ctx)
1562 {
1563     Eina_Bool need_temporary_context = EINA_FALSE;
1564     Eina_Bool has_conformant = EINA_FALSE;
1565     WaylandIMContext *imcontext = NULL;
1566
1567     if (!ctx) {
1568         LOGD("ctx is NULL");
1569         need_temporary_context = EINA_TRUE;
1570     } else {
1571         imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
1572         if (!imcontext) {
1573             LOGD("imcontext is NULL :%p", ctx);
1574             need_temporary_context = EINA_TRUE;
1575         } else {
1576             has_conformant = imcontext->has_conformant;
1577         }
1578     }
1579
1580     /* When the RENDER_POST event is emitted, it is possible that our IMF_Context is already deleted,
1581        meaning that there is no connection available for communicating with the window manager.
1582        So we are creating a temporary context for sending WILL_HIDE_ACK message */
1583     if (need_temporary_context) {
1584         LOGD("creating temporary context for sending WILL_HIDE_ACK");
1585         const char *ctx_id = ecore_imf_context_default_id_get();
1586         ctx = ecore_imf_context_add(ctx_id);
1587         if (ctx) {
1588             imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
1589         }
1590     }
1591
1592     if (ctx && imcontext) {
1593         if (ecore_imf_context_client_canvas_get(ctx) && has_conformant) {
1594             if (_conformant_reset_done && _received_will_hide_event) {
1595                 LOGD("Send will hide ack, _conformant_reset_done = 1, received_will_hide_event = 1");
1596                 _send_will_hide_ack(imcontext);
1597                 _conformant_reset_done = EINA_FALSE;
1598                 _received_will_hide_event = EINA_FALSE;
1599             } else {
1600                 LOGD ("_conformant_reset_done=%d, received_will_hide_event=%d",
1601                     _conformant_reset_done, _received_will_hide_event);
1602             }
1603         } else {
1604             LOGD("Send will hide ack right away, since there is no conformant available : %p %d",
1605                 ecore_imf_context_client_canvas_get(ctx), has_conformant);
1606             _send_will_hide_ack (imcontext);
1607         }
1608     }
1609
1610     if (need_temporary_context) {
1611         if (ctx) {
1612             ecore_imf_context_del(ctx);
1613         }
1614     }
1615 }
1616
1617 static void _render_post_cb(void *data, Evas *e, void *event_info)
1618 {
1619     void *callback = evas_event_callback_del(e, EVAS_CALLBACK_RENDER_POST, _render_post_cb);
1620     _conformant_reset_done = EINA_TRUE;
1621     _conformant_reset_started = EINA_FALSE;
1622     LOGD("[_render_post_cb], _conformant_reset_done = 1 , %p", callback);
1623     send_will_hide_ack(NULL);
1624 }
1625
1626 static Eina_Bool _conformant_change_cb(void *data, int ev_type, void *ev)
1627 {
1628     Ecore_Wl2_Event_Conformant_Change *e = (Ecore_Wl2_Event_Conformant_Change *)ev;
1629     if (!e) return ECORE_CALLBACK_PASS_ON;
1630
1631     LOGD ("CONFORMANT changed!! part type : %d, state : %d, win : %d", e->part_type, e->state, e->win);
1632
1633     if (_active_context_window_id != e->win)
1634         return ECORE_CALLBACK_PASS_ON;
1635
1636     Ecore_Wl2_Display *wl2_display = ecore_wl2_connected_display_get(NULL);
1637     if (!wl2_display) return ECORE_CALLBACK_PASS_ON;
1638
1639     Ecore_Wl2_Window *window = ecore_wl2_display_window_find(wl2_display, e->win);
1640     if (!window) return ECORE_CALLBACK_PASS_ON;
1641
1642     if (!(e->state)) {
1643         LOGD("_conformant_reset_done = 0, registering _render_post_cb : %p %p", _active_context_canvas, window);
1644         _conformant_reset_done = EINA_FALSE;
1645         if (_active_context_canvas && ecore_wl2_window_conformant_get(window) && !_custom_conformant_event) {
1646             evas_event_callback_del(_active_context_canvas, EVAS_CALLBACK_RENDER_POST, _render_post_cb);
1647             evas_event_callback_add(_active_context_canvas, EVAS_CALLBACK_RENDER_POST, _render_post_cb, NULL);
1648         }
1649     } else {
1650         _conformant_reset_done = EINA_FALSE;
1651         if (_active_context_canvas) {
1652             evas_event_callback_del(_active_context_canvas, EVAS_CALLBACK_RENDER_POST, _render_post_cb);
1653         }
1654
1655         Eina_Bool result = EINA_FALSE;
1656         int x = 0, y = 0, w = 0, h = 0;
1657
1658         if (_TV) {
1659             /* TV IME consists of two or three windows, so ecore_wl2_window_keyboard_geometry_get() may return wrong size. */
1660             x = _keyboard_geometry.x, y = _keyboard_geometry.y, w = _keyboard_geometry.w, h = _keyboard_geometry.h;
1661             if (_keyboard_geometry.w == 0 || _keyboard_geometry.h == 0) {
1662                 result = ecore_wl2_window_keyboard_geometry_get(window, &x, &y, &w, &h);
1663             }
1664         } else {
1665             /* Since the input_panel_geometry is not delivered right at the moment, we use conformant geometry instead */
1666             x = 0, y = 0, w = 0, h = 0;
1667             result = ecore_wl2_window_keyboard_geometry_get(window, &x, &y, &w, &h);
1668         }
1669
1670         if (result) {
1671             Evas_Coord scr_w = 0, scr_h = 0;
1672             ecore_wl2_sync();
1673             Ecore_Wl2_Display *wl2_display = ecore_wl2_connected_display_get(NULL);
1674             if (wl2_display)
1675                 ecore_wl2_display_screen_size_get(wl2_display ,&scr_w, &scr_h);
1676             int rot = ecore_wl2_window_rotation_get(window);
1677             /* Assume we are using keyboard that has the same width to the screen width*/
1678             switch (rot) {
1679             case 90:
1680                 _keyboard_geometry.h = w;
1681                 _keyboard_geometry.w = h;
1682                 _keyboard_geometry.y = scr_w - _keyboard_geometry.h;
1683                 _keyboard_geometry.x = 0;
1684                 break;
1685             case 180:
1686                 _keyboard_geometry.w = w;
1687                 _keyboard_geometry.h = h;
1688                 _keyboard_geometry.x = 0;
1689                 _keyboard_geometry.y = scr_h - _keyboard_geometry.h;
1690                 break;
1691             case 270:
1692                 _keyboard_geometry.h = w;
1693                 _keyboard_geometry.w = h;
1694                 _keyboard_geometry.y = scr_w - _keyboard_geometry.h;
1695                 _keyboard_geometry.x = 0;
1696                 break;
1697             default:
1698                 _keyboard_geometry.x = x;
1699                 _keyboard_geometry.y = y;
1700                 _keyboard_geometry.w = w;
1701                 _keyboard_geometry.h = h;
1702             }
1703             LOGD("[KEYPAD]: scr %dx%d, rot %d, orig (%d,%d, %dx%d)", scr_w, scr_h, rot, x, y, w, h);
1704             LOGD ("IME geometry x : %d, y : %d, w : %d, h : %d", _keyboard_geometry.x, _keyboard_geometry.y, _keyboard_geometry.w, _keyboard_geometry.h);
1705
1706             if (_show_req_ctx)
1707                 ecore_imf_context_input_panel_event_callback_call(_show_req_ctx, ECORE_IMF_INPUT_PANEL_GEOMETRY_EVENT, 0);
1708         }
1709     }
1710
1711     return ECORE_CALLBACK_PASS_ON;
1712 }
1713
1714 static uint32_t
1715 get_purpose(Ecore_IMF_Context *ctx)
1716 {
1717     int layout_variation = ecore_imf_context_input_panel_layout_variation_get (ctx);
1718     uint32_t new_purpose = 0;
1719
1720     WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
1721     if (!imcontext)
1722         return new_purpose;
1723
1724     switch (imcontext->content_purpose) {
1725         case WL_TEXT_INPUT_CONTENT_PURPOSE_DIGITS:
1726             if (layout_variation == ECORE_IMF_INPUT_PANEL_LAYOUT_NUMBERONLY_VARIATION_SIGNED)
1727                 new_purpose = WL_TEXT_INPUT_CONTENT_PURPOSE_DIGITS_SIGNED;
1728             else if (layout_variation == ECORE_IMF_INPUT_PANEL_LAYOUT_NUMBERONLY_VARIATION_DECIMAL)
1729                 new_purpose = WL_TEXT_INPUT_CONTENT_PURPOSE_DIGITS_DECIMAL;
1730             else if (layout_variation == ECORE_IMF_INPUT_PANEL_LAYOUT_NUMBERONLY_VARIATION_SIGNED_AND_DECIMAL)
1731                 new_purpose = WL_TEXT_INPUT_CONTENT_PURPOSE_DIGITS_SIGNEDDECIMAL;
1732             else
1733                 new_purpose = WL_TEXT_INPUT_CONTENT_PURPOSE_DIGITS;
1734             break;
1735         case WL_TEXT_INPUT_CONTENT_PURPOSE_PASSWORD:
1736             if (layout_variation == ECORE_IMF_INPUT_PANEL_LAYOUT_PASSWORD_VARIATION_NUMBERONLY)
1737                 new_purpose = WL_TEXT_INPUT_CONTENT_PURPOSE_PASSWORD_DIGITS;
1738             else
1739                 new_purpose = WL_TEXT_INPUT_CONTENT_PURPOSE_PASSWORD;
1740             break;
1741         case WL_TEXT_INPUT_CONTENT_PURPOSE_NORMAL:
1742             if (layout_variation == ECORE_IMF_INPUT_PANEL_LAYOUT_NORMAL_VARIATION_FILENAME)
1743                 new_purpose = WL_TEXT_INPUT_CONTENT_PURPOSE_FILENAME;
1744             else if (layout_variation == ECORE_IMF_INPUT_PANEL_LAYOUT_NORMAL_VARIATION_PERSON_NAME)
1745                 new_purpose = WL_TEXT_INPUT_CONTENT_PURPOSE_NAME;
1746             else
1747                 new_purpose = WL_TEXT_INPUT_CONTENT_PURPOSE_NORMAL;
1748             break;
1749         default :
1750             new_purpose = imcontext->content_purpose;
1751             break;
1752     }
1753
1754     return new_purpose;
1755 }
1756
1757 static void _canvas_focus_in_cb(void *data, Evas *e, void *event_info)
1758 {
1759     LOGD("ctx : %p %d", _focus_req_ctx, _focus_req_only);
1760
1761     if (_focus_req_ctx) {
1762         set_focus(_focus_req_ctx);
1763         if (ecore_imf_context_input_panel_enabled_get (_focus_req_ctx) || !_focus_req_only)
1764             if (!ecore_imf_context_input_panel_show_on_demand_get (_focus_req_ctx) || !_focus_req_only)
1765                 show_input_panel (_focus_req_ctx);
1766
1767         WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(_focus_req_ctx);
1768         if (imcontext && imcontext->canvas)
1769             evas_event_callback_del(imcontext->canvas, EVAS_CALLBACK_CANVAS_FOCUS_IN, _canvas_focus_in_cb);
1770         _focus_req_ctx = NULL;
1771         _focus_req_only = EINA_TRUE;
1772     }
1773 }
1774
1775 static Eina_Bool
1776 show_input_panel(Ecore_IMF_Context *ctx)
1777 {
1778     WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
1779
1780     char *surrounding = NULL;
1781     int cursor_pos;
1782
1783     if ((!imcontext) || (!imcontext->text_input))
1784         return EINA_FALSE;
1785
1786     if (!imcontext->input) {
1787         set_focus(ctx);
1788         if (!imcontext->input) {
1789             _focus_req_ctx = ctx;
1790             _focus_req_only = EINA_FALSE;
1791             if (imcontext->canvas) {
1792                 evas_event_callback_del(imcontext->canvas, EVAS_CALLBACK_CANVAS_FOCUS_IN, _canvas_focus_in_cb);
1793                 evas_event_callback_add(imcontext->canvas, EVAS_CALLBACK_CANVAS_FOCUS_IN, _canvas_focus_in_cb, NULL);
1794             }
1795         }
1796     }
1797
1798     _clear_hide_timer ();
1799
1800     _win_focus_out_handler_del ();
1801
1802     if (!imcontext->input)
1803         return EINA_FALSE;
1804
1805     ignore_hide = EINA_TRUE;
1806
1807     _win_focus_out_handler = ecore_event_handler_add (ECORE_WL2_EVENT_FOCUS_OUT, _client_window_focus_out_cb, ctx);
1808     _conformant_change_handler_del ();
1809     _conformant_change_handler = ecore_event_handler_add(ECORE_WL2_EVENT_CONFORMANT_CHANGE, _conformant_change_cb, NULL);
1810
1811     // TIZEN_ONLY(20160217): ignore the duplicate show request
1812     if ((_show_req_ctx == ctx) && _compare_context(_show_req_ctx, ctx) && (!will_hide)) {
1813         if (_input_panel_state == ECORE_IMF_INPUT_PANEL_STATE_WILL_SHOW ||
1814             _input_panel_state == ECORE_IMF_INPUT_PANEL_STATE_SHOW) {
1815             LOGD("already show. ctx : %p", ctx);
1816
1817             return EINA_FALSE;
1818         }
1819     }
1820
1821     will_hide = EINA_FALSE;
1822     _show_req_ctx = ctx;
1823     _input_panel_ctx = ctx;
1824     _active_context_canvas = ecore_imf_context_client_canvas_get(ctx);
1825
1826     //
1827
1828     // TIZEN_ONLY(20150715): Support input_panel_state_get
1829     int layout = ecore_imf_context_input_panel_layout_get (ctx);
1830     int layout_variation = ecore_imf_context_input_panel_layout_variation_get (ctx);
1831     //
1832
1833     if (layout == ECORE_IMF_INPUT_PANEL_LAYOUT_PASSWORD)
1834         imcontext->content_hint |= (WL_TEXT_INPUT_CONTENT_HINT_SENSITIVE_DATA | WL_TEXT_INPUT_CONTENT_HINT_PASSWORD);
1835
1836     wl_text_input_set_content_type(imcontext->text_input,
1837             imcontext->content_hint,
1838             get_purpose(ctx));
1839
1840     if (ecore_imf_context_surrounding_get(imcontext->ctx, &surrounding, &cursor_pos)) {
1841         SECURE_LOGD ("surrounding text : %s", surrounding);
1842         if (surrounding)
1843             free (surrounding);
1844
1845         imcontext->cursor_position = cursor_pos;
1846         wl_text_input_set_cursor_position(imcontext->text_input, cursor_pos);
1847     }
1848     // TIZEN_ONLY(20150716): Support return key type
1849     wl_text_input_set_return_key_type(imcontext->text_input,
1850             imcontext->return_key_type);
1851
1852     wl_text_input_set_return_key_disabled(imcontext->text_input,
1853             imcontext->return_key_disabled);
1854
1855     if (imcontext->imdata_size > 0)
1856         wl_text_input_set_input_panel_data(imcontext->text_input, (const char *)imcontext->imdata, imcontext->imdata_size);
1857
1858     wl_text_input_bidi_direction(imcontext->text_input, imcontext->bidi_direction);
1859
1860     set_autocapital (ctx);
1861
1862     if (imcontext->mime_type)
1863         wl_text_input_set_mime_type(imcontext->text_input, imcontext->mime_type);
1864
1865     if (imcontext->input_panel_position.x >= 0 && imcontext->input_panel_position.y >= 0)
1866             wl_text_input_set_input_panel_position(imcontext->text_input,
1867                 imcontext->input_panel_position.x, imcontext->input_panel_position.y);
1868
1869     LOGD ("ctx : %p, layout : %d, layout variation : %d, language : %d, cursor position : %d",
1870            ctx, layout, layout_variation,
1871            ecore_imf_context_input_panel_language_get (ctx),
1872            cursor_pos);
1873     LOGD ("input hint : %#x, bidi direction : %d, return key type : %d, return key disabled : %d, autocapital type : %d",
1874            ecore_imf_context_input_hint_get (ctx),
1875            imcontext->bidi_direction,
1876            ecore_imf_context_input_panel_return_key_type_get (ctx),
1877            ecore_imf_context_input_panel_return_key_disabled_get (ctx),
1878            ecore_imf_context_autocapital_type_get (ctx));
1879     LOGD ("client_window : %#lx, Ecore_Wl2_Window : %p, password mode : %d, prediction_allow : %d, mime_type : %s, input panel position x : %d, y : %d",
1880            (unsigned long int)ecore_imf_context_client_window_get (ctx),
1881            imcontext->window,
1882            (imcontext->content_hint & WL_TEXT_INPUT_CONTENT_HINT_SENSITIVE_DATA) ? 1 : 0,
1883            ecore_imf_context_prediction_allow_get (ctx),
1884            imcontext->mime_type,
1885            imcontext->input_panel_position.x,
1886            imcontext->input_panel_position.y);
1887
1888     if (_active_context_canvas && !evas_focus_state_get (_active_context_canvas)) {
1889         LOGW ("Canvas does not have focus!");
1890     }
1891     //
1892
1893     if (hw_keyboard_mode) {
1894         LOGD("hw_keyboard_mode is TRUE, returning");
1895         return EINA_FALSE;
1896     }
1897
1898     _input_panel_state = ECORE_IMF_INPUT_PANEL_STATE_WILL_SHOW;
1899
1900     wl_text_input_show_input_panel(imcontext->text_input);
1901
1902     if (imcontext->window) {
1903         _active_context_window_id = ecore_wl2_window_id_get(imcontext->window);
1904         imcontext->has_conformant = ecore_wl2_window_conformant_get(imcontext->window);
1905     } else {
1906         imcontext->has_conformant = EINA_FALSE;
1907     }
1908
1909     return EINA_TRUE;
1910 }
1911
1912 static void delete_surrounding_text(WaylandIMContext *imcontext, int index, int length)
1913 {
1914     Ecore_IMF_Event_Delete_Surrounding ev;
1915     LOGD("delete surrounding text (index: %d, length: %u)",
1916             index, length);
1917
1918     ev.offset = index;
1919     ev.n_chars = length;
1920
1921     ecore_imf_context_event_callback_call(imcontext->ctx, ECORE_IMF_CALLBACK_DELETE_SURROUNDING, &ev);
1922 }
1923
1924 static void
1925 text_input_preedit_string(void                 *data,
1926                           struct wl_text_input *text_input EINA_UNUSED,
1927                           uint32_t              serial,
1928                           const char           *text,
1929                           const char           *commit)
1930 {
1931     WaylandIMContext *imcontext = (WaylandIMContext *)data;
1932     Eina_Bool old_preedit = EINA_FALSE;
1933     Eina_Bool preedit_changed = EINA_FALSE;
1934
1935     SECURE_LOGD("ctx : %p, preedit event (text: '%s', current pre-edit: '%s')",
1936                 imcontext->ctx,
1937                 text,
1938                 imcontext->preedit_text ? imcontext->preedit_text : "");
1939
1940     if (!check_serial(imcontext, serial))
1941         return;
1942
1943     old_preedit =
1944         imcontext->preedit_text && strlen(imcontext->preedit_text) > 0;
1945
1946     if (imcontext->preedit_text)
1947         preedit_changed = (strcmp(imcontext->preedit_text, text) != 0);
1948     else
1949         preedit_changed = (strlen(text) != 0);
1950
1951     if (_preedit_cursor_changed) {
1952         preedit_changed = EINA_TRUE;
1953         _preedit_cursor_changed = EINA_FALSE;
1954     }
1955
1956     if (imcontext->pending_preedit.attrs)
1957         preedit_changed = EINA_TRUE;
1958
1959     clear_preedit(imcontext);
1960
1961     imcontext->preedit_text = strdup(text);
1962     imcontext->preedit_commit = (strlen(text) > 0 ? strdup(commit) : NULL);
1963     imcontext->preedit_cursor =
1964         utf8_offset_to_characters(text, imcontext->pending_preedit.cursor);
1965     imcontext->preedit_attrs = imcontext->pending_preedit.attrs;
1966
1967     imcontext->pending_preedit.attrs = NULL;
1968
1969     if (preedit_changed) {
1970         if (!old_preedit) {
1971             ecore_imf_context_event_callback_call(imcontext->ctx,
1972                     ECORE_IMF_CALLBACK_PREEDIT_START,
1973                     NULL);
1974         }
1975
1976         ecore_imf_context_event_callback_call(imcontext->ctx,
1977                 ECORE_IMF_CALLBACK_PREEDIT_CHANGED,
1978                 NULL);
1979
1980         if (imcontext->preedit_text && strlen(imcontext->preedit_text) == 0) {
1981             ecore_imf_context_event_callback_call(imcontext->ctx,
1982                     ECORE_IMF_CALLBACK_PREEDIT_END,
1983                     NULL);
1984         }
1985     }
1986 }
1987
1988 static void
1989 text_input_delete_surrounding_text(void                 *data,
1990                                    struct wl_text_input *text_input EINA_UNUSED,
1991                                    int32_t               index,
1992                                    uint32_t              length)
1993 {
1994     WaylandIMContext *imcontext = (WaylandIMContext *)data;
1995     delete_surrounding_text(imcontext, index, length);
1996 }
1997
1998 static void
1999 text_input_cursor_position(void                 *data EINA_UNUSED,
2000                            struct wl_text_input *text_input EINA_UNUSED,
2001                            int32_t               index,
2002                            int32_t               anchor)
2003 {
2004     LOGD("cursor_position for next commit (index: %d, anchor: %d)",
2005             index, anchor);
2006 }
2007
2008 static void
2009 text_input_preedit_styling(void                 *data,
2010                            struct wl_text_input *text_input EINA_UNUSED,
2011                            uint32_t              index,
2012                            uint32_t              length,
2013                            uint32_t              style)
2014 {
2015     WaylandIMContext *imcontext = (WaylandIMContext *)data;
2016     Ecore_IMF_Preedit_Attr *attr = calloc(1, sizeof(*attr));
2017     if (!attr) return;
2018
2019     switch (style)
2020     {
2021         case WL_TEXT_INPUT_PREEDIT_STYLE_DEFAULT:
2022             attr->preedit_type = ECORE_IMF_PREEDIT_TYPE_NONE;
2023             break;
2024         case WL_TEXT_INPUT_PREEDIT_STYLE_UNDERLINE:
2025             attr->preedit_type = ECORE_IMF_PREEDIT_TYPE_SUB1;
2026             break;
2027         case WL_TEXT_INPUT_PREEDIT_STYLE_REVERSE:
2028             attr->preedit_type = ECORE_IMF_PREEDIT_TYPE_SUB2;
2029             break;
2030         case WL_TEXT_INPUT_PREEDIT_STYLE_HIGHLIGHT:
2031             attr->preedit_type = ECORE_IMF_PREEDIT_TYPE_SUB3;
2032             break;
2033         case WL_TEXT_INPUT_PREEDIT_STYLE_BGCOLOR1:
2034             attr->preedit_type = ECORE_IMF_PREEDIT_TYPE_SUB4;
2035             break;
2036         case WL_TEXT_INPUT_PREEDIT_STYLE_BGCOLOR2:
2037             attr->preedit_type = ECORE_IMF_PREEDIT_TYPE_SUB5;
2038             break;
2039         case WL_TEXT_INPUT_PREEDIT_STYLE_BGCOLOR3:
2040             attr->preedit_type = ECORE_IMF_PREEDIT_TYPE_SUB6;
2041             break;
2042         case WL_TEXT_INPUT_PREEDIT_STYLE_BGCOLOR4:
2043             attr->preedit_type = ECORE_IMF_PREEDIT_TYPE_SUB7;
2044             break;
2045         default:
2046             attr->preedit_type = ECORE_IMF_PREEDIT_TYPE_SUB1;
2047             break;
2048     }
2049
2050     attr->start_index = index;
2051     attr->end_index = index + length;
2052
2053     imcontext->pending_preedit.attrs =
2054         eina_list_append(imcontext->pending_preedit.attrs, attr);
2055 }
2056
2057 static void
2058 text_input_preedit_cursor(void                 *data,
2059                           struct wl_text_input *text_input EINA_UNUSED,
2060                           int32_t               index)
2061 {
2062     WaylandIMContext *imcontext = (WaylandIMContext *)data;
2063
2064     LOGD("preedit cursor : %d", index);
2065
2066     if (imcontext->pending_preedit.cursor != index) {
2067         imcontext->pending_preedit.cursor = index;
2068         _preedit_cursor_changed = EINA_TRUE;
2069     }
2070 }
2071
2072 static xkb_mod_index_t
2073 modifiers_get_index(struct wl_array *modifiers_map, const char *name)
2074 {
2075     xkb_mod_index_t index = 0;
2076     char *p = modifiers_map->data;
2077
2078     while ((const char *)p < ((const char *)modifiers_map->data + modifiers_map->size))
2079     {
2080         if (strcmp(p, name) == 0)
2081             return index;
2082
2083         index++;
2084         p += strlen(p) + 1;
2085     }
2086
2087     return XKB_MOD_INVALID;
2088 }
2089
2090 static xkb_mod_mask_t
2091 modifiers_get_mask(struct wl_array *modifiers_map,
2092         const char *name)
2093 {
2094     xkb_mod_index_t index = modifiers_get_index(modifiers_map, name);
2095
2096     if (index == XKB_MOD_INVALID)
2097         return XKB_MOD_INVALID;
2098
2099     return 1 << index;
2100 }
2101
2102 static void
2103 text_input_modifiers_map(void                 *data,
2104                          struct wl_text_input *text_input EINA_UNUSED,
2105                          struct wl_array      *map)
2106 {
2107     WaylandIMContext *imcontext = (WaylandIMContext *)data;
2108     imcontext->shift_mask = modifiers_get_mask(map, XKB_MOD_NAME_SHIFT);
2109     imcontext->control_mask = modifiers_get_mask(map, XKB_MOD_NAME_CTRL);
2110     imcontext->alt_mask = modifiers_get_mask(map, XKB_MOD_NAME_ALT);
2111     imcontext->caps_mask = modifiers_get_mask(map, XKB_MOD_NAME_CAPS);
2112     imcontext->num_mask = modifiers_get_mask(map, XKB_MOD_NAME_NUM);
2113 }
2114
2115 static void
2116 _ecore_keyevent_free (void *data EINA_UNUSED, void *ev)
2117 {
2118     Ecore_Event_Key *e = ev;
2119     if (e->dev) ecore_device_unref(e->dev);
2120     free(e);
2121     e = NULL;
2122 }
2123
2124 static void
2125 text_input_keysym(void                 *data,
2126                   struct wl_text_input *text_input EINA_UNUSED,
2127                   uint32_t              serial EINA_UNUSED,
2128                   uint32_t              time,
2129                   uint32_t              sym,
2130                   uint32_t              state,
2131                   uint32_t              modifiers)
2132 {
2133     WaylandIMContext *imcontext = (WaylandIMContext *)data;
2134     char string[32] = {'\0'};
2135     char key[32] = {'\0'};
2136     char keyname[32] = {'\0'};
2137     Ecore_Event_Key *e;
2138
2139     memset(key, 0, sizeof(key));
2140     xkb_keysym_get_name(sym, key, sizeof(key));
2141
2142     memset(keyname, 0, sizeof(keyname));
2143     xkb_keysym_get_name(sym, keyname, sizeof(keyname));
2144     if (keyname[0] == '\0')
2145         snprintf(keyname, sizeof(keyname), "Keysym-%u", sym);
2146
2147     memset(string, 0, sizeof(string));
2148     xkb_keysym_to_utf8(sym, string, 32);
2149
2150     SECURE_LOGD("key event (key: %s)", keyname);
2151
2152     unsigned int key_len = strlen(key);
2153     unsigned int key_name_len = strlen(keyname);
2154     unsigned int key_string_len = strlen(string);
2155
2156     if (key_len > sizeof(key)-1)
2157         key_len = sizeof(key)-1;
2158
2159     if (key_name_len > sizeof(keyname)-1)
2160         key_name_len = sizeof(keyname)-1;
2161
2162     if (key_string_len > sizeof(string)-1)
2163         key_string_len = sizeof(string)-1;
2164
2165     e = calloc(1, sizeof(Ecore_Event_Key) + key_len + key_name_len +
2166             key_string_len + 3);
2167     if (!e) return;
2168
2169     e->keyname = (char *)(e + 1);
2170     e->key = e->keyname + key_name_len + 1;
2171     e->string = e->key + key_len + 1;
2172     e->compose = e->string;
2173
2174     memcpy((void *)e->keyname, keyname, key_name_len);
2175     *((char *)e->keyname + key_name_len) = '\0';
2176     memcpy((void *)e->key, key, key_len);
2177     *((char *)e->key + key_len) = '\0';
2178     memcpy((void *)e->string, string, key_string_len);
2179     *((char *)e->string + key_string_len) = '\0';
2180
2181     e->window = (Ecore_Window)ecore_wl2_window_id_get(imcontext->window);
2182     e->event_window = (Ecore_Window)ecore_wl2_window_id_get(imcontext->window);
2183     e->dev = ecore_device_ref(_ime_device);
2184     e->timestamp = 0; /* For distinguishing S/W keyboard event */
2185
2186     e->modifiers = 0;
2187     if (modifiers & imcontext->shift_mask)
2188         e->modifiers |= ECORE_EVENT_MODIFIER_SHIFT;
2189
2190     if (modifiers & imcontext->control_mask)
2191         e->modifiers |= ECORE_EVENT_MODIFIER_CTRL;
2192
2193     if (modifiers & imcontext->alt_mask)
2194         e->modifiers |= ECORE_EVENT_MODIFIER_ALT;
2195
2196     if (modifiers & MOD_Mod5_MASK)
2197         e->modifiers |= MOD_Mod5_MASK;
2198
2199     if (modifiers & imcontext->caps_mask)
2200         e->modifiers |= ECORE_EVENT_LOCK_CAPS;
2201
2202     if (modifiers & imcontext->num_mask)
2203         e->modifiers |= ECORE_EVENT_LOCK_NUM;
2204
2205     //Save "wl_text_input::keysym" keysym to list if list is not empty,
2206     //if not, send keysym to ecore loop as key event.
2207     //This code let key event which will be filtered by IME one by one.
2208     if (eina_list_count(imcontext->keysym_list)) {
2209         e->data = (void *)(unsigned long int)(state ? ECORE_EVENT_KEY_DOWN : ECORE_EVENT_KEY_UP);
2210         imcontext->keysym_list = eina_list_prepend(imcontext->keysym_list, e);
2211     }
2212     else {
2213         if (state)
2214             ecore_event_add(ECORE_EVENT_KEY_DOWN, e, _ecore_keyevent_free, NULL);
2215         else
2216             ecore_event_add(ECORE_EVENT_KEY_UP, e, _ecore_keyevent_free, NULL);
2217     }
2218 }
2219
2220 static void
2221 text_input_enter(void                 *data,
2222                  struct wl_text_input *text_input EINA_UNUSED,
2223                  struct wl_surface    *surface EINA_UNUSED)
2224 {
2225     WaylandIMContext *imcontext = (WaylandIMContext *)data;
2226
2227     update_state(imcontext);
2228
2229     imcontext->reset_serial = imcontext->serial;
2230 }
2231
2232 static void
2233 text_input_leave(void                 *data,
2234                  struct wl_text_input *text_input EINA_UNUSED)
2235 {
2236     WaylandIMContext *imcontext = (WaylandIMContext *)data;
2237
2238     /* clear preedit */
2239     commit_preedit(imcontext);
2240     clear_preedit(imcontext);
2241 }
2242
2243 static void
2244 text_input_input_panel_state(void                 *data EINA_UNUSED,
2245                              struct wl_text_input *text_input EINA_UNUSED,
2246                              uint32_t              state EINA_UNUSED)
2247 {
2248     // TIZEN_ONLY(20150708): Support input panel state callback
2249     WaylandIMContext *imcontext = (WaylandIMContext *)data;
2250     LOGD("input panel state: %d", state);
2251     switch (state) {
2252         case WL_TEXT_INPUT_INPUT_PANEL_STATE_HIDE:
2253             _input_panel_state = ECORE_IMF_INPUT_PANEL_STATE_HIDE;
2254             if (imcontext->ctx == _show_req_ctx)
2255                 _show_req_ctx = NULL;
2256
2257             will_hide = EINA_FALSE;
2258
2259             _received_will_hide_event = EINA_TRUE;
2260             LOGD("_received_will_hide_event = 1");
2261             send_will_hide_ack(imcontext->ctx);
2262             break;
2263         case WL_TEXT_INPUT_INPUT_PANEL_STATE_SHOW:
2264             _input_panel_state = ECORE_IMF_INPUT_PANEL_STATE_SHOW;
2265             _received_will_hide_event = EINA_FALSE;
2266             if (!_show_req_ctx)
2267                 _show_req_ctx = imcontext->ctx;
2268             LOGD("_received_will_hide_event = 0");
2269             break;
2270         default:
2271             _input_panel_state = (Ecore_IMF_Input_Panel_State)state;
2272             break;
2273     }
2274
2275     ecore_imf_context_input_panel_event_callback_call(imcontext->ctx,
2276             ECORE_IMF_INPUT_PANEL_STATE_EVENT,
2277             _input_panel_state);
2278
2279     if (state == WL_TEXT_INPUT_INPUT_PANEL_STATE_HIDE) {
2280         reset_keyboard_geometry();
2281         LOGD ("IME geometry x : %d, y : %d, w : %d, h : %d", _keyboard_geometry.x, _keyboard_geometry.y, _keyboard_geometry.w, _keyboard_geometry.h);
2282         ecore_imf_context_input_panel_event_callback_call(imcontext->ctx, ECORE_IMF_INPUT_PANEL_GEOMETRY_EVENT, 0);
2283     }
2284     //
2285 }
2286
2287 // TIZEN_ONLY(20151221): Support input panel geometry
2288 static void
2289 text_input_input_panel_geometry(void                 *data EINA_UNUSED,
2290                                 struct wl_text_input *text_input EINA_UNUSED,
2291                                 uint32_t              x,
2292                                 uint32_t              y,
2293                                 uint32_t              w,
2294                                 uint32_t              h)
2295 {
2296     WaylandIMContext *imcontext = (WaylandIMContext *)data;
2297
2298     if (_keyboard_geometry.x != (int)x || _keyboard_geometry.y != (int)y ||
2299         _keyboard_geometry.w != (int)w || _keyboard_geometry.h != (int)h)
2300     {
2301         _keyboard_geometry.x = x;
2302         _keyboard_geometry.y = y;
2303         _keyboard_geometry.w = w;
2304         _keyboard_geometry.h = h;
2305         LOGD ("IME geometry x : %d, y : %d, w : %d, h : %d", _keyboard_geometry.x, _keyboard_geometry.y, _keyboard_geometry.w, _keyboard_geometry.h);
2306         ecore_imf_context_input_panel_event_callback_call(imcontext->ctx, ECORE_IMF_INPUT_PANEL_GEOMETRY_EVENT, 0);
2307     }
2308 }
2309 //
2310
2311 static void
2312 text_input_language(void                 *data,
2313                     struct wl_text_input *text_input EINA_UNUSED,
2314                     uint32_t              serial EINA_UNUSED,
2315                     const char           *language)
2316 {
2317     WaylandIMContext *imcontext = (WaylandIMContext *)data;
2318     Eina_Bool changed = EINA_FALSE;
2319
2320     if (!imcontext || !language) return;
2321
2322     if (imcontext->language) {
2323         if (strcmp(imcontext->language, language) != 0) {
2324             changed = EINA_TRUE;
2325             free(imcontext->language);
2326         }
2327     }
2328     else {
2329         changed = EINA_TRUE;
2330     }
2331
2332     if (changed) {
2333         imcontext->language = strdup(language);
2334
2335         if (imcontext->ctx)
2336             ecore_imf_context_input_panel_event_callback_call(imcontext->ctx, ECORE_IMF_INPUT_PANEL_LANGUAGE_EVENT, 0);
2337     }
2338 }
2339
2340 static void
2341 text_input_text_direction(void                 *data EINA_UNUSED,
2342                           struct wl_text_input *text_input EINA_UNUSED,
2343                           uint32_t              serial EINA_UNUSED,
2344                           uint32_t              direction EINA_UNUSED)
2345 {
2346 }
2347
2348 // TIZEN_ONLY(20150918): Support to set the selection region
2349 static void
2350 text_input_selection_region(void                 *data,
2351                             struct wl_text_input *text_input EINA_UNUSED,
2352                             uint32_t              serial EINA_UNUSED,
2353                             int32_t               start,
2354                             int32_t               end)
2355 {
2356     WaylandIMContext *imcontext = (WaylandIMContext *)data;
2357     if (!imcontext || !imcontext->ctx) return;
2358
2359     Ecore_IMF_Event_Selection ev;
2360     ev.ctx = imcontext->ctx;
2361     ev.start = start;
2362     ev.end = end;
2363     ecore_imf_context_event_callback_call(imcontext->ctx, ECORE_IMF_CALLBACK_SELECTION_SET, &ev);
2364 }
2365
2366 static void
2367 text_input_private_command(void                 *data,
2368                            struct wl_text_input *text_input EINA_UNUSED,
2369                            uint32_t              serial EINA_UNUSED,
2370                            const char           *command)
2371 {
2372     WaylandIMContext *imcontext = (WaylandIMContext *)data;
2373     if (!imcontext || !imcontext->ctx) return;
2374
2375     const char *szConformantReset = "CONFORMANT_RESET";
2376     const char *szConformantRestore = "CONFORMANT_RESTORE";
2377     LOGD("Checking command : %s", command);
2378
2379     if (strncmp(command, szConformantReset, strlen(szConformantReset)) == 0) {
2380         Ecore_Wl2_Window *window = imcontext->window;
2381         if (!window) return;
2382
2383         if (!reset_conformant_area(imcontext->ctx) && !_conformant_reset_started) {
2384             LOGD("Could not reset conformant area, send will_hide_ack right away %d", _conformant_reset_started);
2385             _send_will_hide_ack(imcontext);
2386         } else if (_conformant_reset_done) {
2387             LOGD("Conformant reset has been already finished, send will_hide_ack right away");
2388             _send_will_hide_ack(imcontext);
2389         }
2390     } else if (strncmp(command, szConformantRestore, strlen(szConformantRestore)) == 0) {
2391         Ecore_Wl2_Window *window = imcontext->window;
2392         if (!window) return;
2393
2394         restore_conformant_area(imcontext->ctx);
2395     } else {
2396         ecore_imf_context_event_callback_call(imcontext->ctx, ECORE_IMF_CALLBACK_PRIVATE_COMMAND_SEND, (void *)command);
2397     }
2398 }
2399
2400 static void
2401 text_input_commit_content(void                 *data,
2402                           struct wl_text_input *text_input EINA_UNUSED,
2403                           uint32_t              serial EINA_UNUSED,
2404                           const char           *content,
2405                           const char           *description,
2406                           const char           *mime_types)
2407 {
2408     WaylandIMContext *imcontext = (WaylandIMContext *)data;
2409     if (!imcontext || !imcontext->ctx) return;
2410
2411     Ecore_IMF_Event_Commit_Content ev;
2412     ev.content_uri = content;
2413     ev.mime_types = mime_types;
2414     ev.description = description;
2415
2416     SECURE_LOGD("commit content : %s, description : %s, mime types : %s", content, description, mime_types);
2417
2418     ecore_imf_context_event_callback_call(imcontext->ctx, ECORE_IMF_CALLBACK_COMMIT_CONTENT, (void *)&ev);
2419 }
2420
2421 static void
2422 text_input_input_panel_data(void                 *data,
2423                             struct wl_text_input *text_input EINA_UNUSED,
2424                             uint32_t              serial EINA_UNUSED,
2425                             const char           *input_panel_data,
2426                             uint32_t              length)
2427 {
2428     WaylandIMContext *imcontext = (WaylandIMContext *)data;
2429     if (!imcontext || !imcontext->ctx) return;
2430
2431     if (imcontext->input_panel_data)
2432         free (imcontext->input_panel_data);
2433
2434     imcontext->input_panel_data = calloc (1, length);
2435     if (imcontext->input_panel_data)
2436         memcpy (imcontext->input_panel_data, input_panel_data, length);
2437
2438     imcontext->input_panel_data_length = length;
2439 }
2440
2441 static void
2442 text_input_get_selection_text (void                 *data,
2443                                struct wl_text_input *text_input EINA_UNUSED,
2444                                int32_t              fd)
2445 {
2446     char *selection = NULL;
2447     LOGD ("%d", fd);
2448     WaylandIMContext *imcontext = (WaylandIMContext *)data;
2449     if (!imcontext || !imcontext->ctx) {
2450         LOGD ("No context!");
2451         close (fd);
2452         return;
2453     }
2454
2455     ecore_imf_context_selection_get (imcontext->ctx, &selection);
2456     if (imcontext->text_input) {
2457         SECURE_LOGD ("selection :%s", selection ? selection : "");
2458         if (selection) {
2459             char *_selection = selection;
2460             size_t len = strlen (selection);
2461             while (len) {
2462                 ssize_t ret = write (fd, _selection, len);
2463                 if (ret <= 0) {
2464                     if (errno == EINTR)
2465                         continue;
2466                     LOGW ("write pipe failed, errno: %d", errno);
2467                     break;
2468                 }
2469                 _selection += ret;
2470                 len -= ret;
2471             }
2472         }
2473     }
2474     if (selection)
2475         free (selection);
2476     close (fd);
2477 }
2478
2479 static void
2480 text_input_get_surrounding_text (void                 *data,
2481                                  struct wl_text_input *text_input EINA_UNUSED,
2482                                  uint32_t              maxlen_before,
2483                                  uint32_t              maxlen_after,
2484                                  int32_t              fd)
2485 {
2486     int cursor_pos;
2487     char *surrounding = NULL;
2488     LOGD("fd: %d maxlen_before: %d maxlen_after: %d", fd, maxlen_before, maxlen_after);
2489     WaylandIMContext *imcontext = (WaylandIMContext *)data;
2490     if (!imcontext || !imcontext->ctx) {
2491         LOGD ("No context!");
2492         close(fd);
2493         return;
2494     }
2495
2496     /* cursor_pos is a byte index */
2497     if (ecore_imf_context_surrounding_get (imcontext->ctx, &surrounding, &cursor_pos)) {
2498         SECURE_LOGD ("surrounding : '%s', cursor: %d", surrounding ? surrounding : "", cursor_pos);
2499         if (imcontext->text_input) {
2500             Eina_Unicode *wide_surrounding = eina_unicode_utf8_to_unicode (surrounding, NULL);
2501             size_t wlen = eina_unicode_strlen (wide_surrounding);
2502
2503             if (cursor_pos > (int)wlen || cursor_pos < 0)
2504                 cursor_pos = 0;
2505
2506             if (maxlen_before > cursor_pos)
2507                 maxlen_before = 0;
2508             else
2509                 maxlen_before = cursor_pos - maxlen_before;
2510
2511             if (maxlen_after > wlen - cursor_pos)
2512                 maxlen_after = (uint32_t)wlen;
2513             else
2514                 maxlen_after = cursor_pos + maxlen_after;
2515
2516             char *req_surrounding = eina_unicode_unicode_to_utf8_range (wide_surrounding + maxlen_before, maxlen_after - maxlen_before, NULL);
2517
2518             ssize_t ret = write(fd, &cursor_pos, sizeof(cursor_pos));
2519             if (ret <= 0) {
2520                 LOGW ("write pipe failed, errno: %d", errno);
2521             } else if (req_surrounding) {
2522                 char *_surrounding = req_surrounding;
2523                 size_t len = strlen(req_surrounding);
2524                 while (len) {
2525                     ssize_t ret = write(fd, _surrounding, len);
2526                     if (ret <= 0) {
2527                         if (errno == EINTR)
2528                             continue;
2529                         LOGW ("write pipe failed, errno: %d", errno);
2530                         break;
2531                     }
2532                     _surrounding += ret;
2533                     len -= ret;
2534                 }
2535             }
2536
2537             if (req_surrounding)
2538                 free (req_surrounding);
2539
2540             if (wide_surrounding)
2541                 free (wide_surrounding);
2542         }
2543
2544         if (surrounding)
2545             free (surrounding);
2546     }
2547     close(fd);
2548 }
2549
2550 static void
2551 text_input_filter_key_event_done(void                 *data,
2552                                  struct wl_text_input *text_input EINA_UNUSED,
2553                                  uint32_t              serial,
2554                                  uint32_t              state)
2555 {
2556     LOGD("serial: %d, state: %d", serial, state);
2557     WaylandIMContext *imcontext = (WaylandIMContext *)data;
2558     if (!imcontext) return;
2559
2560     imcontext->last_key_event_filter.serial = serial;
2561     imcontext->last_key_event_filter.state = state;
2562 }
2563
2564 static void
2565 text_input_hide_permission(void                 *data,
2566                            struct wl_text_input *text_input EINA_UNUSED,
2567                            uint32_t              permission)
2568 {
2569     LOGD("permission : %d", permission);
2570     WaylandIMContext *imcontext = (WaylandIMContext *)data;
2571     if (!imcontext || !imcontext->ctx || ignore_hide)
2572         return;
2573
2574     if (permission)
2575         ecore_imf_context_input_panel_hide(imcontext->ctx);
2576 }
2577
2578 static void
2579 text_input_recapture_string(void                 *data,
2580                             struct wl_text_input *text_input EINA_UNUSED,
2581                             uint32_t              serial,
2582                             int32_t               index,
2583                             uint32_t              length,
2584                             const char           *preedit,
2585                             const char           *preedit_commit,
2586                             const char           *commit)
2587 {
2588     WaylandIMContext *imcontext = (WaylandIMContext *)data;
2589     Eina_Bool old_preedit = EINA_FALSE;
2590     Eina_Bool preedit_changed = EINA_FALSE;
2591
2592     SECURE_LOGD("ctx : %p, index : %d, length : %d, preedit event (preedit: '%s', current pre-edit: '%s')",
2593                 imcontext->ctx,
2594                 index,
2595                 length,
2596                 preedit,
2597                 imcontext->preedit_text ? imcontext->preedit_text : "");
2598
2599     if (!check_serial(imcontext, serial))
2600         return;
2601
2602     old_preedit =
2603         imcontext->preedit_text && strlen(imcontext->preedit_text) > 0;
2604
2605     if (imcontext->preedit_text)
2606         preedit_changed = (strcmp(imcontext->preedit_text, preedit) != 0);
2607     else
2608         preedit_changed = (strlen(preedit) != 0);
2609
2610     // send transaction start
2611     ecore_imf_context_event_callback_call(imcontext->ctx, ECORE_IMF_CALLBACK_PRIVATE_COMMAND_SEND, (void *)"TRANSACTION_START");
2612     ecore_imf_context_event_callback_call(imcontext->ctx, ECORE_IMF_CALLBACK_TRANSACTION_START, NULL);
2613
2614     commit_preedit(imcontext);
2615     clear_preedit(imcontext);
2616
2617     // delete surrounding text
2618     delete_surrounding_text(imcontext, index, length);
2619
2620     // update preedit string
2621     imcontext->preedit_text = strdup(preedit);
2622     imcontext->preedit_commit = (strlen(preedit) > 0 ? strdup(preedit_commit) : NULL);
2623     imcontext->preedit_cursor =
2624         utf8_offset_to_characters(preedit, imcontext->pending_preedit.cursor);
2625     imcontext->preedit_attrs = imcontext->pending_preedit.attrs;
2626
2627     imcontext->pending_preedit.attrs = NULL;
2628
2629     if (preedit_changed) {
2630         if (!old_preedit) {
2631             ecore_imf_context_event_callback_call(imcontext->ctx,
2632                     ECORE_IMF_CALLBACK_PREEDIT_START,
2633                     NULL);
2634         }
2635
2636         ecore_imf_context_event_callback_call(imcontext->ctx,
2637                 ECORE_IMF_CALLBACK_PREEDIT_CHANGED,
2638                 NULL);
2639
2640         if (imcontext->preedit_text && strlen(imcontext->preedit_text) == 0) {
2641             ecore_imf_context_event_callback_call(imcontext->ctx,
2642                     ECORE_IMF_CALLBACK_PREEDIT_END,
2643                     NULL);
2644         }
2645     }
2646
2647     // commit string
2648     if (commit && strlen(commit) != 0) {
2649         ecore_imf_context_event_callback_call(imcontext->ctx, ECORE_IMF_CALLBACK_COMMIT, (void *)commit);
2650     }
2651
2652     // send transaction end
2653     ecore_imf_context_event_callback_call(imcontext->ctx, ECORE_IMF_CALLBACK_PRIVATE_COMMAND_SEND, (void *)"TRANSACTION_END");
2654     ecore_imf_context_event_callback_call(imcontext->ctx, ECORE_IMF_CALLBACK_TRANSACTION_END, NULL);
2655 }
2656
2657 static void
2658 text_input_input_panel_event(void                 *data,
2659                              struct wl_text_input *text_input EINA_UNUSED,
2660                              uint32_t              serial EINA_UNUSED,
2661                              uint32_t              event_type,
2662                              uint32_t              value)
2663 {
2664     WaylandIMContext *imcontext = (WaylandIMContext *)data;
2665     if (!imcontext || !imcontext->ctx) return;
2666
2667     LOGD("event type : %d, value : %d", event_type, value);
2668
2669     ecore_imf_context_input_panel_event_callback_call(imcontext->ctx, event_type, value);
2670 }
2671 //
2672
2673 static const struct wl_text_input_listener text_input_listener =
2674 {
2675     text_input_enter,
2676     text_input_leave,
2677     text_input_modifiers_map,
2678     text_input_input_panel_state,
2679     text_input_preedit_string,
2680     text_input_preedit_styling,
2681     text_input_preedit_cursor,
2682     text_input_commit_string,
2683     text_input_cursor_position,
2684     text_input_delete_surrounding_text,
2685     text_input_keysym,
2686     text_input_language,
2687     text_input_text_direction,
2688     // TIZEN_ONLY(20150918): Support to set the selection region
2689     text_input_selection_region,
2690     text_input_private_command,
2691     text_input_input_panel_geometry,
2692     text_input_input_panel_data,
2693     text_input_get_selection_text,
2694     text_input_get_surrounding_text,
2695     text_input_filter_key_event_done,
2696     text_input_hide_permission,
2697     text_input_recapture_string,
2698     text_input_input_panel_event,
2699     text_input_commit_content
2700     //
2701 };
2702
2703 #ifdef HAVE_VCONF
2704 static void
2705 keyboard_mode_changed_cb (keynode_t *key, void* data)
2706 {
2707     hw_keyboard_mode = vconf_keynode_get_bool (key);
2708     Ecore_IMF_Context *active_ctx = get_using_ctx ();
2709     if (active_ctx) {
2710         LOGD ("ctx : %p, input detect : %d", active_ctx, hw_keyboard_mode);
2711
2712         Ecore_IMF_Input_Panel_Keyboard_Mode input_mode = hw_keyboard_mode ? ECORE_IMF_INPUT_PANEL_HW_KEYBOARD_MODE : ECORE_IMF_INPUT_PANEL_SW_KEYBOARD_MODE;
2713         ecore_imf_context_input_panel_event_callback_call (active_ctx, ECORE_IMF_INPUT_PANEL_KEYBOARD_MODE_EVENT, input_mode);
2714
2715         if (input_mode == ECORE_IMF_INPUT_PANEL_HW_KEYBOARD_MODE && _input_panel_state == ECORE_IMF_INPUT_PANEL_STATE_WILL_SHOW)
2716             _input_panel_state = ECORE_IMF_INPUT_PANEL_STATE_HIDE;
2717
2718         if ((input_mode == ECORE_IMF_INPUT_PANEL_SW_KEYBOARD_MODE) && _focused_ctx && (active_ctx == _focused_ctx)) {
2719             if (ecore_imf_context_input_panel_enabled_get (active_ctx)) {
2720                 ecore_imf_context_input_panel_show (active_ctx);
2721             }
2722         }
2723     }
2724 }
2725 #endif
2726
2727 #ifdef SOCKET_ACTIVATION
2728 static int activate_socket () {
2729     int s;
2730     struct sockaddr_un svr;
2731     int len;
2732     int r;
2733     int cnt = 5;
2734     int flag;
2735
2736     LOGD("socket_activate start");
2737     s = socket(AF_UNIX, SOCK_STREAM, 0);
2738     if (s == -1) {
2739         LOGW("socket error");
2740         return -1;
2741     }
2742
2743     flag = fcntl(s, F_GETFL, NULL);
2744     flag |= O_NONBLOCK;
2745     fcntl(s, F_SETFL, flag);
2746
2747     svr.sun_family = AF_UNIX;
2748     strcpy(svr.sun_path, SOCK_PATH);
2749     len = sizeof(svr);
2750
2751     r = connect(s, (struct sockaddr *)&svr, len);
2752     if (r == -1) {
2753         LOGD("connect error");
2754         close(s);
2755         return -1;
2756     }
2757
2758     while (cnt > 0) {
2759         struct timeval s1;
2760
2761         gettimeofday(&s1, NULL);
2762         LOGD("%d %06d\n", (int)s1.tv_sec, (int)s1.tv_usec);
2763
2764         r = send(s, (const void *)&s1, sizeof(s1), 0);
2765         if (r == -1) {
2766             LOGW("send error");
2767             break;
2768         }
2769         cnt--;
2770     }
2771
2772     close(s);
2773     return 0;
2774 }
2775 #endif
2776
2777 void wayland_im_initialize ()
2778 {
2779     register_key_handler ();
2780
2781     /* get input language vconf value */
2782     char *input_lang_str = vconf_get_str (VCONFKEY_ISF_INPUT_LANGUAGE);
2783     if (input_lang_str) {
2784         set_input_language (input_lang_str);
2785         free (input_lang_str);
2786     }
2787
2788 #ifdef HAVE_VCONF
2789     /* get autoperiod allow vconf value */
2790     int val;
2791     if (vconf_get_bool (VCONFKEY_AUTOPERIOD_ALLOW_BOOL, &val) == 0) {
2792         if (val == EINA_TRUE)
2793             autoperiod_allow = EINA_TRUE;
2794     }
2795
2796     /* get autocapital allow vconf value */
2797     if (vconf_get_bool (VCONFKEY_AUTOCAPITAL_ALLOW_BOOL, &val) == 0) {
2798         if (val == EINA_TRUE)
2799             autocap_allow = EINA_TRUE;
2800     }
2801
2802     /* get hardware keyboard input detected vconf value */
2803     if (vconf_get_bool (VCONFKEY_ISF_HW_KEYBOARD_INPUT_DETECTED, &val) == 0) {
2804         if (val == EINA_TRUE)
2805             hw_keyboard_mode = EINA_TRUE;
2806     }
2807
2808     vconf_notify_key_changed (VCONFKEY_AUTOCAPITAL_ALLOW_BOOL, autocapital_allow_changed_cb, NULL);
2809     vconf_notify_key_changed (VCONFKEY_AUTOPERIOD_ALLOW_BOOL, autoperiod_allow_changed_cb, NULL);
2810     vconf_notify_key_changed (VCONFKEY_ISF_INPUT_LANGUAGE, input_language_changed_cb, NULL);
2811     vconf_notify_key_changed (VCONFKEY_ISF_HW_KEYBOARD_INPUT_DETECTED, keyboard_mode_changed_cb, NULL);
2812 #endif
2813
2814     _ime_device = ecore_device_add();
2815     if (_ime_device) {
2816         ecore_device_name_set (_ime_device, IME_DEVICE_NAME);
2817         ecore_device_description_set (_ime_device, IME_DEVICE_NAME);
2818         ecore_device_identifier_set (_ime_device, IME_DEVICE_NAME);
2819         ecore_device_class_set (_ime_device, ECORE_DEVICE_CLASS_KEYBOARD);
2820         ecore_device_subclass_set (_ime_device, ECORE_DEVICE_SUBCLASS_VIRTUAL_KEYBOARD);
2821     }
2822 }
2823
2824 void wayland_im_uninitialize ()
2825 {
2826     _ecore_imf_wayland_imcontext_pair_destroy ();
2827
2828     unregister_key_handler ();
2829
2830     _win_focus_out_handler_del ();
2831     _conformant_change_handler_del ();
2832
2833 #ifdef HAVE_VCONF
2834     vconf_ignore_key_changed (VCONFKEY_AUTOPERIOD_ALLOW_BOOL, autoperiod_allow_changed_cb);
2835     vconf_ignore_key_changed (VCONFKEY_AUTOCAPITAL_ALLOW_BOOL, autocapital_allow_changed_cb);
2836     vconf_ignore_key_changed (VCONFKEY_ISF_INPUT_LANGUAGE, input_language_changed_cb);
2837     vconf_ignore_key_changed (VCONFKEY_ISF_HW_KEYBOARD_INPUT_DETECTED, keyboard_mode_changed_cb);
2838 #endif
2839
2840     if (_ime_device) {
2841         ecore_device_del (_ime_device);
2842         _ime_device = NULL;
2843     }
2844
2845     ecore_event_type_flush(ECORE_EVENT_DEVICE_ADD, ECORE_EVENT_DEVICE_DEL);
2846 }
2847
2848 void
2849 wayland_im_context_add(Ecore_IMF_Context *ctx)
2850 {
2851     WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
2852     char *appid = NULL;
2853
2854     LOGD("ctx : %p", ctx);
2855
2856     if (!imcontext) return;
2857
2858     imcontext->ctx = ctx;
2859     imcontext->input_panel_layout = ECORE_IMF_INPUT_PANEL_LAYOUT_NORMAL;
2860     imcontext->keysym_list = NULL;
2861
2862     imcontext->shift_mask = MOD_SHIFT_MASK;
2863     imcontext->control_mask = MOD_CONTROL_MASK;
2864     imcontext->alt_mask = MOD_ALT_MASK;
2865     imcontext->caps_mask = MOD_CAPS_MASK;
2866     imcontext->num_mask = MOD_NUM_MASK;
2867
2868     imcontext->input_panel_position.x = -1;
2869     imcontext->input_panel_position.y = -1;
2870
2871     LOGD("text_input_manager : %p", imcontext->text_input_manager);
2872     imcontext->text_input =
2873         wl_text_input_manager_create_text_input(imcontext->text_input_manager);
2874
2875     if (imcontext->text_input)
2876         wl_text_input_add_listener(imcontext->text_input,
2877                                    &text_input_listener, imcontext);
2878
2879     app_get_id(&appid);
2880     LOGD("app id : %s\n", appid);
2881
2882     ecore_imf_context_prediction_hint_hash_set(ctx, "appid", appid ? appid : "");
2883
2884     if (appid)
2885         free (appid);
2886 }
2887
2888 void
2889 wayland_im_context_del (Ecore_IMF_Context *ctx)
2890 {
2891     WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
2892
2893     Eina_Bool valid = EINA_FALSE;
2894     Ecore_Imf_Wayland_Imcontext_Pair *pair = _ecore_imf_wayland_imcontext_pair_find(ctx);
2895     if (pair && pair->imcontext == imcontext) {
2896         _ecore_imf_wayland_imcontext_pair_del(ctx);
2897         valid = EINA_TRUE;
2898     }
2899     else {
2900         LOGE("The Ecore_Imf %p and WaylandIMContext %p pair not found!! pair : %p, pair->imcontext %p",
2901             ctx, imcontext, pair, pair ? pair->imcontext : NULL);
2902         _ecore_imf_wayland_imcontext_pair_log();
2903     }
2904
2905     Ecore_Event_Key *ev;
2906     LOGD ("ctx : %p, ctx valid : %d, focused_ctx : %p, show_req_ctx : %p", ctx, valid, _focused_ctx, _show_req_ctx);
2907
2908     if (!imcontext) return;
2909
2910     // TIZEN_ONLY(20150708): Support back key
2911     if (_input_panel_ctx == ctx) {
2912         _clear_hide_timer();
2913         _input_panel_hide(ctx, EINA_TRUE);
2914         _input_panel_state = ECORE_IMF_INPUT_PANEL_STATE_HIDE;
2915         _input_panel_ctx = NULL;
2916     }
2917
2918     if (_focused_ctx == ctx)
2919         _focused_ctx = NULL;
2920
2921     if (_show_req_ctx == ctx)
2922         _show_req_ctx = NULL;
2923
2924     if (_focus_req_ctx == ctx) {
2925         if (imcontext->canvas)
2926             evas_event_callback_del(imcontext->canvas, EVAS_CALLBACK_CANVAS_FOCUS_IN, _canvas_focus_in_cb);
2927
2928         _focus_req_ctx = NULL;
2929         _focus_req_only = EINA_TRUE;
2930     }
2931     //
2932
2933     if (imcontext->language) {
2934         free (imcontext->language);
2935         imcontext->language = NULL;
2936     }
2937
2938     // TIZEN_ONLY(20150922): Support to set input panel data
2939     if (imcontext->imdata) {
2940         free (imcontext->imdata);
2941         imcontext->imdata = NULL;
2942         imcontext->imdata_size = 0;
2943     }
2944
2945     if (imcontext->input_panel_data) {
2946         free (imcontext->input_panel_data);
2947         imcontext->input_panel_data = NULL;
2948         imcontext->input_panel_data_length = 0;
2949     }
2950     //
2951
2952     if (imcontext->prediction_hint) {
2953         free (imcontext->prediction_hint);
2954         imcontext->prediction_hint = NULL;
2955     }
2956
2957     if (imcontext->mime_type) {
2958         free (imcontext->mime_type);
2959         imcontext->mime_type = NULL;
2960     }
2961
2962     if (imcontext->text_input)
2963         wl_text_input_destroy (imcontext->text_input);
2964
2965     clear_preedit (imcontext);
2966
2967     EINA_LIST_FREE(imcontext->keysym_list, ev) {
2968         if (ev)
2969             free(ev);
2970     }
2971
2972     free(imcontext);
2973 }
2974
2975 void
2976 wayland_im_context_reset(Ecore_IMF_Context *ctx)
2977 {
2978     WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
2979
2980     LOGD("ctx : %p", ctx);
2981
2982     if (!imcontext) return;
2983
2984     commit_preedit (imcontext);
2985
2986     if (!imcontext->input) return;
2987
2988     if (imcontext->text_input) {
2989         wl_text_input_reset(imcontext->text_input);
2990     }
2991     update_state(imcontext);
2992
2993     imcontext->reset_serial = imcontext->serial;
2994 }
2995
2996 static Eina_Bool
2997 _prediction_hint_data_foreach_cb(const Eina_Hash *hash, const void *key,
2998                                  void *data, void *fdata)
2999 {
3000     const char *key_str = key;
3001     const char *value = data;
3002     Ecore_IMF_Context *ctx = (Ecore_IMF_Context *)fdata;
3003     WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
3004
3005     SECURE_LOGD("key : %s, value : %s\n", key_str, value);
3006
3007     if (imcontext && imcontext->text_input)
3008         wl_text_input_prediction_hint_data(imcontext->text_input, key_str, value);
3009
3010     return EINA_TRUE;
3011 }
3012
3013 void
3014 wayland_im_context_focus_in(Ecore_IMF_Context *ctx)
3015 {
3016     LOGD ("ctx : %p. enable : %d, on demand : %d", ctx,
3017           ecore_imf_context_input_panel_enabled_get(ctx),
3018           ecore_imf_context_input_panel_show_on_demand_get (ctx));
3019
3020 #ifdef SOCKET_ACTIVATION
3021     activate_socket ();
3022 #endif
3023
3024     if (!set_focus(ctx)) {
3025         WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
3026         if (imcontext && !imcontext->input) {
3027             if (_focus_req_ctx != ctx)
3028                 _focus_req_only = EINA_TRUE;
3029             _focus_req_ctx = ctx;
3030             if (imcontext->canvas) {
3031                 evas_event_callback_del(imcontext->canvas, EVAS_CALLBACK_CANVAS_FOCUS_IN, _canvas_focus_in_cb);
3032                 evas_event_callback_add(imcontext->canvas, EVAS_CALLBACK_CANVAS_FOCUS_IN, _canvas_focus_in_cb, NULL);
3033             }
3034         }
3035         LOGW("ctx : %p. Fail to set focus!", ctx);
3036         return;
3037     }
3038
3039     WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
3040     if (imcontext && imcontext->input && imcontext->text_input) {
3041         wl_text_input_set_return_key_disabled(imcontext->text_input,
3042                 imcontext->return_key_disabled);
3043
3044         if (imcontext->prediction_hint)
3045             wl_text_input_prediction_hint(imcontext->text_input, imcontext->prediction_hint);
3046
3047         if (imcontext->mime_type)
3048             wl_text_input_set_mime_type(imcontext->text_input, imcontext->mime_type);
3049
3050         if (imcontext->input_panel_position.x >= 0 && imcontext->input_panel_position.y >= 0)
3051             wl_text_input_set_input_panel_position(imcontext->text_input,
3052                 imcontext->input_panel_position.x, imcontext->input_panel_position.y);
3053
3054         const Eina_Hash *hash = ecore_imf_context_prediction_hint_hash_get(ctx);
3055         if (hash)
3056             eina_hash_foreach(hash, _prediction_hint_data_foreach_cb, ctx);
3057
3058         wl_text_input_set_content_type(imcontext->text_input, imcontext->content_hint, get_purpose(ctx));
3059     }
3060
3061     if (_TV)
3062         hw_keyboard_mode = EINA_FALSE;
3063
3064     if (ecore_imf_context_input_panel_enabled_get(ctx))
3065         if (!ecore_imf_context_input_panel_show_on_demand_get (ctx))
3066             show_input_panel(ctx);
3067         else
3068             LOGD ("ctx : %p input panel on demand mode : TRUE", ctx);
3069     else
3070         LOGD ("ctx : %p input panel enable : FALSE", ctx);
3071 }
3072
3073 void
3074 wayland_im_context_focus_out(Ecore_IMF_Context *ctx)
3075 {
3076     WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
3077
3078     LOGD("ctx : %p", ctx);
3079
3080     if (_focus_req_ctx == ctx) {
3081         _focus_req_ctx = NULL;
3082         _focus_req_only = EINA_TRUE;
3083     }
3084
3085     if (!imcontext || !imcontext->input) return;
3086
3087     if (_TV) {
3088         if (hw_keyboard_mode == EINA_TRUE) {
3089             vconf_set_bool (VCONFKEY_ISF_HW_KEYBOARD_INPUT_DETECTED, 0);
3090             hw_keyboard_mode = EINA_FALSE;
3091         }
3092     }
3093
3094     if (ecore_imf_context_input_panel_enabled_get(ctx)) {
3095         ecore_imf_context_input_panel_hide(ctx);
3096     }
3097
3098     set_focus_out(ctx);
3099 }
3100
3101 void
3102 wayland_im_context_preedit_string_get(Ecore_IMF_Context  *ctx,
3103                                       char              **str,
3104                                       int                *cursor_pos)
3105 {
3106     WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
3107     if (!imcontext) return;
3108
3109     SECURE_LOGD("pre-edit string requested (preedit: '%s', preedit cursor : %d)",
3110                 imcontext->preedit_text ? imcontext->preedit_text : "", imcontext->preedit_cursor);
3111
3112     if (str)
3113         *str = strdup(imcontext->preedit_text ? imcontext->preedit_text : "");
3114
3115     if (cursor_pos)
3116         *cursor_pos = imcontext->preedit_cursor;
3117 }
3118
3119 void
3120 wayland_im_context_preedit_string_with_attributes_get(Ecore_IMF_Context  *ctx,
3121                                                       char              **str,
3122                                                       Eina_List         **attrs,
3123                                                       int                *cursor_pos)
3124 {
3125     WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
3126     if (!imcontext) return;
3127
3128     SECURE_LOGD("pre-edit string with attributes requested (preedit: '%s', preedit cursor : %d)",
3129                 imcontext->preedit_text ? imcontext->preedit_text : "", imcontext->preedit_cursor);
3130
3131     if (str)
3132         *str = strdup(imcontext->preedit_text ? imcontext->preedit_text : "");
3133
3134     if (attrs) {
3135         Eina_List *l;
3136         Ecore_IMF_Preedit_Attr *a, *attr;
3137
3138         if (imcontext->preedit_attrs) {
3139             EINA_LIST_FOREACH(imcontext->preedit_attrs, l, a) {
3140                 attr = malloc(sizeof(*attr));
3141                 if (attr) {
3142                     attr = memcpy(attr, a, sizeof(*attr));
3143                     *attrs = eina_list_append(*attrs, attr);
3144                 }
3145             }
3146         }
3147         else {
3148             if (imcontext->preedit_text) {
3149                 Ecore_IMF_Preedit_Attr *attr = calloc(1, sizeof(*attr));
3150                 if (attr) {
3151                     // use REVERSE style as default
3152                     attr->preedit_type = ECORE_IMF_PREEDIT_TYPE_SUB2;
3153                     attr->start_index = 0;
3154                     attr->end_index = strlen(imcontext->preedit_text);
3155                     *attrs = eina_list_append(*attrs, attr);
3156                 }
3157             }
3158         }
3159     }
3160
3161     if (cursor_pos)
3162         *cursor_pos = imcontext->preedit_cursor;
3163 }
3164
3165 void
3166 wayland_im_context_cursor_position_set (Ecore_IMF_Context *ctx,
3167                                        int                cursor_pos)
3168 {
3169     WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
3170     if (!imcontext) return;
3171
3172     if (imcontext->cursor_position != cursor_pos) {
3173         imcontext->cursor_position = cursor_pos;
3174
3175         if (imcontext->input && imcontext->text_input) {
3176             LOGD ("ctx : %p, cursor pos : %d", ctx, cursor_pos);
3177
3178             set_autocapital (ctx);
3179
3180             if (!imcontext->preedit_text || strlen(imcontext->preedit_text) == 0)
3181                 wl_text_input_set_cursor_position (imcontext->text_input, cursor_pos);
3182         }
3183     }
3184 }
3185
3186 void
3187 wayland_im_context_use_preedit_set(Ecore_IMF_Context *ctx EINA_UNUSED,
3188                                    Eina_Bool          use_preedit EINA_UNUSED)
3189 {
3190 }
3191
3192 void
3193 wayland_im_context_client_window_set(Ecore_IMF_Context *ctx,
3194                                      void              *window)
3195 {
3196     WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
3197
3198     LOGD("client window set (Ecore_Window: %p)", window);
3199
3200     if (imcontext && window) {
3201         Ecore_Wl2_Display *wl2_display = ecore_wl2_connected_display_get(NULL);
3202
3203         if (wl2_display) {
3204             imcontext->window = ecore_wl2_display_window_find(wl2_display, (Ecore_Window)window);
3205             LOGD("client Ecore_Wl2_Window : %p", imcontext->window);
3206         }
3207
3208         if (_ime_device && imcontext->window)
3209             _device_info_send (ecore_wl2_window_id_get (imcontext->window), EINA_TRUE);
3210     }
3211 }
3212
3213 void
3214 wayland_im_context_client_canvas_set(Ecore_IMF_Context *ctx,
3215                                      void              *canvas)
3216 {
3217     WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
3218
3219     LOGD("client canvas set (canvas: %p)", canvas);
3220
3221     if (imcontext && canvas) {
3222         Ecore_Wl2_Display *wl2_display = ecore_wl2_connected_display_get(NULL);
3223         imcontext->canvas = canvas;
3224
3225         if (wl2_display && !imcontext->window) {
3226             imcontext->window = ecore_wl2_display_window_find(wl2_display, ecore_evas_window_get(ecore_evas_ecore_evas_get(canvas)));
3227             LOGD("client Ecore_Wl2_Window : %p", imcontext->window);
3228         }
3229
3230         if (_ime_device && imcontext->window)
3231             _device_info_send (ecore_wl2_window_id_get (imcontext->window), EINA_TRUE);
3232     }
3233 }
3234
3235 void
3236 wayland_im_context_show(Ecore_IMF_Context *ctx)
3237 {
3238     LOGD("ctx : %p", ctx);
3239
3240     show_input_panel(ctx);
3241 }
3242
3243 void
3244 wayland_im_context_hide(Ecore_IMF_Context *ctx)
3245 {
3246     LOGD("ctx : %p", ctx);
3247
3248     if (!get_using_ctx()) {
3249         LOGW("Can't hide input_panel because there is no using context!!");
3250         return;
3251     }
3252
3253     _input_panel_hide(ctx, EINA_FALSE);
3254 }
3255
3256 #if !(ENABLE_GRAB_KEYBOARD)
3257 static unsigned int
3258 _ecore_imf_lock_to_ecore_key_modifier(unsigned int locks)
3259 {
3260    unsigned int mask = 0;
3261
3262     if (locks & ECORE_IMF_KEYBOARD_LOCK_SCROLL)
3263         mask |= ECORE_EVENT_LOCK_SCROLL;
3264
3265     if (locks & ECORE_IMF_KEYBOARD_LOCK_CAPS)
3266         mask |= ECORE_EVENT_LOCK_CAPS;
3267
3268     if (locks & ECORE_IMF_KEYBOARD_LOCK_NUM)
3269         mask |= ECORE_EVENT_LOCK_NUM;
3270
3271    return mask;
3272 }
3273
3274 static unsigned int
3275 _ecore_imf_modifier_to_ecore_key_modifier(Ecore_IMF_Keyboard_Modifiers modifiers)
3276 {
3277    unsigned int mask = 0;
3278
3279    /**< "Control" is pressed */
3280    if (modifiers & ECORE_IMF_KEYBOARD_MODIFIER_CTRL)
3281      mask |= ECORE_EVENT_MODIFIER_CTRL;
3282
3283    /**< "Alt" is pressed */
3284    if (modifiers & ECORE_IMF_KEYBOARD_MODIFIER_ALT)
3285      mask |= ECORE_EVENT_MODIFIER_ALT;
3286
3287    /**< "Shift" is pressed */
3288    if (modifiers & ECORE_IMF_KEYBOARD_MODIFIER_SHIFT)
3289      mask |= ECORE_EVENT_MODIFIER_SHIFT;
3290
3291    /**< "Win" (between "Ctrl" and "Alt") is pressed */
3292    if (modifiers & ECORE_IMF_KEYBOARD_MODIFIER_WIN)
3293      mask |= ECORE_EVENT_MODIFIER_WIN;
3294
3295    /**< "AltGr" is pressed */
3296    if (modifiers & ECORE_IMF_KEYBOARD_MODIFIER_ALTGR)
3297      mask |= ECORE_EVENT_MODIFIER_ALTGR;
3298
3299    return mask;
3300 }
3301 #endif
3302
3303 Eina_Bool
3304 wayland_im_context_filter_event(Ecore_IMF_Context    *ctx,
3305                                 Ecore_IMF_Event_Type  type,
3306                                 Ecore_IMF_Event      *imf_event)
3307 {
3308
3309 #if !(ENABLE_GRAB_KEYBOARD)
3310     Eina_Bool ret = EINA_FALSE;
3311     Ecore_Event_Key ecore_key_ev;
3312     char *key_dev_name = NULL;
3313     uint32_t key_dev_class = 0;
3314     uint32_t key_dev_subclass = 0;
3315 #endif
3316     if (type == ECORE_IMF_EVENT_MOUSE_UP) {
3317         if (ecore_imf_context_input_panel_enabled_get(ctx)) {
3318             LOGD ("[Mouse-up event] ctx : %p", ctx);
3319             if (ctx == _focused_ctx) {
3320                 ecore_imf_context_input_panel_show(ctx);
3321             }
3322             else
3323                 LOGE ("Can't show IME because there is no focus. ctx : %p", ctx);
3324         }
3325     }
3326 #if !(ENABLE_GRAB_KEYBOARD)
3327     else if (type == ECORE_IMF_EVENT_KEY_UP) {
3328         Ecore_IMF_Event_Key_Up *key_ev = (Ecore_IMF_Event_Key_Up *)imf_event;
3329         ecore_key_ev.keyname = key_ev->keyname;
3330         ecore_key_ev.key = key_ev->key;
3331         ecore_key_ev.string = key_ev->string;
3332         ecore_key_ev.compose = key_ev->compose;
3333         ecore_key_ev.timestamp = key_ev->timestamp;
3334         ecore_key_ev.modifiers = _ecore_imf_modifier_to_ecore_key_modifier(key_ev->modifiers);
3335         ecore_key_ev.modifiers |= _ecore_imf_lock_to_ecore_key_modifier(key_ev->locks);
3336         key_dev_name = (char *)key_ev->dev_name;
3337         key_dev_class = key_ev->dev_class;
3338         key_dev_subclass = key_ev->dev_subclass;
3339         ecore_key_ev.keycode = key_ev->keycode;
3340     }
3341     else if (type == ECORE_IMF_EVENT_KEY_DOWN) {
3342         Ecore_IMF_Event_Key_Down *key_ev = (Ecore_IMF_Event_Key_Down *)imf_event;
3343         ecore_key_ev.keyname = key_ev->keyname;
3344         ecore_key_ev.key = key_ev->key;
3345         ecore_key_ev.string = key_ev->string;
3346         ecore_key_ev.compose = key_ev->compose;
3347         ecore_key_ev.timestamp = key_ev->timestamp;
3348         ecore_key_ev.modifiers = _ecore_imf_modifier_to_ecore_key_modifier(key_ev->modifiers);
3349         ecore_key_ev.modifiers |= _ecore_imf_lock_to_ecore_key_modifier(key_ev->locks);
3350         key_dev_name = (char *)key_ev->dev_name;
3351         key_dev_class = key_ev->dev_class;
3352         key_dev_subclass = key_ev->dev_subclass;
3353         ecore_key_ev.keycode = key_ev->keycode;
3354     }
3355
3356     if (type == ECORE_IMF_EVENT_KEY_UP || type == ECORE_IMF_EVENT_KEY_DOWN) {
3357         WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
3358         if (!imcontext || !imcontext->input || !imcontext->text_input)
3359             return EINA_FALSE;
3360
3361         if (!_focused_ctx) {
3362             LOGW ("no focus");
3363             return EINA_FALSE;
3364         }
3365
3366         if (_focused_ctx != ctx) {
3367             LOGW ("focused context is different from the context used in ecore_imf_context_filter_event.");
3368             LOGW ("focus context : %p, context : %p", _focused_ctx, ctx);
3369             return EINA_FALSE;
3370         }
3371
3372         do {
3373             if (!ecore_key_ev.timestamp && (ecore_key_ev.modifiers & MOD_Mod5_MASK)
3374                 && key_dev_subclass == ECORE_DEVICE_SUBCLASS_VIRTUAL_KEYBOARD) {
3375                 if (type == ECORE_IMF_EVENT_KEY_DOWN) {
3376                     if (strcmp (ecore_key_ev.key, "space") == 0 ||
3377                         strcmp (ecore_key_ev.key, "KP_Space") == 0 ) {
3378                         autoperiod_insert (ctx);
3379                     }
3380                 }
3381
3382                 LOGD("Return! This is SW keyboard fake event!");
3383                 break;
3384             }
3385
3386             int serial = imcontext->serial++;
3387             double start_time = ecore_time_get();
3388
3389             /* xkb_mod_mask */
3390             uint32_t modifiers = 0;
3391             if (ecore_key_ev.modifiers & ECORE_EVENT_MODIFIER_SHIFT)
3392                 modifiers |= imcontext->shift_mask;
3393             if (ecore_key_ev.modifiers & ECORE_EVENT_MODIFIER_CTRL)
3394                 modifiers |= imcontext->control_mask;
3395             if (ecore_key_ev.modifiers & ECORE_EVENT_MODIFIER_ALT)
3396                 modifiers |= imcontext->alt_mask;
3397             if (ecore_key_ev.modifiers & ECORE_EVENT_LOCK_CAPS)
3398                 modifiers |= imcontext->caps_mask;
3399             if (ecore_key_ev.modifiers & ECORE_EVENT_LOCK_NUM)
3400                 modifiers |= imcontext->num_mask;
3401
3402             SECURE_LOGD ("ev:modifiers=0x%x, modifiers=0x%x, shift_mask=0x%x, control_mask=0x%0x, alt_mask=0x%x, caps_mask=0x%x, num_mask=0x%x, keycode=%u", ecore_key_ev.modifiers, modifiers, imcontext->shift_mask, imcontext->control_mask, imcontext->alt_mask, imcontext->caps_mask, imcontext->num_mask, ecore_key_ev.keycode);
3403             //Send key event to IME.
3404             wl_text_input_filter_key_event(imcontext->text_input, serial, ecore_key_ev.timestamp, ecore_key_ev.key,
3405                                            type == ECORE_IMF_EVENT_KEY_UP? WL_KEYBOARD_KEY_STATE_RELEASED : WL_KEYBOARD_KEY_STATE_PRESSED,
3406                                            modifiers, (key_dev_name ? key_dev_name : ""), key_dev_class, key_dev_subclass, ecore_key_ev.keycode);
3407             //Waiting for filter_key_event_done from IME.
3408             //This function should return IME filtering result with boolean type.
3409             Ecore_Wl2_Display *wl2_display = ecore_wl2_connected_display_get(NULL);
3410             struct wl_display *display = NULL;
3411             if (wl2_display)
3412                 display = ecore_wl2_display_get(wl2_display);
3413
3414             if (display) {
3415                 struct wl_event_queue *queue = wl_display_create_queue(display);
3416
3417                 if (queue) {
3418                     while (ecore_time_get() - start_time < WAIT_FOR_FILTER_DONE_SECOND && _focused_ctx == ctx && wl_display_roundtrip_queue(display, queue) != -1) {
3419                         wl_display_dispatch_pending(display);
3420                         if (imcontext->last_key_event_filter.serial == serial) {
3421                             ret = imcontext->last_key_event_filter.state;
3422                             break;
3423                         } else if (imcontext->last_key_event_filter.serial > serial)
3424                             break;
3425                     }
3426
3427                     if (ecore_time_get() - start_time > WAIT_FOR_FILTER_DONE_SECOND) {
3428                         LOGE("Key processing result not received");
3429                         ret = EINA_FALSE;
3430                     }
3431
3432                     if (imcontext->last_key_event_filter.serial < serial) {
3433                         LOGW("Timeout occured");
3434                         ret = EINA_TRUE;
3435                     }
3436
3437                     wl_event_queue_destroy(queue);
3438                 }
3439
3440                 LOGD ("elapsed : %.3f ms, serial (last, require) : (%d, %d)", (ecore_time_get() - start_time)*1000, imcontext->last_key_event_filter.serial, serial);
3441             }
3442         } while (0);
3443
3444         if (type == ECORE_IMF_EVENT_KEY_DOWN) {
3445             if (ret == EINA_FALSE) {
3446                 if (_TV) {
3447                     if (strcmp (ecore_key_ev.keyname, "Return") == 0 && key_dev_subclass == ECORE_DEVICE_SUBCLASS_REMOCON) {
3448                         int val;
3449                         if (vconf_get_bool (VCONFKEY_ISF_HW_KEYBOARD_INPUT_DETECTED, &val) == 0) {
3450                             if (val) {
3451                                 LOGD ("Changed keyboard mode from H/W to S/W ");
3452                                 hw_keyboard_mode = EINA_FALSE;
3453                                 vconf_set_bool (VCONFKEY_ISF_HW_KEYBOARD_INPUT_DETECTED, 0);
3454                                 if (ecore_imf_context_input_panel_enabled_get (ctx)) {
3455                                     ecore_imf_context_input_panel_show (ctx);
3456                                 }
3457                                 return EINA_TRUE;
3458                             }
3459                         }
3460                     }
3461                 }
3462                 if (strcmp (ecore_key_ev.key, "space") == 0 ||
3463                     strcmp (ecore_key_ev.key, "KP_Space") == 0) {
3464                     autoperiod_insert (ctx);
3465                 }
3466             }
3467         }
3468
3469         //Deal with the next key event in list.
3470         Ecore_Event_Key *ev = NULL;
3471         if (eina_list_count (imcontext->keysym_list)) {
3472             Eina_List *n = eina_list_last(imcontext->keysym_list);
3473             ev = (Ecore_Event_Key *)eina_list_data_get(n);
3474             int event_type = (unsigned long int)ev->data;
3475
3476             ev->data = NULL;
3477             ecore_event_add(event_type, ev, _ecore_keyevent_free, NULL);
3478             imcontext->keysym_list = eina_list_remove_list(imcontext->keysym_list, n);
3479         }
3480     }
3481
3482     return ret;
3483 #else
3484     return EINA_FALSE;
3485 #endif
3486 }
3487
3488 void
3489 wayland_im_context_cursor_location_set(Ecore_IMF_Context *ctx, int x, int y, int width, int height)
3490 {
3491     WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
3492     if (!imcontext) return;
3493
3494     if ((imcontext->cursor_location.x != x) ||
3495         (imcontext->cursor_location.y != y) ||
3496         (imcontext->cursor_location.width != width) ||
3497         (imcontext->cursor_location.height != height)) {
3498         imcontext->cursor_location.x = x;
3499         imcontext->cursor_location.y = y;
3500         imcontext->cursor_location.width = width;
3501         imcontext->cursor_location.height = height;
3502
3503         if (_focused_ctx == ctx)
3504             send_cursor_location (imcontext);
3505     }
3506 }
3507
3508 void wayland_im_context_autocapital_type_set(Ecore_IMF_Context *ctx,
3509                                                   Ecore_IMF_Autocapital_Type autocapital_type)
3510 {
3511     WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
3512     if (!imcontext) return;
3513
3514     imcontext->content_hint &= ~(WL_TEXT_INPUT_CONTENT_HINT_AUTO_CAPITALIZATION |
3515                                  // TIZEN_ONLY(20160201): Add autocapitalization word
3516                                  WL_TEXT_INPUT_CONTENT_HINT_WORD_CAPITALIZATION |
3517                                  //
3518                                  WL_TEXT_INPUT_CONTENT_HINT_UPPERCASE |
3519                                  WL_TEXT_INPUT_CONTENT_HINT_LOWERCASE);
3520
3521     if (autocapital_type == ECORE_IMF_AUTOCAPITAL_TYPE_SENTENCE)
3522         imcontext->content_hint |= WL_TEXT_INPUT_CONTENT_HINT_AUTO_CAPITALIZATION;
3523     // TIZEN_ONLY(20160201): Add autocapitalization word
3524     else if (autocapital_type == ECORE_IMF_AUTOCAPITAL_TYPE_WORD)
3525         imcontext->content_hint |= WL_TEXT_INPUT_CONTENT_HINT_WORD_CAPITALIZATION;
3526     //
3527     else if (autocapital_type == ECORE_IMF_AUTOCAPITAL_TYPE_ALLCHARACTER)
3528         imcontext->content_hint |= WL_TEXT_INPUT_CONTENT_HINT_UPPERCASE;
3529     else
3530         imcontext->content_hint |= WL_TEXT_INPUT_CONTENT_HINT_LOWERCASE;
3531
3532     if (imcontext->input && imcontext->text_input) {
3533         LOGD ("ctx : %p. set autocapital type : %d", ctx, autocapital_type);
3534         wl_text_input_set_content_type(imcontext->text_input,
3535                 imcontext->content_hint,
3536                 get_purpose(ctx));
3537     }
3538 }
3539
3540 void
3541 wayland_im_context_input_panel_layout_set(Ecore_IMF_Context *ctx,
3542                                           Ecore_IMF_Input_Panel_Layout layout)
3543 {
3544     WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
3545     if (!imcontext) return;
3546
3547     imcontext->input_panel_layout = layout;
3548
3549     switch (layout) {
3550         case ECORE_IMF_INPUT_PANEL_LAYOUT_NUMBER:
3551             imcontext->content_purpose = WL_TEXT_INPUT_CONTENT_PURPOSE_NUMBER;
3552             break;
3553         case ECORE_IMF_INPUT_PANEL_LAYOUT_EMAIL:
3554             imcontext->content_purpose = WL_TEXT_INPUT_CONTENT_PURPOSE_EMAIL;
3555             break;
3556         case ECORE_IMF_INPUT_PANEL_LAYOUT_URL:
3557             imcontext->content_purpose = WL_TEXT_INPUT_CONTENT_PURPOSE_URL;
3558             break;
3559         case ECORE_IMF_INPUT_PANEL_LAYOUT_PHONENUMBER:
3560             imcontext->content_purpose = WL_TEXT_INPUT_CONTENT_PURPOSE_PHONE;
3561             break;
3562         case ECORE_IMF_INPUT_PANEL_LAYOUT_IP:
3563             // TIZEN_ONLY(20150710): Support IP and emoticon layout
3564             imcontext->content_purpose = WL_TEXT_INPUT_CONTENT_PURPOSE_IP;
3565             //
3566             break;
3567         case ECORE_IMF_INPUT_PANEL_LAYOUT_MONTH:
3568             imcontext->content_purpose = WL_TEXT_INPUT_CONTENT_PURPOSE_DATE;
3569             break;
3570         case ECORE_IMF_INPUT_PANEL_LAYOUT_NUMBERONLY:
3571             imcontext->content_purpose = WL_TEXT_INPUT_CONTENT_PURPOSE_DIGITS;
3572             break;
3573         case ECORE_IMF_INPUT_PANEL_LAYOUT_HEX:
3574             imcontext->content_purpose = WL_TEXT_INPUT_CONTENT_PURPOSE_HEX;
3575             break;
3576         case ECORE_IMF_INPUT_PANEL_LAYOUT_TERMINAL:
3577             imcontext->content_purpose = WL_TEXT_INPUT_CONTENT_PURPOSE_TERMINAL;
3578             break;
3579         case ECORE_IMF_INPUT_PANEL_LAYOUT_PASSWORD:
3580             imcontext->content_purpose = WL_TEXT_INPUT_CONTENT_PURPOSE_PASSWORD;
3581             imcontext->content_hint |= (WL_TEXT_INPUT_CONTENT_HINT_SENSITIVE_DATA | WL_TEXT_INPUT_CONTENT_HINT_PASSWORD);
3582             break;
3583         case ECORE_IMF_INPUT_PANEL_LAYOUT_DATETIME:
3584             imcontext->content_purpose = WL_TEXT_INPUT_CONTENT_PURPOSE_DATETIME;
3585             break;
3586             // TIZEN_ONLY(20150710): Support IP and emoticon layout
3587         case ECORE_IMF_INPUT_PANEL_LAYOUT_EMOTICON:
3588             imcontext->content_purpose = WL_TEXT_INPUT_CONTENT_PURPOSE_EMOTICON;
3589             break;
3590             //
3591         case ECORE_IMF_INPUT_PANEL_LAYOUT_VOICE:
3592             imcontext->content_purpose = WL_TEXT_INPUT_CONTENT_PURPOSE_VOICE;
3593             break;
3594         default:
3595             imcontext->content_purpose = WL_TEXT_INPUT_CONTENT_PURPOSE_NORMAL;
3596             break;
3597     }
3598
3599     if (imcontext->input && imcontext->text_input) {
3600         LOGD ("ctx : %p, layout type : %d", ctx, layout);
3601         wl_text_input_set_content_type(imcontext->text_input,
3602                 imcontext->content_hint,
3603                 get_purpose(ctx));
3604     }
3605 }
3606
3607 Ecore_IMF_Input_Panel_Layout
3608 wayland_im_context_input_panel_layout_get(Ecore_IMF_Context *ctx)
3609 {
3610     WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
3611     if (!imcontext) return ECORE_IMF_INPUT_PANEL_LAYOUT_NORMAL;
3612
3613     return imcontext->input_panel_layout;
3614 }
3615
3616 void
3617 wayland_im_context_input_mode_set(Ecore_IMF_Context *ctx,
3618                                   Ecore_IMF_Input_Mode input_mode)
3619 {
3620     WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
3621     if (!imcontext) return;
3622
3623     if (input_mode & ECORE_IMF_INPUT_MODE_INVISIBLE)
3624         imcontext->content_hint |= (WL_TEXT_INPUT_CONTENT_HINT_SENSITIVE_DATA | WL_TEXT_INPUT_CONTENT_HINT_PASSWORD);
3625     else
3626         imcontext->content_hint &= ~(WL_TEXT_INPUT_CONTENT_HINT_SENSITIVE_DATA | WL_TEXT_INPUT_CONTENT_HINT_PASSWORD);
3627
3628     if (imcontext->input && imcontext->text_input) {
3629         LOGD ("ctx : %p, input mode : %d", ctx, input_mode);
3630         wl_text_input_set_content_type(imcontext->text_input,
3631                 imcontext->content_hint,
3632                 get_purpose(ctx));
3633     }
3634 }
3635
3636 void
3637 wayland_im_context_input_hint_set(Ecore_IMF_Context *ctx,
3638                                   Ecore_IMF_Input_Hints input_hints)
3639 {
3640     WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
3641     if (!imcontext) return;
3642
3643     if (input_hints & ECORE_IMF_INPUT_HINT_AUTO_COMPLETE)
3644         imcontext->content_hint |= WL_TEXT_INPUT_CONTENT_HINT_AUTO_COMPLETION;
3645     else
3646         imcontext->content_hint &= ~WL_TEXT_INPUT_CONTENT_HINT_AUTO_COMPLETION;
3647
3648     if (input_hints & ECORE_IMF_INPUT_HINT_SENSITIVE_DATA)
3649         imcontext->content_hint |= WL_TEXT_INPUT_CONTENT_HINT_SENSITIVE_DATA;
3650     else
3651         imcontext->content_hint &= ~WL_TEXT_INPUT_CONTENT_HINT_SENSITIVE_DATA;
3652
3653     if (input_hints & ECORE_IMF_INPUT_HINT_MULTILINE)
3654         imcontext->content_hint |= WL_TEXT_INPUT_CONTENT_HINT_MULTILINE;
3655     else
3656         imcontext->content_hint &= ~WL_TEXT_INPUT_CONTENT_HINT_MULTILINE;
3657
3658     // autofill
3659     LOGD("autofill hint : %x\n", input_hints & ECORE_IMF_INPUT_HINT_AUTOFILL_MASK);
3660
3661     switch(input_hints & ECORE_IMF_INPUT_HINT_AUTOFILL_MASK)
3662     {
3663     case ECORE_IMF_INPUT_HINT_AUTOFILL_CREDIT_CARD_EXPIRATION_DATE:
3664         imcontext->content_hint |= WL_TEXT_INPUT_CONTENT_HINT_AUTOFILL_CREDIT_CARD_EXPIRATION_DATE;
3665         break;
3666     case ECORE_IMF_INPUT_HINT_AUTOFILL_CREDIT_CARD_EXPIRATION_DAY:
3667         imcontext->content_hint |= WL_TEXT_INPUT_CONTENT_HINT_AUTOFILL_CREDIT_CARD_EXPIRATION_DAY;
3668         break;
3669     case ECORE_IMF_INPUT_HINT_AUTOFILL_CREDIT_CARD_EXPIRATION_MONTH:
3670         imcontext->content_hint |= WL_TEXT_INPUT_CONTENT_HINT_AUTOFILL_CREDIT_CARD_EXPIRATION_MONTH;
3671         break;
3672     case ECORE_IMF_INPUT_HINT_AUTOFILL_CREDIT_CARD_EXPIRATION_YEAR:
3673         imcontext->content_hint |= WL_TEXT_INPUT_CONTENT_HINT_AUTOFILL_CREDIT_CARD_EXPIRATION_YEAR;
3674         break;
3675     case ECORE_IMF_INPUT_HINT_AUTOFILL_CREDIT_CARD_NUMBER:
3676         imcontext->content_hint |= WL_TEXT_INPUT_CONTENT_HINT_AUTOFILL_CREDIT_CARD_NUMBER;
3677         break;
3678     case ECORE_IMF_INPUT_HINT_AUTOFILL_EMAIL_ADDRESS:
3679         imcontext->content_hint |= WL_TEXT_INPUT_CONTENT_HINT_AUTOFILL_EMAIL_ADDRESS;
3680         break;
3681     case ECORE_IMF_INPUT_HINT_AUTOFILL_PHONE:
3682         imcontext->content_hint |= WL_TEXT_INPUT_CONTENT_HINT_AUTOFILL_PHONE;
3683         break;
3684     case ECORE_IMF_INPUT_HINT_AUTOFILL_POSTAL_ADDRESS:
3685         imcontext->content_hint |= WL_TEXT_INPUT_CONTENT_HINT_AUTOFILL_POSTAL_ADDRESS;
3686         break;
3687     case ECORE_IMF_INPUT_HINT_AUTOFILL_POSTAL_CODE:
3688         imcontext->content_hint |= WL_TEXT_INPUT_CONTENT_HINT_AUTOFILL_POSTAL_CODE;
3689         break;
3690     case ECORE_IMF_INPUT_HINT_AUTOFILL_ID:
3691         imcontext->content_hint |= WL_TEXT_INPUT_CONTENT_HINT_AUTOFILL_ID;
3692         break;
3693     case ECORE_IMF_INPUT_HINT_AUTOFILL_NAME:
3694         imcontext->content_hint |= WL_TEXT_INPUT_CONTENT_HINT_AUTOFILL_NAME;
3695         break;
3696     }
3697
3698     if (imcontext->input && imcontext->text_input) {
3699         LOGD("ctx : %p, input hint : %#x", ctx, input_hints);
3700         wl_text_input_set_content_type(imcontext->text_input,
3701                 imcontext->content_hint,
3702                 get_purpose(ctx));
3703     }
3704 }
3705
3706 void
3707 wayland_im_context_input_panel_language_set(Ecore_IMF_Context *ctx,
3708                                             Ecore_IMF_Input_Panel_Lang lang)
3709 {
3710     WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
3711     if (!imcontext) return;
3712
3713     if (lang == ECORE_IMF_INPUT_PANEL_LANG_ALPHABET)
3714         imcontext->content_hint |= WL_TEXT_INPUT_CONTENT_HINT_LATIN;
3715     else
3716         imcontext->content_hint &= ~WL_TEXT_INPUT_CONTENT_HINT_LATIN;
3717
3718     if (imcontext->input && imcontext->text_input)
3719         wl_text_input_set_content_type(imcontext->text_input,
3720                 imcontext->content_hint,
3721                 get_purpose(ctx));
3722 }
3723
3724 // TIZEN_ONLY(20150708): Support input_panel_state_get
3725 Ecore_IMF_Input_Panel_State
3726 wayland_im_context_input_panel_state_get(Ecore_IMF_Context *ctx EINA_UNUSED)
3727 {
3728     return _input_panel_state;
3729 }
3730
3731 void
3732 wayland_im_context_input_panel_return_key_type_set(Ecore_IMF_Context *ctx,
3733                                                    Ecore_IMF_Input_Panel_Return_Key_Type return_key_type)
3734 {
3735     WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
3736     if (!imcontext) return;
3737
3738     imcontext->return_key_type = return_key_type;
3739
3740     if (imcontext->input && imcontext->text_input)
3741         wl_text_input_set_return_key_type(imcontext->text_input,
3742                 imcontext->return_key_type);
3743 }
3744
3745 void
3746 wayland_im_context_input_panel_return_key_disabled_set(Ecore_IMF_Context *ctx,
3747                                                        Eina_Bool disabled)
3748 {
3749     WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
3750     if (!imcontext) return;
3751
3752     imcontext->return_key_disabled = disabled;
3753
3754     if (imcontext->input && imcontext->text_input)
3755         wl_text_input_set_return_key_disabled(imcontext->text_input,
3756                 imcontext->return_key_disabled);
3757 }
3758 //
3759
3760 void
3761 wayland_im_context_input_panel_language_locale_get(Ecore_IMF_Context *ctx,
3762                                                    char **locale)
3763 {
3764     WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
3765     if (!imcontext) return;
3766
3767     if (locale)
3768         *locale = strdup(imcontext->language ? imcontext->language : "");
3769 }
3770
3771 void
3772 wayland_im_context_prediction_allow_set(Ecore_IMF_Context *ctx,
3773                                         Eina_Bool prediction)
3774 {
3775     WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
3776     if (!imcontext) return;
3777
3778     if (prediction)
3779         imcontext->content_hint |= WL_TEXT_INPUT_CONTENT_HINT_AUTO_COMPLETION;
3780     else
3781         imcontext->content_hint &= ~WL_TEXT_INPUT_CONTENT_HINT_AUTO_COMPLETION;
3782
3783     if (imcontext->input && imcontext->text_input)
3784         wl_text_input_set_content_type(imcontext->text_input,
3785                 imcontext->content_hint,
3786                 get_purpose(ctx));
3787 }
3788
3789 // TIZEN_ONLY(20151221): Support input panel geometry
3790 void
3791 wayland_im_context_input_panel_geometry_get(Ecore_IMF_Context *ctx EINA_UNUSED,
3792                                             int *x, int *y, int *w, int *h)
3793 {
3794     if (x)
3795         *x = _keyboard_geometry.x;
3796     if (y)
3797         *y = _keyboard_geometry.y;
3798     if (w)
3799         *w = _keyboard_geometry.w;
3800     if (h)
3801         *h = _keyboard_geometry.h;
3802 }
3803
3804 void
3805 wayland_im_context_input_panel_imdata_set(Ecore_IMF_Context *ctx, const void *data, int length)
3806 {
3807     WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
3808     if (!imcontext) return;
3809
3810     if (data && length > 0) {
3811         const char *custom_conformant_enabled = "conformant:custom,enabled";
3812         const char *custom_conformant_disabled = "conformant:custom,disabled";
3813         const char *custom_conformant_finished = "conformant:custom,finished";
3814
3815         if (strncmp(data, custom_conformant_enabled, strlen(custom_conformant_enabled)) == 0) {
3816             _custom_conformant_event = EINA_TRUE;
3817             return;
3818         }
3819         if (strncmp(data, custom_conformant_disabled, strlen(custom_conformant_disabled)) == 0) {
3820             _custom_conformant_event = EINA_FALSE;
3821             return;
3822         }
3823         if (strncmp(data, custom_conformant_finished, strlen(custom_conformant_finished)) == 0) {
3824             if (_custom_conformant_event) {
3825                 _conformant_reset_done = EINA_TRUE;
3826                 LOGD("[conformant:custom,finished], _conformant_reset_done = 1");
3827                 send_will_hide_ack(NULL);
3828             }
3829             return;
3830         }
3831     }
3832
3833     if (imcontext->imdata)
3834         free(imcontext->imdata);
3835
3836     imcontext->imdata = calloc(1, length + 1);
3837     if (imcontext->imdata && data)
3838         memcpy(imcontext->imdata, data, length);
3839
3840     imcontext->imdata_size = length;
3841
3842     if (imcontext->input && imcontext->text_input && (imcontext->imdata_size > 0))
3843         wl_text_input_set_input_panel_data(imcontext->text_input, (const char *)imcontext->imdata, imcontext->imdata_size);
3844 }
3845
3846 void
3847 wayland_im_context_input_panel_imdata_get(Ecore_IMF_Context *ctx, void *data, int *length)
3848 {
3849     if (!ctx) return;
3850     WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
3851
3852     if (imcontext && imcontext->input_panel_data && (imcontext->input_panel_data_length > 0)) {
3853         if (data)
3854             memcpy(data, imcontext->input_panel_data, imcontext->input_panel_data_length);
3855
3856         if (length)
3857             *length = imcontext->input_panel_data_length;
3858     }
3859     else
3860         if (length)
3861             *length = 0;
3862 }
3863 //
3864
3865 // TIZEN_ONLY(20160218): Support BiDi direction
3866 void
3867 wayland_im_context_bidi_direction_set(Ecore_IMF_Context *ctx, Ecore_IMF_BiDi_Direction bidi_direction)
3868 {
3869     WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
3870     if (!imcontext) return;
3871
3872     imcontext->bidi_direction = bidi_direction;
3873
3874     if (imcontext->input && imcontext->text_input) {
3875         LOGD ("ctx : %p, bidi direction : %#x", ctx, bidi_direction);
3876         wl_text_input_bidi_direction(imcontext->text_input, imcontext->bidi_direction);
3877     }
3878 }
3879 //
3880
3881 Ecore_IMF_Input_Panel_Keyboard_Mode
3882 wayland_im_context_input_panel_keyboard_mode_get(Ecore_IMF_Context *ctx EINA_UNUSED)
3883 {
3884     return hw_keyboard_mode ? ECORE_IMF_INPUT_PANEL_HW_KEYBOARD_MODE : ECORE_IMF_INPUT_PANEL_SW_KEYBOARD_MODE;
3885 }
3886
3887 void
3888 wayland_im_context_prediction_hint_set (Ecore_IMF_Context *ctx, const char *prediction_hint)
3889 {
3890     WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
3891     if (!imcontext) return;
3892
3893     imcontext->prediction_hint = strdup(prediction_hint ? prediction_hint : "");
3894
3895     if (imcontext->input && imcontext->text_input) {
3896         SECURE_LOGD ("ctx : %p, prediction_hint : %s", ctx, imcontext->prediction_hint);
3897         wl_text_input_prediction_hint(imcontext->text_input, imcontext->prediction_hint);
3898     }
3899 }
3900
3901 void
3902 wayland_im_context_mime_type_accept_set (Ecore_IMF_Context *ctx, const char *mime_type)
3903 {
3904     WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
3905     if (!imcontext) return;
3906
3907     imcontext->mime_type = strdup(mime_type);
3908
3909     if (imcontext->input && imcontext->text_input && (strlen(mime_type) > 0)) {
3910         LOGD ("ctx : %p, mime_type : %s", ctx, imcontext->mime_type);
3911         wl_text_input_set_mime_type(imcontext->text_input, imcontext->mime_type);
3912     }
3913 }
3914
3915 void
3916 wayland_im_context_input_panel_position_set (Ecore_IMF_Context *ctx, int x, int y)
3917 {
3918     WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
3919     if (!imcontext) return;
3920
3921     if ((imcontext->input_panel_position.x != x) || (imcontext->input_panel_position.y != y)) {
3922         imcontext->input_panel_position.x = x;
3923         imcontext->input_panel_position.y = y;
3924     }
3925
3926     if (imcontext->input && imcontext->text_input) {
3927         LOGD ("ctx : %p, x = %d, y = %d", ctx, x, y);
3928         wl_text_input_set_input_panel_position(imcontext->text_input,
3929             imcontext->input_panel_position.x, imcontext->input_panel_position.y);
3930     }
3931 }
3932
3933 WaylandIMContext *wayland_im_context_new (struct wl_text_input_manager *text_input_manager)
3934 {
3935     WaylandIMContext *context = calloc(1, sizeof(WaylandIMContext));
3936     if (context) {
3937         LOGD("new context created");
3938         context->text_input_manager = text_input_manager;
3939     }
3940
3941     return context;
3942 }
3943
3944 void wayland_im_context_pair_set (Ecore_IMF_Context *ctx, WaylandIMContext *imcontext)
3945 {
3946     _ecore_imf_wayland_imcontext_pair_add (ctx, imcontext);
3947 }