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