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