upload isf tizen beta package
[framework/uifw/isf.git] / ism / extras / efl_immodule / isf_imf_control_ui.cpp
1 /*
2  * ISF(Input Service Framework)
3  *
4  * ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable.
5  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6  *
7  * Contact: Jihoon Kim <jihoon48.kim@samsung.com>, Haifeng Deng <haifeng.deng@samsung.com>
8  *
9  * This library is free software; you can redistribute it and/or modify it under
10  * the terms of the GNU Lesser General Public License as published by the
11  * Free Software Foundation; either version 2.1 of the License, or (at your option)
12  * any later version.
13  *
14  * This library is distributed in the hope that it will be useful, but WITHOUT ANY
15  * WARRANTY; without even the implied warranty of MERCHANTABILITY or
16  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
17  * License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public License
20  * along with this library; if not, write to the Free Software Foundation, Inc., 51
21  * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22  *
23  */
24
25 #define Uses_SCIM_TRANSACTION
26
27
28 /* IM control UI part */
29 #include <Ecore_X.h>
30 #include <Ecore_Evas.h>
31 #include <Ecore_IMF.h>
32 #include <glib.h>
33 #include "scim.h"
34 #include "isf_imf_control_ui.h"
35 #include "isf_imf_context.h"
36 #include "isf_imf_control.h"
37 #include "ise_context.h"
38
39 using namespace scim;
40
41 #define IMFCONTROLUIDBG(str...)
42 #define IMFCONTROLUIERR(str...) printf(str)
43
44
45 typedef struct {
46     void (*func)(void *data, Ecore_IMF_Context *ctx, int value);
47     void *data;
48     Ecore_IMF_Input_Panel_Event type;
49     Ecore_IMF_Context *imf_context;
50 } EventCallbackNode;
51
52
53 /* IM control related variables */
54 static Ise_Context        iseContext;
55 static bool               IfInitContext     = false;
56 static Eina_List         *EventCallbackList = NULL;
57 static Ecore_IMF_Context *show_req_ic       = NULL;
58 static Ecore_IMF_Context *hide_req_ic       = NULL;
59 static Ecore_Event_Handler *_prop_change_handler = NULL;
60 static Ecore_X_Atom       prop_x_ext_keyboard_exist = 0;
61 static Ecore_X_Window     _rootwin;
62 static unsigned int       hw_kbd_num = 0;
63 static Ecore_Timer       *hide_timer = NULL;
64
65 Ecore_IMF_Context        *input_panel_ctx = NULL;
66
67 static Eina_Bool _prop_change (void *data, int ev_type, void *ev)
68 {
69     Ecore_X_Event_Window_Property *event = (Ecore_X_Event_Window_Property *)ev;
70     unsigned int val = 0;
71
72     if (event->win != _rootwin) return ECORE_CALLBACK_PASS_ON;
73     if (event->atom != prop_x_ext_keyboard_exist) return ECORE_CALLBACK_PASS_ON;
74
75     if (!ecore_x_window_prop_card32_get (event->win, prop_x_ext_keyboard_exist, &val, 1) > 0)
76         return ECORE_CALLBACK_PASS_ON;
77
78     if (val != 0) {
79         if (show_req_ic)
80             isf_imf_context_input_panel_hide (show_req_ic);
81     }
82
83     hw_kbd_num = val;
84
85     return ECORE_CALLBACK_PASS_ON;
86 }
87
88 static void _save_current_xid (Ecore_IMF_Context *ctx)
89 {
90     Ecore_X_Window xid = 0, rootwin_xid = 0;
91     Ecore_Evas *ee = NULL;
92     Evas *evas = NULL;
93
94     evas = (Evas *)ecore_imf_context_client_canvas_get(ctx);
95
96     if (evas) {
97         ee = ecore_evas_ecore_evas_get (evas);
98         if (ee)
99             xid = (Ecore_X_Window)ecore_evas_window_get (ee);
100     } else {
101         xid = (Ecore_X_Window)ecore_imf_context_client_window_get (ctx);
102     }
103
104     if (xid == 0)
105         rootwin_xid = ecore_x_window_root_first_get ();
106     else
107         rootwin_xid = ecore_x_window_root_get (xid);
108
109     Ecore_X_Atom isf_active_window_atom = ecore_x_atom_get ("_ISF_ACTIVE_WINDOW");
110     ecore_x_window_prop_property_set (rootwin_xid, isf_active_window_atom, ((Ecore_X_Atom) 33), 32, &xid, 1);
111     ecore_x_flush ();
112     ecore_x_sync ();
113 }
114
115 static void _event_callback_call (Ecore_IMF_Input_Panel_Event type, int value)
116 {
117     void *list_data = NULL;
118     EventCallbackNode *fn = NULL;
119     Eina_List *l = NULL;
120     Ecore_IMF_Context *using_ic = show_req_ic;
121
122     if (type == ECORE_IMF_INPUT_PANEL_STATE_EVENT &&
123         value == ECORE_IMF_INPUT_PANEL_STATE_HIDE) {
124         if (hide_req_ic) {
125             using_ic = hide_req_ic;
126             hide_req_ic = NULL;
127         }
128     }
129
130     EINA_LIST_FOREACH(EventCallbackList, l, list_data) {
131         fn = (EventCallbackNode *)list_data;
132
133         if ((fn) && (fn->imf_context == using_ic) &&
134             (fn->type == type) && (fn->func))
135             fn->func (fn->data, fn->imf_context, value);
136
137         IMFCONTROLUIDBG("\tFunc : %p\tType : %d\n", fn->func, fn->type);
138     }
139 }
140
141 static void _isf_imf_context_init (void)
142 {
143     IMFCONTROLUIDBG("debug start --%s\n", __FUNCTION__);
144     memset (iseContext.name, '\0', sizeof (iseContext.name));
145     iseContext.IfAlwaysShow = FALSE;
146     iseContext.IfFullStyle  = FALSE;
147     iseContext.state        = ECORE_IMF_INPUT_PANEL_STATE_HIDE;
148     iseContext.language     = ECORE_IMF_INPUT_PANEL_LANG_AUTOMATIC;
149     iseContext.orient       = 0;
150     iseContext.fUseImEffect = TRUE;
151
152     if (!IfInitContext) {
153         IfInitContext = true;
154     }
155
156     IMFCONTROLUIDBG("debug end\n");
157 }
158
159 static Eina_Bool _hide_timer_handler (void *data)
160 {
161     LOGD("input panel hide. ctx : %p\n", data);
162     _isf_imf_context_input_panel_hide ();
163
164     hide_timer = NULL;
165     return ECORE_CALLBACK_CANCEL;
166 }
167
168 static void _input_panel_hide_timer_start(void *data)
169 {
170     if (!hide_timer)
171         hide_timer = ecore_timer_add (0.05, _hide_timer_handler, data);
172 }
173
174 static void _input_panel_hide (Ecore_IMF_Context *ctx, Eina_Bool instant)
175 {
176     IMFCONTROLUIDBG("[%s]\n", __func__);
177
178     if (IfInitContext == false) {
179         _isf_imf_context_init ();
180     }
181
182     if (iseContext.state == ECORE_IMF_INPUT_PANEL_STATE_SHOW) {
183         hide_req_ic = ctx;
184     }
185
186     iseContext.IfAlwaysShow = FALSE;
187
188     if (instant) {
189         if (hide_timer) {
190             ecore_timer_del (hide_timer);
191             hide_timer = NULL;
192         }
193
194         LOGD("input panel hide. ctx : %p\n", ctx);
195         _isf_imf_context_input_panel_hide ();
196     } else {
197         _input_panel_hide_timer_start (ctx);
198     }
199 }
200
201 EAPI void isf_imf_context_control_panel_show (Ecore_IMF_Context *ctx)
202 {
203     IMFCONTROLUIDBG("[%s]\n", __FUNCTION__);
204
205     if (IfInitContext == false) {
206         _isf_imf_context_init ();
207     }
208     _isf_imf_context_control_panel_show ();
209 }
210
211 EAPI void isf_imf_context_control_panel_hide (Ecore_IMF_Context *ctx)
212 {
213     IMFCONTROLUIDBG("[%s]\n", __FUNCTION__);
214
215     if (IfInitContext == false) {
216         _isf_imf_context_init ();
217     }
218     _isf_imf_context_control_panel_hide ();
219 }
220
221 EAPI void isf_imf_input_panel_init (void)
222 {
223     IMFCONTROLUIDBG("[%s]\n", __FUNCTION__);
224
225     if (_prop_change_handler) return;
226
227     _rootwin = ecore_x_window_root_first_get ();
228     ecore_x_event_mask_set (_rootwin, ECORE_X_EVENT_MASK_WINDOW_PROPERTY);
229
230     _prop_change_handler = ecore_event_handler_add (ECORE_X_EVENT_WINDOW_PROPERTY, _prop_change, NULL);
231
232     if (!prop_x_ext_keyboard_exist)
233         prop_x_ext_keyboard_exist = ecore_x_atom_get (PROP_X_EXT_KEYBOARD_EXIST);
234
235     if (!ecore_x_window_prop_card32_get (_rootwin, prop_x_ext_keyboard_exist, &hw_kbd_num, 1)) {
236         printf ("Error! cannot get hw_kbd_num\n");
237         return;
238     }
239 }
240
241 EAPI void isf_imf_input_panel_shutdown (void)
242 {
243     IMFCONTROLUIDBG("[%s]\n", __FUNCTION__);
244
245     if (_prop_change_handler) {
246         ecore_event_handler_del (_prop_change_handler);
247         _prop_change_handler = NULL;
248     }
249
250     if (hide_timer) {
251         ecore_timer_del (hide_timer);
252         hide_timer = NULL;
253     }
254 }
255
256 EAPI void isf_imf_context_input_panel_show (Ecore_IMF_Context* ctx)
257 {
258     int   length = -1;
259     int   i = 0;
260     Disable_Key_Item *dkey_item = NULL;
261     Private_Key_Item *pkey_item = NULL;
262     Eina_List *disable_key_list = NULL;
263     Eina_List *private_key_list = NULL;
264     Eina_List *l = NULL;
265     void *list_data = NULL;
266     void *offset = NULL;
267     void *packet = NULL;
268
269     input_panel_ctx = ctx;
270
271     IMFCONTROLUIDBG("debug start --%s\n", __FUNCTION__);
272
273     if (hw_kbd_num != 0) {
274         printf ("H/W keyboard is existed.\n");
275         return;
276     }
277
278     if (hide_timer) {
279         ecore_timer_del(hide_timer);
280         hide_timer = NULL;
281     }
282
283     if (IfInitContext == false) {
284         _isf_imf_context_init ();
285     }
286
287     show_req_ic = ctx;
288
289     /* get input language */
290     iseContext.language = ecore_imf_context_input_panel_language_get (ctx);
291     IMFCONTROLUIDBG("[%s] language : %d\n", __func__, iseContext.language);
292
293     /* get layout */
294     iseContext.layout = ecore_imf_context_input_panel_layout_get (ctx);
295     IMFCONTROLUIDBG("[%s] layout : %d\n", __func__, iseContext.layout);
296
297     /* get language */
298     iseContext.language = ecore_imf_context_input_panel_language_get (ctx);
299     IMFCONTROLUIDBG("[%s] language : %d\n", __func__, iseContext.language);
300
301     /* get disable key list */
302     disable_key_list = ecore_imf_context_input_panel_key_disabled_list_get (ctx);
303     iseContext.disabled_key_num = eina_list_count (disable_key_list);
304     IMFCONTROLUIDBG("disable key_num : %d\n", iseContext.disabled_key_num);
305
306     /* get private key list */
307     private_key_list = ecore_imf_context_input_panel_private_key_list_get (ctx);
308     iseContext.private_key_num = eina_list_count (private_key_list);
309     IMFCONTROLUIDBG("private key_num : %d\n", iseContext.private_key_num);
310
311     /* calculate packet size */
312     length = sizeof (iseContext);
313     length += iseContext.disabled_key_num * sizeof (Disable_Key_Item);
314     length += iseContext.private_key_num * sizeof (Private_Key_Item);
315
316     /* create packet */
317     packet = calloc (1, length);
318     if (!packet)
319         return;
320
321     memcpy (packet, (void *)&iseContext, sizeof (iseContext));
322
323     i = 0;
324     offset = (void *)((unsigned int)packet + sizeof (iseContext));
325     EINA_LIST_FOREACH(disable_key_list, l, list_data) {
326         dkey_item = (Disable_Key_Item *)list_data;
327
328         memcpy ((void *)((unsigned int)offset+i*sizeof(Disable_Key_Item)), dkey_item, sizeof (Disable_Key_Item));
329         IMFCONTROLUIDBG("[Disable Key] layout : %d, key : %d, disable : %d\n", dkey_item->layout_idx, dkey_item->key_idx, dkey_item->disabled);
330         i++;
331     }
332
333     offset = (void *)((unsigned int)offset + iseContext.disabled_key_num * sizeof (Disable_Key_Item));
334
335     i = 0;
336     EINA_LIST_FOREACH(private_key_list, l, list_data) {
337         pkey_item = (Private_Key_Item *)list_data;
338         memcpy ((void *)((unsigned int)offset + i * sizeof (Private_Key_Item)), pkey_item, sizeof (Private_Key_Item));
339         IMFCONTROLUIDBG("[Private Key] layout : %d, key : %d, label : %s, key_value : %d, key_str : %s\n", pkey_item->layout_idx, pkey_item->key_idx, pkey_item->data, pkey_item->key_value, pkey_item->key_string);
340         i++;
341     }
342
343     /* Set the current XID of the active window into the root window property */
344     _save_current_xid (ctx);
345
346     iseContext.state = ECORE_IMF_INPUT_PANEL_STATE_SHOW;
347
348     LOGD("input panel show. ctx : %p\n", ctx);
349
350     _isf_imf_context_input_panel_show (packet ,length);
351     free (packet);
352
353     send_caps_mode (ctx);
354 }
355
356 EAPI void isf_imf_context_input_panel_hide (Ecore_IMF_Context *ctx)
357 {
358     IMFCONTROLUIDBG("[%s]\n", __func__);
359
360     _input_panel_hide (ctx, EINA_FALSE);
361 }
362
363 EAPI void isf_imf_context_input_panel_instant_hide (Ecore_IMF_Context *ctx)
364 {
365     IMFCONTROLUIDBG("[%s]\n", __func__);
366
367     _input_panel_hide (ctx, EINA_TRUE);
368 }
369
370 EAPI void isf_imf_context_input_panel_language_set (Ecore_IMF_Context *ctx, Ecore_IMF_Input_Panel_Lang language)
371 {
372     IMFCONTROLUIDBG("[%s] language : %d\n", __func__, language);
373
374     EcoreIMFContextISF *context_scim = (EcoreIMFContextISF *)ecore_imf_context_data_get (ctx);
375
376     if (!IfInitContext)
377         _isf_imf_context_init ();
378     iseContext.language = language;
379
380     if (context_scim == get_focused_ic ())
381         _isf_imf_context_input_panel_language_set (language);
382 }
383
384 EAPI Ecore_IMF_Input_Panel_Lang isf_imf_context_input_panel_language_get (Ecore_IMF_Context *ctx)
385 {
386     IMFCONTROLUIDBG("[%s] language : %d\n", __func__, iseContext.language);
387     if (!IfInitContext) _isf_imf_context_init();
388     return iseContext.language;
389 }
390
391 EAPI void isf_imf_context_input_panel_caps_mode_set (Ecore_IMF_Context *ctx, unsigned int mode)
392 {
393     IMFCONTROLUIDBG("[%s] shift mode : %d\n", __func__, mode);
394
395     if (!IfInitContext)
396         _isf_imf_context_init ();
397     _isf_imf_context_input_panel_caps_mode_set (mode);
398 }
399
400 /**
401  * Set up an ISE specific data
402  *
403  * @param[in] ctx a #Ecore_IMF_Context
404  * @param[in] data pointer of data to sets up to ISE
405  * @param[in] length length of data
406  */
407 EAPI void isf_imf_context_input_panel_imdata_set (Ecore_IMF_Context *ctx, const char* data, int length)
408 {
409     IMFCONTROLUIDBG("[%s] data : %s, len : %d\n", __func__, data, length);
410
411     if (length < 0)
412         return;
413     if (!IfInitContext)
414         _isf_imf_context_init ();
415     _isf_imf_context_input_panel_imdata_set (data, length);
416 }
417
418 /**
419  * Get the ISE specific data from ISE
420  *
421  * @param[in] ctx a #Ecore_IMF_Context
422  * @param[out] data pointer of data to return
423  * @param[out] length length of data
424  */
425 EAPI void isf_imf_context_input_panel_imdata_get (Ecore_IMF_Context *ctx, char* data, int* length)
426 {
427     if (!IfInitContext)
428         _isf_imf_context_init ();
429     _isf_imf_context_input_panel_imdata_get (data, length);
430     IMFCONTROLUIDBG("[%s] imdata : %s, len : %d\n", __func__, data, *length);
431 }
432
433 EAPI void isf_imf_context_input_panel_move (Ecore_IMF_Context *ctx, int x, int y)
434 {
435     IMFCONTROLUIDBG("[%s] x : %d, y : %d\n", __func__, x, y);
436
437     if (!IfInitContext)
438         _isf_imf_context_init ();
439     iseContext.input_panel_x = x;
440     iseContext.input_panel_x = y;
441 }
442
443 /**
444  * Get ISE's position and size, in screen coodinates of the ISE rectangle not the client area,
445  * the represents the size and location of the ISE
446  *
447  * @param[in] ctx a #Ecore_IMF_Context
448  * @param[out] x the x position of ISE window
449  * @param[out] y the y position of ISE window
450  * @param[out] w the width of ISE window
451  * @param[out] h the height of ISE window
452  */
453 EAPI void isf_imf_context_input_panel_geometry_get (Ecore_IMF_Context *ctx, int *x, int *y, int *w, int *h)
454 {
455     if (!IfInitContext)
456         _isf_imf_context_init ();
457     _isf_imf_context_input_panel_geometry_get (x, y, w, h);
458
459     IMFCONTROLUIDBG("[%s] x : %d, y : %d, w : %d, h : %d\n", __func__, *x, *y, *w, *h);
460 }
461
462 /**
463  * Sets up a private key in active ISE keyboard layout for own's application.
464  * In some case which does not support the private key will be ignored even 
465  * through the application requested.
466  *
467  * @param[in] ctx a #Ecore_IMF_Context
468  * @param[in] layout_idx an index of layout page to be set
469  * @param[in] key_idx an index of key to be set
470  * @param[in] img_path the image file to be set
471  * @param[in] label a text label to be displayed on private key
472  * @param[in] value a value of key. If null, it will use original value of key
473  */
474 EAPI void isf_imf_context_input_panel_private_key_set (Ecore_IMF_Context *ctx,
475                                                        int                layout_index,
476                                                        int                key_index,
477                                                        const char        *img_path,
478                                                        const char        *label,
479                                                        const char        *value)
480 {
481     IMFCONTROLUIDBG("[%s] layout : %d, key_index : %d, img_path : %s, label : %s, value : %s\n", __func__, layout_index, key_index, img_path, label, value);
482
483     EcoreIMFContextISF *context_scim = (EcoreIMFContextISF *)ecore_imf_context_data_get (ctx);
484
485     if (!IfInitContext)
486         _isf_imf_context_init ();
487
488     if (context_scim != get_focused_ic ())
489         return;
490
491     if (img_path) {
492         _isf_imf_context_input_panel_private_key_set_by_image (layout_index, key_index, img_path, value);
493     } else {
494         _isf_imf_context_input_panel_private_key_set (layout_index, key_index, label, value);
495     }
496 }
497
498 /**
499  * Make a key to be disabled in active ISE keyboard layout for own's application.
500  * In some case which does not support the disable key will be ignored
501  * even through the application requested.
502  *
503  * @param[in] ctx a #Ecore_IMF_Context
504  * @param[in] layout_idx an index of layout page to be set
505  * @param[in] key_idx an index of key to be set
506  * @param[in] disabled the state
507  */
508 EAPI void isf_imf_context_input_panel_key_disabled_set (Ecore_IMF_Context *ctx, int layout_index, int key_index, Eina_Bool disabled)
509 {
510     IMFCONTROLUIDBG("[%s] layout : %d, key_index : %d, value : %d\n", __func__, layout_index, key_index, disabled);
511
512     EcoreIMFContextISF *context_scim = (EcoreIMFContextISF *)ecore_imf_context_data_get (ctx);
513
514     if (!IfInitContext)
515         _isf_imf_context_init ();
516
517     if (context_scim == get_focused_ic())
518         _isf_imf_context_input_panel_key_disabled_set (layout_index, key_index, disabled);
519 }
520
521 /**
522  * Sets up the layout infomation of active ISE
523  *
524  * @param[in] ctx a #Ecore_IMF_Context
525  * @param[in] layout sets a layout ID to be shown. The layout ID will define by the configuration of selected ISE.
526  */
527 EAPI void
528 isf_imf_context_input_panel_layout_set (Ecore_IMF_Context *ctx, Ecore_IMF_Input_Panel_Layout layout)
529 {
530     IMFCONTROLUIDBG("[%s] layout : %d\n", __func__, layout);
531
532     EcoreIMFContextISF *context_scim = (EcoreIMFContextISF *)ecore_imf_context_data_get (ctx);
533
534     if (!IfInitContext)
535         _isf_imf_context_init ();
536
537     if (context_scim == get_focused_ic ())
538         _isf_imf_context_input_panel_layout_set (layout);
539 }
540
541 /**
542 * Get current ISE layout
543 *
544 * @param[in] ctx a #Ecore_IMF_Context
545 *
546 * @return the layout of current ISE.
547 */
548 EAPI Ecore_IMF_Input_Panel_Layout isf_imf_context_input_panel_layout_get (Ecore_IMF_Context *ctx)
549 {
550     Ecore_IMF_Input_Panel_Layout layout;
551     if (!IfInitContext)
552         _isf_imf_context_init ();
553     _isf_imf_context_input_panel_layout_get (&layout);
554
555     IMFCONTROLUIDBG("[%s] layout : %d\n", __func__, layout);
556
557     return layout;
558 }
559
560 /**
561  * Get current ISE state
562  *
563  * @param[in] ctx a #Ecore_IMF_Context
564  *
565  * @return the state of current ISE.
566  */
567 EAPI Ecore_IMF_Input_Panel_State isf_imf_context_input_panel_state_get (Ecore_IMF_Context *ctx)
568 {
569     IMFCONTROLUIDBG("[%s] state : %d\n", __func__, iseContext.state);
570
571     if (!IfInitContext)
572         _isf_imf_context_init ();
573     return iseContext.state;
574 }
575
576 EAPI void isf_imf_context_input_panel_event_callback_add (Ecore_IMF_Context *ctx,
577                                                           Ecore_IMF_Input_Panel_Event type,
578                                                           void (*func) (void *data, Ecore_IMF_Context *ctx, int value),
579                                                           void *data)
580 {
581     EventCallbackNode *fn = NULL;
582
583     fn = (EventCallbackNode *)calloc (1, sizeof (EventCallbackNode));
584     if (!fn)
585         return;
586
587     IMFCONTROLUIDBG("[%s]\n", __func__);
588
589     fn->func = func;
590     fn->data = data;
591     fn->type = type;
592     fn->imf_context = ctx;
593
594     EventCallbackList = eina_list_append (EventCallbackList, fn);
595 }
596
597 EAPI void isf_imf_context_input_panel_event_callback_del (Ecore_IMF_Context *ctx,
598                                                           Ecore_IMF_Input_Panel_Event type,
599                                                           void (*func) (void *data, Ecore_IMF_Context *ctx, int value))
600 {
601     Eina_List *l = NULL;
602     EventCallbackNode *fn = NULL;
603
604     IMFCONTROLUIDBG("[%s]\n", __func__);
605
606     for (l = EventCallbackList; l;) {
607         fn = (EventCallbackNode *)l->data;
608
609         if ((fn) && (fn->func == func) && (fn->type == type)) {
610             EventCallbackList = eina_list_remove (EventCallbackList, fn);
611             free (fn);
612             break;
613         }
614         l = l->next;
615     }
616 }
617
618 EAPI void isf_imf_context_input_panel_event_callback_clear (Ecore_IMF_Context *ctx)
619 {
620     Eina_List *l;
621     EventCallbackNode *fn;
622
623     IMFCONTROLUIDBG("[%s]\n", __func__);
624
625     for (l = EventCallbackList; l;) {
626         fn = (EventCallbackNode *)l->data;
627
628         if ((fn) && (fn->imf_context == ctx)) {
629             EventCallbackList = eina_list_remove (EventCallbackList, fn);
630             free (fn);
631         }
632         l = l->next;
633     }
634 }
635
636 /**
637  * process command message, ISM_TRANS_CMD_ISE_PANEL_SHOWED of ecore_ise_process_event()
638  */
639 static bool _process_ise_panel_showed (void)
640 {
641     /* When the size of ISE gets changed, STATE_SHOW is be delivered again to letting applications know the change.
642        Later, an event type for notifying the size change of ISE needs to be added instead. */
643     iseContext.state = ECORE_IMF_INPUT_PANEL_STATE_SHOW;
644
645     /* Notify that ISE status has changed */
646     _event_callback_call (ECORE_IMF_INPUT_PANEL_STATE_EVENT, ECORE_IMF_INPUT_PANEL_STATE_SHOW);
647
648     return true;
649 }
650
651 /**
652  * process command message, ISM_TRANS_CMD_ISE_PANEL_HIDED of ecore_ise_process_event()
653  */
654 static bool _process_ise_panel_hided (void)
655 {
656     if (iseContext.state == ECORE_IMF_INPUT_PANEL_STATE_HIDE) {
657         IMFCONTROLUIDBG("ISE is already hided (_process_ise_panel_hided)\n");
658         return false;
659     }
660
661     iseContext.state = ECORE_IMF_INPUT_PANEL_STATE_HIDE;
662
663     /* Notify that ISE status has changed */
664     _event_callback_call (ECORE_IMF_INPUT_PANEL_STATE_EVENT, ECORE_IMF_INPUT_PANEL_STATE_HIDE);
665
666     return true;
667 }
668
669 /**
670  * process command message, ISM_TRANS_CMD_UPDATE_ISE_INPUT_CONTEXT of gtk_ise_process_event()
671  */
672 static bool _process_update_input_context (Transaction &trans)
673 {
674     uint32 type;
675     uint32 value;
676
677     if (!(trans.get_data (type) && trans.get_data (value)))
678         return false;
679
680     IMFCONTROLUIDBG("[%s] receive input context: [%d:%d]\n", __FUNCTION__, type, value);
681
682     if (type == (uint32)ECORE_IMF_INPUT_PANEL_STATE_EVENT && value == (uint32)ECORE_IMF_INPUT_PANEL_STATE_HIDE) {
683         _process_ise_panel_hided ();
684         return true;
685     }
686
687     if (type == (uint32)ECORE_IMF_INPUT_PANEL_STATE_EVENT && value == (uint32)ECORE_IMF_INPUT_PANEL_STATE_SHOW) {
688         _process_ise_panel_showed ();
689         return true;
690     }
691
692     _event_callback_call ((Ecore_IMF_Input_Panel_Event)type, (int)value);
693
694     return true;
695 }
696
697 /**
698  * process ISE data of command message with ISF
699  *
700  * @param[in] trans packet data to be processed
701  * @param[in] cmd command ID that defines with ISF
702  */
703 void ecore_ise_process_data (Transaction &trans, int cmd)
704 {
705     switch (cmd) {
706     case ISM_TRANS_CMD_ISE_PANEL_SHOWED : {
707         IMFCONTROLUIDBG ("cmd is ISM_TRANS_CMD_ISE_PANEL_SHOWED\n");
708         _process_ise_panel_showed ();
709         break;
710     }
711     case ISM_TRANS_CMD_ISE_PANEL_HIDED : {
712         IMFCONTROLUIDBG ("cmd is ISM_TRANS_CMD_ISE_PANEL_HIDED\n");
713         _process_ise_panel_hided ();
714         break;
715     }
716     case ISM_TRANS_CMD_UPDATE_ISE_INPUT_CONTEXT : {
717         IMFCONTROLUIDBG ("cmd is ISM_TRANS_CMD_UPDATE_ISE_INPUT_CONTEXT\n");
718         _process_update_input_context (trans);
719         break;
720     }
721     default :
722         IMFCONTROLUIDBG("unknown command");
723         break;
724     }
725 }
726