4942e84dcc6ce03abbc81483119a8f8db8bcabd7
[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     if (instant || (_hide_timer && ecore_timer_pending_get(_hide_timer) <= 0.0)) {
1154         _clear_hide_timer();
1155         _send_input_panel_hide_request(ctx);
1156
1157         if (!reset_conformant_area(ctx) && !_conformant_reset_started) {
1158             LOGD("No need to reset conformant, sending ACK right away");
1159             _send_will_hide_ack((WaylandIMContext *)ecore_imf_context_data_get(ctx));
1160         }
1161
1162         if (_TV)
1163             reset_keyboard_geometry();
1164     } else {
1165         _input_panel_hide_timer_start(ctx);
1166         // TIZEN_ONLY(20150708): Support back key
1167         _hide_req_ctx = ctx;
1168         //
1169     }
1170 }
1171
1172 static unsigned int
1173 utf8_offset_to_characters(const char *str, int offset)
1174 {
1175     int index = 0;
1176     unsigned int i = 0;
1177
1178     for (; index < offset; i++) {
1179         if (eina_unicode_utf8_next_get(str, &index) == 0)
1180             break;
1181     }
1182
1183     return i;
1184 }
1185
1186 static void
1187 send_cursor_location(WaylandIMContext *imcontext)
1188 {
1189 #if ENABLE_SEND_CURSOR_LOCATION
1190     Ecore_Evas *ee = NULL;
1191     int canvas_x = 0, canvas_y = 0;
1192
1193     if (imcontext->canvas) {
1194         ee = ecore_evas_ecore_evas_get(imcontext->canvas);
1195         if (ee)
1196             ecore_evas_geometry_get(ee, &canvas_x, &canvas_y, NULL, NULL);
1197     }
1198
1199     if (imcontext->input && imcontext->text_input) {
1200         wl_text_input_set_cursor_rectangle(imcontext->text_input,
1201                 imcontext->cursor_location.x + canvas_x,
1202                 imcontext->cursor_location.y + canvas_y,
1203                 imcontext->cursor_location.width,
1204                 imcontext->cursor_location.height);
1205     }
1206 #endif
1207 }
1208
1209 static void
1210 update_state(WaylandIMContext *imcontext)
1211 {
1212     if (!imcontext->ctx)
1213         return;
1214
1215     send_cursor_location (imcontext);
1216
1217     if (imcontext->input && imcontext->text_input) {
1218         wl_text_input_commit_state(imcontext->text_input, ++imcontext->serial);
1219     }
1220 }
1221
1222 static Eina_Bool
1223 check_serial(WaylandIMContext *imcontext, uint32_t serial)
1224 {
1225     if (_TV)
1226         return EINA_TRUE;
1227     else {
1228         Ecore_IMF_Preedit_Attr *attr;
1229
1230         if ((imcontext->serial - serial) >
1231                 (imcontext->serial - imcontext->reset_serial)) {
1232             LOGD("outdated serial: %u, current: %u, reset: %u",
1233                     serial, imcontext->serial, imcontext->reset_serial);
1234
1235             imcontext->pending_preedit.cursor = 0;
1236
1237             if (imcontext->pending_preedit.attrs) {
1238                 EINA_LIST_FREE(imcontext->pending_preedit.attrs, attr) {
1239                     if (attr)
1240                         free(attr);
1241                 }
1242                 imcontext->pending_preedit.attrs = NULL;
1243             }
1244
1245             return EINA_FALSE;
1246         }
1247
1248         return EINA_TRUE;
1249     }
1250 }
1251
1252 static void
1253 clear_preedit_text(WaylandIMContext *imcontext)
1254 {
1255     Ecore_IMF_Preedit_Attr *attr = NULL;
1256
1257     imcontext->preedit_cursor = 0;
1258
1259     if (imcontext->preedit_text) {
1260         free(imcontext->preedit_text);
1261         imcontext->preedit_text = NULL;
1262     }
1263
1264     if (imcontext->preedit_attrs) {
1265         EINA_LIST_FREE(imcontext->preedit_attrs, attr) {
1266             if (attr)
1267                 free(attr);
1268         }
1269     }
1270
1271     imcontext->preedit_attrs = NULL;
1272 }
1273
1274 static void
1275 clear_preedit(WaylandIMContext *imcontext)
1276 {
1277     clear_preedit_text(imcontext);
1278
1279     if (imcontext->preedit_commit) {
1280         free(imcontext->preedit_commit);
1281         imcontext->preedit_commit = NULL;
1282     }
1283 }
1284
1285 static void
1286 text_input_commit_string(void                 *data,
1287                          struct wl_text_input *text_input EINA_UNUSED,
1288                          uint32_t              serial,
1289                          const char           *text)
1290 {
1291     WaylandIMContext *imcontext = (WaylandIMContext *)data;
1292     Eina_Bool old_preedit = EINA_FALSE;
1293
1294     SECURE_LOGD("ctx : %p, commit event (text: '%s', current pre-edit: '%s')",
1295                 imcontext->ctx,
1296                 text,
1297                 imcontext->preedit_text ? imcontext->preedit_text : "");
1298
1299     if (!imcontext->ctx)
1300         return;
1301
1302     old_preedit =
1303         imcontext->preedit_text && strlen(imcontext->preedit_text) > 0;
1304
1305     if (!check_serial(imcontext, serial))
1306         return;
1307
1308     if (old_preedit) {
1309         ecore_imf_context_event_callback_call(imcontext->ctx,
1310                 ECORE_IMF_CALLBACK_PREEDIT_END,
1311                 NULL);
1312     }
1313
1314     clear_preedit(imcontext);
1315
1316     if (!text)
1317         return;
1318
1319     Eina_Unicode *ustr = eina_unicode_utf8_to_unicode (text, NULL);
1320
1321     if (ustr) {
1322         if (eina_unicode_strcmp (ustr, L" ") == 0 ||
1323             eina_unicode_strcmp (ustr, L" ") == 0)
1324             autoperiod_insert (imcontext->ctx);
1325
1326         free(ustr);
1327     }
1328
1329     ecore_imf_context_event_callback_call(imcontext->ctx, ECORE_IMF_CALLBACK_COMMIT, (void *)text);
1330 }
1331
1332 static void
1333 commit_preedit(WaylandIMContext *imcontext)
1334 {
1335     if (!imcontext->preedit_commit)
1336         return;
1337
1338     if (!imcontext->ctx)
1339         return;
1340
1341     imcontext->pending_preedit.cursor = 0;
1342     clear_preedit_text(imcontext);
1343
1344     size_t commit_len = strlen(imcontext->preedit_commit);
1345
1346     if (commit_len == 0) {
1347         ecore_imf_context_event_callback_call(imcontext->ctx,
1348                 ECORE_IMF_CALLBACK_PREEDIT_START,
1349                 NULL);
1350
1351         ecore_imf_context_event_callback_call(imcontext->ctx,
1352                 ECORE_IMF_CALLBACK_PREEDIT_CHANGED,
1353                 NULL);
1354
1355         ecore_imf_context_event_callback_call(imcontext->ctx,
1356                 ECORE_IMF_CALLBACK_PREEDIT_END, NULL);
1357     }
1358
1359     if (commit_len > 0) {
1360         char *commit_str = NULL;
1361         commit_str = strdup(imcontext->preedit_commit);
1362         clear_preedit(imcontext);
1363         ecore_imf_context_event_callback_call(imcontext->ctx,
1364                 ECORE_IMF_CALLBACK_COMMIT,
1365                 (void *)commit_str);
1366         free(commit_str);
1367     }
1368 }
1369
1370 static Eina_Bool
1371 set_focus(Ecore_IMF_Context *ctx)
1372 {
1373     LOGD("ctx : %p", ctx);
1374     WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
1375     if (!imcontext) return EINA_FALSE;
1376
1377     if (!imcontext->window) {
1378         LOGW("window is not given");
1379         return EINA_FALSE;
1380     }
1381
1382     Ecore_Wl2_Input *input = ecore_wl2_window_input_get(imcontext->window);
1383     if (!input) {
1384         LOGW("ctx : %p, Can't get Wl_Input", ctx);
1385         return EINA_FALSE;
1386     }
1387
1388     struct wl_seat *seat = ecore_wl2_input_seat_get(input);
1389     if (!seat) {
1390         LOGW("ctx : %p, Can't get Wl_seat", ctx);
1391         return EINA_FALSE;
1392     }
1393
1394     imcontext->input = input;
1395     _focused_ctx = ctx;
1396
1397     wl_text_input_activate(imcontext->text_input, seat,
1398             ecore_wl2_window_surface_get(imcontext->window));
1399
1400     if (g_key_rate_checked == EINA_FALSE && g_desired_key_rate == 0.0) {
1401         char *key_rate = getenv ("ISF_KEY_REPEAT_RATE");
1402         if (key_rate) {
1403             g_desired_key_rate = atof (key_rate);
1404             if (g_desired_key_rate > 0.0) {
1405                 if (!ecore_wl2_input_keyboard_repeat_get (input, &g_original_key_rate, &g_original_key_delay)) {
1406                     LOGE ("ecore_wl2_input_keyboard_repeat_get failed");
1407                 }
1408                 else {
1409                     LOGD ("ecore_wl2_input_keyboard_repeat_get original rate=%f, delay=%f. Desired rate=%f",
1410                         g_original_key_rate, g_original_key_delay, g_desired_key_rate);
1411                 }
1412             }
1413         }
1414         g_key_rate_checked = EINA_TRUE;
1415     }
1416
1417     if (g_desired_key_rate > 0.0 && g_original_key_delay > 0.0 && !g_focused) {
1418         g_focused = EINA_TRUE;
1419         if (!ecore_wl2_input_keyboard_repeat_set (input, g_desired_key_rate, g_original_key_delay)) {
1420             LOGE ("ecore_wl2_input_keyboard_repeat_set failed");
1421         }
1422         else {
1423             LOGD ("ecore_wl2_input_keyboard_repeat_set(%f, %f)", g_desired_key_rate, g_original_key_delay);
1424         }
1425     }
1426
1427     return EINA_TRUE;
1428 }
1429
1430 static void
1431 set_focus_out(Ecore_IMF_Context *ctx)
1432 {
1433     char *surrounding = NULL;
1434     int cursor_pos = 0;
1435
1436     WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
1437     if (!imcontext || !imcontext->input) return;
1438
1439     if (ecore_imf_context_surrounding_get(ctx, &surrounding, &cursor_pos)) {
1440         if (surrounding) {
1441             wl_text_input_finalize_content(imcontext->text_input, surrounding, cursor_pos);
1442             free(surrounding);
1443         }
1444     }
1445
1446     // deactivate
1447     if (imcontext->text_input)
1448         wl_text_input_deactivate(imcontext->text_input,
1449                                  ecore_wl2_input_seat_get(imcontext->input));
1450
1451     if (ctx == _focused_ctx)
1452         _focused_ctx = NULL;
1453
1454     imcontext->input = NULL;
1455     _preedit_cursor_changed = EINA_FALSE;
1456
1457     if (g_desired_key_rate > 0.0 && g_focused) {
1458         g_focused = EINA_FALSE;
1459
1460         Ecore_Wl2_Input *input = ecore_wl2_window_input_get(imcontext->window);
1461         if (input) {
1462             if (!ecore_wl2_input_keyboard_repeat_set (input, g_original_key_rate, g_original_key_delay)) {
1463                 LOGE ("ecore_wl2_input_keyboard_repeat_set failed.");
1464             }
1465             else {
1466                 LOGD ("ecore_wl2_input_keyboard_repeat_set(%f, %f)", g_original_key_rate, g_original_key_delay);
1467             }
1468         }
1469         else {
1470             LOGW("ctx : %p, Can't get Wl_Input", ctx);
1471         }
1472     }
1473 }
1474
1475 // TIZEN_ONLY(20160217): ignore the duplicate show request
1476 static Eina_Bool _compare_context(Ecore_IMF_Context *ctx1, Ecore_IMF_Context *ctx2)
1477 {
1478     if (!ctx1 || !ctx2) return EINA_FALSE;
1479
1480     if ((ecore_imf_context_autocapital_type_get(ctx1) == ecore_imf_context_autocapital_type_get(ctx2)) &&
1481         (ecore_imf_context_input_panel_layout_get(ctx1) == ecore_imf_context_input_panel_layout_get(ctx2)) &&
1482         (ecore_imf_context_input_panel_layout_variation_get(ctx1) == ecore_imf_context_input_panel_layout_variation_get(ctx2)) &&
1483         (ecore_imf_context_input_panel_language_get(ctx1) == ecore_imf_context_input_panel_language_get(ctx2)) &&
1484         (ecore_imf_context_input_panel_return_key_type_get(ctx1) == ecore_imf_context_input_panel_return_key_type_get(ctx2)) &&
1485         (ecore_imf_context_input_panel_return_key_disabled_get(ctx1) == ecore_imf_context_input_panel_return_key_disabled_get(ctx2)) &&
1486         (ecore_imf_context_input_panel_caps_lock_mode_get(ctx1) == ecore_imf_context_input_panel_caps_lock_mode_get(ctx2)))
1487         return EINA_TRUE;
1488
1489     return EINA_FALSE;
1490 }
1491 //
1492
1493 static void send_get_hide_permission(WaylandIMContext *imcontext)
1494 {
1495     if (imcontext->text_input) {
1496         ignore_hide = EINA_FALSE;
1497         wl_text_input_get_hide_permission(imcontext->text_input);
1498     }
1499 }
1500
1501 static Eina_Bool _client_window_focus_out_cb(void *data, int ev_type, void *ev)
1502 {
1503     Ecore_Wl2_Event_Focus_Out *e = (Ecore_Wl2_Event_Focus_Out *)ev;
1504     Ecore_IMF_Context *ctx = (Ecore_IMF_Context *)data;
1505     if (!ctx || !e) return ECORE_CALLBACK_PASS_ON;
1506
1507     WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get (ctx);
1508     if (!imcontext || !imcontext->window) return ECORE_CALLBACK_PASS_ON;
1509
1510     unsigned int client_win_id = ecore_wl2_window_id_get (imcontext->window);
1511
1512     LOGD ("ctx : %p, client_window id : %#x, focus-out win : %#x", ctx, client_win_id, e->window);
1513
1514     if (client_win_id > 0) {
1515         if (e->window == client_win_id) {
1516             LOGD ("window focus out");
1517
1518             if (_focused_ctx == ctx) {
1519                 wayland_im_context_focus_out (ctx);
1520             }
1521
1522             if (_show_req_ctx == ctx) {
1523                 send_get_hide_permission(imcontext);
1524             }
1525         }
1526     }
1527     else {
1528         send_get_hide_permission(imcontext);
1529     }
1530
1531     return ECORE_CALLBACK_PASS_ON;
1532 }
1533
1534 static void send_will_hide_ack(Ecore_IMF_Context *ctx)
1535 {
1536     Eina_Bool need_temporary_context = EINA_FALSE;
1537     Eina_Bool has_conformant = EINA_FALSE;
1538     WaylandIMContext *imcontext = NULL;
1539
1540     if (!ctx) {
1541         LOGD("ctx is NULL");
1542         need_temporary_context = EINA_TRUE;
1543     } else {
1544         imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
1545         if (!imcontext) {
1546             LOGD("imcontext is NULL :%p", ctx);
1547             need_temporary_context = EINA_TRUE;
1548         } else {
1549             has_conformant = imcontext->has_conformant;
1550         }
1551     }
1552
1553     /* When the RENDER_POST event is emitted, it is possible that our IMF_Context is already deleted,
1554        meaning that there is no connection available for communicating with the window manager.
1555        So we are creating a temporary context for sending WILL_HIDE_ACK message */
1556     if (need_temporary_context) {
1557         LOGD("creating temporary context for sending WILL_HIDE_ACK");
1558         const char *ctx_id = ecore_imf_context_default_id_get();
1559         ctx = ecore_imf_context_add(ctx_id);
1560         if (ctx) {
1561             imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
1562         }
1563     }
1564
1565     if (ctx && imcontext) {
1566         if (ecore_imf_context_client_canvas_get(ctx) && has_conformant) {
1567             if (_conformant_reset_done && _received_will_hide_event) {
1568                 LOGD("Send will hide ack, _conformant_reset_done = 1, received_will_hide_event = 1");
1569                 _send_will_hide_ack(imcontext);
1570                 _conformant_reset_done = EINA_FALSE;
1571                 _received_will_hide_event = EINA_FALSE;
1572             } else {
1573                 LOGD ("_conformant_reset_done=%d, received_will_hide_event=%d",
1574                     _conformant_reset_done, _received_will_hide_event);
1575             }
1576         } else {
1577             LOGD("Send will hide ack right away, since there is no conformant available : %p %d",
1578                 ecore_imf_context_client_canvas_get(ctx), has_conformant);
1579             _send_will_hide_ack (imcontext);
1580         }
1581     }
1582
1583     if (need_temporary_context) {
1584         if (ctx) {
1585             ecore_imf_context_del(ctx);
1586         }
1587     }
1588 }
1589
1590 static void _render_post_cb(void *data, Evas *e, void *event_info)
1591 {
1592     void *callback = evas_event_callback_del(e, EVAS_CALLBACK_RENDER_POST, _render_post_cb);
1593     _conformant_reset_done = EINA_TRUE;
1594     _conformant_reset_started = EINA_FALSE;
1595     LOGD("[_render_post_cb], _conformant_reset_done = 1 , %p", callback);
1596     send_will_hide_ack(NULL);
1597 }
1598
1599 static Eina_Bool _conformant_change_cb(void *data, int ev_type, void *ev)
1600 {
1601     Ecore_Wl2_Event_Conformant_Change *e = (Ecore_Wl2_Event_Conformant_Change *)ev;
1602     if (!e) return ECORE_CALLBACK_PASS_ON;
1603
1604     LOGD ("CONFORMANT changed!! part type : %d, state : %d, win : %d", e->part_type, e->state, e->win);
1605
1606     if (_active_context_window_id != e->win)
1607         return ECORE_CALLBACK_PASS_ON;
1608
1609     Ecore_Wl2_Display *wl2_display = ecore_wl2_connected_display_get(NULL);
1610     if (!wl2_display) return ECORE_CALLBACK_PASS_ON;
1611
1612     Ecore_Wl2_Window *window = ecore_wl2_display_window_find(wl2_display, e->win);
1613     if (!window) return ECORE_CALLBACK_PASS_ON;
1614
1615     if (!(e->state)) {
1616         LOGD("_conformant_reset_done = 0, registering _render_post_cb : %p %p", _active_context_canvas, window);
1617         _conformant_reset_done = EINA_FALSE;
1618         if (_active_context_canvas && ecore_wl2_window_conformant_get(window) && !_custom_conformant_event) {
1619             evas_event_callback_del(_active_context_canvas, EVAS_CALLBACK_RENDER_POST, _render_post_cb);
1620             evas_event_callback_add(_active_context_canvas, EVAS_CALLBACK_RENDER_POST, _render_post_cb, NULL);
1621         }
1622     } else {
1623         _conformant_reset_done = EINA_FALSE;
1624         if (_active_context_canvas) {
1625             evas_event_callback_del(_active_context_canvas, EVAS_CALLBACK_RENDER_POST, _render_post_cb);
1626         }
1627
1628         Eina_Bool result = EINA_FALSE;
1629         int x = 0, y = 0, w = 0, h = 0;
1630
1631         if (_TV) {
1632             /* TV IME consists of two or three windows, so ecore_wl2_window_keyboard_geometry_get() may return wrong size. */
1633             x = _keyboard_geometry.x, y = _keyboard_geometry.y, w = _keyboard_geometry.w, h = _keyboard_geometry.h;
1634             if (_keyboard_geometry.w == 0 || _keyboard_geometry.h == 0) {
1635                 result = ecore_wl2_window_keyboard_geometry_get(window, &x, &y, &w, &h);
1636             }
1637         } else {
1638             /* Since the input_panel_geometry is not delivered right at the moment, we use conformant geometry instead */
1639             x = 0, y = 0, w = 0, h = 0;
1640             result = ecore_wl2_window_keyboard_geometry_get(window, &x, &y, &w, &h);
1641         }
1642
1643         if (result) {
1644             Evas_Coord scr_w = 0, scr_h = 0;
1645             ecore_wl2_sync();
1646             Ecore_Wl2_Display *wl2_display = ecore_wl2_connected_display_get(NULL);
1647             if (wl2_display)
1648                 ecore_wl2_display_screen_size_get(wl2_display ,&scr_w, &scr_h);
1649             int rot = ecore_wl2_window_rotation_get(window);
1650             /* Assume we are using keyboard that has the same width to the screen width*/
1651             switch (rot) {
1652             case 90:
1653                 _keyboard_geometry.h = w;
1654                 _keyboard_geometry.w = h;
1655                 _keyboard_geometry.y = scr_w - _keyboard_geometry.h;
1656                 _keyboard_geometry.x = 0;
1657                 break;
1658             case 180:
1659                 _keyboard_geometry.w = w;
1660                 _keyboard_geometry.h = h;
1661                 _keyboard_geometry.x = 0;
1662                 _keyboard_geometry.y = scr_h - _keyboard_geometry.h;
1663                 break;
1664             case 270:
1665                 _keyboard_geometry.h = w;
1666                 _keyboard_geometry.w = h;
1667                 _keyboard_geometry.y = scr_w - _keyboard_geometry.h;
1668                 _keyboard_geometry.x = 0;
1669                 break;
1670             default:
1671                 _keyboard_geometry.x = x;
1672                 _keyboard_geometry.y = y;
1673                 _keyboard_geometry.w = w;
1674                 _keyboard_geometry.h = h;
1675             }
1676             LOGD("[KEYPAD]: scr %dx%d, rot %d, orig (%d,%d, %dx%d)", scr_w, scr_h, rot, x, y, w, h);
1677             LOGD ("IME geometry x : %d, y : %d, w : %d, h : %d", _keyboard_geometry.x, _keyboard_geometry.y, _keyboard_geometry.w, _keyboard_geometry.h);
1678
1679             if (_show_req_ctx)
1680                 ecore_imf_context_input_panel_event_callback_call(_show_req_ctx, ECORE_IMF_INPUT_PANEL_GEOMETRY_EVENT, 0);
1681         }
1682     }
1683
1684     return ECORE_CALLBACK_PASS_ON;
1685 }
1686
1687 static uint32_t
1688 get_purpose(Ecore_IMF_Context *ctx)
1689 {
1690     int layout_variation = ecore_imf_context_input_panel_layout_variation_get (ctx);
1691     uint32_t new_purpose = 0;
1692
1693     WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
1694     if (!imcontext)
1695         return new_purpose;
1696
1697     switch (imcontext->content_purpose) {
1698         case WL_TEXT_INPUT_CONTENT_PURPOSE_DIGITS:
1699             if (layout_variation == ECORE_IMF_INPUT_PANEL_LAYOUT_NUMBERONLY_VARIATION_SIGNED)
1700                 new_purpose = WL_TEXT_INPUT_CONTENT_PURPOSE_DIGITS_SIGNED;
1701             else if (layout_variation == ECORE_IMF_INPUT_PANEL_LAYOUT_NUMBERONLY_VARIATION_DECIMAL)
1702                 new_purpose = WL_TEXT_INPUT_CONTENT_PURPOSE_DIGITS_DECIMAL;
1703             else if (layout_variation == ECORE_IMF_INPUT_PANEL_LAYOUT_NUMBERONLY_VARIATION_SIGNED_AND_DECIMAL)
1704                 new_purpose = WL_TEXT_INPUT_CONTENT_PURPOSE_DIGITS_SIGNEDDECIMAL;
1705             else
1706                 new_purpose = WL_TEXT_INPUT_CONTENT_PURPOSE_DIGITS;
1707             break;
1708         case WL_TEXT_INPUT_CONTENT_PURPOSE_PASSWORD:
1709             if (layout_variation == ECORE_IMF_INPUT_PANEL_LAYOUT_PASSWORD_VARIATION_NUMBERONLY)
1710                 new_purpose = WL_TEXT_INPUT_CONTENT_PURPOSE_PASSWORD_DIGITS;
1711             else
1712                 new_purpose = WL_TEXT_INPUT_CONTENT_PURPOSE_PASSWORD;
1713             break;
1714         case WL_TEXT_INPUT_CONTENT_PURPOSE_NORMAL:
1715             if (layout_variation == ECORE_IMF_INPUT_PANEL_LAYOUT_NORMAL_VARIATION_FILENAME)
1716                 new_purpose = WL_TEXT_INPUT_CONTENT_PURPOSE_FILENAME;
1717             else if (layout_variation == ECORE_IMF_INPUT_PANEL_LAYOUT_NORMAL_VARIATION_PERSON_NAME)
1718                 new_purpose = WL_TEXT_INPUT_CONTENT_PURPOSE_NAME;
1719             else
1720                 new_purpose = WL_TEXT_INPUT_CONTENT_PURPOSE_NORMAL;
1721             break;
1722         default :
1723             new_purpose = imcontext->content_purpose;
1724             break;
1725     }
1726
1727     return new_purpose;
1728 }
1729
1730 static void _canvas_focus_in_cb(void *data, Evas *e, void *event_info)
1731 {
1732     LOGD("ctx : %p %d", _focus_req_ctx, _focus_req_only);
1733
1734     if (_focus_req_ctx) {
1735         set_focus(_focus_req_ctx);
1736         if (ecore_imf_context_input_panel_enabled_get (_focus_req_ctx) || !_focus_req_only)
1737             if (!ecore_imf_context_input_panel_show_on_demand_get (_focus_req_ctx) || !_focus_req_only)
1738                 show_input_panel (_focus_req_ctx);
1739
1740         WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(_focus_req_ctx);
1741         if (imcontext && imcontext->canvas)
1742             evas_event_callback_del(imcontext->canvas, EVAS_CALLBACK_CANVAS_FOCUS_IN, _canvas_focus_in_cb);
1743         _focus_req_ctx = NULL;
1744         _focus_req_only = EINA_TRUE;
1745     }
1746 }
1747
1748 static Eina_Bool
1749 show_input_panel(Ecore_IMF_Context *ctx)
1750 {
1751     WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
1752
1753     char *surrounding = NULL;
1754     int cursor_pos;
1755
1756     if ((!imcontext) || (!imcontext->text_input))
1757         return EINA_FALSE;
1758
1759     if (!imcontext->input) {
1760         set_focus(ctx);
1761         if (!imcontext->input) {
1762             _focus_req_ctx = ctx;
1763             _focus_req_only = EINA_FALSE;
1764             if (imcontext->canvas) {
1765                 evas_event_callback_del(imcontext->canvas, EVAS_CALLBACK_CANVAS_FOCUS_IN, _canvas_focus_in_cb);
1766                 evas_event_callback_add(imcontext->canvas, EVAS_CALLBACK_CANVAS_FOCUS_IN, _canvas_focus_in_cb, NULL);
1767             }
1768         }
1769     }
1770
1771     _clear_hide_timer ();
1772
1773     _win_focus_out_handler_del ();
1774
1775     if (!imcontext->input)
1776         return EINA_FALSE;
1777
1778     ignore_hide = EINA_TRUE;
1779
1780     _win_focus_out_handler = ecore_event_handler_add (ECORE_WL2_EVENT_FOCUS_OUT, _client_window_focus_out_cb, ctx);
1781     _conformant_change_handler_del ();
1782     _conformant_change_handler = ecore_event_handler_add(ECORE_WL2_EVENT_CONFORMANT_CHANGE, _conformant_change_cb, NULL);
1783
1784     // TIZEN_ONLY(20160217): ignore the duplicate show request
1785     if ((_show_req_ctx == ctx) && _compare_context(_show_req_ctx, ctx) && (!will_hide)) {
1786         if (_input_panel_state == ECORE_IMF_INPUT_PANEL_STATE_WILL_SHOW ||
1787             _input_panel_state == ECORE_IMF_INPUT_PANEL_STATE_SHOW) {
1788             LOGD("already show. ctx : %p", ctx);
1789
1790             return EINA_FALSE;
1791         }
1792     }
1793
1794     _conformant_reset_started = EINA_FALSE;
1795     will_hide = EINA_FALSE;
1796     _show_req_ctx = ctx;
1797     _input_panel_ctx = ctx;
1798     _active_context_canvas = ecore_imf_context_client_canvas_get(ctx);
1799
1800     //
1801
1802     // TIZEN_ONLY(20150715): Support input_panel_state_get
1803     int layout = ecore_imf_context_input_panel_layout_get (ctx);
1804     int layout_variation = ecore_imf_context_input_panel_layout_variation_get (ctx);
1805     //
1806
1807     if (layout == ECORE_IMF_INPUT_PANEL_LAYOUT_PASSWORD)
1808         imcontext->content_hint |= (WL_TEXT_INPUT_CONTENT_HINT_SENSITIVE_DATA | WL_TEXT_INPUT_CONTENT_HINT_PASSWORD);
1809
1810     wl_text_input_set_content_type(imcontext->text_input,
1811             imcontext->content_hint,
1812             get_purpose(ctx));
1813
1814     if (ecore_imf_context_surrounding_get(imcontext->ctx, &surrounding, &cursor_pos)) {
1815         SECURE_LOGD ("surrounding text : %s", surrounding);
1816         if (surrounding)
1817             free (surrounding);
1818
1819         imcontext->cursor_position = cursor_pos;
1820         wl_text_input_set_cursor_position(imcontext->text_input, cursor_pos);
1821     }
1822     // TIZEN_ONLY(20150716): Support return key type
1823     wl_text_input_set_return_key_type(imcontext->text_input,
1824             imcontext->return_key_type);
1825
1826     wl_text_input_set_return_key_disabled(imcontext->text_input,
1827             imcontext->return_key_disabled);
1828
1829     if (imcontext->imdata_size > 0)
1830         wl_text_input_set_input_panel_data(imcontext->text_input, (const char *)imcontext->imdata, imcontext->imdata_size);
1831
1832     wl_text_input_bidi_direction(imcontext->text_input, imcontext->bidi_direction);
1833
1834     set_autocapital (ctx);
1835
1836     if (imcontext->mime_type)
1837         wl_text_input_set_mime_type(imcontext->text_input, imcontext->mime_type);
1838
1839     if (imcontext->input_panel_position.x >= 0 && imcontext->input_panel_position.y >= 0)
1840             wl_text_input_set_input_panel_position(imcontext->text_input,
1841                 imcontext->input_panel_position.x, imcontext->input_panel_position.y);
1842
1843     LOGD ("ctx : %p, layout : %d, layout variation : %d, language : %d, cursor position : %d",
1844            ctx, layout, layout_variation,
1845            ecore_imf_context_input_panel_language_get (ctx),
1846            cursor_pos);
1847     LOGD ("input hint : %#x, bidi direction : %d, return key type : %d, return key disabled : %d, autocapital type : %d",
1848            ecore_imf_context_input_hint_get (ctx),
1849            imcontext->bidi_direction,
1850            ecore_imf_context_input_panel_return_key_type_get (ctx),
1851            ecore_imf_context_input_panel_return_key_disabled_get (ctx),
1852            ecore_imf_context_autocapital_type_get (ctx));
1853     LOGD ("client_window : %#lx, password mode : %d, prediction_allow : %d, mime_type : %s, input panel position x : %d, y : %d",
1854            (unsigned long int)ecore_imf_context_client_window_get (ctx),
1855            (imcontext->content_hint & WL_TEXT_INPUT_CONTENT_HINT_SENSITIVE_DATA) ? 1 : 0,
1856            ecore_imf_context_prediction_allow_get (ctx),
1857            imcontext->mime_type,
1858            imcontext->input_panel_position.x,
1859            imcontext->input_panel_position.y);
1860
1861     if (_active_context_canvas && !evas_focus_state_get (_active_context_canvas)) {
1862         LOGW ("Canvas does not have focus!");
1863     }
1864     //
1865
1866     if (hw_keyboard_mode) {
1867         LOGD("hw_keyboard_mode is TRUE, returning");
1868         return EINA_FALSE;
1869     }
1870
1871     _input_panel_state = ECORE_IMF_INPUT_PANEL_STATE_WILL_SHOW;
1872
1873     wl_text_input_show_input_panel(imcontext->text_input);
1874
1875     if (imcontext->window) {
1876         _active_context_window_id = ecore_wl2_window_id_get(imcontext->window);
1877         imcontext->has_conformant = ecore_wl2_window_conformant_get(imcontext->window);
1878     } else {
1879         imcontext->has_conformant = EINA_FALSE;
1880     }
1881
1882     return EINA_TRUE;
1883 }
1884
1885 static void delete_surrounding_text(WaylandIMContext *imcontext, int index, int length)
1886 {
1887     Ecore_IMF_Event_Delete_Surrounding ev;
1888     LOGD("delete surrounding text (index: %d, length: %u)",
1889             index, length);
1890
1891     ev.offset = index;
1892     ev.n_chars = length;
1893
1894     ecore_imf_context_event_callback_call(imcontext->ctx, ECORE_IMF_CALLBACK_DELETE_SURROUNDING, &ev);
1895 }
1896
1897 static void
1898 text_input_preedit_string(void                 *data,
1899                           struct wl_text_input *text_input EINA_UNUSED,
1900                           uint32_t              serial,
1901                           const char           *text,
1902                           const char           *commit)
1903 {
1904     WaylandIMContext *imcontext = (WaylandIMContext *)data;
1905     Eina_Bool old_preedit = EINA_FALSE;
1906     Eina_Bool preedit_changed = EINA_FALSE;
1907
1908     SECURE_LOGD("ctx : %p, preedit event (text: '%s', current pre-edit: '%s')",
1909                 imcontext->ctx,
1910                 text,
1911                 imcontext->preedit_text ? imcontext->preedit_text : "");
1912
1913     if (!check_serial(imcontext, serial))
1914         return;
1915
1916     old_preedit =
1917         imcontext->preedit_text && strlen(imcontext->preedit_text) > 0;
1918
1919     if (imcontext->preedit_text)
1920         preedit_changed = (strcmp(imcontext->preedit_text, text) != 0);
1921     else
1922         preedit_changed = (strlen(text) != 0);
1923
1924     if (_preedit_cursor_changed) {
1925         preedit_changed = EINA_TRUE;
1926         _preedit_cursor_changed = EINA_FALSE;
1927     }
1928
1929     if (imcontext->pending_preedit.attrs)
1930         preedit_changed = EINA_TRUE;
1931
1932     clear_preedit(imcontext);
1933
1934     imcontext->preedit_text = strdup(text);
1935     imcontext->preedit_commit = (strlen(text) > 0 ? strdup(commit) : NULL);
1936     imcontext->preedit_cursor =
1937         utf8_offset_to_characters(text, imcontext->pending_preedit.cursor);
1938     imcontext->preedit_attrs = imcontext->pending_preedit.attrs;
1939
1940     imcontext->pending_preedit.attrs = NULL;
1941
1942     if (preedit_changed) {
1943         if (!old_preedit) {
1944             ecore_imf_context_event_callback_call(imcontext->ctx,
1945                     ECORE_IMF_CALLBACK_PREEDIT_START,
1946                     NULL);
1947         }
1948
1949         ecore_imf_context_event_callback_call(imcontext->ctx,
1950                 ECORE_IMF_CALLBACK_PREEDIT_CHANGED,
1951                 NULL);
1952
1953         if (imcontext->preedit_text && strlen(imcontext->preedit_text) == 0) {
1954             ecore_imf_context_event_callback_call(imcontext->ctx,
1955                     ECORE_IMF_CALLBACK_PREEDIT_END,
1956                     NULL);
1957         }
1958     }
1959 }
1960
1961 static void
1962 text_input_delete_surrounding_text(void                 *data,
1963                                    struct wl_text_input *text_input EINA_UNUSED,
1964                                    int32_t               index,
1965                                    uint32_t              length)
1966 {
1967     WaylandIMContext *imcontext = (WaylandIMContext *)data;
1968     delete_surrounding_text(imcontext, index, length);
1969 }
1970
1971 static void
1972 text_input_cursor_position(void                 *data EINA_UNUSED,
1973                            struct wl_text_input *text_input EINA_UNUSED,
1974                            int32_t               index,
1975                            int32_t               anchor)
1976 {
1977     LOGD("cursor_position for next commit (index: %d, anchor: %d)",
1978             index, anchor);
1979 }
1980
1981 static void
1982 text_input_preedit_styling(void                 *data,
1983                            struct wl_text_input *text_input EINA_UNUSED,
1984                            uint32_t              index,
1985                            uint32_t              length,
1986                            uint32_t              style)
1987 {
1988     WaylandIMContext *imcontext = (WaylandIMContext *)data;
1989     Ecore_IMF_Preedit_Attr *attr = calloc(1, sizeof(*attr));
1990     if (!attr) return;
1991
1992     switch (style)
1993     {
1994         case WL_TEXT_INPUT_PREEDIT_STYLE_DEFAULT:
1995             attr->preedit_type = ECORE_IMF_PREEDIT_TYPE_NONE;
1996             break;
1997         case WL_TEXT_INPUT_PREEDIT_STYLE_UNDERLINE:
1998             attr->preedit_type = ECORE_IMF_PREEDIT_TYPE_SUB1;
1999             break;
2000         case WL_TEXT_INPUT_PREEDIT_STYLE_REVERSE:
2001             attr->preedit_type = ECORE_IMF_PREEDIT_TYPE_SUB2;
2002             break;
2003         case WL_TEXT_INPUT_PREEDIT_STYLE_HIGHLIGHT:
2004             attr->preedit_type = ECORE_IMF_PREEDIT_TYPE_SUB3;
2005             break;
2006         case WL_TEXT_INPUT_PREEDIT_STYLE_BGCOLOR1:
2007             attr->preedit_type = ECORE_IMF_PREEDIT_TYPE_SUB4;
2008             break;
2009         case WL_TEXT_INPUT_PREEDIT_STYLE_BGCOLOR2:
2010             attr->preedit_type = ECORE_IMF_PREEDIT_TYPE_SUB5;
2011             break;
2012         case WL_TEXT_INPUT_PREEDIT_STYLE_BGCOLOR3:
2013             attr->preedit_type = ECORE_IMF_PREEDIT_TYPE_SUB6;
2014             break;
2015         case WL_TEXT_INPUT_PREEDIT_STYLE_BGCOLOR4:
2016             attr->preedit_type = ECORE_IMF_PREEDIT_TYPE_SUB7;
2017             break;
2018         default:
2019             attr->preedit_type = ECORE_IMF_PREEDIT_TYPE_SUB1;
2020             break;
2021     }
2022
2023     attr->start_index = index;
2024     attr->end_index = index + length;
2025
2026     imcontext->pending_preedit.attrs =
2027         eina_list_append(imcontext->pending_preedit.attrs, attr);
2028 }
2029
2030 static void
2031 text_input_preedit_cursor(void                 *data,
2032                           struct wl_text_input *text_input EINA_UNUSED,
2033                           int32_t               index)
2034 {
2035     WaylandIMContext *imcontext = (WaylandIMContext *)data;
2036
2037     LOGD("preedit cursor : %d", index);
2038
2039     if (imcontext->pending_preedit.cursor != index) {
2040         imcontext->pending_preedit.cursor = index;
2041         _preedit_cursor_changed = EINA_TRUE;
2042     }
2043 }
2044
2045 static xkb_mod_index_t
2046 modifiers_get_index(struct wl_array *modifiers_map, const char *name)
2047 {
2048     xkb_mod_index_t index = 0;
2049     char *p = modifiers_map->data;
2050
2051     while ((const char *)p < ((const char *)modifiers_map->data + modifiers_map->size))
2052     {
2053         if (strcmp(p, name) == 0)
2054             return index;
2055
2056         index++;
2057         p += strlen(p) + 1;
2058     }
2059
2060     return XKB_MOD_INVALID;
2061 }
2062
2063 static xkb_mod_mask_t
2064 modifiers_get_mask(struct wl_array *modifiers_map,
2065         const char *name)
2066 {
2067     xkb_mod_index_t index = modifiers_get_index(modifiers_map, name);
2068
2069     if (index == XKB_MOD_INVALID)
2070         return XKB_MOD_INVALID;
2071
2072     return 1 << index;
2073 }
2074
2075 static void
2076 text_input_modifiers_map(void                 *data,
2077                          struct wl_text_input *text_input EINA_UNUSED,
2078                          struct wl_array      *map)
2079 {
2080     WaylandIMContext *imcontext = (WaylandIMContext *)data;
2081     imcontext->shift_mask = modifiers_get_mask(map, XKB_MOD_NAME_SHIFT);
2082     imcontext->control_mask = modifiers_get_mask(map, XKB_MOD_NAME_CTRL);
2083     imcontext->alt_mask = modifiers_get_mask(map, XKB_MOD_NAME_ALT);
2084     imcontext->caps_mask = modifiers_get_mask(map, XKB_MOD_NAME_CAPS);
2085     imcontext->num_mask = modifiers_get_mask(map, XKB_MOD_NAME_NUM);
2086 }
2087
2088 static void
2089 _ecore_keyevent_free (void *data EINA_UNUSED, void *ev)
2090 {
2091     Ecore_Event_Key *e = ev;
2092     if (e->dev) ecore_device_unref(e->dev);
2093     free(e);
2094     e = NULL;
2095 }
2096
2097 static void
2098 text_input_keysym(void                 *data,
2099                   struct wl_text_input *text_input EINA_UNUSED,
2100                   uint32_t              serial EINA_UNUSED,
2101                   uint32_t              time,
2102                   uint32_t              sym,
2103                   uint32_t              state,
2104                   uint32_t              modifiers)
2105 {
2106     WaylandIMContext *imcontext = (WaylandIMContext *)data;
2107     char string[32], key[32], keyname[32];
2108     Ecore_Event_Key *e;
2109
2110     memset(key, 0, sizeof(key));
2111     xkb_keysym_get_name(sym, key, sizeof(key));
2112
2113     memset(keyname, 0, sizeof(keyname));
2114     xkb_keysym_get_name(sym, keyname, sizeof(keyname));
2115     if (keyname[0] == '\0')
2116         snprintf(keyname, sizeof(keyname), "Keysym-%u", sym);
2117
2118     memset(string, 0, sizeof(string));
2119     xkb_keysym_to_utf8(sym, string, 32);
2120
2121     SECURE_LOGD("key event (key: %s)", keyname);
2122
2123     e = calloc(1, sizeof(Ecore_Event_Key) + strlen(key) + strlen(keyname) +
2124             strlen(string) + 3);
2125     if (!e) return;
2126
2127     e->keyname = (char *)(e + 1);
2128     e->key = e->keyname + strlen(keyname) + 1;
2129     e->string = e->key + strlen(key) + 1;
2130     e->compose = e->string;
2131
2132     strncpy((char *)e->keyname, keyname, strlen(keyname));
2133     strncpy((char *)e->key, key, strlen(key));
2134     strncpy((char *)e->string, string, strlen(string));
2135
2136     e->window = (Ecore_Window)ecore_wl2_window_id_get(imcontext->window);
2137     e->event_window = (Ecore_Window)ecore_wl2_window_id_get(imcontext->window);
2138     e->dev = ecore_device_ref(_ime_device);
2139     e->timestamp = 0; /* For distinguishing S/W keyboard event */
2140
2141     e->modifiers = 0;
2142     if (modifiers & imcontext->shift_mask)
2143         e->modifiers |= ECORE_EVENT_MODIFIER_SHIFT;
2144
2145     if (modifiers & imcontext->control_mask)
2146         e->modifiers |= ECORE_EVENT_MODIFIER_CTRL;
2147
2148     if (modifiers & imcontext->alt_mask)
2149         e->modifiers |= ECORE_EVENT_MODIFIER_ALT;
2150
2151     if (modifiers & MOD_Mod5_MASK)
2152         e->modifiers |= MOD_Mod5_MASK;
2153
2154     if (modifiers & imcontext->caps_mask)
2155         e->modifiers |= ECORE_EVENT_LOCK_CAPS;
2156
2157     if (modifiers & imcontext->num_mask)
2158         e->modifiers |= ECORE_EVENT_LOCK_NUM;
2159
2160     //Save "wl_text_input::keysym" keysym to list if list is not empty,
2161     //if not, send keysym to ecore loop as key event.
2162     //This code let key event which will be filtered by IME one by one.
2163     if (eina_list_count(imcontext->keysym_list)) {
2164         e->data = (void *)(unsigned long int)(state ? ECORE_EVENT_KEY_DOWN : ECORE_EVENT_KEY_UP);
2165         imcontext->keysym_list = eina_list_prepend(imcontext->keysym_list, e);
2166     }
2167     else {
2168         if (state)
2169             ecore_event_add(ECORE_EVENT_KEY_DOWN, e, _ecore_keyevent_free, NULL);
2170         else
2171             ecore_event_add(ECORE_EVENT_KEY_UP, e, _ecore_keyevent_free, NULL);
2172     }
2173 }
2174
2175 static void
2176 text_input_enter(void                 *data,
2177                  struct wl_text_input *text_input EINA_UNUSED,
2178                  struct wl_surface    *surface EINA_UNUSED)
2179 {
2180     WaylandIMContext *imcontext = (WaylandIMContext *)data;
2181
2182     update_state(imcontext);
2183
2184     imcontext->reset_serial = imcontext->serial;
2185 }
2186
2187 static void
2188 text_input_leave(void                 *data,
2189                  struct wl_text_input *text_input EINA_UNUSED)
2190 {
2191     WaylandIMContext *imcontext = (WaylandIMContext *)data;
2192
2193     /* clear preedit */
2194     commit_preedit(imcontext);
2195     clear_preedit(imcontext);
2196 }
2197
2198 static void
2199 text_input_input_panel_state(void                 *data EINA_UNUSED,
2200                              struct wl_text_input *text_input EINA_UNUSED,
2201                              uint32_t              state EINA_UNUSED)
2202 {
2203     // TIZEN_ONLY(20150708): Support input panel state callback
2204     WaylandIMContext *imcontext = (WaylandIMContext *)data;
2205     LOGD("input panel state: %d", state);
2206     switch (state) {
2207         case WL_TEXT_INPUT_INPUT_PANEL_STATE_HIDE:
2208             _input_panel_state = ECORE_IMF_INPUT_PANEL_STATE_HIDE;
2209             if (imcontext->ctx == _show_req_ctx)
2210                 _show_req_ctx = NULL;
2211
2212             will_hide = EINA_FALSE;
2213
2214             _received_will_hide_event = EINA_TRUE;
2215             LOGD("_received_will_hide_event = 1");
2216             send_will_hide_ack(imcontext->ctx);
2217             break;
2218         case WL_TEXT_INPUT_INPUT_PANEL_STATE_SHOW:
2219             _input_panel_state = ECORE_IMF_INPUT_PANEL_STATE_SHOW;
2220             _received_will_hide_event = EINA_FALSE;
2221             if (!_show_req_ctx)
2222                 _show_req_ctx = imcontext->ctx;
2223             LOGD("_received_will_hide_event = 0");
2224             break;
2225         default:
2226             _input_panel_state = (Ecore_IMF_Input_Panel_State)state;
2227             break;
2228     }
2229
2230     ecore_imf_context_input_panel_event_callback_call(imcontext->ctx,
2231             ECORE_IMF_INPUT_PANEL_STATE_EVENT,
2232             _input_panel_state);
2233
2234     if (state == WL_TEXT_INPUT_INPUT_PANEL_STATE_HIDE) {
2235         reset_keyboard_geometry();
2236         LOGD ("IME geometry x : %d, y : %d, w : %d, h : %d", _keyboard_geometry.x, _keyboard_geometry.y, _keyboard_geometry.w, _keyboard_geometry.h);
2237         ecore_imf_context_input_panel_event_callback_call(imcontext->ctx, ECORE_IMF_INPUT_PANEL_GEOMETRY_EVENT, 0);
2238     }
2239     //
2240 }
2241
2242 // TIZEN_ONLY(20151221): Support input panel geometry
2243 static void
2244 text_input_input_panel_geometry(void                 *data EINA_UNUSED,
2245                                 struct wl_text_input *text_input EINA_UNUSED,
2246                                 uint32_t              x,
2247                                 uint32_t              y,
2248                                 uint32_t              w,
2249                                 uint32_t              h)
2250 {
2251     WaylandIMContext *imcontext = (WaylandIMContext *)data;
2252
2253     if (_keyboard_geometry.x != (int)x || _keyboard_geometry.y != (int)y ||
2254         _keyboard_geometry.w != (int)w || _keyboard_geometry.h != (int)h)
2255     {
2256         _keyboard_geometry.x = x;
2257         _keyboard_geometry.y = y;
2258         _keyboard_geometry.w = w;
2259         _keyboard_geometry.h = h;
2260         LOGD ("IME geometry x : %d, y : %d, w : %d, h : %d", _keyboard_geometry.x, _keyboard_geometry.y, _keyboard_geometry.w, _keyboard_geometry.h);
2261         ecore_imf_context_input_panel_event_callback_call(imcontext->ctx, ECORE_IMF_INPUT_PANEL_GEOMETRY_EVENT, 0);
2262     }
2263 }
2264 //
2265
2266 static void
2267 text_input_language(void                 *data,
2268                     struct wl_text_input *text_input EINA_UNUSED,
2269                     uint32_t              serial EINA_UNUSED,
2270                     const char           *language)
2271 {
2272     WaylandIMContext *imcontext = (WaylandIMContext *)data;
2273     Eina_Bool changed = EINA_FALSE;
2274
2275     if (!imcontext || !language) return;
2276
2277     if (imcontext->language) {
2278         if (strcmp(imcontext->language, language) != 0) {
2279             changed = EINA_TRUE;
2280             free(imcontext->language);
2281         }
2282     }
2283     else {
2284         changed = EINA_TRUE;
2285     }
2286
2287     if (changed) {
2288         imcontext->language = strdup(language);
2289
2290         if (imcontext->ctx)
2291             ecore_imf_context_input_panel_event_callback_call(imcontext->ctx, ECORE_IMF_INPUT_PANEL_LANGUAGE_EVENT, 0);
2292     }
2293 }
2294
2295 static void
2296 text_input_text_direction(void                 *data EINA_UNUSED,
2297                           struct wl_text_input *text_input EINA_UNUSED,
2298                           uint32_t              serial EINA_UNUSED,
2299                           uint32_t              direction EINA_UNUSED)
2300 {
2301 }
2302
2303 // TIZEN_ONLY(20150918): Support to set the selection region
2304 static void
2305 text_input_selection_region(void                 *data,
2306                             struct wl_text_input *text_input EINA_UNUSED,
2307                             uint32_t              serial EINA_UNUSED,
2308                             int32_t               start,
2309                             int32_t               end)
2310 {
2311     WaylandIMContext *imcontext = (WaylandIMContext *)data;
2312     if (!imcontext || !imcontext->ctx) return;
2313
2314     Ecore_IMF_Event_Selection ev;
2315     ev.ctx = imcontext->ctx;
2316     ev.start = start;
2317     ev.end = end;
2318     ecore_imf_context_event_callback_call(imcontext->ctx, ECORE_IMF_CALLBACK_SELECTION_SET, &ev);
2319 }
2320
2321 static void
2322 text_input_private_command(void                 *data,
2323                            struct wl_text_input *text_input EINA_UNUSED,
2324                            uint32_t              serial EINA_UNUSED,
2325                            const char           *command)
2326 {
2327     WaylandIMContext *imcontext = (WaylandIMContext *)data;
2328     if (!imcontext || !imcontext->ctx) return;
2329
2330     const char *szConformantReset = "CONFORMANT_RESET";
2331     const char *szConformantRestore = "CONFORMANT_RESTORE";
2332     LOGD("Checking command : %s", command);
2333
2334     if (strncmp(command, szConformantReset, strlen(szConformantReset)) == 0) {
2335         Ecore_Wl2_Window *window = imcontext->window;
2336         if (!window) return;
2337
2338         if (!reset_conformant_area(imcontext->ctx) && !_conformant_reset_started) {
2339             LOGD("Could not reset conformant area, send will_hide_ack right away %d", _conformant_reset_started);
2340             _send_will_hide_ack(imcontext);
2341         } else if (_conformant_reset_done) {
2342             LOGD("Conformant reset has been already finished, send will_hide_ack right away");
2343             _send_will_hide_ack(imcontext);
2344         }
2345     } else if (strncmp(command, szConformantRestore, strlen(szConformantRestore)) == 0) {
2346         Ecore_Wl2_Window *window = imcontext->window;
2347         if (!window) return;
2348
2349         restore_conformant_area(imcontext->ctx);
2350     } else {
2351         ecore_imf_context_event_callback_call(imcontext->ctx, ECORE_IMF_CALLBACK_PRIVATE_COMMAND_SEND, (void *)command);
2352     }
2353 }
2354
2355 static void
2356 text_input_commit_content(void                 *data,
2357                           struct wl_text_input *text_input EINA_UNUSED,
2358                           uint32_t              serial EINA_UNUSED,
2359                           const char           *content,
2360                           const char           *description,
2361                           const char           *mime_types)
2362 {
2363     WaylandIMContext *imcontext = (WaylandIMContext *)data;
2364     if (!imcontext || !imcontext->ctx) return;
2365
2366     Ecore_IMF_Event_Commit_Content ev;
2367     ev.content_uri = content;
2368     ev.mime_types = mime_types;
2369     ev.description = description;
2370
2371     SECURE_LOGD("commit content : %s, description : %s, mime types : %s", content, description, mime_types);
2372
2373     ecore_imf_context_event_callback_call(imcontext->ctx, ECORE_IMF_CALLBACK_COMMIT_CONTENT, (void *)&ev);
2374 }
2375
2376 static void
2377 text_input_input_panel_data(void                 *data,
2378                             struct wl_text_input *text_input EINA_UNUSED,
2379                             uint32_t              serial EINA_UNUSED,
2380                             const char           *input_panel_data,
2381                             uint32_t              length)
2382 {
2383     WaylandIMContext *imcontext = (WaylandIMContext *)data;
2384     if (!imcontext || !imcontext->ctx) return;
2385
2386     if (imcontext->input_panel_data)
2387         free (imcontext->input_panel_data);
2388
2389     imcontext->input_panel_data = calloc (1, length);
2390     if (imcontext->input_panel_data)
2391         memcpy (imcontext->input_panel_data, input_panel_data, length);
2392
2393     imcontext->input_panel_data_length = length;
2394 }
2395
2396 static void
2397 text_input_get_selection_text (void                 *data,
2398                                struct wl_text_input *text_input EINA_UNUSED,
2399                                int32_t              fd)
2400 {
2401     char *selection = NULL;
2402     LOGD ("%d", fd);
2403     WaylandIMContext *imcontext = (WaylandIMContext *)data;
2404     if (!imcontext || !imcontext->ctx) {
2405         LOGD ("No context!");
2406         close (fd);
2407         return;
2408     }
2409
2410     ecore_imf_context_selection_get (imcontext->ctx, &selection);
2411     if (imcontext->text_input) {
2412         SECURE_LOGD ("selection :%s", selection ? selection : "");
2413         if (selection) {
2414             char *_selection = selection;
2415             size_t len = strlen (selection);
2416             while (len) {
2417                 ssize_t ret = write (fd, _selection, len);
2418                 if (ret <= 0) {
2419                     if (errno == EINTR)
2420                         continue;
2421                     LOGW ("write pipe failed, errno: %d", errno);
2422                     break;
2423                 }
2424                 _selection += ret;
2425                 len -= ret;
2426             }
2427         }
2428     }
2429     if (selection)
2430         free (selection);
2431     close (fd);
2432 }
2433
2434 static void
2435 text_input_get_surrounding_text (void                 *data,
2436                                  struct wl_text_input *text_input EINA_UNUSED,
2437                                  uint32_t              maxlen_before,
2438                                  uint32_t              maxlen_after,
2439                                  int32_t              fd)
2440 {
2441     int cursor_pos;
2442     char *surrounding = NULL;
2443     LOGD("fd: %d maxlen_before: %d maxlen_after: %d", fd, maxlen_before, maxlen_after);
2444     WaylandIMContext *imcontext = (WaylandIMContext *)data;
2445     if (!imcontext || !imcontext->ctx) {
2446         LOGD ("No context!");
2447         close(fd);
2448         return;
2449     }
2450
2451     /* cursor_pos is a byte index */
2452     if (ecore_imf_context_surrounding_get (imcontext->ctx, &surrounding, &cursor_pos)) {
2453         SECURE_LOGD ("surrounding : '%s', cursor: %d", surrounding ? surrounding : "", cursor_pos);
2454         if (imcontext->text_input) {
2455             Eina_Unicode *wide_surrounding = eina_unicode_utf8_to_unicode (surrounding, NULL);
2456             size_t wlen = eina_unicode_strlen (wide_surrounding);
2457
2458             if (cursor_pos > (int)wlen || cursor_pos < 0)
2459                 cursor_pos = 0;
2460
2461             if (maxlen_before > cursor_pos)
2462                 maxlen_before = 0;
2463             else
2464                 maxlen_before = cursor_pos - maxlen_before;
2465
2466             if (maxlen_after > wlen - cursor_pos)
2467                 maxlen_after = (uint32_t)wlen;
2468             else
2469                 maxlen_after = cursor_pos + maxlen_after;
2470
2471             char *req_surrounding = eina_unicode_unicode_to_utf8_range (wide_surrounding + maxlen_before, maxlen_after - maxlen_before, NULL);
2472
2473             ssize_t ret = write(fd, &cursor_pos, sizeof(cursor_pos));
2474             if (ret <= 0) {
2475                 LOGW ("write pipe failed, errno: %d", errno);
2476             } else if (req_surrounding) {
2477                 char *_surrounding = req_surrounding;
2478                 size_t len = strlen(req_surrounding);
2479                 while (len) {
2480                     ssize_t ret = write(fd, _surrounding, len);
2481                     if (ret <= 0) {
2482                         if (errno == EINTR)
2483                             continue;
2484                         LOGW ("write pipe failed, errno: %d", errno);
2485                         break;
2486                     }
2487                     _surrounding += ret;
2488                     len -= ret;
2489                 }
2490             }
2491
2492             if (req_surrounding)
2493                 free (req_surrounding);
2494
2495             if (wide_surrounding)
2496                 free (wide_surrounding);
2497         }
2498
2499         if (surrounding)
2500             free (surrounding);
2501     }
2502     close(fd);
2503 }
2504
2505 static void
2506 text_input_filter_key_event_done(void                 *data,
2507                                  struct wl_text_input *text_input EINA_UNUSED,
2508                                  uint32_t              serial,
2509                                  uint32_t              state)
2510 {
2511     LOGD("serial: %d, state: %d", serial, state);
2512     WaylandIMContext *imcontext = (WaylandIMContext *)data;
2513     if (!imcontext) return;
2514
2515     imcontext->last_key_event_filter.serial = serial;
2516     imcontext->last_key_event_filter.state = state;
2517 }
2518
2519 static void
2520 text_input_hide_permission(void                 *data,
2521                            struct wl_text_input *text_input EINA_UNUSED,
2522                            uint32_t              permission)
2523 {
2524     LOGD("permission : %d", permission);
2525     WaylandIMContext *imcontext = (WaylandIMContext *)data;
2526     if (!imcontext || !imcontext->ctx || ignore_hide)
2527         return;
2528
2529     if (permission)
2530         ecore_imf_context_input_panel_hide(imcontext->ctx);
2531 }
2532
2533 static void
2534 text_input_recapture_string(void                 *data,
2535                             struct wl_text_input *text_input EINA_UNUSED,
2536                             uint32_t              serial,
2537                             int32_t               index,
2538                             uint32_t              length,
2539                             const char           *preedit,
2540                             const char           *preedit_commit,
2541                             const char           *commit)
2542 {
2543     WaylandIMContext *imcontext = (WaylandIMContext *)data;
2544     Eina_Bool old_preedit = EINA_FALSE;
2545     Eina_Bool preedit_changed = EINA_FALSE;
2546
2547     SECURE_LOGD("ctx : %p, index : %d, length : %d, preedit event (preedit: '%s', current pre-edit: '%s')",
2548                 imcontext->ctx,
2549                 index,
2550                 length,
2551                 preedit,
2552                 imcontext->preedit_text ? imcontext->preedit_text : "");
2553
2554     if (!check_serial(imcontext, serial))
2555         return;
2556
2557     old_preedit =
2558         imcontext->preedit_text && strlen(imcontext->preedit_text) > 0;
2559
2560     if (imcontext->preedit_text)
2561         preedit_changed = (strcmp(imcontext->preedit_text, preedit) != 0);
2562     else
2563         preedit_changed = (strlen(preedit) != 0);
2564
2565     // send transaction start
2566     ecore_imf_context_event_callback_call(imcontext->ctx, ECORE_IMF_CALLBACK_PRIVATE_COMMAND_SEND, (void *)"TRANSACTION_START");
2567     ecore_imf_context_event_callback_call(imcontext->ctx, ECORE_IMF_CALLBACK_TRANSACTION_START, NULL);
2568
2569     commit_preedit(imcontext);
2570     clear_preedit(imcontext);
2571
2572     // delete surrounding text
2573     delete_surrounding_text(imcontext, index, length);
2574
2575     // update preedit string
2576     imcontext->preedit_text = strdup(preedit);
2577     imcontext->preedit_commit = (strlen(preedit) > 0 ? strdup(preedit_commit) : NULL);
2578     imcontext->preedit_cursor =
2579         utf8_offset_to_characters(preedit, imcontext->pending_preedit.cursor);
2580     imcontext->preedit_attrs = imcontext->pending_preedit.attrs;
2581
2582     imcontext->pending_preedit.attrs = NULL;
2583
2584     if (preedit_changed) {
2585         if (!old_preedit) {
2586             ecore_imf_context_event_callback_call(imcontext->ctx,
2587                     ECORE_IMF_CALLBACK_PREEDIT_START,
2588                     NULL);
2589         }
2590
2591         ecore_imf_context_event_callback_call(imcontext->ctx,
2592                 ECORE_IMF_CALLBACK_PREEDIT_CHANGED,
2593                 NULL);
2594
2595         if (imcontext->preedit_text && strlen(imcontext->preedit_text) == 0) {
2596             ecore_imf_context_event_callback_call(imcontext->ctx,
2597                     ECORE_IMF_CALLBACK_PREEDIT_END,
2598                     NULL);
2599         }
2600     }
2601
2602     // commit string
2603     if (commit && strlen(commit) != 0) {
2604         ecore_imf_context_event_callback_call(imcontext->ctx, ECORE_IMF_CALLBACK_COMMIT, (void *)commit);
2605     }
2606
2607     // send transaction end
2608     ecore_imf_context_event_callback_call(imcontext->ctx, ECORE_IMF_CALLBACK_PRIVATE_COMMAND_SEND, (void *)"TRANSACTION_END");
2609     ecore_imf_context_event_callback_call(imcontext->ctx, ECORE_IMF_CALLBACK_TRANSACTION_END, NULL);
2610 }
2611
2612 static void
2613 text_input_input_panel_event(void                 *data,
2614                              struct wl_text_input *text_input EINA_UNUSED,
2615                              uint32_t              serial EINA_UNUSED,
2616                              uint32_t              event_type,
2617                              uint32_t              value)
2618 {
2619     WaylandIMContext *imcontext = (WaylandIMContext *)data;
2620     if (!imcontext || !imcontext->ctx) return;
2621
2622     LOGD("event type : %d, value : %d", event_type, value);
2623
2624     ecore_imf_context_input_panel_event_callback_call(imcontext->ctx, event_type, value);
2625 }
2626 //
2627
2628 static const struct wl_text_input_listener text_input_listener =
2629 {
2630     text_input_enter,
2631     text_input_leave,
2632     text_input_modifiers_map,
2633     text_input_input_panel_state,
2634     text_input_preedit_string,
2635     text_input_preedit_styling,
2636     text_input_preedit_cursor,
2637     text_input_commit_string,
2638     text_input_cursor_position,
2639     text_input_delete_surrounding_text,
2640     text_input_keysym,
2641     text_input_language,
2642     text_input_text_direction,
2643     // TIZEN_ONLY(20150918): Support to set the selection region
2644     text_input_selection_region,
2645     text_input_private_command,
2646     text_input_input_panel_geometry,
2647     text_input_input_panel_data,
2648     text_input_get_selection_text,
2649     text_input_get_surrounding_text,
2650     text_input_filter_key_event_done,
2651     text_input_hide_permission,
2652     text_input_recapture_string,
2653     text_input_input_panel_event,
2654     text_input_commit_content
2655     //
2656 };
2657
2658 #ifdef HAVE_VCONF
2659 static void
2660 keyboard_mode_changed_cb (keynode_t *key, void* data)
2661 {
2662     hw_keyboard_mode = vconf_keynode_get_bool (key);
2663     Ecore_IMF_Context *active_ctx = get_using_ctx ();
2664     if (active_ctx) {
2665         LOGD ("ctx : %p, input detect : %d", active_ctx, hw_keyboard_mode);
2666
2667         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;
2668         ecore_imf_context_input_panel_event_callback_call (active_ctx, ECORE_IMF_INPUT_PANEL_KEYBOARD_MODE_EVENT, input_mode);
2669
2670         if (input_mode == ECORE_IMF_INPUT_PANEL_HW_KEYBOARD_MODE && _input_panel_state == ECORE_IMF_INPUT_PANEL_STATE_WILL_SHOW)
2671             _input_panel_state = ECORE_IMF_INPUT_PANEL_STATE_HIDE;
2672
2673         if ((input_mode == ECORE_IMF_INPUT_PANEL_SW_KEYBOARD_MODE) && _focused_ctx && (active_ctx == _focused_ctx)) {
2674             if (ecore_imf_context_input_panel_enabled_get (active_ctx)) {
2675                 ecore_imf_context_input_panel_show (active_ctx);
2676             }
2677         }
2678     }
2679 }
2680 #endif
2681
2682 #ifdef SOCKET_ACTIVATION
2683 static int activate_socket () {
2684     int s;
2685     struct sockaddr_un svr;
2686     int len;
2687     int r;
2688     int cnt = 5;
2689     int flag;
2690
2691     LOGD("socket_activate start");
2692     s = socket(AF_UNIX, SOCK_STREAM, 0);
2693     if (s == -1) {
2694         LOGW("socket error");
2695         return -1;
2696     }
2697
2698     flag = fcntl(s, F_GETFL, NULL);
2699     flag |= O_NONBLOCK;
2700     fcntl(s, F_SETFL, flag);
2701
2702     svr.sun_family = AF_UNIX;
2703     strcpy(svr.sun_path, SOCK_PATH);
2704     len = sizeof(svr);
2705
2706     r = connect(s, (struct sockaddr *)&svr, len);
2707     if (r == -1) {
2708         LOGD("connect error");
2709         close(s);
2710         return -1;
2711     }
2712
2713     while (cnt > 0) {
2714         struct timeval s1;
2715
2716         gettimeofday(&s1, NULL);
2717         LOGD("%d %06d\n", (int)s1.tv_sec, (int)s1.tv_usec);
2718
2719         r = send(s, (const void *)&s1, sizeof(s1), 0);
2720         if (r == -1) {
2721             LOGW("send error");
2722             break;
2723         }
2724         cnt--;
2725     }
2726
2727     close(s);
2728     return 0;
2729 }
2730 #endif
2731
2732 void wayland_im_initialize ()
2733 {
2734     register_key_handler ();
2735
2736     /* get input language vconf value */
2737     char *input_lang_str = vconf_get_str (VCONFKEY_ISF_INPUT_LANGUAGE);
2738     if (input_lang_str) {
2739         set_input_language (input_lang_str);
2740         free (input_lang_str);
2741     }
2742
2743 #ifdef HAVE_VCONF
2744     /* get autoperiod allow vconf value */
2745     int val;
2746     if (vconf_get_bool (VCONFKEY_AUTOPERIOD_ALLOW_BOOL, &val) == 0) {
2747         if (val == EINA_TRUE)
2748             autoperiod_allow = EINA_TRUE;
2749     }
2750
2751     /* get autocapital allow vconf value */
2752     if (vconf_get_bool (VCONFKEY_AUTOCAPITAL_ALLOW_BOOL, &val) == 0) {
2753         if (val == EINA_TRUE)
2754             autocap_allow = EINA_TRUE;
2755     }
2756
2757     /* get hardware keyboard input detected vconf value */
2758     if (vconf_get_bool (VCONFKEY_ISF_HW_KEYBOARD_INPUT_DETECTED, &val) == 0) {
2759         if (val == EINA_TRUE)
2760             hw_keyboard_mode = EINA_TRUE;
2761     }
2762
2763     vconf_notify_key_changed (VCONFKEY_AUTOCAPITAL_ALLOW_BOOL, autocapital_allow_changed_cb, NULL);
2764     vconf_notify_key_changed (VCONFKEY_AUTOPERIOD_ALLOW_BOOL, autoperiod_allow_changed_cb, NULL);
2765     vconf_notify_key_changed (VCONFKEY_ISF_INPUT_LANGUAGE, input_language_changed_cb, NULL);
2766     vconf_notify_key_changed (VCONFKEY_ISF_HW_KEYBOARD_INPUT_DETECTED, keyboard_mode_changed_cb, NULL);
2767 #endif
2768
2769     _ime_device = ecore_device_add();
2770     if (_ime_device) {
2771         ecore_device_name_set (_ime_device, IME_DEVICE_NAME);
2772         ecore_device_description_set (_ime_device, IME_DEVICE_NAME);
2773         ecore_device_identifier_set (_ime_device, IME_DEVICE_NAME);
2774         ecore_device_class_set (_ime_device, ECORE_DEVICE_CLASS_KEYBOARD);
2775         ecore_device_subclass_set (_ime_device, ECORE_DEVICE_SUBCLASS_VIRTUAL_KEYBOARD);
2776     }
2777 }
2778
2779 void wayland_im_uninitialize ()
2780 {
2781     _ecore_imf_wayland_imcontext_pair_destroy ();
2782
2783     unregister_key_handler ();
2784
2785     _win_focus_out_handler_del ();
2786     _conformant_change_handler_del ();
2787
2788 #ifdef HAVE_VCONF
2789     vconf_ignore_key_changed (VCONFKEY_AUTOPERIOD_ALLOW_BOOL, autoperiod_allow_changed_cb);
2790     vconf_ignore_key_changed (VCONFKEY_AUTOCAPITAL_ALLOW_BOOL, autocapital_allow_changed_cb);
2791     vconf_ignore_key_changed (VCONFKEY_ISF_INPUT_LANGUAGE, input_language_changed_cb);
2792     vconf_ignore_key_changed (VCONFKEY_ISF_HW_KEYBOARD_INPUT_DETECTED, keyboard_mode_changed_cb);
2793 #endif
2794
2795     if (_ime_device) {
2796         ecore_device_del (_ime_device);
2797         _ime_device = NULL;
2798     }
2799
2800     ecore_event_type_flush(ECORE_EVENT_DEVICE_ADD, ECORE_EVENT_DEVICE_DEL);
2801 }
2802
2803 void
2804 wayland_im_context_add(Ecore_IMF_Context *ctx)
2805 {
2806     WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
2807     char *appid = NULL;
2808
2809     LOGD("ctx : %p", ctx);
2810
2811     if (!imcontext) return;
2812
2813     imcontext->ctx = ctx;
2814     imcontext->input_panel_layout = ECORE_IMF_INPUT_PANEL_LAYOUT_NORMAL;
2815     imcontext->keysym_list = NULL;
2816
2817     imcontext->shift_mask = MOD_SHIFT_MASK;
2818     imcontext->control_mask = MOD_CONTROL_MASK;
2819     imcontext->alt_mask = MOD_ALT_MASK;
2820     imcontext->caps_mask = MOD_CAPS_MASK;
2821     imcontext->num_mask = MOD_NUM_MASK;
2822
2823     imcontext->input_panel_position.x = -1;
2824     imcontext->input_panel_position.y = -1;
2825
2826     LOGD("text_input_manager : %p", imcontext->text_input_manager);
2827     imcontext->text_input =
2828         wl_text_input_manager_create_text_input(imcontext->text_input_manager);
2829
2830     if (imcontext->text_input)
2831         wl_text_input_add_listener(imcontext->text_input,
2832                                    &text_input_listener, imcontext);
2833
2834     app_get_id(&appid);
2835     LOGD("app id : %s\n", appid);
2836
2837     ecore_imf_context_prediction_hint_hash_set(ctx, "appid", appid ? appid : "");
2838
2839     if (appid)
2840         free (appid);
2841 }
2842
2843 void
2844 wayland_im_context_del (Ecore_IMF_Context *ctx)
2845 {
2846     WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
2847
2848     Eina_Bool valid = EINA_FALSE;
2849     Ecore_Imf_Wayland_Imcontext_Pair *pair = _ecore_imf_wayland_imcontext_pair_find(ctx);
2850     if (pair && pair->imcontext == imcontext) {
2851         _ecore_imf_wayland_imcontext_pair_del(ctx);
2852         valid = EINA_TRUE;
2853     }
2854     else {
2855         LOGE("The Ecore_Imf %p and WaylandIMContext %p pair not found!! pair : %p, pair->imcontext %p",
2856             ctx, imcontext, pair, pair ? pair->imcontext : NULL);
2857         _ecore_imf_wayland_imcontext_pair_log();
2858     }
2859
2860     Ecore_Event_Key *ev;
2861     LOGD ("ctx : %p, ctx valid : %d, focused_ctx : %p, show_req_ctx : %p", ctx, valid, _focused_ctx, _show_req_ctx);
2862
2863     if (!imcontext) return;
2864
2865     // TIZEN_ONLY(20150708): Support back key
2866     if (_input_panel_ctx == ctx) {
2867         _clear_hide_timer();
2868         _input_panel_hide(ctx, EINA_TRUE);
2869         _input_panel_state = ECORE_IMF_INPUT_PANEL_STATE_HIDE;
2870         _input_panel_ctx = NULL;
2871     }
2872
2873     if (_focused_ctx == ctx)
2874         _focused_ctx = NULL;
2875
2876     if (_show_req_ctx == ctx)
2877         _show_req_ctx = NULL;
2878
2879     if (_focus_req_ctx == ctx) {
2880         if (imcontext->canvas)
2881             evas_event_callback_del(imcontext->canvas, EVAS_CALLBACK_CANVAS_FOCUS_IN, _canvas_focus_in_cb);
2882
2883         _focus_req_ctx = NULL;
2884         _focus_req_only = EINA_TRUE;
2885     }
2886     //
2887
2888     if (imcontext->language) {
2889         free (imcontext->language);
2890         imcontext->language = NULL;
2891     }
2892
2893     // TIZEN_ONLY(20150922): Support to set input panel data
2894     if (imcontext->imdata) {
2895         free (imcontext->imdata);
2896         imcontext->imdata = NULL;
2897         imcontext->imdata_size = 0;
2898     }
2899
2900     if (imcontext->input_panel_data) {
2901         free (imcontext->input_panel_data);
2902         imcontext->input_panel_data = NULL;
2903         imcontext->input_panel_data_length = 0;
2904     }
2905     //
2906
2907     if (imcontext->prediction_hint) {
2908         free (imcontext->prediction_hint);
2909         imcontext->prediction_hint = NULL;
2910     }
2911
2912     if (imcontext->mime_type) {
2913         free (imcontext->mime_type);
2914         imcontext->mime_type = NULL;
2915     }
2916
2917     if (imcontext->text_input)
2918         wl_text_input_destroy (imcontext->text_input);
2919
2920     clear_preedit (imcontext);
2921
2922     EINA_LIST_FREE(imcontext->keysym_list, ev) {
2923         if (ev)
2924             free(ev);
2925     }
2926
2927     free(imcontext);
2928 }
2929
2930 void
2931 wayland_im_context_reset(Ecore_IMF_Context *ctx)
2932 {
2933     WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
2934
2935     LOGD("ctx : %p", ctx);
2936
2937     if (!imcontext) return;
2938
2939     commit_preedit (imcontext);
2940
2941     if (!imcontext->input) return;
2942
2943     if (imcontext->text_input) {
2944         wl_text_input_reset(imcontext->text_input);
2945     }
2946     update_state(imcontext);
2947
2948     imcontext->reset_serial = imcontext->serial;
2949 }
2950
2951 static Eina_Bool
2952 _prediction_hint_data_foreach_cb(const Eina_Hash *hash, const void *key,
2953                                  void *data, void *fdata)
2954 {
2955     const char *key_str = key;
2956     const char *value = data;
2957     Ecore_IMF_Context *ctx = (Ecore_IMF_Context *)fdata;
2958     WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
2959
2960     SECURE_LOGD("key : %s, value : %s\n", key_str, value);
2961
2962     if (imcontext && imcontext->text_input)
2963         wl_text_input_prediction_hint_data(imcontext->text_input, key_str, value);
2964
2965     return EINA_TRUE;
2966 }
2967
2968 void
2969 wayland_im_context_focus_in(Ecore_IMF_Context *ctx)
2970 {
2971     LOGD ("ctx : %p. enable : %d, on demand : %d", ctx,
2972           ecore_imf_context_input_panel_enabled_get(ctx),
2973           ecore_imf_context_input_panel_show_on_demand_get (ctx));
2974
2975 #ifdef SOCKET_ACTIVATION
2976     activate_socket ();
2977 #endif
2978
2979     if (!set_focus(ctx)) {
2980         WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
2981         if (imcontext && !imcontext->input) {
2982             if (_focus_req_ctx != ctx)
2983                 _focus_req_only = EINA_TRUE;
2984             _focus_req_ctx = ctx;
2985             if (imcontext->canvas) {
2986                 evas_event_callback_del(imcontext->canvas, EVAS_CALLBACK_CANVAS_FOCUS_IN, _canvas_focus_in_cb);
2987                 evas_event_callback_add(imcontext->canvas, EVAS_CALLBACK_CANVAS_FOCUS_IN, _canvas_focus_in_cb, NULL);
2988             }
2989         }
2990         LOGW("ctx : %p. Fail to set focus!", ctx);
2991         return;
2992     }
2993
2994     WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
2995     if (imcontext && imcontext->input && imcontext->text_input) {
2996         wl_text_input_set_return_key_disabled(imcontext->text_input,
2997                 imcontext->return_key_disabled);
2998
2999         if (imcontext->prediction_hint)
3000             wl_text_input_prediction_hint(imcontext->text_input, imcontext->prediction_hint);
3001
3002         if (imcontext->mime_type)
3003             wl_text_input_set_mime_type(imcontext->text_input, imcontext->mime_type);
3004
3005         if (imcontext->input_panel_position.x >= 0 && imcontext->input_panel_position.y >= 0)
3006             wl_text_input_set_input_panel_position(imcontext->text_input,
3007                 imcontext->input_panel_position.x, imcontext->input_panel_position.y);
3008
3009         const Eina_Hash *hash = ecore_imf_context_prediction_hint_hash_get(ctx);
3010         if (hash)
3011             eina_hash_foreach(hash, _prediction_hint_data_foreach_cb, ctx);
3012
3013         wl_text_input_set_content_type(imcontext->text_input, imcontext->content_hint, get_purpose(ctx));
3014     }
3015
3016     if (_TV)
3017         hw_keyboard_mode = EINA_FALSE;
3018
3019     if (ecore_imf_context_input_panel_enabled_get(ctx))
3020         if (!ecore_imf_context_input_panel_show_on_demand_get (ctx))
3021             show_input_panel(ctx);
3022         else
3023             LOGD ("ctx : %p input panel on demand mode : TRUE", ctx);
3024     else
3025         LOGD ("ctx : %p input panel enable : FALSE", ctx);
3026 }
3027
3028 void
3029 wayland_im_context_focus_out(Ecore_IMF_Context *ctx)
3030 {
3031     WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
3032
3033     LOGD("ctx : %p", ctx);
3034
3035     if (_focus_req_ctx == ctx) {
3036         _focus_req_ctx = NULL;
3037         _focus_req_only = EINA_TRUE;
3038     }
3039
3040     if (!imcontext || !imcontext->input) return;
3041
3042     if (_TV) {
3043         if (hw_keyboard_mode == EINA_TRUE) {
3044             vconf_set_bool (VCONFKEY_ISF_HW_KEYBOARD_INPUT_DETECTED, 0);
3045             hw_keyboard_mode = EINA_FALSE;
3046         }
3047     }
3048
3049     if (ecore_imf_context_input_panel_enabled_get(ctx)) {
3050         ecore_imf_context_input_panel_hide(ctx);
3051     }
3052
3053     set_focus_out(ctx);
3054 }
3055
3056 void
3057 wayland_im_context_preedit_string_get(Ecore_IMF_Context  *ctx,
3058                                       char              **str,
3059                                       int                *cursor_pos)
3060 {
3061     WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
3062     if (!imcontext) return;
3063
3064     SECURE_LOGD("pre-edit string requested (preedit: '%s', preedit cursor : %d)",
3065                 imcontext->preedit_text ? imcontext->preedit_text : "", imcontext->preedit_cursor);
3066
3067     if (str)
3068         *str = strdup(imcontext->preedit_text ? imcontext->preedit_text : "");
3069
3070     if (cursor_pos)
3071         *cursor_pos = imcontext->preedit_cursor;
3072 }
3073
3074 void
3075 wayland_im_context_preedit_string_with_attributes_get(Ecore_IMF_Context  *ctx,
3076                                                       char              **str,
3077                                                       Eina_List         **attrs,
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 with attributes 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 (attrs) {
3090         Eina_List *l;
3091         Ecore_IMF_Preedit_Attr *a, *attr;
3092
3093         if (imcontext->preedit_attrs) {
3094             EINA_LIST_FOREACH(imcontext->preedit_attrs, l, a) {
3095                 attr = malloc(sizeof(*attr));
3096                 if (attr) {
3097                     attr = memcpy(attr, a, sizeof(*attr));
3098                     *attrs = eina_list_append(*attrs, attr);
3099                 }
3100             }
3101         }
3102         else {
3103             if (imcontext->preedit_text) {
3104                 Ecore_IMF_Preedit_Attr *attr = calloc(1, sizeof(*attr));
3105                 if (attr) {
3106                     // use REVERSE style as default
3107                     attr->preedit_type = ECORE_IMF_PREEDIT_TYPE_SUB2;
3108                     attr->start_index = 0;
3109                     attr->end_index = strlen(imcontext->preedit_text);
3110                     *attrs = eina_list_append(*attrs, attr);
3111                 }
3112             }
3113         }
3114     }
3115
3116     if (cursor_pos)
3117         *cursor_pos = imcontext->preedit_cursor;
3118 }
3119
3120 void
3121 wayland_im_context_cursor_position_set (Ecore_IMF_Context *ctx,
3122                                        int                cursor_pos)
3123 {
3124     WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
3125     if (!imcontext) return;
3126
3127     if (imcontext->cursor_position != cursor_pos) {
3128         imcontext->cursor_position = cursor_pos;
3129
3130         if (imcontext->input && imcontext->text_input) {
3131             LOGD ("ctx : %p, cursor pos : %d", ctx, cursor_pos);
3132
3133             set_autocapital (ctx);
3134
3135             if (!imcontext->preedit_text || strlen(imcontext->preedit_text) == 0)
3136                 wl_text_input_set_cursor_position (imcontext->text_input, cursor_pos);
3137         }
3138     }
3139 }
3140
3141 void
3142 wayland_im_context_use_preedit_set(Ecore_IMF_Context *ctx EINA_UNUSED,
3143                                    Eina_Bool          use_preedit EINA_UNUSED)
3144 {
3145 }
3146
3147 void
3148 wayland_im_context_client_window_set(Ecore_IMF_Context *ctx,
3149                                      void              *window)
3150 {
3151     WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
3152
3153     LOGD("client window set (window: %p)", window);
3154
3155     if (imcontext && window) {
3156         Ecore_Wl2_Display *wl2_display = ecore_wl2_connected_display_get(NULL);
3157
3158         if (wl2_display)
3159             imcontext->window = ecore_wl2_display_window_find(wl2_display, (Ecore_Window)window);
3160
3161         if (_ime_device && imcontext->window)
3162             _device_info_send (ecore_wl2_window_id_get (imcontext->window), EINA_TRUE);
3163     }
3164 }
3165
3166 void
3167 wayland_im_context_client_canvas_set(Ecore_IMF_Context *ctx,
3168                                      void              *canvas)
3169 {
3170     WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
3171
3172     LOGD("client canvas set (canvas: %p)", canvas);
3173
3174     if (imcontext && canvas) {
3175         Ecore_Wl2_Display *wl2_display = ecore_wl2_connected_display_get(NULL);
3176         imcontext->canvas = canvas;
3177
3178         if (wl2_display && !imcontext->window)
3179             imcontext->window = ecore_wl2_display_window_find(wl2_display, ecore_evas_window_get(ecore_evas_ecore_evas_get(canvas)));
3180
3181         if (_ime_device && imcontext->window)
3182             _device_info_send (ecore_wl2_window_id_get (imcontext->window), EINA_TRUE);
3183     }
3184 }
3185
3186 void
3187 wayland_im_context_show(Ecore_IMF_Context *ctx)
3188 {
3189     LOGD("ctx : %p", ctx);
3190
3191     show_input_panel(ctx);
3192 }
3193
3194 void
3195 wayland_im_context_hide(Ecore_IMF_Context *ctx)
3196 {
3197     LOGD("ctx : %p", ctx);
3198
3199     if (!get_using_ctx()) {
3200         LOGW("Can't hide input_panel because there is no using context!!");
3201         return;
3202     }
3203
3204     _input_panel_hide(ctx, EINA_FALSE);
3205 }
3206
3207 #if !(ENABLE_GRAB_KEYBOARD)
3208 static unsigned int
3209 _ecore_imf_lock_to_ecore_key_modifier(unsigned int locks)
3210 {
3211    unsigned int mask = 0;
3212
3213     if (locks & ECORE_IMF_KEYBOARD_LOCK_SCROLL)
3214         mask |= ECORE_EVENT_LOCK_SCROLL;
3215
3216     if (locks & ECORE_IMF_KEYBOARD_LOCK_CAPS)
3217         mask |= ECORE_EVENT_LOCK_CAPS;
3218
3219     if (locks & ECORE_IMF_KEYBOARD_LOCK_NUM)
3220         mask |= ECORE_EVENT_LOCK_NUM;
3221
3222    return mask;
3223 }
3224
3225 static unsigned int
3226 _ecore_imf_modifier_to_ecore_key_modifier(Ecore_IMF_Keyboard_Modifiers modifiers)
3227 {
3228    unsigned int mask = 0;
3229
3230    /**< "Control" is pressed */
3231    if (modifiers & ECORE_IMF_KEYBOARD_MODIFIER_CTRL)
3232      mask |= ECORE_EVENT_MODIFIER_CTRL;
3233
3234    /**< "Alt" is pressed */
3235    if (modifiers & ECORE_IMF_KEYBOARD_MODIFIER_ALT)
3236      mask |= ECORE_EVENT_MODIFIER_ALT;
3237
3238    /**< "Shift" is pressed */
3239    if (modifiers & ECORE_IMF_KEYBOARD_MODIFIER_SHIFT)
3240      mask |= ECORE_EVENT_MODIFIER_SHIFT;
3241
3242    /**< "Win" (between "Ctrl" and "Alt") is pressed */
3243    if (modifiers & ECORE_IMF_KEYBOARD_MODIFIER_WIN)
3244      mask |= ECORE_EVENT_MODIFIER_WIN;
3245
3246    /**< "AltGr" is pressed */
3247    if (modifiers & ECORE_IMF_KEYBOARD_MODIFIER_ALTGR)
3248      mask |= ECORE_EVENT_MODIFIER_ALTGR;
3249
3250    return mask;
3251 }
3252 #endif
3253
3254 Eina_Bool
3255 wayland_im_context_filter_event(Ecore_IMF_Context    *ctx,
3256                                 Ecore_IMF_Event_Type  type,
3257                                 Ecore_IMF_Event      *imf_event)
3258 {
3259
3260 #if !(ENABLE_GRAB_KEYBOARD)
3261     Eina_Bool ret = EINA_FALSE;
3262     Ecore_Event_Key ecore_key_ev;
3263     char *key_dev_name = NULL;
3264     uint32_t key_dev_class = 0;
3265     uint32_t key_dev_subclass = 0;
3266 #endif
3267     if (type == ECORE_IMF_EVENT_MOUSE_UP) {
3268         if (ecore_imf_context_input_panel_enabled_get(ctx)) {
3269             LOGD ("[Mouse-up event] ctx : %p", ctx);
3270             if (ctx == _focused_ctx) {
3271                 ecore_imf_context_input_panel_show(ctx);
3272             }
3273             else
3274                 LOGE ("Can't show IME because there is no focus. ctx : %p", ctx);
3275         }
3276     }
3277 #if !(ENABLE_GRAB_KEYBOARD)
3278     else if (type == ECORE_IMF_EVENT_KEY_UP) {
3279         Ecore_IMF_Event_Key_Up *key_ev = (Ecore_IMF_Event_Key_Up *)imf_event;
3280         ecore_key_ev.keyname = key_ev->keyname;
3281         ecore_key_ev.key = key_ev->key;
3282         ecore_key_ev.string = key_ev->string;
3283         ecore_key_ev.compose = key_ev->compose;
3284         ecore_key_ev.timestamp = key_ev->timestamp;
3285         ecore_key_ev.modifiers = _ecore_imf_modifier_to_ecore_key_modifier(key_ev->modifiers);
3286         ecore_key_ev.modifiers |= _ecore_imf_lock_to_ecore_key_modifier(key_ev->locks);
3287         key_dev_name = (char *)key_ev->dev_name;
3288         key_dev_class = key_ev->dev_class;
3289         key_dev_subclass = key_ev->dev_subclass;
3290         ecore_key_ev.keycode = key_ev->keycode;
3291     }
3292     else if (type == ECORE_IMF_EVENT_KEY_DOWN) {
3293         Ecore_IMF_Event_Key_Down *key_ev = (Ecore_IMF_Event_Key_Down *)imf_event;
3294         ecore_key_ev.keyname = key_ev->keyname;
3295         ecore_key_ev.key = key_ev->key;
3296         ecore_key_ev.string = key_ev->string;
3297         ecore_key_ev.compose = key_ev->compose;
3298         ecore_key_ev.timestamp = key_ev->timestamp;
3299         ecore_key_ev.modifiers = _ecore_imf_modifier_to_ecore_key_modifier(key_ev->modifiers);
3300         ecore_key_ev.modifiers |= _ecore_imf_lock_to_ecore_key_modifier(key_ev->locks);
3301         key_dev_name = (char *)key_ev->dev_name;
3302         key_dev_class = key_ev->dev_class;
3303         key_dev_subclass = key_ev->dev_subclass;
3304         ecore_key_ev.keycode = key_ev->keycode;
3305     }
3306
3307     if (type == ECORE_IMF_EVENT_KEY_UP || type == ECORE_IMF_EVENT_KEY_DOWN) {
3308         WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
3309         if (!imcontext || !imcontext->input || !imcontext->text_input)
3310             return EINA_FALSE;
3311
3312         if (!_focused_ctx) {
3313             LOGW ("no focus");
3314             return EINA_FALSE;
3315         }
3316
3317         if (_focused_ctx != ctx) {
3318             LOGW ("focused context is different from the context used in ecore_imf_context_filter_event.");
3319             LOGW ("focus context : %p, context : %p", _focused_ctx, ctx);
3320             return EINA_FALSE;
3321         }
3322
3323         do {
3324             if (!ecore_key_ev.timestamp && (ecore_key_ev.modifiers & MOD_Mod5_MASK)
3325                 && key_dev_subclass == ECORE_DEVICE_SUBCLASS_VIRTUAL_KEYBOARD) {
3326                 if (type == ECORE_IMF_EVENT_KEY_DOWN) {
3327                     if (strcmp (ecore_key_ev.key, "space") == 0 ||
3328                         strcmp (ecore_key_ev.key, "KP_Space") == 0 ) {
3329                         autoperiod_insert (ctx);
3330                     }
3331                 }
3332
3333                 LOGD("Return! This is SW keyboard fake event!");
3334                 break;
3335             }
3336
3337             int serial = imcontext->serial++;
3338             double start_time = ecore_time_get();
3339
3340             /* xkb_mod_mask */
3341             uint32_t modifiers = 0;
3342             if (ecore_key_ev.modifiers & ECORE_EVENT_MODIFIER_SHIFT)
3343                 modifiers |= imcontext->shift_mask;
3344             if (ecore_key_ev.modifiers & ECORE_EVENT_MODIFIER_CTRL)
3345                 modifiers |= imcontext->control_mask;
3346             if (ecore_key_ev.modifiers & ECORE_EVENT_MODIFIER_ALT)
3347                 modifiers |= imcontext->alt_mask;
3348             if (ecore_key_ev.modifiers & ECORE_EVENT_LOCK_CAPS)
3349                 modifiers |= imcontext->caps_mask;
3350             if (ecore_key_ev.modifiers & ECORE_EVENT_LOCK_NUM)
3351                 modifiers |= imcontext->num_mask;
3352
3353             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);
3354             //Send key event to IME.
3355             wl_text_input_filter_key_event(imcontext->text_input, serial, ecore_key_ev.timestamp, ecore_key_ev.key,
3356                                            type == ECORE_IMF_EVENT_KEY_UP? WL_KEYBOARD_KEY_STATE_RELEASED : WL_KEYBOARD_KEY_STATE_PRESSED,
3357                                            modifiers, (key_dev_name ? key_dev_name : ""), key_dev_class, key_dev_subclass, ecore_key_ev.keycode);
3358             //Waiting for filter_key_event_done from IME.
3359             //This function should return IME filtering result with boolean type.
3360             Ecore_Wl2_Display *wl2_display = ecore_wl2_connected_display_get(NULL);
3361             struct wl_display *display = NULL;
3362             if (wl2_display)
3363                 display = ecore_wl2_display_get(wl2_display);
3364
3365             if (display) {
3366                 struct wl_event_queue *queue = wl_display_create_queue(display);
3367
3368                 if (queue) {
3369                     while (ecore_time_get() - start_time < WAIT_FOR_FILTER_DONE_SECOND && _focused_ctx == ctx && wl_display_roundtrip_queue(display, queue) != -1) {
3370                         wl_display_dispatch_pending(display);
3371                         if (imcontext->last_key_event_filter.serial == serial) {
3372                             ret = imcontext->last_key_event_filter.state;
3373                             break;
3374                         } else if (imcontext->last_key_event_filter.serial > serial)
3375                             break;
3376                     }
3377
3378                     if (imcontext->last_key_event_filter.serial < serial) {
3379                         LOGW("Timeout occured");
3380                         ret = EINA_TRUE;
3381                     }
3382
3383                     wl_event_queue_destroy(queue);
3384                 }
3385
3386                 LOGD ("elapsed : %.3f ms, serial (last, require) : (%d, %d)", (ecore_time_get() - start_time)*1000, imcontext->last_key_event_filter.serial, serial);
3387             }
3388         } while (0);
3389
3390         if (type == ECORE_IMF_EVENT_KEY_DOWN) {
3391             if (ret == EINA_FALSE) {
3392                 if (_TV) {
3393                     if (strcmp (ecore_key_ev.keyname, "Return") == 0 && key_dev_subclass == ECORE_DEVICE_SUBCLASS_REMOCON) {
3394                         int val;
3395                         if (vconf_get_bool (VCONFKEY_ISF_HW_KEYBOARD_INPUT_DETECTED, &val) == 0) {
3396                             if (val) {
3397                                 LOGD ("Changed keyboard mode from H/W to S/W ");
3398                                 hw_keyboard_mode = EINA_FALSE;
3399                                 vconf_set_bool (VCONFKEY_ISF_HW_KEYBOARD_INPUT_DETECTED, 0);
3400                                 if (ecore_imf_context_input_panel_enabled_get (ctx)) {
3401                                     ecore_imf_context_input_panel_show (ctx);
3402                                 }
3403                                 return EINA_TRUE;
3404                             }
3405                         }
3406                     }
3407                 }
3408                 if (strcmp (ecore_key_ev.key, "space") == 0 ||
3409                     strcmp (ecore_key_ev.key, "KP_Space") == 0) {
3410                     autoperiod_insert (ctx);
3411                 }
3412             }
3413         }
3414
3415         //Deal with the next key event in list.
3416         Ecore_Event_Key *ev = NULL;
3417         if (eina_list_count (imcontext->keysym_list)) {
3418             Eina_List *n = eina_list_last(imcontext->keysym_list);
3419             ev = (Ecore_Event_Key *)eina_list_data_get(n);
3420             int event_type = (unsigned long int)ev->data;
3421
3422             ev->data = NULL;
3423             ecore_event_add(event_type, ev, _ecore_keyevent_free, NULL);
3424             imcontext->keysym_list = eina_list_remove_list(imcontext->keysym_list, n);
3425         }
3426     }
3427
3428     return ret;
3429 #else
3430     return EINA_FALSE;
3431 #endif
3432 }
3433
3434 void
3435 wayland_im_context_cursor_location_set(Ecore_IMF_Context *ctx, int x, int y, int width, int height)
3436 {
3437     WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
3438     if (!imcontext) return;
3439
3440     if ((imcontext->cursor_location.x != x) ||
3441         (imcontext->cursor_location.y != y) ||
3442         (imcontext->cursor_location.width != width) ||
3443         (imcontext->cursor_location.height != height)) {
3444         imcontext->cursor_location.x = x;
3445         imcontext->cursor_location.y = y;
3446         imcontext->cursor_location.width = width;
3447         imcontext->cursor_location.height = height;
3448
3449         if (_focused_ctx == ctx)
3450             send_cursor_location (imcontext);
3451     }
3452 }
3453
3454 void wayland_im_context_autocapital_type_set(Ecore_IMF_Context *ctx,
3455                                                   Ecore_IMF_Autocapital_Type autocapital_type)
3456 {
3457     WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
3458     if (!imcontext) return;
3459
3460     imcontext->content_hint &= ~(WL_TEXT_INPUT_CONTENT_HINT_AUTO_CAPITALIZATION |
3461                                  // TIZEN_ONLY(20160201): Add autocapitalization word
3462                                  WL_TEXT_INPUT_CONTENT_HINT_WORD_CAPITALIZATION |
3463                                  //
3464                                  WL_TEXT_INPUT_CONTENT_HINT_UPPERCASE |
3465                                  WL_TEXT_INPUT_CONTENT_HINT_LOWERCASE);
3466
3467     if (autocapital_type == ECORE_IMF_AUTOCAPITAL_TYPE_SENTENCE)
3468         imcontext->content_hint |= WL_TEXT_INPUT_CONTENT_HINT_AUTO_CAPITALIZATION;
3469     // TIZEN_ONLY(20160201): Add autocapitalization word
3470     else if (autocapital_type == ECORE_IMF_AUTOCAPITAL_TYPE_WORD)
3471         imcontext->content_hint |= WL_TEXT_INPUT_CONTENT_HINT_WORD_CAPITALIZATION;
3472     //
3473     else if (autocapital_type == ECORE_IMF_AUTOCAPITAL_TYPE_ALLCHARACTER)
3474         imcontext->content_hint |= WL_TEXT_INPUT_CONTENT_HINT_UPPERCASE;
3475     else
3476         imcontext->content_hint |= WL_TEXT_INPUT_CONTENT_HINT_LOWERCASE;
3477
3478     if (imcontext->input && imcontext->text_input) {
3479         LOGD ("ctx : %p. set autocapital type : %d", ctx, autocapital_type);
3480         wl_text_input_set_content_type(imcontext->text_input,
3481                 imcontext->content_hint,
3482                 get_purpose(ctx));
3483     }
3484 }
3485
3486 void
3487 wayland_im_context_input_panel_layout_set(Ecore_IMF_Context *ctx,
3488                                           Ecore_IMF_Input_Panel_Layout layout)
3489 {
3490     WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
3491     if (!imcontext) return;
3492
3493     imcontext->input_panel_layout = layout;
3494
3495     switch (layout) {
3496         case ECORE_IMF_INPUT_PANEL_LAYOUT_NUMBER:
3497             imcontext->content_purpose = WL_TEXT_INPUT_CONTENT_PURPOSE_NUMBER;
3498             break;
3499         case ECORE_IMF_INPUT_PANEL_LAYOUT_EMAIL:
3500             imcontext->content_purpose = WL_TEXT_INPUT_CONTENT_PURPOSE_EMAIL;
3501             break;
3502         case ECORE_IMF_INPUT_PANEL_LAYOUT_URL:
3503             imcontext->content_purpose = WL_TEXT_INPUT_CONTENT_PURPOSE_URL;
3504             break;
3505         case ECORE_IMF_INPUT_PANEL_LAYOUT_PHONENUMBER:
3506             imcontext->content_purpose = WL_TEXT_INPUT_CONTENT_PURPOSE_PHONE;
3507             break;
3508         case ECORE_IMF_INPUT_PANEL_LAYOUT_IP:
3509             // TIZEN_ONLY(20150710): Support IP and emoticon layout
3510             imcontext->content_purpose = WL_TEXT_INPUT_CONTENT_PURPOSE_IP;
3511             //
3512             break;
3513         case ECORE_IMF_INPUT_PANEL_LAYOUT_MONTH:
3514             imcontext->content_purpose = WL_TEXT_INPUT_CONTENT_PURPOSE_DATE;
3515             break;
3516         case ECORE_IMF_INPUT_PANEL_LAYOUT_NUMBERONLY:
3517             imcontext->content_purpose = WL_TEXT_INPUT_CONTENT_PURPOSE_DIGITS;
3518             break;
3519         case ECORE_IMF_INPUT_PANEL_LAYOUT_HEX:
3520             imcontext->content_purpose = WL_TEXT_INPUT_CONTENT_PURPOSE_HEX;
3521             break;
3522         case ECORE_IMF_INPUT_PANEL_LAYOUT_TERMINAL:
3523             imcontext->content_purpose = WL_TEXT_INPUT_CONTENT_PURPOSE_TERMINAL;
3524             break;
3525         case ECORE_IMF_INPUT_PANEL_LAYOUT_PASSWORD:
3526             imcontext->content_purpose = WL_TEXT_INPUT_CONTENT_PURPOSE_PASSWORD;
3527             imcontext->content_hint |= (WL_TEXT_INPUT_CONTENT_HINT_SENSITIVE_DATA | WL_TEXT_INPUT_CONTENT_HINT_PASSWORD);
3528             break;
3529         case ECORE_IMF_INPUT_PANEL_LAYOUT_DATETIME:
3530             imcontext->content_purpose = WL_TEXT_INPUT_CONTENT_PURPOSE_DATETIME;
3531             break;
3532             // TIZEN_ONLY(20150710): Support IP and emoticon layout
3533         case ECORE_IMF_INPUT_PANEL_LAYOUT_EMOTICON:
3534             imcontext->content_purpose = WL_TEXT_INPUT_CONTENT_PURPOSE_EMOTICON;
3535             break;
3536             //
3537         case ECORE_IMF_INPUT_PANEL_LAYOUT_VOICE:
3538             imcontext->content_purpose = WL_TEXT_INPUT_CONTENT_PURPOSE_VOICE;
3539             break;
3540         default:
3541             imcontext->content_purpose = WL_TEXT_INPUT_CONTENT_PURPOSE_NORMAL;
3542             break;
3543     }
3544
3545     if (imcontext->input && imcontext->text_input) {
3546         LOGD ("ctx : %p, layout type : %d", ctx, layout);
3547         wl_text_input_set_content_type(imcontext->text_input,
3548                 imcontext->content_hint,
3549                 get_purpose(ctx));
3550     }
3551 }
3552
3553 Ecore_IMF_Input_Panel_Layout
3554 wayland_im_context_input_panel_layout_get(Ecore_IMF_Context *ctx)
3555 {
3556     WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
3557     if (!imcontext) return ECORE_IMF_INPUT_PANEL_LAYOUT_NORMAL;
3558
3559     return imcontext->input_panel_layout;
3560 }
3561
3562 void
3563 wayland_im_context_input_mode_set(Ecore_IMF_Context *ctx,
3564                                   Ecore_IMF_Input_Mode input_mode)
3565 {
3566     WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
3567     if (!imcontext) return;
3568
3569     if (input_mode & ECORE_IMF_INPUT_MODE_INVISIBLE)
3570         imcontext->content_hint |= (WL_TEXT_INPUT_CONTENT_HINT_SENSITIVE_DATA | WL_TEXT_INPUT_CONTENT_HINT_PASSWORD);
3571     else
3572         imcontext->content_hint &= ~(WL_TEXT_INPUT_CONTENT_HINT_SENSITIVE_DATA | WL_TEXT_INPUT_CONTENT_HINT_PASSWORD);
3573
3574     if (imcontext->input && imcontext->text_input) {
3575         LOGD ("ctx : %p, input mode : %d", ctx, input_mode);
3576         wl_text_input_set_content_type(imcontext->text_input,
3577                 imcontext->content_hint,
3578                 get_purpose(ctx));
3579     }
3580 }
3581
3582 void
3583 wayland_im_context_input_hint_set(Ecore_IMF_Context *ctx,
3584                                   Ecore_IMF_Input_Hints input_hints)
3585 {
3586     WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
3587     if (!imcontext) return;
3588
3589     if (input_hints & ECORE_IMF_INPUT_HINT_AUTO_COMPLETE)
3590         imcontext->content_hint |= WL_TEXT_INPUT_CONTENT_HINT_AUTO_COMPLETION;
3591     else
3592         imcontext->content_hint &= ~WL_TEXT_INPUT_CONTENT_HINT_AUTO_COMPLETION;
3593
3594     if (input_hints & ECORE_IMF_INPUT_HINT_SENSITIVE_DATA)
3595         imcontext->content_hint |= WL_TEXT_INPUT_CONTENT_HINT_SENSITIVE_DATA;
3596     else
3597         imcontext->content_hint &= ~WL_TEXT_INPUT_CONTENT_HINT_SENSITIVE_DATA;
3598
3599     if (input_hints & ECORE_IMF_INPUT_HINT_MULTILINE)
3600         imcontext->content_hint |= WL_TEXT_INPUT_CONTENT_HINT_MULTILINE;
3601     else
3602         imcontext->content_hint &= ~WL_TEXT_INPUT_CONTENT_HINT_MULTILINE;
3603
3604     // autofill
3605     LOGD("autofill hint : %x\n", input_hints & ECORE_IMF_INPUT_HINT_AUTOFILL_MASK);
3606
3607     switch(input_hints & ECORE_IMF_INPUT_HINT_AUTOFILL_MASK)
3608     {
3609     case ECORE_IMF_INPUT_HINT_AUTOFILL_CREDIT_CARD_EXPIRATION_DATE:
3610         imcontext->content_hint |= WL_TEXT_INPUT_CONTENT_HINT_AUTOFILL_CREDIT_CARD_EXPIRATION_DATE;
3611         break;
3612     case ECORE_IMF_INPUT_HINT_AUTOFILL_CREDIT_CARD_EXPIRATION_DAY:
3613         imcontext->content_hint |= WL_TEXT_INPUT_CONTENT_HINT_AUTOFILL_CREDIT_CARD_EXPIRATION_DAY;
3614         break;
3615     case ECORE_IMF_INPUT_HINT_AUTOFILL_CREDIT_CARD_EXPIRATION_MONTH:
3616         imcontext->content_hint |= WL_TEXT_INPUT_CONTENT_HINT_AUTOFILL_CREDIT_CARD_EXPIRATION_MONTH;
3617         break;
3618     case ECORE_IMF_INPUT_HINT_AUTOFILL_CREDIT_CARD_EXPIRATION_YEAR:
3619         imcontext->content_hint |= WL_TEXT_INPUT_CONTENT_HINT_AUTOFILL_CREDIT_CARD_EXPIRATION_YEAR;
3620         break;
3621     case ECORE_IMF_INPUT_HINT_AUTOFILL_CREDIT_CARD_NUMBER:
3622         imcontext->content_hint |= WL_TEXT_INPUT_CONTENT_HINT_AUTOFILL_CREDIT_CARD_NUMBER;
3623         break;
3624     case ECORE_IMF_INPUT_HINT_AUTOFILL_EMAIL_ADDRESS:
3625         imcontext->content_hint |= WL_TEXT_INPUT_CONTENT_HINT_AUTOFILL_EMAIL_ADDRESS;
3626         break;
3627     case ECORE_IMF_INPUT_HINT_AUTOFILL_PHONE:
3628         imcontext->content_hint |= WL_TEXT_INPUT_CONTENT_HINT_AUTOFILL_PHONE;
3629         break;
3630     case ECORE_IMF_INPUT_HINT_AUTOFILL_POSTAL_ADDRESS:
3631         imcontext->content_hint |= WL_TEXT_INPUT_CONTENT_HINT_AUTOFILL_POSTAL_ADDRESS;
3632         break;
3633     case ECORE_IMF_INPUT_HINT_AUTOFILL_POSTAL_CODE:
3634         imcontext->content_hint |= WL_TEXT_INPUT_CONTENT_HINT_AUTOFILL_POSTAL_CODE;
3635         break;
3636     case ECORE_IMF_INPUT_HINT_AUTOFILL_ID:
3637         imcontext->content_hint |= WL_TEXT_INPUT_CONTENT_HINT_AUTOFILL_ID;
3638         break;
3639     case ECORE_IMF_INPUT_HINT_AUTOFILL_NAME:
3640         imcontext->content_hint |= WL_TEXT_INPUT_CONTENT_HINT_AUTOFILL_NAME;
3641         break;
3642     }
3643
3644     if (imcontext->input && imcontext->text_input) {
3645         LOGD("ctx : %p, input hint : %#x", ctx, input_hints);
3646         wl_text_input_set_content_type(imcontext->text_input,
3647                 imcontext->content_hint,
3648                 get_purpose(ctx));
3649     }
3650 }
3651
3652 void
3653 wayland_im_context_input_panel_language_set(Ecore_IMF_Context *ctx,
3654                                             Ecore_IMF_Input_Panel_Lang lang)
3655 {
3656     WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
3657     if (!imcontext) return;
3658
3659     if (lang == ECORE_IMF_INPUT_PANEL_LANG_ALPHABET)
3660         imcontext->content_hint |= WL_TEXT_INPUT_CONTENT_HINT_LATIN;
3661     else
3662         imcontext->content_hint &= ~WL_TEXT_INPUT_CONTENT_HINT_LATIN;
3663
3664     if (imcontext->input && imcontext->text_input)
3665         wl_text_input_set_content_type(imcontext->text_input,
3666                 imcontext->content_hint,
3667                 get_purpose(ctx));
3668 }
3669
3670 // TIZEN_ONLY(20150708): Support input_panel_state_get
3671 Ecore_IMF_Input_Panel_State
3672 wayland_im_context_input_panel_state_get(Ecore_IMF_Context *ctx EINA_UNUSED)
3673 {
3674     return _input_panel_state;
3675 }
3676
3677 void
3678 wayland_im_context_input_panel_return_key_type_set(Ecore_IMF_Context *ctx,
3679                                                    Ecore_IMF_Input_Panel_Return_Key_Type return_key_type)
3680 {
3681     WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
3682     if (!imcontext) return;
3683
3684     imcontext->return_key_type = return_key_type;
3685
3686     if (imcontext->input && imcontext->text_input)
3687         wl_text_input_set_return_key_type(imcontext->text_input,
3688                 imcontext->return_key_type);
3689 }
3690
3691 void
3692 wayland_im_context_input_panel_return_key_disabled_set(Ecore_IMF_Context *ctx,
3693                                                        Eina_Bool disabled)
3694 {
3695     WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
3696     if (!imcontext) return;
3697
3698     imcontext->return_key_disabled = disabled;
3699
3700     if (imcontext->input && imcontext->text_input)
3701         wl_text_input_set_return_key_disabled(imcontext->text_input,
3702                 imcontext->return_key_disabled);
3703 }
3704 //
3705
3706 void
3707 wayland_im_context_input_panel_language_locale_get(Ecore_IMF_Context *ctx,
3708                                                    char **locale)
3709 {
3710     WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
3711     if (!imcontext) return;
3712
3713     if (locale)
3714         *locale = strdup(imcontext->language ? imcontext->language : "");
3715 }
3716
3717 void
3718 wayland_im_context_prediction_allow_set(Ecore_IMF_Context *ctx,
3719                                         Eina_Bool prediction)
3720 {
3721     WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
3722     if (!imcontext) return;
3723
3724     if (prediction)
3725         imcontext->content_hint |= WL_TEXT_INPUT_CONTENT_HINT_AUTO_COMPLETION;
3726     else
3727         imcontext->content_hint &= ~WL_TEXT_INPUT_CONTENT_HINT_AUTO_COMPLETION;
3728
3729     if (imcontext->input && imcontext->text_input)
3730         wl_text_input_set_content_type(imcontext->text_input,
3731                 imcontext->content_hint,
3732                 get_purpose(ctx));
3733 }
3734
3735 // TIZEN_ONLY(20151221): Support input panel geometry
3736 void
3737 wayland_im_context_input_panel_geometry_get(Ecore_IMF_Context *ctx EINA_UNUSED,
3738                                             int *x, int *y, int *w, int *h)
3739 {
3740     if (x)
3741         *x = _keyboard_geometry.x;
3742     if (y)
3743         *y = _keyboard_geometry.y;
3744     if (w)
3745         *w = _keyboard_geometry.w;
3746     if (h)
3747         *h = _keyboard_geometry.h;
3748 }
3749
3750 void
3751 wayland_im_context_input_panel_imdata_set(Ecore_IMF_Context *ctx, const void *data, int length)
3752 {
3753     WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
3754     if (!imcontext) return;
3755
3756     if (data && length > 0) {
3757         const char *custom_conformant_enabled = "conformant:custom,enabled";
3758         const char *custom_conformant_disabled = "conformant:custom,disabled";
3759         const char *custom_conformant_finished = "conformant:custom,finished";
3760
3761         if (strncmp(data, custom_conformant_enabled, strlen(custom_conformant_enabled)) == 0) {
3762             _custom_conformant_event = EINA_TRUE;
3763             return;
3764         }
3765         if (strncmp(data, custom_conformant_disabled, strlen(custom_conformant_disabled)) == 0) {
3766             _custom_conformant_event = EINA_FALSE;
3767             return;
3768         }
3769         if (strncmp(data, custom_conformant_finished, strlen(custom_conformant_finished)) == 0) {
3770             if (_custom_conformant_event) {
3771                 _conformant_reset_done = EINA_TRUE;
3772                 LOGD("[conformant:custom,finished], _conformant_reset_done = 1");
3773                 send_will_hide_ack(NULL);
3774             }
3775             return;
3776         }
3777     }
3778
3779     if (imcontext->imdata)
3780         free(imcontext->imdata);
3781
3782     imcontext->imdata = calloc(1, length);
3783     if (imcontext->imdata && data)
3784         memcpy(imcontext->imdata, data, length);
3785
3786     imcontext->imdata_size = length;
3787
3788     if (imcontext->input && imcontext->text_input && (imcontext->imdata_size > 0))
3789         wl_text_input_set_input_panel_data(imcontext->text_input, (const char *)imcontext->imdata, imcontext->imdata_size);
3790 }
3791
3792 void
3793 wayland_im_context_input_panel_imdata_get(Ecore_IMF_Context *ctx, void *data, int *length)
3794 {
3795     if (!ctx) return;
3796     WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
3797
3798     if (imcontext && imcontext->input_panel_data && (imcontext->input_panel_data_length > 0)) {
3799         if (data)
3800             memcpy(data, imcontext->input_panel_data, imcontext->input_panel_data_length);
3801
3802         if (length)
3803             *length = imcontext->input_panel_data_length;
3804     }
3805     else
3806         if (length)
3807             *length = 0;
3808 }
3809 //
3810
3811 // TIZEN_ONLY(20160218): Support BiDi direction
3812 void
3813 wayland_im_context_bidi_direction_set(Ecore_IMF_Context *ctx, Ecore_IMF_BiDi_Direction bidi_direction)
3814 {
3815     WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
3816     if (!imcontext) return;
3817
3818     imcontext->bidi_direction = bidi_direction;
3819
3820     if (imcontext->input && imcontext->text_input) {
3821         LOGD ("ctx : %p, bidi direction : %#x", ctx, bidi_direction);
3822         wl_text_input_bidi_direction(imcontext->text_input, imcontext->bidi_direction);
3823     }
3824 }
3825 //
3826
3827 Ecore_IMF_Input_Panel_Keyboard_Mode
3828 wayland_im_context_input_panel_keyboard_mode_get(Ecore_IMF_Context *ctx EINA_UNUSED)
3829 {
3830     return hw_keyboard_mode ? ECORE_IMF_INPUT_PANEL_HW_KEYBOARD_MODE : ECORE_IMF_INPUT_PANEL_SW_KEYBOARD_MODE;
3831 }
3832
3833 void
3834 wayland_im_context_prediction_hint_set (Ecore_IMF_Context *ctx, const char *prediction_hint)
3835 {
3836     WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
3837     if (!imcontext) return;
3838
3839     imcontext->prediction_hint = strdup(prediction_hint ? prediction_hint : "");
3840
3841     if (imcontext->input && imcontext->text_input) {
3842         SECURE_LOGD ("ctx : %p, prediction_hint : %s", ctx, imcontext->prediction_hint);
3843         wl_text_input_prediction_hint(imcontext->text_input, imcontext->prediction_hint);
3844     }
3845 }
3846
3847 void
3848 wayland_im_context_mime_type_accept_set (Ecore_IMF_Context *ctx, const char *mime_type)
3849 {
3850     WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
3851     if (!imcontext) return;
3852
3853     imcontext->mime_type = strdup(mime_type);
3854
3855     if (imcontext->input && imcontext->text_input && (strlen(mime_type) > 0)) {
3856         LOGD ("ctx : %p, mime_type : %s", ctx, imcontext->mime_type);
3857         wl_text_input_set_mime_type(imcontext->text_input, imcontext->mime_type);
3858     }
3859 }
3860
3861 void
3862 wayland_im_context_input_panel_position_set (Ecore_IMF_Context *ctx, int x, int y)
3863 {
3864     WaylandIMContext *imcontext = (WaylandIMContext *)ecore_imf_context_data_get(ctx);
3865     if (!imcontext) return;
3866
3867     if ((imcontext->input_panel_position.x != x) || (imcontext->input_panel_position.y != y)) {
3868         imcontext->input_panel_position.x = x;
3869         imcontext->input_panel_position.y = y;
3870     }
3871
3872     if (imcontext->input && imcontext->text_input) {
3873         LOGD ("ctx : %p, x = %d, y = %d", ctx, x, y);
3874         wl_text_input_set_input_panel_position(imcontext->text_input,
3875             imcontext->input_panel_position.x, imcontext->input_panel_position.y);
3876     }
3877 }
3878
3879 WaylandIMContext *wayland_im_context_new (struct wl_text_input_manager *text_input_manager)
3880 {
3881     WaylandIMContext *context = calloc(1, sizeof(WaylandIMContext));
3882     if (context) {
3883         LOGD("new context created");
3884         context->text_input_manager = text_input_manager;
3885     }
3886
3887     return context;
3888 }
3889
3890 void wayland_im_context_pair_set (Ecore_IMF_Context *ctx, WaylandIMContext *imcontext)
3891 {
3892     _ecore_imf_wayland_imcontext_pair_add (ctx, imcontext);
3893 }