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