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