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