Fix CM key is not changed as translation button
[platform/core/uifw/ise-default.git] / src / ise.cpp
1 /*
2  * Copyright (c) 2012 - 2015 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 #include <stdlib.h>
19 #include <sys/types.h>
20 #include <unistd.h>
21 #include <sys/stat.h>
22 #include <fcntl.h>
23 #include <vconf.h>
24 #include <Ecore.h>
25 #include <Ecore_IMF.h>
26 #include <Elementary.h>
27 #include <sclui.h>
28 #include <sclutils.h>
29 #include <inputmethod.h>
30 #include <inputmethod_internal.h>
31 #include <app_control.h>
32 #include <app_preference.h>
33 #include <ode/internal-encryption.h>
34 #include "clipboard.h"
35 #include "autofill.h"
36 #include "ise.h"
37 #include "utils.h"
38 #include "option.h"
39 #include "languages.h"
40 #include "candidate-factory.h"
41 #include "ise-emoticon-mode.h"
42 #include "ise-emoticon-list.h"
43 #include "ise-stt-mode.h"
44 #include "ise-stt-option.h"
45 #include "ise-language-change.h"
46 #include "ise-tutorial-mode.h"
47 #include "modeindicator.h"
48 #include "w-input-smartreply.h"
49 #include "ise-floating-mode.h"
50 #include "ise-dbus.h"
51 #include "ise-sticker-mode.h"
52 #include "ise-nmt-mode.h"
53 #include "nmt.h"
54
55 #define EDJ_FILE                        RESDIR"/edje/" PROFILE_NAME"/customised_ctxpopup.edj"
56
57 #define EXIT_ISE_ON_HIDE 0
58 #define DEFER_ISE_CREATION 0
59
60 #define CANDIDATE_WINDOW_HEIGHT 84
61 using namespace scl;
62 #include <vector>
63 using namespace std;
64
65 static CSCLUI *g_ui = NULL;
66 CSCLUI* get_ui() { return g_ui; }
67
68 static int g_imdata_state = 0;
69
70 static sclboolean g_need_send_shift_event = FALSE;
71
72 extern void set_ise_imdata(const char * buf, size_t &len);
73 static void init_recent_used_punctuation();
74 static void update_recent_used_punctuation(const char *key_value);
75 static void set_ime_size(bool floating_mode, ISE_CANDIDATE_REQUEST candidate_req);
76 static sclboolean g_punctuation_popup_opened = FALSE;
77 static sclboolean g_popup_opened = FALSE;
78 static vector<string> g_recent_used_punctuation;
79 static const int MAX_DEFAULT_PUNCTUATION = 6;
80 static string g_default_punctuation[MAX_DEFAULT_PUNCTUATION] = {"-", "@", "'", "!", "?", ","};
81 static string g_current_punctuation[MAX_DEFAULT_PUNCTUATION-1] = {"RCENT1", "RCENT2", "RCENT3", "RCENT4", "RCENT5"};
82 static vector<string> g_softcandidate_string;
83 static bool g_input_panel_show = false;
84 static bool g_caps_mode_pending = false;
85 static bool g_floating_mode = false;
86 static bool g_candidate_more_view = false;
87 static bool g_ise_created = false;
88
89 static vector<string> g_lookup_table_strings;
90 static vector<string> g_smartreply_strings;
91 #if EXIT_ISE_ON_HIDE
92 static Ecore_Timer *exit_timer = NULL;
93 #endif
94
95 #define SOFT_CANDIDATE_DELETE_TIME (100.0/1000)
96 static Ecore_Timer *g_softcandidate_hide_timer = NULL;
97
98 static int g_ic = 0;
99 static int g_ic_smartreply = -1;
100
101 static KEYBOARD_STATE g_keyboard_state = {
102     0,
103     0,
104     ISE_LAYOUT_STYLE_NORMAL,
105     0,
106     FALSE,
107     TRUE,
108     FALSE,
109     "",
110     KEY_MODIFIER_NONE,
111     FALSE,
112     FALSE
113 };
114
115 KEYBOARD_STATE* get_keyboard_state() {
116     return &g_keyboard_state;
117 }
118
119 #define ISE_LAYOUT_NUMBERONLY_VARIATION_MAX 4
120 /*static const sclchar *_ise_numberonly_variation_name[ISE_LAYOUT_NUMBERONLY_VARIATION_MAX] = {
121     "DEFAULT", "SIG", "DEC", "SIGDEC"
122 };*/
123
124 #define SIG_DEC_SIZE        2
125 static scluint              _click_count = 0;
126 static const char          *_sig_dec[SIG_DEC_SIZE] = {".", "-"};
127 static scluint              _sig_dec_event[SIG_DEC_SIZE] = {'.', '-'};
128 static Ecore_Timer         *_commit_timer = NULL;
129
130 static sclu32               _context_layout = ISE_LAYOUT_STYLE_NORMAL;
131 static sclu32               _context_layout_variation = 0;
132
133 static Candidate           *g_candidate = NULL;
134 Candidate* get_candidate() {
135     return g_candidate;
136 }
137
138 static ISELanguageManager _language_manager;
139
140 class CandidateEventListener: public EventListener
141 {
142     public:
143         void on_event(const EventDesc &desc)
144         {
145             CSCLUI *ui = get_ui();
146             const MultiEventDesc &multidesc = dynamic_cast<const MultiEventDesc &>(desc);
147             LANGUAGE_INFO *info = _language_manager.get_language_info(_language_manager.get_current_language());
148
149             unsigned int smartreply_size = input_smartreply_get_reply_num();
150
151             switch (multidesc.type) {
152                 case MultiEventDesc::CANDIDATE_ITEM_MOUSE_DOWN:
153                     if (ime_autofill_get_exist()) {
154                         if (multidesc.index == 0) {
155                             string autofill_string = ime_autofill_get_string();
156                             ise_send_string(autofill_string.c_str());
157                         } else if (multidesc.index < (int)smartreply_size + 1) {
158                             ise_send_string(g_softcandidate_string[multidesc.index].c_str());
159                             ise_update_table(g_smartreply_strings);
160                         } else {
161                             if (info && info->load_in_ime)
162                                 ime_select_candidate(multidesc.index - smartreply_size - 1);
163                             else
164                                 engine_loader_select_candidate(multidesc.index - smartreply_size - 1);
165                         }
166                     } else {
167                         if (multidesc.index < (int)smartreply_size) {
168                             ise_send_string(g_softcandidate_string[multidesc.index].c_str());
169                             ise_update_table(g_smartreply_strings);
170                         }
171                         else {
172                             if (info && info->load_in_ime)
173                                 ime_select_candidate(multidesc.index - smartreply_size);
174                             else
175                                 engine_loader_select_candidate(multidesc.index - smartreply_size);
176                         }
177                     }
178                     break;
179                 case MultiEventDesc::CANDIDATE_MORE_VIEW_SHOW:
180                     // when more parts shows, click on the candidate will
181                     // not affect the key click event
182                     g_candidate_more_view = true;
183                     if (!g_input_panel_show)
184                         set_ime_size(g_floating_mode, ISE_CANDIDATE_REQ_SHOW);
185                     if (ui)
186                         ui->disable_input_events(TRUE);
187                     break;
188                 case MultiEventDesc::CANDIDATE_MORE_VIEW_HIDE:
189                     g_candidate_more_view = false;
190                     if (!g_input_panel_show)
191                         set_ime_size(g_floating_mode, ISE_CANDIDATE_REQ_SHOW);
192                     if (ui)
193                         ui->disable_input_events(FALSE);
194                     break;
195                 default: break;
196             }
197         }
198 };
199 static CandidateEventListener g_candidate_event_listener;
200
201 #define MVK_Shift_L 0xffe1
202 #define MVK_Caps_Lock 0xffe5
203 #define MVK_Shift_Off 0xffe1
204 #define MVK_Shift_On 0xffe2
205 #define MVK_Shift_Lock 0xffe6
206 #define MVK_Shift_Enable 0x9fe7
207 #define MVK_Shift_Disable 0x9fe8
208 #define MVK_space 0x020
209 #define MVK_Done 0xff0d
210
211 #define CM_KEY_LIST_SIZE         7
212 #define MULTITAP_TIMEOUT         3.0
213 #define USER_KEYSTRING_OPTION    "OPTION"
214 #define USER_KEYSTRING_EMOTICON  "EMOTICON_LAYOUT"
215 #define USER_KEYSTRING_CLIPBOARD "CLIPBOARD"
216 #define USER_KEYSTRING_VOICE     "STT_3X4"
217 #define USER_KEYSTRING_FLOATING  "FLOATING"
218 #define USER_KEYSTRING_STICKER   "STICKER_LAYOUT"
219 #define USER_KEYSTRING_TRANSLATION "TRANSLATION_LAYOUT"
220
221 #define USER_VOICE_LANGUAGE     "LANGUAGE"
222
223 static sclboolean           _cm_popup_opened = FALSE;
224 static const char          *_cm_key_list[CM_KEY_LIST_SIZE] = {USER_KEYSTRING_OPTION, USER_KEYSTRING_EMOTICON, USER_KEYSTRING_CLIPBOARD,
225                                                               USER_KEYSTRING_VOICE, USER_KEYSTRING_FLOATING, USER_KEYSTRING_STICKER, USER_KEYSTRING_TRANSLATION};
226 static scluint              _current_cm_key_id = 0;
227 static Evas_Object* _guide_popup_setting = NULL;
228 static Evas_Object* _guide_popup_space = NULL;
229
230 /*
231  * This callback class will receive all response events from SCL
232  * So you should perform desired tasks in this class.
233  */
234 class CUIEventCallback : public ISCLUIEventCallback
235 {
236 public :
237     Ecore_Timer* word_timer = NULL;
238     static Eina_Bool _multi_tap_timer_cb(void *data)
239     {
240         LOGD("Time Out");
241         ise_send_event(MVK_Done, KEY_MASK_NULL);
242         return ECORE_CALLBACK_CANCEL;
243     }
244     SCLEventReturnType on_event_key_clicked(SclUIEventDesc event_desc);
245     SCLEventReturnType on_event_drag_state_changed(SclUIEventDesc event_desc);
246     SCLEventReturnType on_event_notification(SCLUINotiType noti_type, SclNotiDesc *etc_info);
247 };
248
249 static CUIEventCallback callback;
250
251 int ise_get_imdata_state()
252 {
253     return g_imdata_state;
254 }
255
256 void ise_set_imdata_state(int state)
257 {
258     g_imdata_state = state;
259 }
260
261 static void update_candidate_table()
262 {
263     g_softcandidate_string.clear();
264     vector<string>::iterator iter;
265
266     g_smartreply_strings.clear();
267     input_smartreply_deinit();
268     g_ic_smartreply = -1;
269
270     // add autofill string
271     if (ime_autofill_get_exist())
272         g_softcandidate_string.push_back(ime_autofill_get_string());
273
274     // add lookup table string(s)
275     iter = g_lookup_table_strings.begin();
276     for (; iter != g_lookup_table_strings.end(); ++iter)
277     {
278         g_softcandidate_string.push_back(string(iter->c_str()));
279     }
280
281     ise_update_table(g_softcandidate_string);
282 }
283
284 static void _input_smartreply_notify_cb(void *user_data)
285 {
286     g_smartreply_strings.clear();
287     char *candidate = NULL;
288
289     if (input_smartreply_is_enabled()) {
290         /* Append newly added smartreply list */
291         int len = input_smartreply_get_reply_num();
292         if (len > 0) {
293             for (int i = 0; i < len; i++) {
294                 int type;
295                 char *reply = (char *)"";
296                 reply = input_smartreply_get_nth_item(i, &type);
297                 if (reply == NULL)
298                     continue;
299                 SECURE_LOGD("SmartReply = [%d] %s", i, reply);
300                 candidate = reply;
301                 if (candidate) {
302                     g_smartreply_strings.push_back(string(candidate));
303                     free(candidate);
304                     candidate = NULL;
305                 }
306             }
307             g_ic_smartreply = g_ic;
308
309             ise_app_candidate_show();
310             g_softcandidate_string = g_smartreply_strings;
311             ise_update_table(g_softcandidate_string);
312         }
313     }
314 }
315
316 sclboolean
317 check_ic_temporary(int ic)
318 {
319     if ((ic & 0xFFFF) == 0) {
320         return TRUE;
321     }
322     return FALSE;
323 }
324
325 static void _reset_shift_state(void)
326 {
327     CSCLUI *ui = get_ui();
328     if (ui) {
329         /* Reset all shift state variables */
330         SCLShiftState old_shift_state = ui->get_shift_state();
331         SCLShiftState new_shift_state = SCL_SHIFT_STATE_OFF;
332         if (old_shift_state != new_shift_state) {
333             g_need_send_shift_event = true;
334             ui->set_shift_state(new_shift_state);
335         }
336         LOGD("Shift state changed from (%d) to (%d)\n", (int)old_shift_state, (int)new_shift_state);
337     }
338 }
339
340 static void set_caps_mode(sclboolean mode) {
341     CSCLUI *ui = get_ui();
342     LOGD("mode : %d\n", mode);
343     if (ui) {
344         if (ui->get_shift_state() != SCL_SHIFT_STATE_LOCK) {
345             ui->set_shift_state(mode ? SCL_SHIFT_STATE_ON : SCL_SHIFT_STATE_OFF);
346             ui->set_autocapital_shift_state(!mode);
347
348             bool load_in_ime = false;
349             const sclchar *cur_lang = _language_manager.get_current_language();
350             if (cur_lang) {
351                 LANGUAGE_INFO *info = _language_manager.get_language_info(cur_lang);
352                 if (info)
353                     load_in_ime = info->load_in_ime;
354             }
355
356             if (load_in_ime)
357                 ime_send_imengine_event(mode ? MVK_Shift_On : MVK_Shift_Off, 0);
358             else
359                 engine_loader_send_imengine_event(mode ? MVK_Shift_On : MVK_Shift_Off, 0);
360         }
361     }
362 }
363
364 static void _reset_multitap_state(bool skip_commit = false)
365 {
366     KEYBOARD_STATE *keyboard_state = get_keyboard_state();
367     if (!keyboard_state) return;
368
369     LOGD("keyboard_state.prev_modifier : %d", keyboard_state->prev_modifier);
370     if (keyboard_state->prev_modifier == KEY_MODIFIER_MULTITAP_START ||
371         keyboard_state->prev_modifier == KEY_MODIFIER_MULTITAP_REPEAT) {
372         if (!skip_commit) {
373             ise_send_string(keyboard_state->multitap_value.c_str());
374         }
375         ise_update_preedit_string("");
376     }
377     keyboard_state->multitap_value = "";
378     keyboard_state->prev_modifier = KEY_MODIFIER_NONE;
379     if (g_caps_mode_pending) {
380         g_caps_mode_pending = false;
381         set_caps_mode(keyboard_state->caps_mode);
382     }
383 }
384
385 static void ise_set_cm_private_key(scluint cm_key_id)
386 {
387     CSCLUI *ui = get_ui();
388     if (cm_key_id >= CM_KEY_LIST_SIZE || ui == NULL) {
389         LOGE("cm_key_id=%d\n", cm_key_id);
390         return;
391     }
392
393     if (strcmp(_cm_key_list[cm_key_id], USER_KEYSTRING_EMOTICON) == 0) {
394         sclchar* imagelabel[SCL_BUTTON_STATE_MAX] = {
395             const_cast<sclchar*>("icon/54x54/icon_emotion_nor.png"),
396             const_cast<sclchar*>("icon/54x54/icon_emotion_press.png"),
397             const_cast<sclchar*>("icon/54x54/icon_emotion_dim.png")};
398         ui->set_private_key("CM_KEY", const_cast<sclchar*>(" "), imagelabel, NULL, 0, const_cast<sclchar*>(USER_KEYSTRING_EMOTICON), TRUE);
399     } else if (strcmp(_cm_key_list[cm_key_id], USER_KEYSTRING_OPTION) == 0) {
400         sclchar* imagelabel[SCL_BUTTON_STATE_MAX] = {
401             const_cast<sclchar*>("icon/54x54/icon_setting_nor.png"),
402             const_cast<sclchar*>("icon/54x54/icon_setting_press.png"),
403             const_cast<sclchar*>("icon/54x54/icon_setting_dim.png")};
404         ui->set_private_key("CM_KEY", const_cast<sclchar*>(" "), imagelabel, NULL, 0, const_cast<sclchar*>(USER_KEYSTRING_OPTION), TRUE);
405     } else if (strcmp(_cm_key_list[cm_key_id], USER_KEYSTRING_CLIPBOARD) == 0) {
406         sclchar* imagelabel[SCL_BUTTON_STATE_MAX] = {
407             const_cast<sclchar*>("icon/54x54/icon_clipboard_nor.png"),
408             const_cast<sclchar*>("icon/54x54/icon_clipboard_press.png"),
409             const_cast<sclchar*>("icon/54x54/icon_clipboard_dim.png")};
410         ui->set_private_key("CM_KEY", const_cast<sclchar*>(" "), imagelabel, NULL, 0, const_cast<sclchar*>(USER_KEYSTRING_CLIPBOARD), TRUE);
411     } else if (strcmp(_cm_key_list[cm_key_id], USER_KEYSTRING_VOICE) == 0) {
412         sclchar* imagelabel[SCL_BUTTON_STATE_MAX] = {
413             const_cast<sclchar*>("icon/54x54/icon_mic_nor.png"),
414             const_cast<sclchar*>("icon/54x54/icon_mic_press.png"),
415             const_cast<sclchar*>("icon/54x54/icon_mic_dim.png")};
416         ui->set_private_key("CM_KEY", const_cast<sclchar*>(" "), imagelabel, NULL, 0, const_cast<sclchar*>(USER_KEYSTRING_VOICE), TRUE);
417     } else if (strcmp(_cm_key_list[cm_key_id], USER_KEYSTRING_FLOATING) == 0) {
418         sclchar* imagelabel[SCL_BUTTON_STATE_MAX] = {
419             const_cast<sclchar*>("icon/54x54/icon_floating_keypad_nor.png"),
420             const_cast<sclchar*>("icon/54x54/icon_floating_keypad_press.png"),
421             const_cast<sclchar*>("icon/54x54/icon_floating_keypad_dim.png")};
422         ui->set_private_key("CM_KEY", const_cast<sclchar*>(" "), imagelabel, NULL, 0, const_cast<sclchar*>(USER_KEYSTRING_FLOATING), TRUE);
423     } else if (strcmp(_cm_key_list[cm_key_id], USER_KEYSTRING_TRANSLATION) == 0) {
424         sclchar* imagelabel[SCL_BUTTON_STATE_MAX] = {
425             const_cast<sclchar*>("icon/54x54/icon_translation_nor.png"),
426             const_cast<sclchar*>("icon/54x54/icon_translation_press.png"),
427             const_cast<sclchar*>("icon/54x54/icon_translation_dim.png")};
428         ui->set_private_key("CM_KEY", const_cast<sclchar*>(" "), imagelabel, NULL, 0, const_cast<sclchar*>(USER_KEYSTRING_TRANSLATION), TRUE);
429     } else if (strcmp(_cm_key_list[cm_key_id], USER_KEYSTRING_STICKER) == 0) {
430         sclchar* imagelabel[SCL_BUTTON_STATE_MAX] = {
431             const_cast<sclchar*>("icon/54x54/icon_sticker_nor.png"),
432             const_cast<sclchar*>("icon/54x54/icon_sticker_press.png"),
433             const_cast<sclchar*>("icon/54x54/icon_sticker_dim.png")};
434         ui->set_private_key("CM_KEY", const_cast<sclchar*>(" "), imagelabel, NULL, 0, const_cast<sclchar*>(USER_KEYSTRING_STICKER), TRUE);
435     }
436 }
437
438 static void ise_update_space_key(void)
439 {
440     CSCLUI *ui = get_ui();
441     if (ui == NULL) {
442         LOGE("ui = NULL\n");
443         return;
444     }
445
446     scluint num = _language_manager.get_enabled_languages_num();
447     LOGD("language number: %d\n", num);
448     if (num <= 1) {
449         LANGUAGE_INFO *info = _language_manager.get_language_info(_language_manager.get_current_language());
450         if (info && info->enabled) {
451 #ifdef _WEARABLE
452             sclchar* imagelabel[SCL_BUTTON_STATE_MAX] = {
453                 const_cast<sclchar*>("w_sip_3x4_btn_ic_space_no_arrow.png"),
454                 const_cast<sclchar*>("w_sip_3x4_btn_ic_space_no_arrow.png"),
455                 const_cast<sclchar*>("w_sip_3x4_btn_ic_space_no_arrow.png")};
456             ui->set_private_key("SPACE_KEY", const_cast<sclchar*>(info->display_name.c_str()), imagelabel, NULL, 0, const_cast<sclchar*>("Space"), TRUE);
457 #else
458             ui->enable_button("SPACE_ARROW_LEFT", false);
459             ui->enable_button("SPACE_ARROW_RIGHT", false);
460 #endif
461         }
462     } else {
463 #ifdef _WEARABLE
464         ui->unset_private_key("SPACE_KEY");
465 #else
466         ui->enable_button("SPACE_ARROW_LEFT", true);
467         ui->enable_button("SPACE_ARROW_RIGHT", true);
468 #endif
469     }
470 }
471
472 static scluint ise_get_cm_key_id(const sclchar *key_value)
473 {
474     for (int i = 0; i < CM_KEY_LIST_SIZE; ++i) {
475         if (0 == strcmp (key_value, _cm_key_list[i]))
476             return i;
477     }
478     return 0;
479 }
480
481 static bool ise_is_emoticons_disabled(void)
482 {
483     bool ret = true;
484
485     KEYBOARD_STATE *keyboard_state = get_keyboard_state();
486     if (!keyboard_state) return ret;
487
488     sclu32 current_layout = keyboard_state->layout;
489     LOGD("layout=%d\n", current_layout);
490
491     if ((current_layout == ISE_LAYOUT_STYLE_NORMAL) ||
492         (current_layout == ISE_LAYOUT_STYLE_NUMBER) ||
493         (current_layout == ISE_LAYOUT_STYLE_EMOTICON))
494         ret = false;
495
496     if (g_imdata_state & IMDATA_ACTION_DISABLE_EMOTICONS)
497         ret = true;
498
499     return ret;
500 }
501
502 static Eina_Bool softcandidate_hide_timer_callback(void *data)
503 {
504     LOGD("Enter\n");
505     set_ime_size(g_floating_mode, ISE_CANDIDATE_REQ_HIDE);
506
507     Candidate *candidate = get_candidate();
508     if (candidate) {
509         candidate->hide();
510     }
511     return ECORE_CALLBACK_CANCEL;
512 }
513
514 static void delete_softcandidate_hide_timer(void)
515 {
516     if (g_softcandidate_hide_timer) {
517         ecore_timer_del(g_softcandidate_hide_timer);
518         g_softcandidate_hide_timer = NULL;
519     }
520 }
521
522 static void add_softcandidate_hide_timer(void)
523 {
524     delete_softcandidate_hide_timer();
525     g_softcandidate_hide_timer = ecore_timer_add(SOFT_CANDIDATE_DELETE_TIME, softcandidate_hide_timer_callback, NULL);
526 }
527
528 static void create_softcandidate(void)
529 {
530     if (!g_candidate) {
531         g_candidate = CandidateFactory::make_candidate(CANDIDATE_MULTILINE, ime_get_main_window());
532         if (g_candidate) {
533             g_candidate->add_event_listener(&g_candidate_event_listener);
534         }
535     }
536 }
537
538 /**
539  * Send the given string to input framework
540  */
541 void
542 ise_send_string(const sclchar *key_value)
543 {
544     int ic = -1;
545     KEYBOARD_STATE *keyboard_state = get_keyboard_state();
546     if (keyboard_state && !check_ic_temporary(keyboard_state->ic)) {
547         ic = keyboard_state->ic;
548     }
549     ime_commit_string(key_value);
550     LOGD("ic : %x, %s\n", ic, key_value);
551 }
552
553 /**
554 * Send the preedit string to input framework
555 */
556 void
557 ise_update_preedit_string(const sclchar *str, const sclboolean underline)
558 {
559     int ic = -1;
560     Eina_List *attr_list = NULL;
561     ime_preedit_attribute *preedit_attr;
562
563     KEYBOARD_STATE *keyboard_state = get_keyboard_state();
564     if (keyboard_state && !check_ic_temporary(keyboard_state->ic)) {
565         ic = keyboard_state->ic;
566     }
567     if (underline) {
568         /* Count UTF-8 string length */
569         int len = 0;
570         const sclchar *s = str;
571         while (*s) len += (*s++ & 0xc0) != 0x80;
572
573         preedit_attr = (ime_preedit_attribute *)calloc(1, sizeof(ime_preedit_attribute));
574         if (preedit_attr) {
575             preedit_attr->start = 0;
576             preedit_attr->length = len;
577             preedit_attr->type = IME_ATTR_FONTSTYLE;
578             preedit_attr->value = IME_ATTR_FONTSTYLE_UNDERLINE;
579             attr_list = eina_list_append(attr_list, (void *)preedit_attr);
580         }
581
582         ime_update_preedit_string(str, attr_list);
583     } else {
584         ime_update_preedit_string(str, NULL);
585     }
586     LOGD("ic : %x, %s\n", ic, str);
587 }
588
589 /**
590 * Send the given event to input framework
591 */
592 void
593 ise_send_event(sclulong key_event, sclulong key_mask)
594 {
595     int ic = -1;
596     KEYBOARD_STATE *keyboard_state = get_keyboard_state();
597     if (keyboard_state && !check_ic_temporary(keyboard_state->ic)) {
598         ic = keyboard_state->ic;
599     }
600     ime_send_key_event((ime_key_code_e)key_event, IME_KEY_MASK_PRESSED, false);
601     ime_send_key_event((ime_key_code_e)key_event, IME_KEY_MASK_RELEASED, false);
602
603     LOGD("ic : %x, %lx\n", (unsigned int)ic, key_event);
604 }
605
606 /**
607 * Forward the given event to input framework
608 */
609 void
610 ise_forward_key_event(sclulong key_event)
611 {
612     int ic = -1;
613     KEYBOARD_STATE *keyboard_state = get_keyboard_state();
614     if (!check_ic_temporary(keyboard_state->ic)) {
615         ic = keyboard_state->ic;
616     }
617     ime_send_key_event((ime_key_code_e)key_event, IME_KEY_MASK_PRESSED, true);
618     ime_send_key_event((ime_key_code_e)key_event, IME_KEY_MASK_RELEASED, true);
619
620     LOGD("ic : %x, %lx\n", (unsigned int)ic, key_event);
621 }
622
623 /**
624  * @brief Delete commit timer.
625  *
626  * @return void
627  */
628 static void delete_commit_timer(void)
629 {
630     if (_commit_timer != NULL) {
631         ecore_timer_del(_commit_timer);
632         _commit_timer = NULL;
633     }
634 }
635
636 /**
637  * @brief Callback function for commit timer.
638  *
639  * @param data Data to pass when it is called.
640  *
641  * @return ECORE_CALLBACK_CANCEL
642  */
643 static Eina_Bool commit_timeout(void *data)
644 {
645     if (_commit_timer != NULL) {
646         ime_hide_preedit_string();
647         ise_forward_key_event(_sig_dec_event[(_click_count-1)%SIG_DEC_SIZE]);
648         _click_count = 0;
649     }
650     _commit_timer = NULL;
651     return ECORE_CALLBACK_CANCEL;
652 }
653
654 static sclboolean
655 on_input_mode_changed(const sclchar *key_value, sclulong key_event, sclint key_type)
656 {
657     sclboolean ret = FALSE;
658
659     CSCLUI *ui = get_ui();
660     KEYBOARD_STATE *keyboard_state = get_keyboard_state();
661     if (ui && keyboard_state) {
662         if (key_value) {
663             SECURE_LOGD("key_value : %s\n", key_value);
664             if (strcmp(key_value, "CUR_LANG") == 0) {
665                 keyboard_state->disable_force_latin = TRUE;
666                 ret = _language_manager.select_current_language();
667             }
668             if (strcmp(key_value, "NEXT_LANG") == 0) {
669                 keyboard_state->disable_force_latin = TRUE;
670                 ret = _language_manager.select_next_language();
671             }
672         }
673
674         const sclchar *cur_lang = _language_manager.get_current_language();
675         if (cur_lang) {
676             LANGUAGE_INFO *info = _language_manager.get_language_info(cur_lang);
677             if (info) {
678                 if (info->accepts_caps_mode) {
679                     if (info->load_in_ime)
680                         ime_send_imengine_event(MVK_Shift_Enable, 0);
681                     else
682                         engine_loader_send_imengine_event(MVK_Shift_Enable, 0);
683
684                     set_caps_mode(keyboard_state->caps_mode);
685                 } else {
686                     if (info->load_in_ime)
687                         ime_send_imengine_event(MVK_Shift_Disable, 0);
688                     else
689                         engine_loader_send_imengine_event(MVK_Shift_Disable, 0);
690
691                     ui->set_shift_state(SCL_SHIFT_STATE_OFF);
692                 }
693             }
694         }
695
696         if (ise_sticker_is_show())
697             ise_sticker_destroy_layout();
698
699         if (ise_emoticon_is_show()) {
700             ise_emoticon_destroy_layout();
701         }
702
703         if (ise_nmt_is_show()) {
704             ise_nmt_destroy_layout();
705         }
706
707         if (key_value) {
708             if (!strcmp(key_value, USER_KEYSTRING_EMOTICON)) {
709                 ise_emoticon_init_list();
710 #ifdef _WEARABLE
711                     ise_emoticon_set_current_group(EMOTICON_GROUP_1);
712 #else
713                 if (ise_emoticon_get_recent_list_size() == 0)
714                     ise_emoticon_set_current_group(EMOTICON_GROUP_1);
715                 else
716                     ise_emoticon_set_current_group(EMOTICON_GROUP_RECENTLY_USED);
717 #endif
718                 SCLRotation rotation = ui->get_rotation();
719                 ise_emoticon_show_layout(ise_emoticon_get_current_group(), ROTATION_TO_DEGREE(rotation), false, ime_get_main_window());
720             }
721             else if (!strcmp(key_value, USER_KEYSTRING_TRANSLATION)) {
722                 LOGD("");
723                 SCLRotation rotation = ui->get_rotation();
724                 ise_nmt_show_layout(ROTATION_TO_DEGREE(rotation), false, ime_get_main_window());
725             }
726         }
727     }
728
729     return ret;
730 }
731
732 SCLEventReturnType CUIEventCallback::on_event_notification(SCLUINotiType noti_type, SclNotiDesc *etc_info)
733 {
734     CSCLUI *ui = get_ui();
735     SCLEventReturnType ret = SCL_EVENT_PASS_ON;
736     LOGD("noti type: %d, g_need_send_shift_event: %d\n", noti_type, g_need_send_shift_event);
737
738     if (noti_type == SCL_UINOTITYPE_SHIFT_STATE_CHANGE) {
739         if (g_need_send_shift_event) {
740             const sclchar *cur_lang = _language_manager.get_current_language();
741             if (cur_lang) {
742                 LANGUAGE_INFO *info = _language_manager.get_language_info(cur_lang);
743                 SclNotiShiftStateChangeDesc *desc = static_cast<SclNotiShiftStateChangeDesc*>(etc_info);
744                 if (info && desc) {
745                     if (info->accepts_caps_mode) {
746                         LOGD("shift state: %d\n", desc->shift_state);
747                         if (desc->shift_state == SCL_SHIFT_STATE_OFF) {
748                             if (info->load_in_ime)
749                                 ime_send_imengine_event(MVK_Shift_Off, 0);
750                             else
751                                 engine_loader_send_imengine_event(MVK_Shift_Off, 0);
752                         } else if (desc->shift_state == SCL_SHIFT_STATE_ON) {
753                             if (info->load_in_ime)
754                                 ime_send_imengine_event(MVK_Shift_On, 0);
755                             else
756                                 engine_loader_send_imengine_event(MVK_Shift_On, 0);
757                         } else if (desc->shift_state == SCL_SHIFT_STATE_LOCK) {
758                             if (info->load_in_ime)
759                                 ime_send_imengine_event(MVK_Shift_Lock, 0);
760                             else
761                                 engine_loader_send_imengine_event(MVK_Shift_Lock, 0);
762                         }
763                         ret = SCL_EVENT_PASS_ON;
764                     }
765                 }
766             }
767             g_need_send_shift_event = FALSE;
768         }
769     } else if (noti_type == SCL_UINOTITYPE_POPUP_OPENING) {
770         vector<string>::reverse_iterator iter = g_recent_used_punctuation.rbegin();
771         int punc_pos = 0;
772         for (; iter != g_recent_used_punctuation.rend(); ++iter)
773         {
774             if (ui)
775                 ui->set_string_substitution(g_current_punctuation[punc_pos].c_str(), iter->c_str());
776             punc_pos++;
777         }
778         SclNotiPopupOpeningDesc *openingDesc = (SclNotiPopupOpeningDesc *)etc_info;
779         if (ui && 0 == strcmp(openingDesc->input_mode, "CM_POPUP")) {
780             if (!ise_sticker_check_sticker_exists())
781                 ui->enable_button("STICKER_KEY", EINA_FALSE);
782
783             if (ise_is_emoticons_disabled())
784                 ui->enable_button("EMOTICON_KEY", false);
785             else
786                 ui->enable_button("EMOTICON_KEY", true);
787         }
788     } else if (noti_type == SCL_UINOTITYPE_POPUP_OPENED) {
789         g_popup_opened = TRUE;
790         SclNotiPopupOpenedDesc *openedDesc = (SclNotiPopupOpenedDesc *)etc_info;
791         if (0 == strcmp(openedDesc->input_mode, "PUNCTUATION_POPUP")) {
792             g_punctuation_popup_opened = TRUE;
793         } else if (0 == strcmp(openedDesc->input_mode, "CM_POPUP")) {
794             _cm_popup_opened = TRUE;
795         }
796     } else if (noti_type == SCL_UINOTITYPE_POPUP_CLOSED) {
797         g_popup_opened = FALSE;
798         SclNotiPopupClosedDesc *closedDesc = (SclNotiPopupClosedDesc *)etc_info;
799         if (closedDesc && closedDesc->input_mode) {
800             if (0 == strcmp(closedDesc->input_mode, "PUNCTUATION_POPUP")) {
801                 g_punctuation_popup_opened = FALSE;
802             } else if (0 == strcmp(closedDesc->input_mode, "CM_POPUP")) {
803                 _cm_popup_opened = FALSE;
804             }
805         }
806     } else if (noti_type == SCL_UINOTITYPE_INPUT_MODE_CHANGE) {
807         SclNotiInputModeChangeDesc *desc = static_cast<SclNotiInputModeChangeDesc*>(etc_info);
808         if (desc && ui) {
809             set_ime_size(g_floating_mode, ISE_CANDIDATE_REQ_NONE);
810
811             const char *input_mode = ui->get_input_mode();
812             if (input_mode) {
813                 if (strcmp(input_mode, "STT_3X4") == 0 &&
814                         strcmp(desc->input_mode, "STT_3X4") != 0) {
815                     ise_hide_stt_mode();
816                 }
817                 if (strcmp(input_mode, "STT_3X4") != 0 &&
818                         strcmp(desc->input_mode, "STT_3X4") == 0) {
819                     ise_show_stt_mode(NATIVE_WINDOW_CAST(ime_get_main_window()));
820                 }
821             }
822         }
823     }
824
825     return ret;
826 }
827
828 void ise_destroy_popup_setting()
829 {
830     if (_guide_popup_setting != NULL) {
831         LOGD("destroy setting popup iter\n");
832         evas_object_del(_guide_popup_setting);
833         _guide_popup_setting = NULL;
834         CONFIG_VALUES *config_values = get_config_values();
835         if (config_values) {
836             config_values->first_guideset = TRUE;
837         }
838         write_ise_config_values();
839     }
840 }
841
842 void ise_destroy_popup_space()
843 {
844     if (_guide_popup_space != NULL) {
845         LOGD("destroy space popup iter\n");
846         evas_object_del(_guide_popup_space);
847         _guide_popup_setting = NULL;
848         CONFIG_VALUES *config_values = get_config_values();
849         if (config_values) {
850             config_values->first_guidechange = TRUE;
851         }
852         write_ise_config_values();
853     }
854 }
855
856 Evas_Object *open_message_popup(Evas_Object *parentWnd)
857 {
858     static Evas_Object *msg_window = NULL;
859     if (msg_window) {
860         evas_object_del(msg_window);
861         msg_window = NULL;
862     }
863     msg_window = elm_win_add(parentWnd, "MCFMessagePopup", ELM_WIN_UTILITY);
864     if (msg_window) {
865         int w, h;
866         elm_win_borderless_set(msg_window, EINA_TRUE);
867         elm_win_alpha_set(msg_window, EINA_TRUE);
868         elm_win_title_set(msg_window, "ISF Popup");
869         elm_win_screen_size_get(msg_window, NULL, NULL, &w, &h);
870         elm_win_prop_focus_skip_set(msg_window, TRUE);
871         int rots[4] = {0, 90, 180, 270};
872         elm_win_wm_rotation_available_rotations_set(msg_window, rots, 4);
873         evas_object_resize(msg_window, w, h);
874     }
875
876     int rots[4] = { 0, 90, 180, 270 };
877     elm_win_wm_rotation_available_rotations_set(msg_window, rots, 4);
878     evas_object_show(msg_window);
879     return msg_window;
880 }
881
882 void _guideline_popup_setting_cb(void *data, Evas_Object *obj, void *event_info)
883 {
884     evas_object_smart_callback_del(obj, "dismissed", _guideline_popup_setting_cb);
885     evas_object_del(obj);
886     obj = NULL;
887     ise_destroy_popup_setting();
888     CONFIG_VALUES *config_values = get_config_values();
889     if (config_values) {
890         config_values->first_guideset = TRUE;
891     }
892     write_ise_config_values();
893 }
894
895 void _guideline_popup_space_cb(void *data, Evas_Object *obj, void *event_info)
896 {
897     evas_object_smart_callback_del(obj, "dismissed", _guideline_popup_space_cb);
898     evas_object_del(obj);
899     obj = NULL;
900     ise_destroy_popup_space();
901     CONFIG_VALUES *config_values = get_config_values();
902     if (config_values) {
903         config_values->first_guidechange = TRUE;
904     }
905     write_ise_config_values();
906 }
907
908 bool get_landscape_device(int degree)
909 {
910     sclint width = 0;
911     sclint height = 0;
912     bool landscape_device = false;
913
914     CSCLUI *ui = get_ui();
915     if (!ui) return false;
916
917     ui->get_screen_resolution(&width, &height);
918
919     if (degree == 0 || degree == 180) {
920         if (width > height)
921             landscape_device = true;
922     }
923     else {
924         if (width < height)
925             landscape_device = true;
926     }
927
928     return landscape_device;
929 }
930
931 void ise_show_help_popup(sclulong keyEvent)
932 {
933     char buf[2048] = {0, };
934     int font_size = 40;
935     sclint scr_w = 0;
936     sclint scr_h = 0;
937     SclRectangle rectangle = {0};
938     Evas_Object *ctxpopup = NULL;
939     Elm_Theme *theme = NULL;
940
941     CSCLUI *ui = get_ui();
942     if (ui) {
943         ui->get_screen_resolution(&scr_w, &scr_h);
944
945         if (keyEvent == MVK_space) {
946             CONFIG_VALUES *config_values = get_config_values();
947             if (config_values) {
948                 config_values->first_guidechange = TRUE;
949             }
950             write_ise_config_values();
951             ui->get_button_geometry("SPACE_KEY", &rectangle);
952             _guide_popup_space = open_message_popup(NATIVE_WINDOW_CAST(ime_get_main_window()));
953
954             theme = elm_theme_new();
955             elm_theme_ref_set(theme, NULL);
956             elm_theme_extension_add(theme, EDJ_FILE);
957
958             ctxpopup = elm_ctxpopup_add(_guide_popup_space);
959             elm_object_theme_set(ctxpopup, theme);
960             evas_object_smart_callback_add(ctxpopup, "dismissed", _guideline_popup_space_cb, (void *)keyEvent);
961         } else {
962             CONFIG_VALUES *config_values = get_config_values();
963             if (config_values) {
964                 config_values->first_guideset = TRUE;
965             }
966             write_ise_config_values();
967             ui->get_button_geometry("CM_KEY", &rectangle);
968             _guide_popup_setting = open_message_popup(NATIVE_WINDOW_CAST(ime_get_main_window()));
969             theme = elm_theme_new();
970             elm_theme_ref_set(theme, NULL);
971             elm_theme_extension_add(theme, EDJ_FILE);
972             ctxpopup = elm_ctxpopup_add(_guide_popup_setting);
973             elm_object_theme_set(ctxpopup, theme);
974             evas_object_smart_callback_add(ctxpopup, "dismissed", _guideline_popup_setting_cb, (void *)keyEvent);
975         }
976     }
977
978     int rotation = elm_win_rotation_get(NATIVE_WINDOW_CAST(ime_get_main_window()));
979     bool landscape_device = get_landscape_device(rotation);
980     if (rotation == 0 || rotation == 180) {
981         elm_object_style_set(ctxpopup, landscape_device ? "customised_guideline_popup_landscape" : "customised_guideline_popup");
982     } else {
983         elm_object_style_set(ctxpopup, landscape_device ?  "customised_guideline_popup" : "customised_guideline_popup_landscape");
984     }
985
986     elm_ctxpopup_direction_priority_set(ctxpopup, ELM_CTXPOPUP_DIRECTION_UP,
987                           ELM_CTXPOPUP_DIRECTION_UNKNOWN,
988                           ELM_CTXPOPUP_DIRECTION_UNKNOWN,
989                           ELM_CTXPOPUP_DIRECTION_UNKNOWN);
990
991     Evas_Object* text = elm_label_add(ctxpopup);
992
993     if (keyEvent == MVK_space) {
994         snprintf(buf, sizeof(buf), "<font_style=Regular font_size=%d align=left wrap=mixed color=#000000>%s</>", font_size,
995             dgettext(PACKAGE, "IDS_IME_BODY_SWIPE_THE_SPACE_BAR_LEFT_OR_RIGHT_TO_CHANGE_BETWEEN_LANGUAGES"));
996     } else {
997         snprintf(buf, sizeof(buf), "<font_style=Regular font_size=%d align=left wrap=mixed color=#000000>%s</>", font_size,
998                dgettext(PACKAGE, "IDS_IME_BODY_TAP_AND_HOLD_THIS_KEY_TO_SEE_THE_SYMBOL_LIST_SELECT_ONE_TO_USE_IT_AS_A_SHORTCUT"));
999     }
1000     elm_object_text_set(text, buf);
1001     elm_object_content_set(ctxpopup, text);
1002     Evas_Coord x, y, w, h;
1003     evas_object_geometry_get(NATIVE_WINDOW_CAST(ime_get_main_window()), &x, &y, &w, &h);
1004
1005     if (rotation == 0 || rotation == 180) {
1006         elm_label_wrap_width_set(text, (scr_w * 4) / 5);
1007         evas_object_size_hint_min_set(ctxpopup, ELM_SCALE_SIZE(scr_w), ELM_SCALE_SIZE(50));
1008         evas_object_size_hint_max_set(ctxpopup, ELM_SCALE_SIZE(scr_w), ELM_SCALE_SIZE(600));
1009         evas_object_move(ctxpopup, rectangle.x + rectangle.width / 2,
1010                     (scr_h - h) + rectangle.y - ELM_SCALE_SIZE(5));
1011     } else {
1012         elm_label_wrap_width_set(text, (scr_h * 4) / 5);
1013         evas_object_size_hint_min_set(ctxpopup, ELM_SCALE_SIZE(scr_h), ELM_SCALE_SIZE(50));
1014         evas_object_size_hint_max_set(ctxpopup, ELM_SCALE_SIZE(scr_h), ELM_SCALE_SIZE(600));
1015         evas_object_move(ctxpopup, rectangle.x + rectangle.width / 2,
1016                 (scr_w - h)+ rectangle.y - ELM_SCALE_SIZE(5));
1017     }
1018     elm_label_line_wrap_set(text, ELM_WRAP_MIXED);
1019     evas_object_show(text);
1020
1021     if (keyEvent == MVK_space) {
1022         evas_object_layer_set(_guide_popup_space, EVAS_LAYER_MAX);
1023         evas_object_show(_guide_popup_space);
1024     } else {
1025         evas_object_layer_set(_guide_popup_setting, EVAS_LAYER_MAX);
1026         evas_object_show(_guide_popup_setting);
1027     }
1028
1029     evas_object_layer_set(ctxpopup, EVAS_LAYER_MAX);
1030     evas_object_show(ctxpopup);
1031 }
1032
1033 SCLEventReturnType CUIEventCallback::on_event_drag_state_changed(SclUIEventDesc event_desc)
1034 {
1035     SECURE_LOGD("button %s is clicked\n", event_desc.key_value);
1036     if (event_desc.event_type == EVENT_TYPE_MOVE) {
1037         if (event_desc.key_event == MVK_space) {
1038             SclRectangle rectangle = {0};
1039             CSCLUI *ui = get_ui();
1040             if (ui) ui->get_button_geometry("SPACE_KEY", &rectangle);
1041             ise_show_space_flick_language_change_popup(rectangle.x, rectangle.y, rectangle.width, rectangle.height);
1042         }
1043     } else if (event_desc.event_type == EVENT_TYPE_RELEASE) {
1044         if (event_desc.key_event == MVK_space) {
1045             ise_destroy_space_flick_language_change_popup();
1046         }
1047
1048         if (g_floating_mode)
1049             ime_set_floating_drag_end();
1050     } else if (event_desc.event_type == EVENT_TYPE_PRESS) {
1051 #if defined(_MOBILE) || defined(_COMMON)
1052         CONFIG_VALUES *config_values = get_config_values();
1053
1054         if (config_values && (!config_values->first_guideset) && event_desc.key_value && (strncmp(event_desc.key_value, "OPTION", strlen(event_desc.key_value)) == 0)) {
1055             ise_show_help_popup(event_desc.key_event);//show help popup in on_event_drag_state_changed other than on_event_key_clicked for fixing help popup show delay issue
1056             LOGD("setting popup show\n");
1057             return SCL_EVENT_PASS_ON;
1058         } else {
1059             ise_destroy_popup_setting();//destroy popup manually in case of abnormal situation
1060         }
1061 #endif
1062         if (g_floating_mode && event_desc.mouse_current_point.y <= FLOATING_TITLE_BAR_HEIGHT
1063             && event_desc.mouse_current_point.y >= 0)
1064             ime_set_floating_drag_start();
1065     }
1066     return SCL_EVENT_PASS_ON;
1067 }
1068
1069 static void launch_option()
1070 {
1071     app_control_h app_control;
1072     int ret = app_control_create(&app_control);
1073     if (ret != APP_CONTROL_ERROR_NONE) {
1074         LOGW("app_control_create returned %d\n", ret);
1075         return;
1076     }
1077
1078     ret = app_control_set_operation(app_control, APP_CONTROL_OPERATION_DEFAULT);
1079     if (ret != APP_CONTROL_ERROR_NONE) {
1080         LOGW("app_control_set_operation returned %d\n", ret);
1081         goto end;
1082     }
1083
1084     ret = app_control_set_app_id(app_control, "org.tizen.ise-default-setting");
1085     if (ret != APP_CONTROL_ERROR_NONE) {
1086         LOGW("app_control_set_app_id returned %d\n", ret);
1087         goto end;
1088     }
1089
1090     app_control_add_extra_data(app_control, "caller", "ise-default");
1091     app_control_set_launch_mode(app_control, APP_CONTROL_LAUNCH_MODE_GROUP);
1092
1093     ret = app_control_send_launch_request(app_control, NULL, NULL);
1094     if (ret != APP_CONTROL_ERROR_NONE) {
1095         goto end;
1096     }
1097
1098 end:
1099     if (app_control)
1100         app_control_destroy(app_control);
1101 }
1102
1103 SCLEventReturnType CUIEventCallback::on_event_key_clicked(SclUIEventDesc event_desc)
1104 {
1105     SCLEventReturnType ret = SCL_EVENT_PASS_ON;
1106     if (word_timer != NULL) {
1107         ecore_timer_del(word_timer);
1108         word_timer = NULL;
1109     }
1110
1111     KEYBOARD_STATE *keyboard_state = get_keyboard_state();
1112     if (!keyboard_state) return ret;
1113
1114     if (event_desc.key_modifier == KEY_MODIFIER_MULTITAP_START) {
1115         if (!keyboard_state->multitap_value.empty()) {
1116             ise_send_string(keyboard_state->multitap_value.c_str());
1117         }
1118         ise_update_preedit_string(event_desc.key_value);
1119         keyboard_state->multitap_value = event_desc.key_value;
1120     } else if (event_desc.key_modifier == KEY_MODIFIER_MULTITAP_REPEAT) {
1121         ise_update_preedit_string(event_desc.key_value);
1122         keyboard_state->multitap_value = event_desc.key_value;
1123     } else {
1124         _reset_multitap_state();
1125     }
1126     keyboard_state->prev_modifier = event_desc.key_modifier;
1127
1128     CSCLUI *ui = get_ui();
1129     if (ui) {
1130         switch (event_desc.key_type) {
1131         case KEY_TYPE_STRING: {
1132             if (event_desc.key_modifier != KEY_MODIFIER_MULTITAP_START &&
1133                 event_desc.key_modifier != KEY_MODIFIER_MULTITAP_REPEAT) {
1134                     if (event_desc.key_event) {
1135                         ise_forward_key_event(event_desc.key_event);
1136                     } else {
1137                         ise_send_string(event_desc.key_value);
1138                     }
1139             }
1140             if (!g_popup_opened) {
1141                 const sclchar *input_mode = ui->get_input_mode();
1142                 if (input_mode && ((0 == strcmp(input_mode, "SYM_QTY_1")) || (0 == strcmp(input_mode, "SYM_QTY_2")))) {
1143                     update_recent_used_punctuation(event_desc.key_value);
1144                 }
1145             } else if (g_punctuation_popup_opened) {
1146                 update_recent_used_punctuation(event_desc.key_value);
1147             }
1148             break;
1149         }
1150         case KEY_TYPE_CHAR: {
1151                 sclboolean need_forward = FALSE;
1152                 // FIXME : Should decide when to forward key events
1153                 const sclchar *input_mode = ui->get_input_mode();
1154                 if (input_mode) {
1155                     if (strcmp(input_mode, "SYM_QTY_1") == 0 ||
1156                             strcmp(input_mode, "SYM_QTY_2") == 0 ||
1157                             strcmp(input_mode, "PHONE_3X4") == 0 ||
1158                             strcmp(input_mode, "IPv6_3X4_123") == 0 ||
1159                             strcmp(input_mode, "IPv6_3X4_ABC") == 0 ||
1160                             strcmp(input_mode, "NUMONLY_3X4") == 0 ||
1161                             strcmp(input_mode, "NUMONLY_3X4_SIG") == 0 ||
1162                             strcmp(input_mode, "NUMONLY_3X4_DEC") == 0 ||
1163                             strcmp(input_mode, "NUMONLY_3X4_SIGDEC") == 0 ||
1164                             strcmp(input_mode, "DATETIME_3X4") == 0) {
1165                         need_forward = TRUE;
1166                     }
1167                 }
1168                 if (input_mode && strcmp (input_mode, "NUMONLY_3X4_SIGDEC") == 0 &&
1169                     strcmp(event_desc.key_value, ".") == 0) {
1170                     ime_update_preedit_string(_sig_dec[_click_count%SIG_DEC_SIZE], NULL);
1171                     ime_show_preedit_string();
1172                     delete_commit_timer();
1173                     _commit_timer = ecore_timer_add(1.0, commit_timeout, NULL);
1174                     _click_count++;
1175                 } else if (event_desc.key_event) {
1176                     commit_timeout(NULL);
1177                     if (need_forward) {
1178                         ise_forward_key_event(event_desc.key_event);
1179                     } else {
1180                         if (_cm_popup_opened) {
1181                             static sclchar current_cm_symbol[2] = {'\0'};
1182                             sclchar* imagelabel[SCL_BUTTON_STATE_MAX] = {
1183                                 const_cast<sclchar*>(" "),
1184                                 const_cast<sclchar*>(" "),
1185                                 const_cast<sclchar*>(" ")};
1186                             if (event_desc.key_value) {
1187                                 current_cm_symbol[0] = event_desc.key_value[0];
1188                                 current_cm_symbol[1] = '\0';
1189                             }
1190                             ui->set_private_key("CM_KEY",
1191                                     const_cast<sclchar*>(current_cm_symbol),
1192                                     imagelabel, NULL, 0,
1193                                     const_cast<sclchar*>(current_cm_symbol), TRUE);
1194
1195                             _cm_popup_opened = FALSE;
1196                             _current_cm_key_id = -1;
1197                         }
1198 #ifdef _WEARABLE
1199                         /*
1200                         *
1201                         *change the keyboard mode of GLM from QWERTY to KEYPAD
1202                         *ensure the Number keypad won't be affected
1203                         *
1204                         */
1205                         if (keyboard_state->layout == ISE_LAYOUT_STYLE_NUMBER) {
1206                             ime_send_key_event(IME_KEY_Print, IME_KEY_MASK_CONTROL, false);
1207                         } else {
1208                             Candidate *candidate = get_candidate();
1209                             if (word_timer == NULL && (!candidate || !candidate->get_visible())) {
1210                                 word_timer = ecore_timer_add(MULTITAP_TIMEOUT, _multi_tap_timer_cb, NULL);
1211                             }
1212                             ime_send_key_event(IME_KEY_Select, IME_KEY_MASK_CONTROL, false);
1213                         }
1214 #endif
1215                         ise_send_event(event_desc.key_event, KEY_MASK_NULL);
1216                     }
1217                 }
1218                 if (input_mode) {
1219                     if ((strcmp(input_mode, "SYM_QTY_1") == 0) || (0 == strcmp(input_mode, "SYM_QTY_2"))) {
1220                         update_recent_used_punctuation(event_desc.key_value);
1221                     }
1222                 }
1223                 break;
1224             }
1225         case KEY_TYPE_CONTROL: {
1226                 commit_timeout(NULL);
1227
1228                 const char *long_shift = "LongShift";
1229                 const char *caps_lock = "CapsLock";
1230                 const char *delete_all = "DeleteAll";
1231                 const char *hide_panel = "Hide";
1232                 if (strncmp(event_desc.key_value, long_shift, strlen(long_shift)) == 0) {
1233                     LOGD("shift key is longpress\n");
1234                     ui->set_shift_state(SCL_SHIFT_STATE_ON);
1235                     g_need_send_shift_event = TRUE;
1236                     //ise_send_event (MVK_Shift_Lock, KEY_MASK_NULL);
1237                 } else if (strncmp(event_desc.key_value, caps_lock, strlen(caps_lock)) == 0) {
1238                     bool load_in_ime = false;
1239                     const sclchar *cur_lang = _language_manager.get_current_language();
1240                     if (cur_lang) {
1241                         LANGUAGE_INFO *info = _language_manager.get_language_info(cur_lang);
1242                         if (info)
1243                             load_in_ime = info->load_in_ime;
1244                     }
1245
1246                     if (ui->get_shift_state() != SCL_SHIFT_STATE_LOCK) {
1247                         ui->set_shift_state(SCL_SHIFT_STATE_LOCK);
1248                         if (load_in_ime)
1249                             ime_send_imengine_event(MVK_Shift_Lock, 0);
1250                         else
1251                             engine_loader_send_imengine_event(MVK_Shift_Lock, 0);
1252                     } else {
1253                         ui->set_shift_state(SCL_SHIFT_STATE_OFF);
1254                         if (load_in_ime)
1255                             ime_send_imengine_event(MVK_Shift_Off, 0);
1256                         else
1257                             engine_loader_send_imengine_event(MVK_Shift_Off, 0);
1258                     }
1259                     //g_need_send_shift_event = TRUE;
1260                 } else if (strncmp(event_desc.key_value, delete_all, strlen(delete_all)) == 0) {
1261                     ime_delete_surrounding_text((INT_MAX / 2) * -1, INT_MAX);
1262                 } else if (strncmp(event_desc.key_value, hide_panel, strlen(hide_panel)) == 0) {
1263                     ise_hide();
1264                     ime_request_hide();
1265                 } else if (event_desc.key_event) {
1266                     if (keyboard_state->layout == ISE_LAYOUT_STYLE_VOICE) {
1267                         ise_stt_stop();
1268                     }
1269 #ifdef _WEARABLE
1270                     if (event_desc.key_event == MVK_Done) {
1271                         LOGD("ENTER");
1272                         //commit the preedit string first
1273                         ise_send_event(event_desc.key_event, KEY_MASK_NULL);
1274                     }
1275 #endif
1276                     ise_send_event(event_desc.key_event, KEY_MASK_NULL);
1277                     if (event_desc.key_event == MVK_Shift_L) {
1278                         g_need_send_shift_event = TRUE;
1279                     }
1280                 }
1281                 break;
1282            }
1283         case KEY_TYPE_MODECHANGE:
1284 #if defined(_MOBILE) || defined(_COMMON)
1285             if (_guide_popup_setting != NULL) {//popup is showing
1286                 break;
1287             }
1288 #endif
1289             if (strcmp(event_desc.key_value, USER_VOICE_LANGUAGE) == 0) {
1290                 if (!get_setting_window_open_status()) {
1291                     ise_hide_stt_mode();
1292 #ifdef _WEARABLE
1293                     hide_indicator_window();
1294 #endif
1295                     create_setting_window();
1296                 }
1297             } else if (strcmp(event_desc.key_value, USER_KEYSTRING_VOICE) == 0) {
1298                 keyboard_state->layout = ISE_LAYOUT_STYLE_VOICE;
1299                 ui->set_input_mode("STT_3X4");
1300
1301             } else if (strcmp(event_desc.key_value, USER_KEYSTRING_OPTION) == 0) {
1302                 launch_option();
1303
1304                 ret = SCL_EVENT_DONE;
1305             } else if (strcmp(event_desc.key_value, USER_KEYSTRING_CLIPBOARD) == 0) {
1306                 clipboard_show();
1307
1308                 ret = SCL_EVENT_DONE;
1309             } else if (strcmp(event_desc.key_value, USER_KEYSTRING_FLOATING) == 0) {
1310                 CONFIG_VALUES *config_values = get_config_values();
1311
1312                 if (g_floating_mode) {
1313                     if (config_values) {
1314                         config_values->floating_mode = false;
1315                     }
1316                 } else {
1317                     if (config_values) {
1318                         config_values->floating_mode = true;
1319                     }
1320                 }
1321                 write_ise_config_values();
1322
1323                 ret = SCL_EVENT_DONE;
1324             } else if (strcmp(event_desc.key_value, USER_KEYSTRING_STICKER) == 0) {
1325                 SCLRotation rotation = ui->get_rotation();
1326                 ise_sticker_show_layout(STICKER_GROUP_RECENTLY_USED, ROTATION_TO_DEGREE(rotation), false, ime_get_main_window());
1327             } else if (strcmp(event_desc.key_value, USER_KEYSTRING_TRANSLATION) == 0) {
1328                 if (ise_sticker_is_show())
1329                     ise_sticker_destroy_layout();
1330
1331                 SCLRotation rotation = ui->get_rotation();
1332                 ise_nmt_show_layout(ROTATION_TO_DEGREE(rotation), false, ime_get_main_window());
1333             } else if (on_input_mode_changed(event_desc.key_value, event_desc.key_event, event_desc.key_type)) {
1334                 ret = SCL_EVENT_DONE;
1335             }
1336             if (_cm_popup_opened) {
1337                 if (strcmp(event_desc.key_value, USER_KEYSTRING_EMOTICON) == 0 ||
1338                     strcmp(event_desc.key_value, USER_KEYSTRING_VOICE) == 0 ||
1339                     strcmp(event_desc.key_value, USER_KEYSTRING_FLOATING) == 0 ||
1340                     strcmp(event_desc.key_value, USER_KEYSTRING_STICKER) == 0 ||
1341                     strcmp(event_desc.key_value, USER_KEYSTRING_TRANSLATION) == 0) {
1342                     scluint id = ise_get_cm_key_id(event_desc.key_value);
1343                     if (id != _current_cm_key_id) {
1344                         _current_cm_key_id = id;
1345                         ise_set_cm_private_key(_current_cm_key_id);
1346                     }
1347                 }
1348                 _cm_popup_opened = FALSE;
1349             }
1350             if (strlen(event_desc.key_value) == 1) {
1351                 const char allowed_chars_in_modechange[] = {
1352                     ',', '?', '!', '`', '~', '@', '-'
1353                 };
1354                 const int allowed_chars_in_modechange_num =
1355                     sizeof(allowed_chars_in_modechange) / sizeof(char);
1356                 for (unsigned int loop = 0;loop < sizeof(allowed_chars_in_modechange_num);loop++) {
1357                     if (*(event_desc.key_value) == allowed_chars_in_modechange[loop]) {
1358                         ise_send_string(event_desc.key_value);
1359                     }
1360                 }
1361             }
1362             break;
1363         case KEY_TYPE_USER:
1364             if (strcmp(event_desc.key_value, USER_KEYSTRING_OPTION) == 0) {
1365                 //open_option_window(NULL, ROTATION_TO_DEGREE(ui->get_rotation()));
1366                 launch_option();
1367
1368                 ret = SCL_EVENT_DONE;
1369             } else if (strcmp(event_desc.key_value, USER_KEYSTRING_CLIPBOARD) == 0) {
1370                 clipboard_show();
1371                 ret = SCL_EVENT_DONE;
1372             } else if (strcmp(event_desc.key_value, "Cancel") == 0) {
1373                 ret = SCL_EVENT_DONE;
1374                 const sclchar *input_mode = ui->get_input_mode();
1375                 if (input_mode && strcmp(input_mode, "STT_3X4") == 0 ) {
1376                     keyboard_state->need_reset = TRUE;
1377                     voice_result_string_flush();
1378                     ise_set_layout(keyboard_state->layout, keyboard_state->layout_variation);
1379                     if (keyboard_state->visible_state)
1380                         ise_show(keyboard_state->ic);
1381                 }
1382 #ifdef _TV
1383                 ise_send_event(IME_KEY_Cancel, KEY_MASK_NULL);
1384                 ime_request_hide();
1385 #endif
1386             }  else if (strcmp(event_desc.key_value, "Done") == 0) {
1387 #ifdef _TV
1388                 ret = SCL_EVENT_DONE;
1389                 ise_send_event(IME_KEY_Return, KEY_MASK_NULL);
1390                 ime_request_hide();
1391 #endif
1392             } else if (strcmp(event_desc.key_value, "Translate") == 0) {
1393                 ise_nmt_translate();
1394             }  else {
1395                 const sclchar *input_mode = ui->get_input_mode();
1396                 if ((NULL != input_mode) && (!strcmp(input_mode, "EMOTICON_LAYOUT"))) {
1397                     if (ise_emoticon_is_show()) {
1398                         ise_emoticon_destroy_layout();
1399                     }
1400 #ifdef _WEARABLE
1401                     emoticon_group_t group_id = EMOTICON_GROUP_1;
1402                     if (ise_emoticon_get_current_group() < EMOTICON_GROUP_3)
1403                         group_id = (emoticon_group_t)(ise_emoticon_get_current_group() + 1);
1404
1405                     ise_set_emoticon_label(group_id);
1406 #else
1407                     emoticon_group_t group_id = ise_emoticon_get_group_id(event_desc.key_value);
1408 #endif
1409                     if ((group_id >= 0) && (group_id < MAX_EMOTICON_GROUP)) {
1410                         SCLRotation rotation = ui->get_rotation();
1411                         ise_emoticon_show_layout(group_id, ROTATION_TO_DEGREE(rotation), false, ime_get_main_window());
1412                     }
1413                 }
1414
1415                 if (input_mode && (!strcmp(input_mode, "STICKER_LAYOUT"))) {
1416                     if (ise_sticker_is_show())
1417                         ise_sticker_change_group(ise_sticker_get_group_id(event_desc.key_value));
1418                 }
1419             }
1420             if (_cm_popup_opened) {
1421                 if (strcmp(event_desc.key_value, USER_KEYSTRING_OPTION) == 0 ||
1422                     strcmp(event_desc.key_value, USER_KEYSTRING_CLIPBOARD) == 0 ||
1423                     strcmp(event_desc.key_value, USER_KEYSTRING_STICKER) == 0 ||
1424                     strcmp(event_desc.key_value, USER_KEYSTRING_TRANSLATION) == 0) {
1425                     scluint id = ise_get_cm_key_id(event_desc.key_value);
1426                     if (id != _current_cm_key_id) {
1427                         _current_cm_key_id = id;
1428                         ise_set_cm_private_key(_current_cm_key_id);
1429                     }
1430                 }
1431                 _cm_popup_opened = FALSE;
1432             }
1433             break;
1434         default:
1435             break;
1436         }
1437     }
1438
1439     return ret;
1440 }
1441
1442 void
1443 ise_set_layout(sclu32 layout, sclu32 layout_variation)
1444 {
1445     /* Check if the layoutIdx is in the valid range */
1446     KEYBOARD_STATE *keyboard_state = get_keyboard_state();
1447     if (layout < ISE_LAYOUT_STYLE_MAX) {
1448         if (keyboard_state->layout != layout ||
1449             keyboard_state->layout_variation != layout_variation) {
1450             keyboard_state->need_reset = TRUE;
1451         }
1452         keyboard_state->layout = layout;
1453         keyboard_state->layout_variation = layout_variation;
1454         LOGD("layout:%d, variation:%d\n", keyboard_state->layout, keyboard_state->layout_variation);
1455     }
1456 }
1457
1458 void
1459 ise_reset_context()
1460 {
1461     LOGD("");
1462     _reset_multitap_state(true);
1463     CONFIG_VALUES *config_values = get_config_values();
1464     if (config_values) {
1465         _language_manager.reset_language(config_values->selected_language.c_str());
1466     }
1467 }
1468
1469 void
1470 ise_reset_input_context()
1471 {
1472     LOGD("");
1473     _reset_multitap_state(true);
1474     KEYBOARD_STATE *keyboard_state = get_keyboard_state();
1475     if (keyboard_state) keyboard_state->disable_force_latin = FALSE;
1476     CONFIG_VALUES *config_values = get_config_values();
1477     if (config_values) {
1478         _language_manager.reset_language(config_values->selected_language.c_str());
1479     }
1480 }
1481
1482 void
1483 ise_focus_in(int ic)
1484 {
1485     KEYBOARD_STATE *keyboard_state = get_keyboard_state();
1486     if (!keyboard_state) return;
1487
1488     LOGD("ic : %x , %x , g_ic : %x , %x, g_focused_ic : %x , %x\n", ic, check_ic_temporary(ic),
1489             keyboard_state->ic, check_ic_temporary(keyboard_state->ic),
1490             keyboard_state->focused_ic, check_ic_temporary(keyboard_state->focused_ic));
1491     if (check_ic_temporary(keyboard_state->ic) && !check_ic_temporary(ic)) {
1492         keyboard_state->ic = ic;
1493     }
1494     keyboard_state->focused_ic = ic;
1495 }
1496
1497 static void save_autofill_data()
1498 {
1499     char *text = NULL;
1500     int cursor;
1501
1502     if (ime_autofill_get_hint() == 0)
1503         return;
1504
1505     ime_get_surrounding_text(-1, -1, &text, &cursor);
1506     SECURE_LOGD("surrounding text : %s\n", text);
1507     if (!text) return;
1508
1509     ime_autofill_save_string(text);
1510
1511     free(text);
1512 }
1513
1514 void
1515 ise_focus_out(int ic)
1516 {
1517     KEYBOARD_STATE *keyboard_state = get_keyboard_state();
1518     if (keyboard_state) keyboard_state->focused_ic = 0;
1519     _reset_multitap_state(true);
1520
1521     save_autofill_data();
1522 }
1523
1524 bool ise_is_guideline_popup_enable_layout(void)
1525 {
1526     bool ret;
1527     switch (_context_layout)
1528     {
1529         case ISE_LAYOUT_STYLE_PHONENUMBER:
1530         case ISE_LAYOUT_STYLE_IP:
1531         case ISE_LAYOUT_STYLE_MONTH:
1532         case ISE_LAYOUT_STYLE_NUMBERONLY:
1533         case ISE_LAYOUT_STYLE_HEX:
1534         case ISE_LAYOUT_STYLE_TERMINAL:
1535         case ISE_LAYOUT_STYLE_DATETIME:
1536         case ISE_LAYOUT_STYLE_PASSWORD:
1537             ret = false;
1538             break;
1539         default:
1540             ret = true;
1541             break;
1542     }
1543     return ret;
1544 }
1545
1546 #if EXIT_ISE_ON_HIDE
1547 static Eina_Bool exit_timer_cb(void *data)
1548 {
1549     if (exit_timer) ecore_timer_del(exit_timer);
1550     exit_timer = NULL;
1551     elm_exit();
1552     return ECORE_CALLBACK_CANCEL;
1553 }
1554 #endif
1555
1556 void
1557 ise_show(int ic)
1558 {
1559     CONFIG_VALUES *config_values = get_config_values();
1560 #if EXIT_ISE_ON_HIDE
1561     if (exit_timer) ecore_timer_del(exit_timer);
1562     exit_timer = NULL;
1563 #endif
1564     sclboolean reset_inputmode = FALSE;
1565     g_input_panel_show = true;
1566
1567     CSCLUI *ui = get_ui();
1568     KEYBOARD_STATE *keyboard_state = get_keyboard_state();
1569     if (ui && keyboard_state) {
1570         read_ise_config_values();
1571
1572         if (config_values) {
1573             _language_manager.set_enabled_languages(config_values->enabled_languages);
1574         }
1575         const sclchar *cur_lang = _language_manager.get_current_language();
1576
1577 #ifdef _WEARABLE
1578         ise_check_wearable_candidate();
1579         /*
1580          *Clear the personalized data
1581          */
1582         if (config_values && config_values->dataclear) {
1583             ime_send_key_event(IME_KEY_Clear, IME_KEY_MASK_CONTROL, false);
1584             config_values->dataclear = FALSE;
1585         }
1586 #endif
1587         LOGD("ic : %x , %x , g_ic : %x , %x, g_focused_ic : %x , %x\n", ic, check_ic_temporary(ic),
1588                 keyboard_state->ic, check_ic_temporary(keyboard_state->ic),
1589                 keyboard_state->focused_ic, check_ic_temporary(keyboard_state->focused_ic));
1590
1591         if (check_ic_temporary(ic) && !check_ic_temporary(keyboard_state->focused_ic)) {
1592             ic = keyboard_state->focused_ic;
1593         }
1594
1595         if (!check_ic_temporary(ic) && check_ic_temporary(keyboard_state->focused_ic)) {
1596             keyboard_state->focused_ic = ic;
1597         }
1598
1599         if (ic == keyboard_state->focused_ic) {
1600             switch (keyboard_state->layout)
1601             {
1602                 case ISE_LAYOUT_STYLE_PHONENUMBER:
1603                 case ISE_LAYOUT_STYLE_IP:
1604                 case ISE_LAYOUT_STYLE_MONTH:
1605                 case ISE_LAYOUT_STYLE_NUMBERONLY:
1606                     ime_set_imengine(DEFAULT_KEYBOARD_ISE_UUID);
1607                     break;
1608                 default:
1609                     break;
1610             }
1611         }
1612
1613         const char *input_mode = ui->get_input_mode();
1614
1615         /* Reset input mode if the input context value has changed */
1616         if (ic != keyboard_state->ic) {
1617             /* Do not reset input mode if STT's setting window was opened */
1618             if (get_setting_window_open_status() && input_mode && strcmp(input_mode, "STT_3X4") == 0) {
1619                 LOGD("Setting window was opened while using STT, skip resetting input mode");
1620             } else {
1621                 reset_inputmode = TRUE;
1622             }
1623         }
1624
1625         keyboard_state->ic = ic;
1626         /* Reset input mode if the current language is not the selected language */
1627         if (cur_lang) {
1628             if (config_values && config_values->selected_language.compare(cur_lang) != 0) {
1629                 reset_inputmode = TRUE;
1630             }
1631         }
1632
1633         /* No matter what, just reset the inputmode if it needs to */
1634         if (keyboard_state->need_reset) {
1635             /* Do not reset input mode if STT's setting window was opened */
1636             if (get_setting_window_open_status() && input_mode && strcmp(input_mode, "STT_3X4") == 0) {
1637                 LOGD("Setting window was opened while using STT, skip resetting input mode");
1638             } else {
1639                 reset_inputmode = TRUE;
1640             }
1641         }
1642         keyboard_state->need_reset = FALSE;
1643
1644         /* If the current layout requires latin language and current our language is not latin, enable the primary latin */
1645         sclboolean force_primary_latin = FALSE;
1646         LANGUAGE_INFO *info =
1647             (config_values ? _language_manager.get_language_info(config_values->selected_language.c_str()) : NULL);
1648         if (info) {
1649             if (!info->is_latin_language) {
1650                 if (!keyboard_state->disable_force_latin) {
1651                     if (g_ise_default_values[keyboard_state->layout].force_latin) {
1652                         force_primary_latin = TRUE;
1653                     }
1654                     else {
1655                         if (keyboard_state->prefer_latin) {
1656                             force_primary_latin = TRUE;
1657                         }
1658                     }
1659                 }
1660             }
1661         }
1662
1663         if (force_primary_latin) {
1664             /* If there is enabled latin-based language, select it */
1665             sclboolean selected = FALSE;
1666             for (scluint loop = 0;!selected && loop < _language_manager.get_languages_num();loop++) {
1667                 LANGUAGE_INFO *info = _language_manager.get_language_info(loop);
1668                 if (info) {
1669                     if (info->enabled && info->is_latin_language) {
1670                         selected = _language_manager.select_language(info->name.c_str());
1671                         if (selected) force_primary_latin = FALSE;
1672                     }
1673                 }
1674             }
1675             if (!selected) {
1676                 _language_manager.set_language_enabled_temporarily(PRIMARY_LATIN_LANGUAGE, TRUE);
1677             }
1678         }
1679
1680         if (reset_inputmode) {
1681             ise_reset_context();
1682
1683             bool filename_layout = false;
1684
1685             /* Turn the shift state off if we need to reset our input mode, only when auto-capitalization is not set  */
1686             if (!(keyboard_state->caps_mode)) {
1687                 ui->set_shift_state(SCL_SHIFT_STATE_OFF);
1688             }
1689             if (keyboard_state->layout < ISE_LAYOUT_STYLE_MAX) {
1690                 sclu32 layout_index = keyboard_state->layout;
1691                 if (keyboard_state->layout == ISE_LAYOUT_STYLE_NUMBERONLY &&
1692                     keyboard_state->layout_variation > 0 &&
1693                     keyboard_state->layout_variation < ISE_LAYOUT_NUMBERONLY_VARIATION_MAX) {
1694                     layout_index = ISE_LAYOUT_STYLE_NUMBERONLY_SIG + keyboard_state->layout_variation - 1;
1695                 } else if (keyboard_state->layout == ISE_LAYOUT_STYLE_PASSWORD && keyboard_state->layout_variation > 0) {
1696                     layout_index = ISE_LAYOUT_STYLE_PASSWD_3X4;
1697                 }
1698
1699                 if (keyboard_state->layout == ISE_LAYOUT_STYLE_NORMAL &&
1700                     keyboard_state->layout_variation == ECORE_IMF_INPUT_PANEL_LAYOUT_NORMAL_VARIATION_FILENAME)
1701                     filename_layout = true;
1702                 else
1703                     filename_layout = false;
1704
1705                 ui->enable_button("exclamation", !filename_layout);
1706                 ui->enable_button("question", !filename_layout);
1707                 ui->enable_button("divide", !filename_layout);
1708                 ui->enable_button("multiply", !filename_layout);
1709                 ui->enable_button("colon", !filename_layout);
1710                 ui->enable_button("quotation", !filename_layout);
1711
1712                 ui->enable_button("CM_KEY", !access("/home", X_OK));
1713
1714                 LOGD("new layout index : %d\n", layout_index);
1715                 /* If this layout requires specific input mode, set it */
1716                 if (strlen(g_ise_default_values[layout_index].input_mode) > 0) {
1717                     ui->set_input_mode(g_ise_default_values[layout_index].input_mode);
1718                     set_ime_size(g_floating_mode, ISE_CANDIDATE_REQ_NONE);
1719                 } else {
1720                     if (force_primary_latin) {
1721                         _language_manager.select_language(PRIMARY_LATIN_LANGUAGE, TRUE);
1722                     } else if (config_values) {
1723                         if (!(_language_manager.select_language(config_values->selected_language.c_str()))) {
1724                             _language_manager.select_language(PRIMARY_LATIN_LANGUAGE);
1725                         }
1726                     }
1727                 }
1728                 ui->set_cur_sublayout(g_ise_default_values[layout_index].sublayout_name);
1729                 if (ise_emoticon_is_show()) {
1730                     ise_emoticon_destroy_layout();
1731                 }
1732
1733                 if (keyboard_state->layout == ISE_LAYOUT_STYLE_EMOTICON) {
1734                     ise_emoticon_init_list();
1735 #ifdef _WEARABLE
1736                     ise_emoticon_set_current_group(EMOTICON_GROUP_1);
1737                     ise_set_emoticon_label(1);
1738 #else
1739                     if (ise_emoticon_get_recent_list_size() == 0)
1740                         ise_emoticon_set_current_group(EMOTICON_GROUP_1);
1741                     else
1742                         ise_emoticon_set_current_group(EMOTICON_GROUP_RECENTLY_USED);
1743 #endif
1744                     SCLRotation rotation = ui->get_rotation();
1745                     ise_emoticon_show_layout(ise_emoticon_get_current_group(), ROTATION_TO_DEGREE(rotation), false, ime_get_main_window());
1746                 }
1747
1748                 if (ise_sticker_is_show())
1749                     ise_sticker_destroy_layout();
1750
1751                 if (ise_nmt_is_show())
1752                     ise_nmt_destroy_layout();
1753             }
1754         }
1755
1756         if (info) {
1757             if (info->accepts_caps_mode) {
1758                 // FIXME this if condition means the AC is off
1759                 if (keyboard_state->layout != ISE_LAYOUT_STYLE_NORMAL) {
1760                     ui->set_autocapital_shift_state(TRUE);
1761                     ui->set_shift_state(SCL_SHIFT_STATE_OFF);
1762                 } else {
1763                     ise_send_event(MVK_Shift_Enable, KEY_MASK_NULL);
1764                     // Auto Capital is supported only in normal layout
1765                     if (keyboard_state->caps_mode) {
1766                         ui->set_autocapital_shift_state(FALSE);
1767                     }
1768                 }
1769             } else {
1770                 ui->set_autocapital_shift_state(TRUE);
1771                 ise_send_event(MVK_Shift_Disable, KEY_MASK_NULL);
1772                 ui->set_shift_state(SCL_SHIFT_STATE_OFF);
1773             }
1774         } else {
1775             ui->set_autocapital_shift_state(TRUE);
1776         }
1777
1778         // Update CM key button
1779         if (_current_cm_key_id < CM_KEY_LIST_SIZE) {
1780             if (strcmp(_cm_key_list[_current_cm_key_id], USER_KEYSTRING_EMOTICON) == 0) {
1781                 if (ise_is_emoticons_disabled())
1782                     ise_set_cm_private_key(ise_get_cm_key_id(USER_KEYSTRING_OPTION));
1783                 else
1784                     ise_set_cm_private_key(_current_cm_key_id);
1785             }
1786         }
1787
1788         // Update space key button
1789         ise_update_space_key();
1790
1791         ui->show();
1792         ui->disable_input_events(FALSE);
1793 #ifdef _IVI
1794         ui->enable_button("CM_KEY", false);
1795 #endif
1796
1797 #if defined(_MOBILE) || defined(_COMMON)
1798         if (ise_is_guideline_popup_enable_layout()) {
1799             if ((config_values && config_values->first_guidechange) && (_language_manager.get_enabled_languages_num() > 1)) {
1800                 ise_show_help_popup(MVK_space);
1801                 LOGD("space popup show\n");
1802             } else {
1803                 ise_destroy_popup_space();
1804             }
1805         }
1806 #endif
1807
1808         // Update IME size
1809         if (config_values && config_values->floating_mode != g_floating_mode)
1810             g_floating_mode = config_values->floating_mode;
1811
1812         Candidate *candidate = get_candidate();
1813         if (candidate && candidate->get_visible())
1814             set_ime_size(g_floating_mode, ISE_CANDIDATE_REQ_SHOW);
1815         else
1816             set_ime_size(g_floating_mode, ISE_CANDIDATE_REQ_NONE);
1817     }
1818
1819     keyboard_state->visible_state = TRUE;
1820
1821 #ifdef _WEARABLE
1822     int dot_num = 5;
1823     switch (_context_layout) {
1824         case ISE_LAYOUT_STYLE_PHONENUMBER:
1825         case ISE_LAYOUT_STYLE_IP:
1826         case ISE_LAYOUT_STYLE_MONTH:
1827         case ISE_LAYOUT_STYLE_NUMBERONLY:
1828         case ISE_LAYOUT_STYLE_DATETIME:
1829         case ISE_LAYOUT_STYLE_TERMINAL:
1830             dot_num = 0;
1831             break;
1832         case ISE_LAYOUT_STYLE_EMAIL:
1833         case ISE_LAYOUT_STYLE_URL:
1834             dot_num = 4;
1835             break;
1836         case ISE_LAYOUT_STYLE_PASSWORD:
1837             if (_context_layout == ISE_LAYOUT_STYLE_PASSWORD &&
1838                 _context_layout_variation == ECORE_IMF_INPUT_PANEL_LAYOUT_PASSWORD_VARIATION_NUMBERONLY)
1839                 dot_num = 0;
1840             else
1841                 dot_num = 3;
1842             break;
1843         default:
1844             dot_num = 5;
1845     }
1846
1847     if (dot_num > 0) {
1848         sclint width = 0;
1849         sclint height = 0;
1850         if (ui)
1851             ui->get_screen_resolution(&width, &height);
1852
1853         create_indicator_window(width, height);
1854         destroy_indicator_dots();
1855
1856         int focus_dot = 0;
1857         switch (keyboard_state->layout) {
1858             case ISE_LAYOUT_STYLE_NUMBER:
1859                 focus_dot = 1;
1860                 break;
1861             case ISE_LAYOUT_STYLE_HEX:
1862                 focus_dot = 2;
1863                 break;
1864             case ISE_LAYOUT_STYLE_EMOTICON:
1865                 focus_dot = 3;
1866                 break;
1867             case ISE_LAYOUT_STYLE_VOICE:
1868                 if (_context_layout == ISE_LAYOUT_STYLE_EMAIL ||
1869                     _context_layout == ISE_LAYOUT_STYLE_URL)
1870                     focus_dot = 3;
1871                 else
1872                     focus_dot = 4;
1873                 break;
1874             default:
1875                 break;
1876         }
1877
1878         create_indicator_dots(dot_num, focus_dot);
1879         show_indicator_window();
1880     } else {
1881         hide_indicator_window();
1882     }
1883     if (keyboard_state->layout == ISE_LAYOUT_STYLE_NORMAL && config_values && config_values->number_tutorial_enable) {
1884         ise_show_tutorial_mode_popup(keyboard_state->layout);
1885         config_values->number_tutorial_enable = false;
1886         write_ise_config_values();
1887     }
1888 #endif
1889
1890     if (get_setting_window_open_status()) {
1891         ise_show_stt_mode(NATIVE_WINDOW_CAST(ime_get_main_window()));
1892     }
1893     set_setting_window_open_status(FALSE);
1894
1895     if (keyboard_state->layout == ISE_LAYOUT_STYLE_VOICE) {
1896         ise_show_stt_mode(NATIVE_WINDOW_CAST(ime_get_main_window()));
1897     }
1898 }
1899
1900 /**
1901  * Sets screen rotation
1902  */
1903 void
1904 ise_set_screen_rotation(int degree)
1905 {
1906     CSCLUI *ui = get_ui();
1907     if (ui) {
1908         ui->set_rotation(DEGREE_TO_SCLROTATION(degree));
1909     }
1910
1911     Candidate *candidate = get_candidate();
1912     if (candidate) {
1913         candidate->rotate(degree);
1914         if (candidate->get_visible()) {
1915             candidate->update(g_softcandidate_string);
1916         }
1917     }
1918 }
1919
1920 void
1921 ise_set_accessibility_state(bool state)
1922 {
1923     CSCLUI *ui = get_ui();
1924     if (ui) {
1925         ui->enable_tts(state);
1926     }
1927 }
1928
1929 void
1930 ise_hide()
1931 {
1932     KEYBOARD_STATE *keyboard_state = get_keyboard_state();
1933     CSCLUI *ui = get_ui();
1934     if (ui) {
1935         /* There's no need to update screen when hiding */
1936         ui->set_update_pending(TRUE);
1937         ui->disable_input_events(TRUE);
1938         ui->hide();
1939     }
1940     CONFIG_VALUES *config_values = get_config_values();
1941     if (config_values) {
1942         _language_manager.reset_language(config_values->selected_language.c_str());
1943     }
1944
1945     _click_count = 0;
1946     delete_commit_timer();
1947     ise_destroy_popup_space();
1948     ise_destroy_popup_setting();
1949
1950     if (keyboard_state) keyboard_state->visible_state = FALSE;
1951
1952     _reset_shift_state();
1953     _reset_multitap_state(true);
1954
1955     /* If we were in STT mode, try to reset input mode on our next show event */
1956     if (ui && keyboard_state) {
1957         const char *inputmode = ui->get_input_mode();
1958         if (inputmode && strcmp(inputmode, "STT_3X4") == 0 ) {
1959             keyboard_state->need_reset = TRUE;
1960             ise_hide_stt_mode();
1961         }
1962     }
1963
1964     g_input_panel_show = false;
1965     Candidate *candidate = get_candidate();
1966     if (candidate && candidate->get_visible())
1967         set_ime_size(g_floating_mode, ISE_CANDIDATE_REQ_SHOW);
1968 #ifdef _WEARABLE
1969     hide_indicator_window();
1970     if (check_is_tutorial_show()) {
1971         ise_destroy_tutorial_mode_popup();
1972     }
1973 #endif
1974 #if EXIT_ISE_ON_HIDE
1975     if (exit_timer) ecore_timer_del(exit_timer);
1976     exit_timer = ecore_timer_add(1.0, exit_timer_cb, NULL);
1977 #endif
1978 }
1979
1980 static void ise_keypad_mode_changed_cb(const char *key, void *user_data)
1981 {
1982     read_ise_keypad_mode();
1983 }
1984
1985 static void ise_enabled_languages_changed_cb(const char *key, void *user_data)
1986 {
1987     read_ise_enabled_languages();
1988 }
1989
1990 static void ise_selected_language_changed_cb(const char *key, void *user_data)
1991 {
1992     read_ise_selected_language();
1993 }
1994
1995 static void ise_autocapital_mode_changed_cb(const char *key, void *user_data)
1996 {
1997     read_ise_autocapital_mode();
1998 }
1999
2000 static void ise_autopunctuate_mode_changed_cb(const char *key, void *user_data)
2001 {
2002     read_ise_autopunctuation_mode();
2003 }
2004
2005 static void ise_sound_mode_changed_cb(const char *key, void *user_data)
2006 {
2007     read_ise_sound_mode();
2008
2009     CONFIG_VALUES *config_values = get_config_values();
2010     CSCLUI *ui = get_ui();
2011     if (config_values && ui) {
2012         ui->enable_sound(config_values->sound_on);
2013     }
2014 }
2015
2016 static void ise_vibration_mode_changed_cb(const char *key, void *user_data)
2017 {
2018     read_ise_vibration_mode();
2019
2020     CONFIG_VALUES *config_values = get_config_values();
2021     CSCLUI *ui = get_ui();
2022     if (config_values && ui) {
2023         ui->enable_vibration(config_values->vibration_on);
2024     }
2025 }
2026
2027 static void ise_character_preview_mode_changed_cb(const char *key, void *user_data)
2028 {
2029     read_ise_character_preview_mode();
2030
2031     CONFIG_VALUES *config_values = get_config_values();
2032     CSCLUI *ui = get_ui();
2033     if (config_values && ui) {
2034         ui->enable_magnifier(config_values->preview_on);
2035     }
2036 }
2037
2038 static void ise_setting_guide_popup_changed_cb(const char *key, void *user_data)
2039 {
2040     read_ise_setting_guide_popup_mode();
2041 }
2042
2043 static void ise_language_guide_popup_changed_cb(const char *key, void *user_data)
2044 {
2045     read_ise_language_guide_popup_mode();
2046 }
2047
2048 static void ise_floating_mode_changed_cb(const char *key, void *user_data)
2049 {
2050     read_ise_floating_mode();
2051     CONFIG_VALUES *config_values = get_config_values();
2052     if (config_values) {
2053         g_floating_mode = config_values->floating_mode;
2054     }
2055
2056     ime_set_floating_mode(g_floating_mode);
2057     if (g_candidate && g_floating_mode != g_candidate->get_floating_mode()) {
2058         delete_softcandidate_hide_timer();
2059         delete g_candidate;
2060         g_candidate = NULL;
2061
2062         create_softcandidate();
2063         if (g_candidate && g_candidate->get_visible()) {
2064             g_candidate->show();
2065             set_ime_size(g_floating_mode, ISE_CANDIDATE_REQ_SHOW);
2066             return;
2067         }
2068     }
2069     set_ime_size(g_floating_mode, ISE_CANDIDATE_REQ_NONE);
2070 }
2071
2072 static void register_preference_changed_callback(void)
2073 {
2074     if (preference_set_changed_cb(ISE_CONFIG_KEYPAD_MODE, ise_keypad_mode_changed_cb, NULL) != PREFERENCE_ERROR_NONE)
2075         LOGW("Failed to set ise_keypad_mode_changed_cb()");
2076
2077     if (preference_set_changed_cb(ISE_CONFIG_ENABLED_LANGUAGES, ise_enabled_languages_changed_cb, NULL) != PREFERENCE_ERROR_NONE)
2078         LOGW("Failed to set ise_enabled_languages_changed_cb()");
2079
2080     if (preference_set_changed_cb(ISE_CONFIG_SELECTED_LANGUAGE, ise_selected_language_changed_cb, NULL) != PREFERENCE_ERROR_NONE)
2081         LOGW("Failed to set ise_selected_language_changed_cb()");
2082
2083     if (preference_set_changed_cb(ISE_CONFIG_AUTO_CAPITALISE, ise_autocapital_mode_changed_cb, NULL) != PREFERENCE_ERROR_NONE)
2084         LOGW("Failed to set ise_autocapital_mode_changed_cb()");
2085
2086     if (preference_set_changed_cb(ISE_CONFIG_AUTO_PUNCTUATE, ise_autopunctuate_mode_changed_cb, NULL) != PREFERENCE_ERROR_NONE)
2087         LOGW("Failed to set ise_autopunctuate_mode_changed_cb()");
2088
2089     if (preference_set_changed_cb(ISE_CONFIG_SOUND_ON, ise_sound_mode_changed_cb, NULL) != PREFERENCE_ERROR_NONE)
2090         LOGW("Failed to set ise_sound_mode_changed_cb()");
2091
2092     if (preference_set_changed_cb(ISE_CONFIG_VIBRATION_ON, ise_vibration_mode_changed_cb, NULL) != PREFERENCE_ERROR_NONE)
2093         LOGW("Failed to set ise_vibration_mode_changed_cb()");
2094
2095     if (preference_set_changed_cb(ISE_CONFIG_PREVIEW_ON, ise_character_preview_mode_changed_cb, NULL) != PREFERENCE_ERROR_NONE)
2096         LOGW("Failed to set ise_character_preview_mode_changed_cb()");
2097
2098     if (preference_set_changed_cb(ISE_CONFIG_FIRST_GUIDELINE_POPUP_FOR_SETTING, ise_setting_guide_popup_changed_cb, NULL) != PREFERENCE_ERROR_NONE)
2099         LOGW("Failed to set ise_setting_guide_popup_changed_cb()");
2100
2101     if (preference_set_changed_cb(ISE_CONFIG_FIRST_GUIDELINE_POPUP_FOR_LANGUAGE_CHANGE, ise_language_guide_popup_changed_cb, NULL) != PREFERENCE_ERROR_NONE)
2102         LOGW("Failed to set ise_language_guide_popup_changed_cb()");
2103
2104     if (preference_set_changed_cb(ISE_CONFIG_FLOATING_MODE, ise_floating_mode_changed_cb, NULL) != PREFERENCE_ERROR_NONE)
2105         LOGW("Failed to set ise_floating_mode_changed_cb()");
2106 }
2107
2108 static void ise_mount_changed_cb(void *user_data)
2109 {
2110     register_preference_changed_callback();
2111 }
2112
2113 void
2114 ise_create()
2115 {
2116     LOGD("");
2117
2118     CONFIG_VALUES *config_values = get_config_values();
2119
2120     if (!g_ui) {
2121         g_ui = new CSCLUI;
2122     }
2123
2124     bindtextdomain(PACKAGE, LOCALEDIR);
2125     textdomain(PACKAGE);
2126
2127     /* Set scl_parser_type
2128      * default type is text xml
2129      * use command: export sclres_type="sclres_binary" to enable use binary resource
2130      * please make sure there is sclresource.bin in resource folder
2131      * Or you can use `xml2binary $resource_dir` to generate the sclresource.bin
2132      * xml2binary is in the libscl-ui-devel package
2133      */
2134     SCLParserType scl_parser_type = SCL_PARSER_TYPE_XML;
2135     char* sclres_type = getenv("sclres_type");
2136     if (sclres_type != NULL && 0 == strcmp("sclres_binary", sclres_type)) {
2137         scl_parser_type = SCL_PARSER_TYPE_BINARY_XML;
2138     } else {
2139         scl_parser_type = SCL_PARSER_TYPE_XML;
2140     }
2141
2142     if (g_ui) {
2143         if (ime_get_main_window()) {
2144             g_ise_created = true;
2145
2146             sclboolean succeeded = FALSE;
2147
2148             const sclchar *entry_path = MAIN_ENTRY_XML_PATH;
2149             int nwidth  = 0;
2150             int nheight = 0;
2151             CSCLUtils *utils = CSCLUtils::get_instance();
2152             if (utils) {
2153                 utils->get_screen_resolution(&nwidth, &nheight);
2154             }
2155             _language_manager.set_resource_file_path(entry_path);
2156             const sclchar *resource_file_path = _language_manager.get_resource_file_path();
2157
2158             if (resource_file_path) {
2159                 if (strlen(resource_file_path) > 0) {
2160                     succeeded = g_ui->init(ime_get_main_window(), scl_parser_type, resource_file_path);
2161                 }
2162             }
2163             if (!succeeded) {
2164                 g_ui->init(ime_get_main_window(), scl_parser_type, MAIN_ENTRY_XML_PATH);
2165             }
2166
2167             g_ui->set_longkey_duration(elm_config_longpress_timeout_get() * 1000);
2168
2169             /* Default ISE callback */
2170             g_ui->set_ui_event_callback(&callback);
2171
2172             /* Accumulated customized ISE callbacks, depending on the input modes */
2173             for (scluint loop = 0;loop < _language_manager.get_languages_num();loop++) {
2174                 LANGUAGE_INFO *language = _language_manager.get_language_info(loop);
2175                 if (language) {
2176                     for (scluint inner_loop = 0;inner_loop < language->input_modes.size();inner_loop++) {
2177                         INPUT_MODE_INFO &info = language->input_modes.at(inner_loop);
2178                         LOGD("Registering callback for input mode %s : %p\n", info.name.c_str(), language->callback);
2179                         g_ui->set_ui_event_callback(language->callback, info.name.c_str());
2180                     }
2181                 }
2182             }
2183
2184             read_ise_config_values();
2185             if (access(ISE_CONFIG_FILE_PATH, F_OK) == 0 && !config_values->init_flag)
2186                 read_ise_config_file();
2187
2188             if (config_values) {
2189                 _language_manager.set_enabled_languages(config_values->enabled_languages);
2190                 _language_manager.select_language(config_values->selected_language.c_str());
2191                 vconf_set_bool(VCONFKEY_AUTOCAPITAL_ALLOW_BOOL, config_values->auto_capitalise);
2192                 vconf_set_bool(VCONFKEY_AUTOPERIOD_ALLOW_BOOL, config_values->auto_punctuate);
2193                 g_ui->enable_sound(config_values->sound_on);
2194                 g_ui->enable_vibration(config_values->vibration_on);
2195                 g_ui->enable_magnifier(config_values->preview_on);
2196                 g_floating_mode = config_values->floating_mode;
2197             }
2198 #ifdef _TV
2199             g_ui->enable_highlight_ui(TRUE);
2200 #endif
2201             ime_set_floating_mode(g_floating_mode);
2202         }
2203
2204         set_ime_size(g_floating_mode, ISE_CANDIDATE_REQ_NONE);
2205
2206         bool exist = false;
2207
2208         preference_is_existing(ISE_CONFIG_KEYPAD_MODE, &exist);
2209         if (!exist)
2210             write_ise_config_values();
2211
2212         int state;
2213         if (ode_internal_encryption_get_state(&state) == ODE_ERROR_NONE) {
2214             if (state == ODE_STATE_ENCRYPTED) {
2215                 if (ode_internal_encryption_set_mount_event_cb(ise_mount_changed_cb, NULL) != ODE_ERROR_NONE)
2216                     LOGW("Failed to set mount_event_cb()");
2217             } else if (state == ODE_STATE_UNENCRYPTED) {
2218                 register_preference_changed_callback();
2219             }
2220         } else {
2221             LOGW("Failed to get encryption_state");
2222         }
2223     }
2224     init_recent_used_punctuation();
2225 }
2226
2227 void
2228 ise_destroy()
2229 {
2230     ise_hide_stt_mode();
2231
2232     CSCLUI *ui = get_ui();
2233     if (ui) {
2234         LOGD("calling ui->fini()\n");
2235         ui->fini();
2236         LOGD("deleting ui\n");
2237         delete ui;
2238         ui = NULL;
2239     }
2240
2241     if (g_candidate) {
2242         delete g_candidate;
2243         g_candidate = NULL;
2244     }
2245
2246 #ifdef _WEARABLE
2247     destroy_indicator_window();
2248 #endif
2249
2250     /* This is necessary. If this is not called, 3rd party IME might have auto period input regardless its settings */
2251     vconf_set_bool(VCONFKEY_AUTOPERIOD_ALLOW_BOOL, false);
2252
2253 #if EXIT_ISE_ON_HIDE
2254     if (exit_timer) ecore_timer_del(exit_timer);
2255     exit_timer = NULL;
2256 #endif
2257 }
2258
2259 void
2260 ise_app_candidate_show()
2261 {
2262 #ifdef _WEARABLE
2263     if (!g_candidate)
2264         return;
2265
2266     if (!g_candidate->get_visible())
2267         return;
2268 #endif
2269     LOGD("Enter\n");
2270     delete_softcandidate_hide_timer();
2271
2272     create_softcandidate();
2273
2274     Candidate *candidate = get_candidate();
2275     if (candidate) {
2276         candidate->show();
2277         set_ime_size(g_floating_mode, ISE_CANDIDATE_REQ_SHOW);
2278     }
2279 }
2280
2281 void
2282 ise_app_candidate_hide()
2283 {
2284     LOGD("Enter\n");
2285
2286     Candidate *candidate = get_candidate();
2287     if (!candidate || !candidate->get_visible()) {
2288         LOGD("No candidate\n");
2289         return;
2290     }
2291
2292     if (g_ic_smartreply != -1 || ime_autofill_get_exist())
2293         return;
2294
2295     add_softcandidate_hide_timer();
2296 }
2297
2298 #ifdef _WEARABLE
2299 void ise_check_wearable_candidate()
2300 {
2301     CONFIG_VALUES *config_values = get_config_values();
2302     if (!config_values) return;
2303
2304     KEYBOARD_STATE *keyboard_state = get_keyboard_state();
2305     if (!keyboard_state) return;
2306
2307     if (!config_values->prediction_on) {
2308         ise_app_candidate_hide();
2309     } else if (keyboard_state->layout == ISE_LAYOUT_STYLE_PHONENUMBER ||
2310                   keyboard_state->layout == ISE_LAYOUT_STYLE_VOICE ||
2311                   keyboard_state->layout == ISE_LAYOUT_STYLE_IP ||
2312                   keyboard_state->layout == ISE_LAYOUT_STYLE_MONTH ||
2313                   keyboard_state->layout == ISE_LAYOUT_STYLE_NUMBERONLY ||
2314                   keyboard_state->layout == ISE_LAYOUT_STYLE_PASSWD_3X4||
2315                   keyboard_state->layout == ISE_LAYOUT_STYLE_PASSWORD) {
2316         ise_app_candidate_hide();
2317     } else {
2318         ise_app_candidate_show();
2319     }
2320 }
2321
2322 void ise_set_emoticon_label(int group_id)
2323 {
2324     const int BUF_LEN = 16;
2325     char buf[BUF_LEN] = {0};
2326     snprintf(buf, BUF_LEN, "%d/3", group_id);
2327     CSCLUI *ui = get_ui();
2328     if (ui) ui->set_private_key("EMOTICON_GROUP_ID", buf, NULL, NULL, 0, const_cast<sclchar*>("EMOTICON_GROUP_NEXT"), TRUE);
2329 }
2330 #endif
2331
2332 // when it is the time to auto_cap, the
2333 // ise_set_caps_mode is called.
2334 // -------------------------------------------------------
2335 // For example: [How are you. Fine.], the
2336 // auto-capital process is as below:
2337 // Note: "["<--this is the beginning,
2338 // "|"<--this is the cursor position
2339 // 1) call ise_set_caps_mode, auto_cap = on
2340 //    input: "H",
2341 //    result: [H|
2342 // 2) call ise_set_caps_mode, auto_cap = off
2343 //    input: "o"
2344 //    result: [Ho|
2345 // 3) input: "w are you. "
2346 //    result: [How are you. |
2347 // 4) call ise_set_caps_mode, auto_cap = on
2348 //    input: "F"
2349 //    result: [How are you. F
2350 // 5) input: "ine."
2351 //    result: [How are you. Fine.|
2352 // --------------------------------------------------------
2353 // If we want to change the auto_cap, eg,
2354 // if we want to input [How Are you.]
2355 // Note the "Are" is not use auto-capital rule.
2356 // we should use:
2357 //    ise_send_event(MVK_Shift_On, SclCoreKeyMask_Null);
2358 // when we are want to input "A"
2359 // following input still has the auto_cap rule.
2360 void
2361 ise_set_caps_mode(unsigned int mode)
2362 {
2363     KEYBOARD_STATE *keyboard_state = get_keyboard_state();
2364     if (!keyboard_state) return;
2365
2366     LOGD("caps_mode : %d\n", mode);
2367     if (mode) {
2368         keyboard_state->caps_mode = TRUE;
2369     } else {
2370         keyboard_state->caps_mode = FALSE;
2371     }
2372     g_caps_mode_pending = false;
2373     const sclchar *cur_lang = _language_manager.get_current_language();
2374     if (cur_lang) {
2375         LANGUAGE_INFO *info = _language_manager.get_language_info(cur_lang);
2376         if (info) {
2377             if (info->accepts_caps_mode) {
2378                 /* If we are inputting multitap character, do not manipulate shift mode */
2379                 if (keyboard_state->prev_modifier != KEY_MODIFIER_MULTITAP_START &&
2380                     keyboard_state->prev_modifier != KEY_MODIFIER_MULTITAP_REPEAT) {
2381                     set_caps_mode(keyboard_state->caps_mode);
2382                 } else {
2383                     g_caps_mode_pending = true;
2384                     LOGD("Currently composing multitap string, skipping caps request");
2385                 }
2386             }
2387         }
2388     }
2389 }
2390
2391 void
2392 ise_update_cursor_position(int position)
2393 {
2394     KEYBOARD_STATE *keyboard_state = get_keyboard_state();
2395     if (!keyboard_state) return;
2396
2397     LOGD("cursor position : %d\n", position);
2398     CSCLUI *ui = get_ui();
2399     if (ui && keyboard_state->layout == ISE_LAYOUT_STYLE_URL) {
2400 #ifndef _TV
2401         if (position > 0) {
2402             ui->set_string_substitution("www.", ".com");
2403         } else {
2404             ui->unset_string_substitution("www.");
2405         }
2406 #endif
2407     }
2408 }
2409
2410 void ise_set_return_key_type(unsigned int type)
2411 {
2412     const int BUF_LEN = 256;
2413     char buf[BUF_LEN] = {0};
2414
2415     CSCLUI *ui = get_ui();
2416     if (!ui) return;
2417
2418     LOGD("return key type : %d\n", type);
2419     switch (type)
2420     {
2421     case ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_DONE:
2422         snprintf(buf, BUF_LEN, ISE_RETURN_KEY_LABEL_DONE);
2423         break;
2424     case ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_GO:
2425         snprintf(buf, BUF_LEN, ISE_RETURN_KEY_LABEL_GO);
2426         break;
2427     case ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_JOIN:
2428         snprintf(buf, BUF_LEN, ISE_RETURN_KEY_LABEL_JOIN);
2429         break;
2430     case ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_LOGIN:
2431         snprintf(buf, BUF_LEN, ISE_RETURN_KEY_LABEL_LOGIN);
2432         break;
2433     case ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_NEXT:
2434         snprintf(buf, BUF_LEN, ISE_RETURN_KEY_LABEL_NEXT);
2435         break;
2436     case ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_SEARCH:
2437         snprintf(buf, BUF_LEN, ISE_RETURN_KEY_LABEL_SEARCH);
2438         break;
2439     case ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_SEND:
2440         snprintf(buf, BUF_LEN, ISE_RETURN_KEY_LABEL_SEND);
2441         break;
2442     case ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_SIGNIN:
2443         snprintf(buf, BUF_LEN, ISE_RETURN_KEY_LABEL_SIGNIN);
2444         break;
2445     case ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_DEFAULT:
2446         break;
2447     default:
2448         LOGW("Unknown return key type : %d\n", type);
2449         type = ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_DEFAULT;
2450         break;
2451     }
2452
2453     if (type == ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_DEFAULT) {
2454         ui->unset_private_key("Enter");
2455 #ifdef _TV
2456         ui->unset_private_key("Done");
2457 #endif
2458     } else {
2459 #ifdef _WEARABLE
2460         if (type == ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_SEARCH) {
2461             sclchar* imagelabel[SCL_BUTTON_STATE_MAX] = {
2462                 const_cast<sclchar*>("w_sip_3x4_btn_ic_search.png"),
2463                 const_cast<sclchar*>("w_sip_3x4_btn_ic_search_p.png"),
2464                 const_cast<sclchar*>("w_sip_3x4_btn_ic_search_d.png")};
2465             ui->set_private_key("Enter", const_cast<sclchar*>(""), imagelabel, NULL, 0, const_cast<sclchar*>("Enter"), TRUE);
2466             return;
2467         }
2468 #endif
2469
2470 #ifdef _TV
2471         ui->set_private_key("Done", buf, NULL, NULL, 0, const_cast<sclchar*>("Done"), TRUE);
2472 #else
2473         static sclchar *imagelabel[SCL_BUTTON_STATE_MAX] = {
2474             const_cast<sclchar*>(" "), const_cast<sclchar*>(" "), const_cast<sclchar*>(" ")
2475         };
2476
2477         ui->set_private_key("Enter", buf, imagelabel, NULL, 0, const_cast<sclchar*>("Enter"), TRUE);
2478 #endif
2479         LOGD("return key label : %s\n", buf);
2480     }
2481 }
2482
2483 void ise_set_return_key_disable(unsigned int disabled)
2484 {
2485     CSCLUI *ui = get_ui();
2486     LOGD("enable : %d\n", !disabled);
2487 #ifdef _TV
2488     if (ui)
2489         ui->enable_button("Done", !disabled);
2490 #else
2491     if (ui)
2492         ui->enable_button("Enter", !disabled);
2493 #endif
2494 }
2495
2496 void ise_get_language_locale(char **locale)
2497 {
2498     LANGUAGE_INFO *info = _language_manager.get_current_language_info();
2499     if (info) {
2500         if (!(info->locale_string.empty())) {
2501             *locale = strdup(info->locale_string.c_str());
2502         }
2503     }
2504 }
2505
2506 void ise_update_table(const vector<string> &vec_str)
2507 {
2508     Candidate *candidate = get_candidate();
2509     if (!candidate || !candidate->get_visible()) {
2510         create_softcandidate();
2511     }
2512
2513     candidate = get_candidate();
2514     if (candidate) {
2515         candidate->update(vec_str);
2516     }
2517 }
2518
2519 void ise_process_key_event(scim::KeyEvent& key, sclu32 &ret)
2520 {
2521     Eina_Bool back_key_pressed = EINA_FALSE;
2522     Eina_Bool back_key_released = EINA_FALSE;
2523
2524     if (key.get_key_string().compare("XF86Back") == 0) {
2525         back_key_pressed = EINA_TRUE;
2526     } else if (key.get_key_string().compare("KeyRelease+XF86Back") == 0) {
2527         back_key_released = EINA_TRUE;
2528     }
2529
2530     if (back_key_pressed || back_key_released) {
2531         if (g_popup_opened == TRUE) {
2532             if (back_key_released) {
2533                 CSCLUI *ui = get_ui();
2534                 if (ui) ui->close_all_popups();
2535             }
2536             ret = 1;
2537             return;
2538         }
2539     }
2540
2541     ret = 0;
2542     CSCLUI *ui = get_ui();
2543 #ifdef _TV
2544     Candidate *candidate = get_candidate();
2545     if (candidate) {
2546         if (!candidate->soft_candidate_flag()) {
2547             if (ui) {
2548                 if (key.dev_name.compare("ime") != 0) {
2549                     ret = (sclu32)ui->process_key_event(key.get_key_string().c_str());
2550                 }
2551             }
2552         }
2553         if (!ret) {
2554             ret = candidate->soft_candidate_handle_key_event(key.get_key_string().c_str());
2555         }
2556     } else {
2557         if (ui) {
2558             /* Process this key event if it was not generated by ime */
2559             if (key.dev_name.compare("ime") != 0) {
2560                 ret = (sclu32)ui->process_key_event(key.get_key_string().c_str());
2561             }
2562         }
2563     }
2564 #else
2565     if (ui) {
2566         /* Process this key event if it was not generated by ime */
2567         if (key.dev_name.compare("ime") != 0) {
2568             ret = (sclu32)ui->process_key_event(key.get_key_string().c_str());
2569         }
2570     }
2571 #endif
2572 }
2573
2574 static void init_recent_used_punctuation()
2575 {
2576     if (g_recent_used_punctuation.empty())
2577     {
2578         g_recent_used_punctuation.push_back("#");
2579         g_recent_used_punctuation.push_back("$");
2580         g_recent_used_punctuation.push_back("%");
2581         g_recent_used_punctuation.push_back("^");
2582         g_recent_used_punctuation.push_back("&");
2583     }
2584 }
2585
2586 static void update_recent_used_punctuation(const char * key_value)
2587 {
2588     if (NULL == key_value)
2589     {
2590         return;
2591     }
2592     for (int i = 0; i < 10; ++i)
2593     {
2594         char buf[5] = {0};
2595         snprintf(buf, sizeof(buf), "%d", i);
2596         if (strcmp(key_value, buf) == 0)
2597         {
2598             return;
2599         }
2600     }
2601     string strKey = string(key_value);
2602     for (int i = 0; i < MAX_DEFAULT_PUNCTUATION; ++i)
2603     {
2604         if (0 == strKey.compare(g_default_punctuation[i].c_str()))
2605         {
2606             return;
2607         }
2608     }
2609     vector<string>::iterator iter = g_recent_used_punctuation.begin();
2610     for (; iter != g_recent_used_punctuation.end(); ++iter)
2611     {
2612         if (0 == strKey.compare(iter->c_str()))
2613         {
2614             break;
2615         }
2616     }
2617     if (iter != g_recent_used_punctuation.end())
2618     {
2619         g_recent_used_punctuation.erase(iter);
2620     }
2621     g_recent_used_punctuation.push_back(strKey);
2622     if (g_recent_used_punctuation.size() > MAX_DEFAULT_PUNCTUATION-1)
2623     {
2624         g_recent_used_punctuation.erase(g_recent_used_punctuation.begin());
2625     }
2626 }
2627
2628 static void set_ime_size(bool floating_mode, ISE_CANDIDATE_REQUEST candidate_req)
2629 {
2630     CSCLUI *ui = get_ui();
2631     if (!ui)
2632         return;
2633
2634     Candidate *candidate = get_candidate();
2635
2636     const char *input_mode = ui->get_input_mode();
2637     if (!input_mode)
2638         return;
2639
2640     SclSize size_portrait = ui->get_input_mode_size(input_mode, DISPLAYMODE_PORTRAIT);
2641     SclSize size_landscape = ui->get_input_mode_size(input_mode, DISPLAYMODE_LANDSCAPE);
2642
2643     if (floating_mode) {
2644         size_portrait.width *= FLOATING_SCALE_RATE;
2645         size_portrait.height *= FLOATING_SCALE_RATE;
2646         size_landscape.width *= FLOATING_SCALE_RATE;
2647         size_landscape.height *= FLOATING_SCALE_RATE;
2648         switch (candidate_req) {
2649             case ISE_CANDIDATE_REQ_NONE:
2650                 if (candidate && candidate->get_visible()) {
2651                     ui->set_custom_starting_coordinates(0, FLOATING_TITLE_BAR_HEIGHT + candidate->get_height());
2652                     size_portrait.height += candidate->get_height();
2653                     size_landscape.height += candidate->get_height();
2654                 } else {
2655                     ui->set_custom_starting_coordinates(0, FLOATING_TITLE_BAR_HEIGHT);
2656                 }
2657                 break;
2658             case ISE_CANDIDATE_REQ_SHOW:
2659                 if (candidate) {
2660                     ui->set_custom_starting_coordinates(0, FLOATING_TITLE_BAR_HEIGHT + candidate->get_height());
2661                     if (g_input_panel_show || g_candidate_more_view) {
2662                         size_portrait.height += candidate->get_height();
2663                         size_landscape.height += candidate->get_height();
2664                     } else {
2665                         size_portrait.height = candidate->get_height();
2666                         size_landscape.height = candidate->get_height();
2667                     }
2668                 }
2669                 break;
2670             case ISE_CANDIDATE_REQ_HIDE:
2671                 ui->set_custom_starting_coordinates(0, FLOATING_TITLE_BAR_HEIGHT);
2672                 break;
2673             default: break;
2674         }
2675
2676         if (ui->get_custom_scale_rate_x() != FLOATING_SCALE_RATE || ui->get_custom_scale_rate_y() != FLOATING_SCALE_RATE)
2677             ui->set_custom_scale_rate(FLOATING_SCALE_RATE, FLOATING_SCALE_RATE);
2678
2679         ime_set_size(size_portrait.width, size_portrait.height + FLOATING_TITLE_BAR_HEIGHT,
2680             size_landscape.width, size_landscape.height + FLOATING_TITLE_BAR_HEIGHT);
2681
2682 #if defined(_MOBILE) || defined(_COMMON)
2683         ise_destroy_move_handler();
2684         int rotation = elm_win_rotation_get(NATIVE_WINDOW_CAST(ime_get_main_window()));
2685         int handler_width = (rotation == 0 || rotation == 180) ? size_portrait.width : size_landscape.width;
2686         ise_show_move_handler(handler_width, FLOATING_TITLE_BAR_HEIGHT);
2687 #endif
2688     } else {
2689         switch (candidate_req) {
2690             case ISE_CANDIDATE_REQ_NONE:
2691                 if (candidate && candidate->get_visible()) {
2692                     ui->set_custom_starting_coordinates(0, candidate->get_height());
2693                     size_portrait.height += candidate->get_height();
2694                     size_landscape.height += candidate->get_height();
2695                 } else {
2696                     ui->set_custom_starting_coordinates(0, 0);
2697                 }
2698                 break;
2699             case ISE_CANDIDATE_REQ_SHOW:
2700                 if (candidate) {
2701                     ui->set_custom_starting_coordinates(0, candidate->get_height());
2702                     if (g_input_panel_show || g_candidate_more_view) {
2703                         size_portrait.height += candidate->get_height();
2704                         size_landscape.height += candidate->get_height();
2705                     } else {
2706                         size_portrait.height = candidate->get_height();
2707                         size_landscape.height = candidate->get_height();
2708                     }
2709                 }
2710                 break;
2711             case ISE_CANDIDATE_REQ_HIDE:
2712                 ui->set_custom_starting_coordinates(0, 0);
2713                 break;
2714             default: break;
2715         }
2716
2717         if (ui->get_custom_scale_rate_x() != 1.0 || ui->get_custom_scale_rate_y() != 1.0)
2718             ui->set_custom_scale_rate(1.0, 1.0);
2719
2720         ime_set_size(size_portrait.width, size_portrait.height, size_landscape.width, size_landscape.height);
2721
2722 #if defined(_MOBILE) || defined(_COMMON)
2723         ise_destroy_move_handler();
2724 #endif
2725     }
2726 }
2727
2728 static void ime_app_create_cb(void *user_data)
2729 {
2730     if (!engine_loader_dbus_init(NULL))
2731         LOGE("Failed to initialize dbus");
2732
2733 #if !(DEFER_ISE_CREATION)
2734     ise_create();
2735 #endif
2736     elm_app_name_set(PACKAGE);
2737
2738     char *elm_scale = getenv("ELM_SCALE");
2739     LOGD("ELM_SCALE : %s", elm_scale);
2740
2741     if (elm_scale)
2742         elm_app_base_scale_set(atof(elm_scale));
2743
2744     clipboard_init();
2745
2746     nmt_init();
2747 }
2748
2749 static void ime_app_exit_cb(void *user_data)
2750 {
2751     ise_hide();
2752     ise_destroy();
2753
2754     if (!engine_loader_dbus_shutdown())
2755         LOGE("Failed to finalize dbus");
2756
2757     clipboard_shutdown();
2758
2759     nmt_shutdown();
2760 }
2761
2762 static void show_autofill_data()
2763 {
2764     ime_autofill_set_exist(false);
2765     string autofill_string = ime_autofill_get_string();
2766
2767     SECURE_LOGD("autofill string : %s", autofill_string.c_str());
2768
2769     if (!autofill_string.empty()) {
2770         ime_autofill_set_exist(true);
2771
2772         ise_app_candidate_show();
2773         update_candidate_table();
2774     }
2775 }
2776
2777 static void ime_app_show_cb(int ic, ime_context_h ime_ctx, void *user_data)
2778 {
2779     Ise_Context iseContext;
2780     bool return_key_state, prediction_allow, password_mode, caps_mode;
2781     ime_layout_variation_e layout_variation;
2782
2783     if (!g_ise_created)
2784         ise_create();
2785
2786     ime_context_get_layout(ime_ctx, &iseContext.layout);
2787
2788     ime_context_get_layout_variation(ime_ctx, &layout_variation);
2789     iseContext.layout_variation =  (int)layout_variation;
2790
2791     ime_context_get_cursor_position(ime_ctx, &iseContext.cursor_pos);
2792     ime_context_get_autocapital_type(ime_ctx, &iseContext.autocapital_type);
2793     ime_context_get_return_key_type(ime_ctx, &iseContext.return_key_type);
2794     ime_context_get_return_key_state(ime_ctx, &return_key_state);
2795
2796     ime_context_get_prediction_mode(ime_ctx, &prediction_allow);
2797     iseContext.prediction_allow = prediction_allow;
2798
2799     ime_context_get_password_mode(ime_ctx, &password_mode);
2800     iseContext.password_mode = password_mode;
2801
2802     ime_context_get_input_hint(ime_ctx, &iseContext.input_hint);
2803     ime_context_get_bidi_direction(ime_ctx, &iseContext.bidi_direction);
2804     ime_context_get_language(ime_ctx, &iseContext.language);
2805     ime_context_get_caps_mode(ime_ctx, &caps_mode);
2806     iseContext.caps_mode = caps_mode;
2807
2808     iseContext.return_key_disabled = return_key_state;
2809
2810     engine_loader_set_input_hint((uint32_t)iseContext.input_hint);
2811     engine_loader_update_bidi_direction((uint32_t)iseContext.bidi_direction);
2812
2813     g_ic = ic;
2814
2815     ime_autofill_set_hint(iseContext.input_hint & ECORE_IMF_INPUT_HINT_AUTOFILL_MASK);
2816
2817     LOGD("input hint : %x, autofill hint : %x\n", iseContext.input_hint, ime_autofill_get_hint());
2818
2819     // show autofill data
2820     show_autofill_data();
2821
2822     //g_ise_common->set_keyboard_ise_by_uuid(KEYBD_ISE_UUID);
2823
2824     /* Don't update screen until all the information is correctly set */
2825     CSCLUI *ui = get_ui();
2826     if (ui)
2827         ui->set_update_pending(TRUE);
2828
2829     ise_reset_context(); // reset ISE
2830
2831     KEYBOARD_STATE *keyboard_state = get_keyboard_state();
2832
2833     if (iseContext.language == ECORE_IMF_INPUT_PANEL_LANG_ALPHABET) {
2834         LOGD("prefer latin");
2835         if (keyboard_state)
2836             keyboard_state->prefer_latin = TRUE;
2837     }
2838     else {
2839         LOGD("prefer automatic");
2840         if (keyboard_state)
2841             keyboard_state->prefer_latin = FALSE;
2842     }
2843
2844     _context_layout = iseContext.layout;
2845     _context_layout_variation = iseContext.layout_variation;
2846     ise_set_layout(iseContext.layout, iseContext.layout_variation);
2847
2848     ise_set_return_key_type(iseContext.return_key_type);
2849     ise_set_return_key_disable(iseContext.return_key_disabled);
2850
2851     ise_set_caps_mode(iseContext.caps_mode);
2852     ise_update_cursor_position(iseContext.cursor_pos);
2853
2854     ise_show(ic);
2855
2856     /* Now we update the whole screen */
2857     if (ui)
2858         ui->set_update_pending(FALSE);
2859 }
2860
2861 static void ime_app_hide_cb(int ic, void *user_data)
2862 {
2863     LOGD("Enter\n");
2864     ise_hide();
2865
2866     clipboard_set_mime_type(false);
2867
2868     g_ic_smartreply = -1;
2869 }
2870
2871 static void ime_app_return_key_type_set_cb(Ecore_IMF_Input_Panel_Return_Key_Type type, void *user_data)
2872 {
2873     KEYBOARD_STATE *keyboard_state = get_keyboard_state();
2874     if (!keyboard_state) return;
2875
2876     LOGD("return key type : %d\n", type);
2877     ise_set_return_key_type(type);
2878
2879     if (keyboard_state->visible_state)
2880         ise_show(keyboard_state->ic);
2881 }
2882
2883 static void ime_app_return_key_state_set_cb(bool disabled, void *user_data)
2884 {
2885     LOGD("return key disabled : %d\n", disabled);
2886     ise_set_return_key_disable(disabled);
2887 }
2888
2889 static void ime_app_language_set_cb(Ecore_IMF_Input_Panel_Lang language, void *user_data)
2890 {
2891     LOGD("language : %d\n", language);
2892
2893     // if (language == ECORE_IMF_INPUT_PANEL_LANG_ALPHABET) {
2894     //     ise_explictly_set_language(PRIMARY_LATIN_LANGUAGE_INDEX);
2895     // }
2896 }
2897
2898 static void ime_app_input_context_reset_cb(void *user_data)
2899 {
2900     ise_reset_input_context();
2901     engine_loader_reset_input_context();
2902 }
2903
2904 static void ime_app_cursor_position_updated_cb(int cursor_pos, void *user_data)
2905 {
2906     LOGD("cursor position : %d\n", cursor_pos);
2907     ise_update_cursor_position(cursor_pos);
2908     engine_loader_update_cursor_position(cursor_pos);
2909 }
2910
2911 static void ime_app_language_requested_cb(void *user_data, char **lang_code)
2912 {
2913     ise_get_language_locale(lang_code);
2914 }
2915
2916 static void ime_app_surrounding_text_updated_cb(int context_id, const char *text, int cursor_pos, void *user_data)
2917 {
2918     SECURE_LOGD("surrounding text:%s, cursor=%d\n", text, cursor_pos);
2919     ime_delete_surrounding_text(-cursor_pos, strlen(text));
2920 }
2921
2922 static void ime_app_focus_in_cb(int context_id, void *user_data)
2923 {
2924     LOGD("Enter\n");
2925     ise_focus_in(context_id);
2926     Candidate *candidate = get_candidate();
2927     if (input_smartreply_get_reply_num() == 0) {
2928         if (candidate && candidate->get_visible()) {
2929             ise_app_candidate_hide();
2930             candidate->hide();
2931         }
2932     }
2933
2934     engine_loader_focus_in();
2935 }
2936
2937 static void ime_app_focus_out_cb(int context_id, void *user_data)
2938 {
2939     LOGD("Enter\n");
2940     ise_focus_out(context_id);
2941     g_imdata_state = 0;
2942     clipboard_set_mime_type(false);
2943     input_smartreply_deinit();
2944     g_ic_smartreply = -1;
2945
2946     ime_autofill_set_exist(false);
2947     ime_autofill_set_hint(0);
2948     ime_autofill_set_app_id("");
2949     ime_autofill_set_resource_id("");
2950
2951     g_smartreply_strings.clear();
2952     g_lookup_table_strings.clear();
2953     g_softcandidate_string.clear();
2954
2955     engine_loader_focus_out();
2956 }
2957
2958 static void ime_app_layout_set_cb(Ecore_IMF_Input_Panel_Layout layout, void *user_data)
2959 {
2960     KEYBOARD_STATE *keyboard_state = get_keyboard_state();
2961     if (!keyboard_state) return;
2962
2963     LOGD("layout=%d\n", layout);
2964     /* Check if the layoutIdx is in the valid range */
2965     if (static_cast<int>(layout) < static_cast<int>(ISE_LAYOUT_STYLE_MAX)) {
2966         if (keyboard_state->layout != layout) {
2967             keyboard_state->need_reset = TRUE;
2968         }
2969         keyboard_state->layout = layout;
2970         _context_layout = layout;
2971         _context_layout_variation = 0;
2972     }
2973     if (keyboard_state->visible_state)
2974         ise_show(keyboard_state->ic);
2975
2976     engine_loader_set_layout(static_cast<uint32_t>(layout));
2977 }
2978
2979 static void ime_app_input_hint_set_cb(Ecore_IMF_Input_Hints input_hint, void *user_data)
2980 {
2981     LOGD("input hint=%u\n", input_hint);
2982 }
2983
2984 static void ime_app_rotation_degree_changed_cb(int degree, void *user_data)
2985 {
2986     KEYBOARD_STATE *keyboard_state = get_keyboard_state();
2987     if (!keyboard_state) return;
2988
2989     CSCLUI *ui = get_ui();
2990     ise_set_screen_rotation(degree);
2991
2992     LOGD("degree=%d\n", degree);
2993 #if defined(_MOBILE) || defined(_COMMON)
2994     if (ui && g_floating_mode) {
2995         int handler_width;
2996         ise_destroy_move_handler();
2997         if (degree == 0 || degree == 180) {
2998             SclSize size_portrait = ui->get_input_mode_size(ui->get_input_mode(), DISPLAYMODE_PORTRAIT);
2999             handler_width = size_portrait.width * FLOATING_SCALE_RATE;
3000         } else {
3001             SclSize size_landscape = ui->get_input_mode_size(ui->get_input_mode(), DISPLAYMODE_LANDSCAPE);
3002             handler_width = size_landscape.width * FLOATING_SCALE_RATE;
3003         }
3004         ise_show_move_handler(handler_width, FLOATING_TITLE_BAR_HEIGHT);
3005     }
3006 #endif
3007     if (ise_emoticon_is_show()) {
3008         ise_emoticon_destroy_layout();
3009     }
3010     if (keyboard_state->layout == ISE_LAYOUT_STYLE_VOICE) {
3011         ise_hide_stt_mode();
3012     }
3013     if (keyboard_state->layout == ISE_LAYOUT_STYLE_EMOTICON) {
3014         ise_emoticon_show_layout(ise_emoticon_get_current_group(), degree, false, ime_get_main_window());
3015     } else if (ui) {
3016         const sclchar *input_mode = ui->get_input_mode();
3017         if (input_mode) {
3018             if (!(strcmp(input_mode, "EMOTICON_LAYOUT")))
3019                 ise_emoticon_show_layout(ise_emoticon_get_current_group(), degree, false, ime_get_main_window());
3020             else if (!(strcmp(input_mode, "STT_3X4")))
3021                 ise_show_stt_mode(NATIVE_WINDOW_CAST(ime_get_main_window()));
3022         }
3023     }
3024 }
3025
3026 static void ime_app_accessibility_state_changed_cb(bool state, void *user_data)
3027 {
3028     LOGD("state=%d\n", state);
3029     ise_set_accessibility_state(state);
3030 }
3031
3032 static void ime_app_imdata_set_cb(void *data, unsigned int data_length, void *user_data)
3033 {
3034     LOGD("Enter\n");
3035     g_imdata_state = 0;
3036     size_t _len = data_length;
3037     set_ise_imdata((sclchar *)data, _len);
3038     engine_loader_set_imdata((const char*)data, (uint32_t)data_length);
3039 }
3040
3041 static bool ime_app_process_key_event_cb(ime_key_code_e keycode, ime_key_mask_e keymask, ime_device_info_h dev_info, void *user_data)
3042 {
3043     KEYBOARD_STATE *keyboard_state = get_keyboard_state();
3044     if (!keyboard_state) return FALSE;
3045
3046     scim::KeyEvent key(keycode, keymask);
3047     unsigned int ret;
3048     char *dev_name = NULL;
3049     Ecore_IMF_Device_Class dev_class;
3050     Ecore_IMF_Device_Subclass dev_subclass;
3051
3052     if (ime_device_info_get_name(dev_info, &dev_name) == IME_ERROR_NONE) {
3053         key.dev_name = dev_name;
3054     }
3055
3056     if (ime_device_info_get_class(dev_info, &dev_class) == IME_ERROR_NONE) {
3057         key.dev_class = dev_class;
3058     }
3059
3060     if (ime_device_info_get_subclass(dev_info, &dev_subclass) == IME_ERROR_NONE) {
3061         key.dev_subclass = dev_subclass;
3062     }
3063
3064     if (keyboard_state->visible_state)
3065         ise_process_key_event(key, ret);
3066     else
3067         ret = FALSE;
3068
3069     if (dev_name)
3070         free(dev_name);
3071
3072     return ret;
3073 }
3074
3075 static void ime_app_process_key_event_with_imengine_cb(scim::KeyEvent &key, uint32_t serial, void *user_data)
3076 {
3077     LANGUAGE_INFO *info = _language_manager.get_language_info(_language_manager.get_current_language());
3078     if (info && info->need_surrounding_text)
3079         engine_loader_process_key_event(key, serial, true);
3080     else
3081         engine_loader_process_key_event(key, serial, false);
3082 }
3083
3084 static void ime_app_caps_mode_changed_cb(int mode, void *user_data)
3085 {
3086     ise_set_caps_mode(mode);
3087 }
3088
3089 static void ime_app_candidate_show_cb(int context_id, void *user_data)
3090 {
3091 #ifdef _WEARABLE
3092     ise_check_wearable_candidate();
3093 #else
3094     ise_app_candidate_show();
3095 #endif
3096 }
3097
3098 static void ime_app_candidate_hide_cb(int context_id, void *user_data)
3099 {
3100 #ifdef _WEARABLE
3101     ise_check_wearable_candidate();
3102 #else
3103     ise_app_candidate_hide();
3104 #endif
3105 }
3106
3107 static void ime_app_lookup_table_changed_cb(Eina_List *list, void *user_data)
3108 {
3109     vector<string> candidate_strings;
3110     char *candidate;
3111     void *data;
3112     Eina_List *l;
3113
3114     g_lookup_table_strings.clear();
3115
3116     if (list) {
3117         EINA_LIST_FOREACH(list, l, data) {
3118             candidate = (char *)data;
3119             if (candidate) {
3120                 g_lookup_table_strings.push_back(string(candidate));
3121                 candidate_strings.push_back(string(candidate));
3122             }
3123         }
3124     }
3125
3126     if (input_smartreply_get_reply_num() > 0) {
3127         if (candidate_strings[0] == "#" && candidate_strings[1] == "$") {
3128             char *text = NULL;
3129             int cursor;
3130             ime_get_surrounding_text(0, 0, &text, &cursor);
3131             if (text)
3132                 free(text);
3133
3134             if (cursor == 0)
3135                 return;
3136         }
3137     }
3138
3139     update_candidate_table();
3140 }
3141
3142 #ifdef _WEARABLE
3143 static void ime_app_process_input_device_event_cb(ime_input_device_type_e device_type, ime_input_device_event_h device_event, void *user_data)
3144 {
3145     KEYBOARD_STATE *keyboard_state = get_keyboard_state();
3146     if (!keyboard_state) return;
3147
3148     if (device_type == IME_INPUT_DEVICE_TYPE_ROTARY) {
3149         ime_input_device_rotary_direction_e direction;
3150         if (IME_ERROR_NONE == ime_input_device_rotary_get_direction(device_event, &direction)) {
3151             sclu32 new_layout = keyboard_state->layout;
3152             if (direction == IME_INPUT_DEVICE_ROTARY_DIRECTION_CLOCKWISE) {
3153                 LOGD("CLOCKWISE\n");
3154                 switch (keyboard_state->layout) {
3155                     case ISE_LAYOUT_STYLE_NORMAL:
3156                     case ISE_LAYOUT_STYLE_EMAIL:
3157                     case ISE_LAYOUT_STYLE_URL:
3158                     case ISE_LAYOUT_STYLE_PASSWORD:
3159                         if (_context_layout == ISE_LAYOUT_STYLE_PASSWORD &&
3160                             _context_layout_variation == ECORE_IMF_INPUT_PANEL_LAYOUT_PASSWORD_VARIATION_NUMBERONLY)
3161                             ;   // PASSWORD NUMBER ONLY, do nothing
3162                         else
3163                             new_layout = ISE_LAYOUT_STYLE_NUMBER;
3164                         break;
3165                     case ISE_LAYOUT_STYLE_NUMBER:
3166                         new_layout = ISE_LAYOUT_STYLE_HEX;
3167                         break;
3168                     case ISE_LAYOUT_STYLE_HEX:
3169                         if (_context_layout == ISE_LAYOUT_STYLE_EMAIL ||
3170                             _context_layout == ISE_LAYOUT_STYLE_URL)
3171                             new_layout = ISE_LAYOUT_STYLE_VOICE;
3172                         else if (_context_layout == ISE_LAYOUT_STYLE_PASSWORD)
3173                             new_layout = _context_layout;
3174                         else
3175                             new_layout = ISE_LAYOUT_STYLE_EMOTICON;
3176                         break;
3177                     case ISE_LAYOUT_STYLE_EMOTICON:
3178                         if (_context_layout == ISE_LAYOUT_STYLE_EMAIL ||
3179                             _context_layout == ISE_LAYOUT_STYLE_URL ||
3180                             _context_layout == ISE_LAYOUT_STYLE_PASSWORD)
3181                             new_layout = _context_layout;
3182                         else
3183                             new_layout = ISE_LAYOUT_STYLE_VOICE;
3184                         break;
3185                     case ISE_LAYOUT_STYLE_VOICE:
3186                         new_layout = ISE_LAYOUT_STYLE_NORMAL;
3187                         break;
3188                     default:
3189                         ;
3190                 }
3191             } else if (direction == IME_INPUT_DEVICE_ROTARY_DIRECTION_COUNTER_CLOCKWISE) {
3192                 LOGD("COUNTER_CLOCKWISE\n");
3193                 switch (keyboard_state->layout) {
3194                     case ISE_LAYOUT_STYLE_NORMAL:
3195                     case ISE_LAYOUT_STYLE_EMAIL:
3196                     case ISE_LAYOUT_STYLE_URL:
3197                     case ISE_LAYOUT_STYLE_PASSWORD:
3198                         if (_context_layout == ISE_LAYOUT_STYLE_PASSWORD &&
3199                             _context_layout_variation == ECORE_IMF_INPUT_PANEL_LAYOUT_PASSWORD_VARIATION_NUMBERONLY)
3200                             ;   // PASSWORD NUMBER ONLY, do nothing
3201                         else if (_context_layout == ISE_LAYOUT_STYLE_PASSWORD)
3202                             new_layout = ISE_LAYOUT_STYLE_HEX;
3203                         else
3204                             new_layout = ISE_LAYOUT_STYLE_VOICE;
3205                         break;
3206                     case ISE_LAYOUT_STYLE_NUMBER:
3207                         if (_context_layout == ISE_LAYOUT_STYLE_EMAIL ||
3208                             _context_layout == ISE_LAYOUT_STYLE_URL ||
3209                             _context_layout == ISE_LAYOUT_STYLE_PASSWORD)
3210                             new_layout = _context_layout;
3211                         else
3212                             new_layout = ISE_LAYOUT_STYLE_NORMAL;
3213                         break;
3214                     case ISE_LAYOUT_STYLE_HEX:
3215                         new_layout = ISE_LAYOUT_STYLE_NUMBER;
3216                         break;
3217                     case ISE_LAYOUT_STYLE_EMOTICON:
3218                         new_layout = ISE_LAYOUT_STYLE_HEX;
3219                         break;
3220                     case ISE_LAYOUT_STYLE_VOICE:
3221                         if (_context_layout == ISE_LAYOUT_STYLE_EMAIL ||
3222                             _context_layout == ISE_LAYOUT_STYLE_URL)
3223                             new_layout = ISE_LAYOUT_STYLE_HEX;
3224                         else
3225                             new_layout = ISE_LAYOUT_STYLE_EMOTICON;
3226                         break;
3227                     default:
3228                         ;
3229                 }
3230             }
3231
3232             CONFIG_VALUES *config_values = get_config_values();
3233             if (check_is_tutorial_show() && config_values) {
3234                 read_ise_config_values();
3235                 if ((direction == IME_INPUT_DEVICE_ROTARY_DIRECTION_COUNTER_CLOCKWISE && !config_values->number_tutorial_enable && !config_values->symbol_tutorial_enable) ||
3236                     (direction == IME_INPUT_DEVICE_ROTARY_DIRECTION_CLOCKWISE && config_values->symbol_tutorial_enable)) {
3237                     new_layout = keyboard_state->layout;
3238                 } else if (direction == IME_INPUT_DEVICE_ROTARY_DIRECTION_COUNTER_CLOCKWISE && config_values->symbol_tutorial_enable) {
3239                     ise_destroy_tutorial_mode_popup();
3240                     config_values->symbol_tutorial_enable = false;
3241                      write_ise_config_values();
3242                 } else if (direction == IME_INPUT_DEVICE_ROTARY_DIRECTION_CLOCKWISE && !config_values->number_tutorial_enable) {
3243                     ise_destroy_tutorial_mode_popup();
3244                     new_layout = ISE_LAYOUT_STYLE_NUMBER;
3245                     if (!config_values->symbol_tutorial_enable) {
3246                         ise_show_tutorial_mode_popup(new_layout);
3247                         config_values->symbol_tutorial_enable = true;
3248                          write_ise_config_values();
3249                     }
3250                 }
3251             }
3252
3253             if (new_layout != keyboard_state->layout && new_layout < ISE_LAYOUT_STYLE_MAX) {
3254                 keyboard_state->need_reset = TRUE;
3255                 keyboard_state->layout = new_layout;
3256
3257                 if (keyboard_state->visible_state) {
3258                     _reset_multitap_state();
3259                     if (config_values) {
3260                         _language_manager.reset_language(config_values->selected_language.c_str());
3261                     }
3262                     ise_show(keyboard_state->ic);
3263                 }
3264             }
3265         }
3266     }
3267 }
3268 #endif
3269
3270 static void ime_app_prediction_hint_set_cb(const char *prediction_hint, void *user_data)
3271 {
3272     char *sender = (char *)"mms";
3273     char *caller_id = (char *)"mms";
3274     char *hint = (char *)prediction_hint;
3275
3276     if (!prediction_hint) return;
3277     SECURE_LOGD("prediction hint : %s\n", prediction_hint);
3278
3279     if (strlen(prediction_hint) > 0) {
3280         input_smartreply_init(caller_id, sender, hint);
3281         input_smartreply_set_notify(_input_smartreply_notify_cb, NULL);
3282
3283         if (input_smartreply_is_enabled()) {
3284             input_smartreply_get_reply_async();
3285         }
3286     }
3287 }
3288
3289 static void ime_app_mime_type_set_request_cb(const char *mime_types, void *user_data)
3290 {
3291     LOGD("mime type : %s\n", mime_types);
3292
3293     clipboard_set_mime_type(true);
3294     clipboard_init_sel_type();
3295
3296     string str(mime_types), text_key = "text/", image_key = "image/";
3297
3298     if (str.find(text_key) != string::npos)
3299         clipboard_add_sel_type(CLIPBOARD_SEL_TEXT);
3300
3301     if (str.find(image_key) != string::npos)
3302         clipboard_add_sel_type(CLIPBOARD_SEL_IMAGE);
3303 }
3304
3305 static void ime_app_prediction_hint_data_set_cb(const char *key, const char *value, void *user_data)
3306 {
3307     SECURE_LOGD("key : %s, value : %s\n", key, value);
3308
3309     if (string(key) == "appid")
3310         ime_autofill_set_app_id(value);
3311     else if (string(key) == "res_id")
3312         ime_autofill_set_resource_id(value);
3313 }
3314
3315 static void ime_app_autocapital_type_set_cb(uint32_t type, void *user_data)
3316 {
3317     LOGD("autocapital type : %u\n", type);
3318     engine_loader_set_autocapital_type(type);
3319 }
3320
3321 static void ime_app_prediction_allow_set_cb(uint32_t prediction_allow, void *user_data)
3322 {
3323     LOGD("prediction allow : %u\n", prediction_allow);
3324     engine_loader_set_prediction_allow(prediction_allow);
3325 }
3326
3327 static void ime_app_trigger_property_set_cb(const char *property, void *user_data)
3328 {
3329     LOGD("trigger property : %s\n", property);
3330     engine_loader_trigger_property(property);
3331 }
3332
3333 static void ime_app_candidate_more_window_show_cb(void *user_data)
3334 {
3335     LOGD("");
3336     engine_loader_show_candidate_more_window();
3337 }
3338
3339 static void ime_app_candidate_more_window_hide_cb(void *user_data)
3340 {
3341     LOGD("");
3342     engine_loader_hide_candidate_more_window();
3343 }
3344
3345 static void ime_app_aux_select_cb(uint32_t item, void *user_data)
3346 {
3347     LOGD("aux select : %u\n", item);
3348     engine_loader_select_aux(item);
3349 }
3350
3351 static void ime_app_candidate_select_cb(uint32_t item, void *user_data)
3352 {
3353     LOGD("candidate select : %u\n", item);
3354     engine_loader_select_candidate(item);
3355 }
3356
3357 static void ime_app_candidate_table_page_up_cb(void *user_data)
3358 {
3359     LOGD("");
3360     engine_loader_candidate_table_page_up();
3361 }
3362
3363 static void ime_app_candidate_table_page_down_cb(void *user_data)
3364 {
3365     LOGD("");
3366     engine_loader_candidate_table_page_down();
3367 }
3368
3369 static void ime_app_candidate_table_page_size_chaned_cb(uint32_t size, void *user_data)
3370 {
3371     LOGD("candidate page size : %u\n", size);
3372     engine_loader_change_candidate_page_size(size);
3373 }
3374
3375 static void ime_app_candidate_item_layout_set_cb(vector<uint32_t> item, void *user_data)
3376 {
3377     LOGD("item layout size : %zu", item.size());
3378     engine_loader_set_candidate_item_layout(item);
3379 }
3380
3381 static void ime_app_displayed_candidate_number_chaned_cb(uint32_t page_num, void *user_data)
3382 {
3383     LOGD("candidate number changed : %u\n", page_num);
3384     engine_loader_change_candidate_number(page_num);
3385 }
3386
3387 static void ime_app_candidate_item_long_pressed_cb(uint32_t index, void *user_data)
3388 {
3389     LOGD("candidate item : %u\n", index);
3390     engine_loader_long_press_candidate_item(index);
3391 }
3392
3393 #ifdef __cplusplus
3394 extern "C"{
3395 #endif
3396 EXPORTED void ime_app_main(int argc, char **argv)
3397 {
3398     ime_callback_s basic_callback = {
3399         ime_app_create_cb,
3400         ime_app_exit_cb,
3401         ime_app_show_cb,
3402         ime_app_hide_cb
3403     };
3404
3405     ime_event_set_focus_in_cb(ime_app_focus_in_cb, NULL);
3406     ime_event_set_focus_out_cb(ime_app_focus_out_cb, NULL);
3407     ime_event_set_rotation_degree_changed_cb(ime_app_rotation_degree_changed_cb, NULL);
3408     ime_event_set_accessibility_state_changed_cb(ime_app_accessibility_state_changed_cb, NULL);
3409     ime_event_set_layout_set_cb(ime_app_layout_set_cb, NULL);
3410     ime_event_set_caps_mode_changed_cb(ime_app_caps_mode_changed_cb, NULL);
3411     ime_event_set_cursor_position_updated_cb(ime_app_cursor_position_updated_cb, NULL);
3412     ime_event_set_surrounding_text_updated_cb(ime_app_surrounding_text_updated_cb, NULL);
3413     ime_event_set_return_key_type_set_cb(ime_app_return_key_type_set_cb, NULL);
3414     ime_event_set_return_key_state_set_cb(ime_app_return_key_state_set_cb, NULL);
3415     ime_event_set_language_set_cb(ime_app_language_set_cb, NULL);
3416     ime_event_set_imdata_set_cb(ime_app_imdata_set_cb, NULL);
3417     ime_event_set_process_key_event_cb(ime_app_process_key_event_cb, NULL);
3418     ime_event_set_process_key_event_with_imengine_cb(ime_app_process_key_event_with_imengine_cb, NULL);
3419     ime_event_set_input_hint_set_cb(ime_app_input_hint_set_cb, NULL);
3420
3421     ime_event_set_candidate_show_cb(ime_app_candidate_show_cb, NULL);
3422     ime_event_set_candidate_hide_cb(ime_app_candidate_hide_cb, NULL);
3423     ime_event_set_lookup_table_changed_cb(ime_app_lookup_table_changed_cb, NULL);
3424
3425 #ifdef _WEARABLE
3426     ime_event_set_process_input_device_event_cb(ime_app_process_input_device_event_cb, NULL);
3427 #endif
3428
3429     ime_event_set_input_context_reset_cb(ime_app_input_context_reset_cb, NULL);
3430     ime_event_set_language_requested_cb(ime_app_language_requested_cb, NULL);
3431
3432     ime_event_set_prediction_hint_set_cb(ime_app_prediction_hint_set_cb, NULL);
3433     ime_event_set_mime_type_set_request_cb(ime_app_mime_type_set_request_cb, NULL);
3434     ime_event_set_prediction_hint_data_set_cb(ime_app_prediction_hint_data_set_cb, NULL);
3435
3436     ime_event_set_autocapital_type_set_cb(ime_app_autocapital_type_set_cb, NULL);
3437     ime_event_set_prediction_allow_set_cb(ime_app_prediction_allow_set_cb, NULL);
3438     ime_event_set_trigger_property_set_cb(ime_app_trigger_property_set_cb, NULL);
3439     ime_event_set_candidate_more_window_show_cb(ime_app_candidate_more_window_show_cb, NULL);
3440     ime_event_set_candidate_more_window_hide_cb(ime_app_candidate_more_window_hide_cb, NULL);
3441     ime_event_set_aux_select_cb(ime_app_aux_select_cb, NULL);
3442     ime_event_set_candidate_select_cb(ime_app_candidate_select_cb, NULL);
3443     ime_event_set_candidate_table_page_up_cb(ime_app_candidate_table_page_up_cb, NULL);
3444     ime_event_set_candidate_table_page_down_cb(ime_app_candidate_table_page_down_cb, NULL);
3445     ime_event_set_candidate_table_page_size_chaned_cb(ime_app_candidate_table_page_size_chaned_cb, NULL);
3446     ime_event_set_candidate_item_layout_set_cb(ime_app_candidate_item_layout_set_cb, NULL);
3447     ime_event_set_displayed_candidate_number_chaned_cb(ime_app_displayed_candidate_number_chaned_cb, NULL);
3448     ime_event_set_candidate_item_long_pressed_cb(ime_app_candidate_item_long_pressed_cb, NULL);
3449
3450 #if DEFER_ISE_CREATION
3451     ime_set_window_creation_defer_flag(TRUE);
3452 #endif
3453
3454     ime_run(&basic_callback, NULL);
3455 }
3456 #ifdef __cplusplus
3457 }
3458 #endif
3459
3460 EXPORTED int main(int argc, char *argv[])
3461 {
3462     ime_app_main(argc, argv);
3463
3464     return 0;
3465 }