3 #include "e_mod_main.h"
4 #include <text-server-protocol.h>
5 #include <input-method-server-protocol.h>
7 #include <vconf-keys.h>
11 #include <system_info.h>
16 #define LOG_TAG "WL_TEXTINPUT"
18 #define WTI_WARNING(resource, code, msg) (_e_text_input_log_show((resource), (code), (msg), __func__))
20 tizen_profile_t _get_tizen_profile()
22 static tizen_profile_t profile = TIZEN_PROFILE_UNKNOWN;
23 if (__builtin_expect(profile != TIZEN_PROFILE_UNKNOWN, 1))
27 system_info_get_platform_string("http://tizen.org/feature/profile", &profileName);
32 profile = TIZEN_PROFILE_MOBILE;
36 profile = TIZEN_PROFILE_WEARABLE;
40 profile = TIZEN_PROFILE_TV;
44 profile = TIZEN_PROFILE_IVI;
46 default: // common or unknown ==> ALL ARE COMMON.
47 profile = TIZEN_PROFILE_COMMON;
54 static Eina_Bool _e_text_input_method_context_cb_client_resize(void *data EINA_UNUSED, int type, void *event);
55 static void set_soft_keyboard_mode();
57 typedef struct _E_Text_Input E_Text_Input;
58 typedef struct _E_Text_Input_Mgr E_Text_Input_Mgr;
59 typedef struct _E_Input_Method E_Input_Method;
60 typedef struct _E_Input_Method_Context E_Input_Method_Context;
61 typedef struct _E_Mod_Text_Input_Shutdown_Cb E_Mod_Text_Input_Shutdown_Cb;
65 struct wl_resource *resource;
67 Eina_List *input_methods;
68 Eina_Bool input_panel_visibile;
72 struct _E_Text_Input_Mgr
74 struct wl_global *global;
75 struct wl_resource *resource;
77 Eina_List *text_input_list;
80 struct _E_Input_Method
82 struct wl_global *global;
83 struct wl_resource *resource;
86 E_Input_Method_Context *context;
89 struct _E_Input_Method_Context
91 struct wl_resource *resource;
94 E_Input_Method *input_method;
96 #if ENABLE_GRAB_KEYBOARD
99 struct wl_resource *resource;
102 struct xkb_keymap *keymap;
103 struct xkb_state *state;
104 xkb_mod_mask_t mod_depressed, mod_latched, mod_locked;
105 xkb_layout_index_t mod_group;
111 struct _E_Mod_Text_Input_Shutdown_Cb
113 void (*func)(void *data);
117 /* This represents the overall input panel's state including the candidate area */
118 enum _E_Input_Panel_State
120 E_INPUT_PANEL_STATE_DID_HIDE,
121 E_INPUT_PANEL_STATE_WILL_HIDE,
122 E_INPUT_PANEL_STATE_DID_SHOW,
123 E_INPUT_PANEL_STATE_WILL_SHOW,
126 static E_Input_Method *g_input_method = NULL;
127 static E_Text_Input *g_text_input = NULL;
128 static struct wl_client *g_client = NULL;
129 static Eina_List *shutdown_list = NULL;
130 static Eina_Bool g_disable_show_panel = EINA_FALSE;
131 static Eeze_Udev_Watch *eeze_udev_watch_hander = NULL;
132 static Ecore_Event_Handler *ecore_key_down_handler = NULL;
133 static Eina_List *handlers = NULL;
134 static uint32_t g_text_input_count = 1;
135 static Ecore_Timer *g_timer_will_hide = NULL;
136 static enum _E_Input_Panel_State g_input_panel_state = E_INPUT_PANEL_STATE_DID_HIDE;
137 static E_Client *client_surface_ec = NULL;
138 static E_Text_Input *g_show_text_input = NULL;
139 static struct wl_client *g_show_client = NULL;
140 static Eina_Bool g_updated_geometry = EINA_FALSE;
142 /* The candidate's show state that was requested by the application or IME */
143 static Eina_Bool g_show_state_candidate = EINA_FALSE;
145 static Eina_List *hooks_ec = NULL;
147 const int WILL_HIDE_TIMER_INTERVAL = 1.0f;
149 #undef E_CLIENT_HOOK_APPEND
150 #define E_CLIENT_HOOK_APPEND(l, t, cb, d) \
154 _h = e_client_hook_add(t, cb, d); \
156 l = eina_list_append(l, _h); \
160 static void _e_text_input_cb_input_panel_show(struct wl_client *client, struct wl_resource *resource);
161 static void _e_text_input_deactivate(E_Text_Input *text_input, E_Input_Method *input_method, Eina_Bool need_focus_in);
162 static Eina_Bool _e_text_input_method_create_context(struct wl_client *client, E_Input_Method *input_method, E_Text_Input *text_input, Eina_Bool need_focus_out);
165 e_text_input_client_surface_get(void)
167 return client_surface_ec;
171 _e_text_input_log_show(struct wl_resource *resource, uint32_t code, const char *msg, const char *warning_msg)
173 LOGE("%s() is failed. msg : %s\n", warning_msg, msg);
177 _e_text_input_send_input_panel_geometry(struct wl_resource *resource, int x, int y, int w, int h)
182 if (client_surface_ec)
184 angle = client_surface_ec->e.state.rot.ang.next < 0 ?
185 client_surface_ec->e.state.rot.ang.curr :
186 client_surface_ec->e.state.rot.ang.next;
188 LOGD("curr : %d, next : %d, angle : %d\n", client_surface_ec->e.state.rot.ang.curr,
189 client_surface_ec->e.state.rot.ang.next, angle);
192 snprintf(geometry, sizeof(geometry), "%d,%d,%d,%d", x, y, w, h);
198 vconf_set_str(VCONFKEY_ISF_IME_RECENT_LAND_GEOMETRY, geometry);
201 vconf_set_str(VCONFKEY_ISF_IME_RECENT_PORT_GEOMETRY, geometry);
205 LOGD("angle : %d, x : %d, y : %d, w : %d, h : %d\n", angle, x, y, w, h);
207 wl_text_input_send_input_panel_geometry(resource, x, y, w, h);
211 _will_hide_timer_handler(void *data)
213 INF("TIMED OUT while waiting for WILL_HIDE_ACK : %d", g_input_panel_state);
214 if (g_input_panel_state == E_INPUT_PANEL_STATE_WILL_HIDE)
216 e_input_panel_visibility_change(EINA_FALSE);
217 e_input_panel_transient_for_set(NULL);
218 g_input_panel_state = E_INPUT_PANEL_STATE_DID_HIDE;
221 if (g_timer_will_hide)
223 ecore_timer_del(g_timer_will_hide);
224 g_timer_will_hide = NULL;
227 return ECORE_CALLBACK_CANCEL;
231 _input_panel_hide(struct wl_client *client, struct wl_resource *resource, Eina_Bool force_hide)
233 E_Text_Input *text_input = wl_resource_get_user_data(resource);
234 E_Input_Method *input_method = NULL;
235 Eina_Bool _context_created = EINA_FALSE;
242 WTI_WARNING(resource,
243 WL_DISPLAY_ERROR_INVALID_OBJECT,
244 "No Text Input For Resource");
248 text_input->input_panel_visibile = EINA_FALSE;
250 if (text_input->resource)
252 wl_text_input_send_input_panel_geometry(text_input->resource, 0, 0, 0, 0);
253 wl_text_input_send_input_panel_state(text_input->resource, WL_TEXT_INPUT_INPUT_PANEL_STATE_HIDE);
258 e_input_panel_visibility_change(EINA_FALSE);
259 e_input_panel_transient_for_set(NULL);
260 g_input_panel_state = E_INPUT_PANEL_STATE_DID_HIDE;
264 g_input_panel_state = E_INPUT_PANEL_STATE_WILL_HIDE;
265 /* Temporarily sending private command, will need for a new wayland protocol */
266 if (text_input->resource)
267 wl_text_input_send_private_command(text_input->resource, 0, "CONFORMANT_RESET");
269 if (g_timer_will_hide)
271 ecore_timer_del(g_timer_will_hide);
272 g_timer_will_hide = NULL;
275 zone = e_zone_current_get();
276 effect_run = e_input_panel_is_effect_running();
277 if (zone && (zone->display_state == E_ZONE_DISPLAY_STATE_OFF))
282 timeout = WILL_HIDE_TIMER_INTERVAL;
283 g_timer_will_hide = ecore_timer_add(timeout, _will_hide_timer_handler, NULL);
286 if (g_input_method && g_input_method->resource)
287 input_method = wl_resource_get_user_data(g_input_method->resource);
290 If input_method->context is already deleted, create context struct again to send input_panel_hide event to Input Method(IME) correctly.
291 Because input_panel_hide event can be called after focus_out(deactivate) by application.
292 And Input Method(IME) should know the state of their own input_panel to manage their resource when the input_panel is hidden.
295 ((!input_method->context) || (!input_method->context->resource)))
296 _context_created = _e_text_input_method_create_context(client, input_method, text_input, EINA_FALSE);
298 if (input_method && input_method->resource && input_method->context && input_method->context->resource)
299 wl_input_method_send_hide_input_panel(input_method->resource, input_method->context->resource);
301 if (_context_created)
302 _e_text_input_deactivate(text_input, input_method, EINA_FALSE);
304 e_input_panel_wait_update_set(EINA_FALSE);
306 /* When the input panel suface is hidden, the candidate will hide too */
307 g_show_state_candidate = EINA_FALSE;
311 _keyboard_mode_changed_cb(keynode_t *key, void* data)
313 bool val = vconf_keynode_get_bool(key);
314 LOGD("keyboard mode : %d\n", val);
318 #ifdef SUPPORT_CANDIDATE_ONEWINDOW
319 /* Switching to S/W keyboard mode, hide input panel since it could be displaying candidate only */
320 if (g_disable_show_panel && g_text_input && g_text_input->resource && g_client)
321 _input_panel_hide(g_client, g_text_input->resource, EINA_FALSE);
323 g_disable_show_panel = EINA_FALSE;
327 #ifdef SUPPORT_CANDIDATE_ONEWINDOW
328 /* Switching to H/W keyboard mode, hide input panel only if there is no candidate */
329 if (!g_show_state_candidate && g_text_input && g_text_input->resource && g_client)
331 if (g_text_input && g_text_input->resource && g_client)
333 _input_panel_hide(g_client, g_text_input->resource, EINA_FALSE);
335 g_disable_show_panel = EINA_TRUE;
340 #if ENABLE_GRAB_KEYBOARD
342 _e_text_input_method_context_keyboard_grab_keyboard_state_update(E_Input_Method_Context *context, uint32_t keycode, Eina_Bool pressed)
344 enum xkb_key_direction dir;
346 if (!context->kbd.state) return;
348 if (pressed) dir = XKB_KEY_DOWN;
349 else dir = XKB_KEY_UP;
351 context->kbd.mod_changed =
352 xkb_state_update_key(context->kbd.state, keycode + 8, dir);
356 _e_text_input_method_context_keyboard_grab_keyboard_modifiers_update(E_Input_Method_Context *context, struct wl_resource *keyboard)
360 if (!context->input) return;
361 if (!context->kbd.state) return;
363 context->kbd.mod_depressed =
364 xkb_state_serialize_mods(context->kbd.state, XKB_STATE_DEPRESSED);
365 context->kbd.mod_latched =
366 xkb_state_serialize_mods(context->kbd.state, XKB_STATE_MODS_LATCHED);
367 context->kbd.mod_locked =
368 xkb_state_serialize_mods(context->kbd.state, XKB_STATE_MODS_LOCKED);
369 context->kbd.mod_group =
370 xkb_state_serialize_layout(context->kbd.state, XKB_STATE_LAYOUT_EFFECTIVE);
372 serial = wl_display_next_serial(e_comp_wl->wl.disp);
373 wl_keyboard_send_modifiers(keyboard, serial,
374 context->kbd.mod_depressed,
375 context->kbd.mod_latched,
376 context->kbd.mod_locked,
377 context->kbd.mod_group);
381 _e_text_input_method_context_key_send(E_Input_Method_Context *context, unsigned int keycode, unsigned int timestamp, enum wl_keyboard_key_state state)
385 if (!context->input) return;
388 /* update modifier state */
389 _e_text_input_method_context_keyboard_grab_keyboard_state_update(context, nk, state == WL_KEYBOARD_KEY_STATE_PRESSED);
391 serial = wl_display_next_serial(e_comp_wl->wl.disp);
393 wl_keyboard_send_key(context->kbd.resource, serial, timestamp, nk, state);
394 if (context->kbd.mod_changed)
396 _e_text_input_method_context_keyboard_grab_keyboard_modifiers_update(context, context->kbd.resource);
397 context->kbd.mod_changed = 0;
402 _e_text_input_method_context_ecore_cb_key_down(void *data, int ev_type EINA_UNUSED, Ecore_Event_Key *ev)
404 E_Input_Method_Context *context = data;
406 _e_text_input_method_context_key_send(context, ev->keycode, ev->timestamp,
407 WL_KEYBOARD_KEY_STATE_PRESSED);
409 return ECORE_CALLBACK_RENEW;
413 _e_text_input_method_context_ecore_cb_key_up(void *data, int ev_type EINA_UNUSED, Ecore_Event_Key *ev)
415 E_Input_Method_Context *context = data;
417 _e_text_input_method_context_key_send(context, ev->keycode, ev->timestamp,
418 WL_KEYBOARD_KEY_STATE_RELEASED);
420 return ECORE_CALLBACK_RENEW;
424 _e_text_input_method_context_grab_set(E_Input_Method_Context *context, Eina_Bool set)
426 if (set == context->kbd.grabbed)
432 context->kbd.grabbed = set;
436 if (context->kbd.keymap) xkb_map_unref(context->kbd.keymap);
437 if (context->kbd.state) xkb_state_unref(context->kbd.state);
438 context->kbd.keymap = xkb_map_ref(e_comp_wl->xkb.keymap);
439 context->kbd.state = xkb_state_new(e_comp_wl->xkb.keymap);
440 E_LIST_HANDLER_APPEND(context->kbd.handlers, ECORE_EVENT_KEY_DOWN,
441 _e_text_input_method_context_ecore_cb_key_down,
443 E_LIST_HANDLER_APPEND(context->kbd.handlers, ECORE_EVENT_KEY_UP,
444 _e_text_input_method_context_ecore_cb_key_up,
447 e_comp_grab_input(0, 1);
451 E_FREE_LIST(context->kbd.handlers, ecore_event_handler_del);
453 e_comp_ungrab_input(0, 1);
455 if (context->kbd.keymap)
457 xkb_map_unref(context->kbd.keymap);
458 context->kbd.keymap = NULL;
461 if (context->kbd.state)
463 xkb_state_unref(context->kbd.state);
464 context->kbd.state = NULL;
471 _e_mod_text_input_shutdown_cb_add(void (*func)(void *data), void *data)
473 E_Mod_Text_Input_Shutdown_Cb *cb;
475 if (!(cb = E_NEW(E_Mod_Text_Input_Shutdown_Cb, 1)))
477 ERR("Could not allocate space for Text Input Shutdown Callback");
484 shutdown_list = eina_list_append(shutdown_list, cb);
488 _e_text_input_method_context_cb_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
490 wl_resource_destroy(resource);
494 _e_text_input_method_context_cb_string_commit(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t serial, const char *text)
496 E_Input_Method_Context *context = wl_resource_get_user_data(resource);
500 WTI_WARNING(resource,
501 WL_DISPLAY_ERROR_INVALID_OBJECT,
502 "No Input Method Context For Resource");
506 if ((context->input) && (context->input->resource))
507 wl_text_input_send_commit_string(context->input->resource,
512 _e_text_input_method_context_cb_preedit_string(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t serial, const char *text, const char *commit)
514 E_Input_Method_Context *context = wl_resource_get_user_data(resource);
518 WTI_WARNING(resource,
519 WL_DISPLAY_ERROR_INVALID_OBJECT,
520 "No Input Method Context For Resource");
524 if ((context->input) && (context->input->resource))
525 wl_text_input_send_preedit_string(context->input->resource,
526 serial, text, commit);
530 _e_text_input_method_context_cb_recapture_string(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t serial, int32_t index, uint32_t length, const char *preedit, const char *preedit_commit, const char *commit)
532 E_Input_Method_Context *context = wl_resource_get_user_data(resource);
536 WTI_WARNING(resource,
537 WL_DISPLAY_ERROR_INVALID_OBJECT,
538 "No Input Method Context For Resource");
542 if ((context->input) && (context->input->resource))
543 wl_text_input_send_recapture_string(context->input->resource,
544 serial, index, length, preedit, preedit_commit, commit);
548 _e_text_input_method_context_cb_preedit_styling(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t index, uint32_t length, uint32_t style)
550 E_Input_Method_Context *context = wl_resource_get_user_data(resource);
554 WTI_WARNING(resource,
555 WL_DISPLAY_ERROR_INVALID_OBJECT,
556 "No Input Method Context For Resource");
560 if ((context->input) && (context->input->resource))
561 wl_text_input_send_preedit_styling(context->input->resource,
562 index, length, style);
566 _e_text_input_method_context_cb_preedit_cursor(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, int32_t cursor)
568 E_Input_Method_Context *context = wl_resource_get_user_data(resource);
572 WTI_WARNING(resource,
573 WL_DISPLAY_ERROR_INVALID_OBJECT,
574 "No Input Method Context For Resource");
578 if ((context->input) && (context->input->resource))
579 wl_text_input_send_preedit_cursor(context->input->resource,
584 _e_text_input_method_context_cb_surrounding_text_delete(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, int32_t index, uint32_t length)
586 E_Input_Method_Context *context = wl_resource_get_user_data(resource);
590 WTI_WARNING(resource,
591 WL_DISPLAY_ERROR_INVALID_OBJECT,
592 "No Input Method Context For Resource");
596 if ((context->input) && (context->input->resource))
597 wl_text_input_send_delete_surrounding_text(context->input->resource,
602 _e_text_input_method_context_cb_cursor_position(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, int32_t index, int32_t anchor)
604 E_Input_Method_Context *context = wl_resource_get_user_data(resource);
608 WTI_WARNING(resource,
609 WL_DISPLAY_ERROR_INVALID_OBJECT,
610 "No Input Method Context For Resource");
614 if ((context->input) && (context->input->resource))
615 wl_text_input_send_cursor_position(context->input->resource,
620 _e_text_input_method_context_cb_modifiers_map(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_array *map)
622 E_Input_Method_Context *context = wl_resource_get_user_data(resource);
626 WTI_WARNING(resource,
627 WL_DISPLAY_ERROR_INVALID_OBJECT,
628 "No Input Method Context For Resource");
632 if ((context->input) && (context->input->resource))
633 wl_text_input_send_modifiers_map(context->input->resource, map);
637 _e_keyevent_free(void *data EINA_UNUSED, void *ev)
639 Ecore_Event_Key *e = ev;
642 eina_stringshare_del(e->keyname);
645 eina_stringshare_del(e->key);
648 eina_stringshare_del(e->compose);
651 eina_stringshare_del(e->string);
657 feed_key_event(const char *keyname, const char *key, const char *string, int keycode, int state)
659 Ecore_Event_Key *e = E_NEW(Ecore_Event_Key, 1);
662 e->keyname = (char *)eina_stringshare_add(keyname);
663 e->key = (char *)eina_stringshare_add(key);
664 e->string = (char *)eina_stringshare_add(string);
665 e->compose = (char *)eina_stringshare_add(e->string);
667 e->timestamp = 0; /* For distinguishing S/W keyboard event */
669 e->keycode = keycode;
671 ecore_event_add(state ? ECORE_EVENT_KEY_DOWN : ECORE_EVENT_KEY_UP, e, _e_keyevent_free, NULL);
675 _e_text_input_method_context_cb_keysym(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t serial, uint32_t time, uint32_t sym, uint32_t state, uint32_t modifiers)
677 E_Input_Method_Context *context = wl_resource_get_user_data(resource);
681 WTI_WARNING(resource,
682 WL_DISPLAY_ERROR_INVALID_OBJECT,
683 "No Input Method Context For Resource");
687 if ((context->input) && (context->input->resource))
689 wl_text_input_send_keysym(context->input->resource,
690 serial, time, sym, state, modifiers);
694 char string[32], key[32], keyname[32];
696 memset(keyname, 0, sizeof(keyname));
697 xkb_keysym_get_name(sym, keyname, sizeof(keyname));
698 if (keyname[0] == '\0')
699 snprintf(keyname, sizeof(keyname), "Keysym-%u", sym);
701 if (strcmp(keyname, "BackSpace") == 0)
703 /* backspace key should be supported in the multibutton entry of elementary
704 even though it losts focus */
705 memset(key, 0, sizeof(key));
706 xkb_keysym_get_name(sym, key, sizeof(key));
708 memset(string, 0, sizeof(string));
709 xkb_keysym_to_utf8(sym, string, 32);
713 /* Backspace keycode (22) */
714 feed_key_event(keyname, key, string, 22, 1); /* key down */
715 feed_key_event(keyname, key, string, 22, 0); /* key up */
721 #if ENABLE_GRAB_KEYBOARD
723 _e_text_input_method_context_keyboard_grab_cb_resource_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
725 wl_resource_destroy(resource);
728 static const struct wl_keyboard_interface _e_keyboard_grab_interface =
730 _e_text_input_method_context_keyboard_grab_cb_resource_destroy
734 _e_text_input_method_context_keyboard_grab_cb_keyboard_unbind(struct wl_resource *resource)
736 E_Input_Method_Context *context = wl_resource_get_user_data(resource);
740 WTI_WARNING(resource,
741 WL_DISPLAY_ERROR_INVALID_OBJECT,
742 "No Input Method Context For Resource");
746 _e_text_input_method_context_grab_set(context, EINA_FALSE);
748 context->kbd.resource = NULL;
753 _e_text_input_method_context_cb_keyboard_grab(struct wl_client *client, struct wl_resource *resource, uint32_t id)
755 DBG("Input Method Context - grab keyboard %d", wl_resource_get_id(resource));
756 #if ENABLE_GRAB_KEYBOARD
757 E_Input_Method_Context *context = wl_resource_get_user_data(resource);
758 struct wl_resource *keyboard = NULL;
762 WTI_WARNING(resource,
763 WL_DISPLAY_ERROR_INVALID_OBJECT,
764 "No Input Method Context For Resource");
768 keyboard = wl_resource_create(client, &wl_keyboard_interface, 1, id);
771 wl_client_post_no_memory(client);
775 wl_resource_set_implementation(keyboard, &_e_keyboard_grab_interface, context, _e_text_input_method_context_keyboard_grab_cb_keyboard_unbind);
777 /* send current keymap */
778 wl_keyboard_send_keymap(keyboard, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
779 e_comp_wl->xkb.fd, e_comp_wl->xkb.size);
781 context->kbd.resource = keyboard;
783 _e_text_input_method_context_grab_set(context, EINA_TRUE);
788 _e_text_input_method_context_cb_key(struct wl_client *client, struct wl_resource *resource, uint32_t serial, uint32_t time, uint32_t key, uint32_t state_w)
790 DBG("Input Method Context - key %d", wl_resource_get_id(resource));
801 _e_text_input_method_context_cb_modifiers(struct wl_client *client, struct wl_resource *resource, uint32_t serial, uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, uint32_t group)
803 DBG("Input Method Context - modifiers %d", wl_resource_get_id(resource));
808 (void)mods_depressed;
815 _e_text_input_method_context_cb_language(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t serial, const char *language)
817 E_Input_Method_Context *context = wl_resource_get_user_data(resource);
821 WTI_WARNING(resource,
822 WL_DISPLAY_ERROR_INVALID_OBJECT,
823 "No Input Method Context For Resource");
827 if ((context->input) && (context->input->resource))
828 wl_text_input_send_language(context->input->resource,
833 _e_text_input_method_context_cb_text_direction(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t serial, uint32_t direction)
835 E_Input_Method_Context *context = wl_resource_get_user_data(resource);
839 WTI_WARNING(resource,
840 WL_DISPLAY_ERROR_INVALID_OBJECT,
841 "No Input Method Context For Resource");
845 if ((context->input) && (context->input->resource))
846 wl_text_input_send_text_direction(context->input->resource,
851 _e_text_input_method_context_cb_selection_region(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t serial, int32_t start, int32_t end)
853 E_Input_Method_Context *context = wl_resource_get_user_data(resource);
857 WTI_WARNING(resource,
858 WL_DISPLAY_ERROR_INVALID_OBJECT,
859 "No Input Method Context For Resource");
863 if ((context->input) && (context->input->resource))
864 wl_text_input_send_selection_region(context->input->resource,
869 _e_text_input_method_context_cb_private_command(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t serial, const char *command)
871 E_Input_Method_Context *context = wl_resource_get_user_data(resource);
875 WTI_WARNING(resource,
876 WL_DISPLAY_ERROR_INVALID_OBJECT,
877 "No Input Method Context For Resource");
881 if ((context->input) && (context->input->resource))
882 wl_text_input_send_private_command(context->input->resource,
887 _e_text_input_method_context_cb_commit_content(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t serial, const char *content, const char *description, const char *mime_types)
889 E_Input_Method_Context *context = wl_resource_get_user_data(resource);
893 WTI_WARNING(resource,
894 WL_DISPLAY_ERROR_INVALID_OBJECT,
895 "No Input Method Context For Resource");
899 if ((context->input) && (context->input->resource))
900 wl_text_input_send_commit_content(context->input->resource,
901 serial, content, description, mime_types);
905 _e_text_input_method_context_cb_input_panel_event(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t serial, uint32_t event_type, uint32_t value)
907 E_Input_Method_Context *context = wl_resource_get_user_data(resource);
911 WTI_WARNING(resource,
912 WL_DISPLAY_ERROR_INVALID_OBJECT,
913 "No Input Method Context For Resource");
917 if ((context->input) && (context->input->resource))
918 wl_text_input_send_input_panel_event(context->input->resource,
919 serial, event_type, value);
923 _e_text_input_method_context_cb_update_candidate_state(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t state)
925 E_Input_Method_Context *context = wl_resource_get_user_data(resource);
929 WTI_WARNING(resource,
930 WL_DISPLAY_ERROR_INVALID_OBJECT,
931 "No Input Method Context For Resource");
935 LOGD("Candidate State : %d", state);
936 Eina_Bool prev_show_state = g_show_state_candidate;
937 g_show_state_candidate = state;
938 if (g_input_panel_state == E_INPUT_PANEL_STATE_DID_HIDE)
939 prev_show_state = EINA_FALSE;
943 /* If the candidate state has been changed to OFF when panel is not in show state, */
944 if (!g_show_state_candidate && prev_show_state && g_disable_show_panel && g_client && g_text_input)
945 _input_panel_hide(g_client, g_text_input->resource, EINA_FALSE);
949 /* If the candidate state has been changed to ON when panel is not in show state */
950 if (g_show_state_candidate && !prev_show_state && g_disable_show_panel && g_client && g_text_input)
952 _e_text_input_cb_input_panel_show(g_client, g_text_input->resource);
953 int x = 0, y = 0, w = 0, h = 0;
954 if (e_input_panel_client_geometry_get(NULL, &x, &y, &w, &h) && !(w <= 1 || h <= 1))
955 _e_text_input_send_input_panel_geometry(g_text_input->resource, x, y, w, h);
961 _e_text_input_method_context_cb_input_panel_data_update(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t serial, const char *data, uint32_t length)
963 E_Input_Method_Context *context = wl_resource_get_user_data(resource);
967 WTI_WARNING(resource,
968 WL_DISPLAY_ERROR_INVALID_OBJECT,
969 "No Input Method Context For Resource");
973 if ((context->input) && (context->input->resource))
974 wl_text_input_send_input_panel_data(context->input->resource,
975 serial, data, length);
979 _e_text_input_method_context_cb_hide_input_panel(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t serial)
981 E_Text_Input *text_input = g_text_input;
982 E_Input_Method *input_method = NULL;
986 WTI_WARNING(resource,
987 WL_DISPLAY_ERROR_INVALID_OBJECT,
988 "No Text Input For Resource");
992 text_input->input_panel_visibile = EINA_FALSE;
994 if (g_text_input && g_text_input->resource && g_client)
995 _input_panel_hide(g_client, g_text_input->resource, EINA_FALSE);
997 if (g_input_method && g_input_method->resource)
998 input_method = wl_resource_get_user_data(g_input_method->resource);
1000 if (input_method && input_method->resource && input_method->context && input_method->context->resource)
1001 wl_input_method_send_hide_input_panel(input_method->resource, input_method->context->resource);
1005 _e_text_input_method_context_cb_get_selection_text(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, int32_t fd)
1007 E_Input_Method_Context *context = wl_resource_get_user_data(resource);
1011 WTI_WARNING(resource,
1012 WL_DISPLAY_ERROR_INVALID_OBJECT,
1013 "No Input Method Context For Resource");
1018 if ((context->input) && (context->input->resource))
1019 wl_text_input_send_get_selection_text(context->input->resource, fd);
1025 _e_text_input_method_context_cb_get_surrounding_text(struct wl_client *client EINA_UNUSED, struct wl_resource *resource,
1026 uint32_t maxlen_before, uint32_t maxlen_after, int32_t fd)
1028 E_Input_Method_Context *context = wl_resource_get_user_data(resource);
1032 WTI_WARNING(resource,
1033 WL_DISPLAY_ERROR_INVALID_OBJECT,
1034 "No Input Method Context For Resource");
1039 if ((context->input) && (context->input->resource))
1040 wl_text_input_send_get_surrounding_text(context->input->resource, maxlen_before, maxlen_after, fd);
1046 _e_text_input_method_context_cb_filter_key_event_done(struct wl_client *client EINA_UNUSED, struct wl_resource *resource,
1047 uint32_t serial, uint32_t state)
1049 E_Input_Method_Context *context = wl_resource_get_user_data(resource);
1053 WTI_WARNING(resource,
1054 WL_DISPLAY_ERROR_INVALID_OBJECT,
1055 "No Input Method Context For Resource");
1059 if ((context->input) && (context->input->resource))
1060 wl_text_input_send_filter_key_event_done(context->input->resource,
1065 _e_text_input_method_context_cb_update_ise_geometry(struct wl_client *client EINA_UNUSED, struct wl_resource *resource,
1066 uint32_t serial, uint32_t x, uint32_t y, uint32_t width, uint32_t height)
1068 E_Input_Method_Context *context = wl_resource_get_user_data(resource);
1072 WTI_WARNING(resource,
1073 WL_DISPLAY_ERROR_INVALID_OBJECT,
1074 "No Input Method Context For Resource");
1078 if ((context->input) && (context->input->resource))
1080 _e_text_input_send_input_panel_geometry(context->input->resource, x, y, width, height);
1081 g_updated_geometry = EINA_TRUE;
1087 _e_text_input_method_context_cb_reshow_input_panel(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
1089 e_input_panel_transient_for_set(client_surface_ec);
1090 e_input_panel_wait_update_set(EINA_TRUE);
1092 static const struct wl_input_method_context_interface _e_text_input_method_context_implementation = {
1093 _e_text_input_method_context_cb_destroy,
1094 _e_text_input_method_context_cb_string_commit,
1095 _e_text_input_method_context_cb_preedit_string,
1096 _e_text_input_method_context_cb_preedit_styling,
1097 _e_text_input_method_context_cb_preedit_cursor,
1098 _e_text_input_method_context_cb_surrounding_text_delete,
1099 _e_text_input_method_context_cb_cursor_position,
1100 _e_text_input_method_context_cb_modifiers_map,
1101 _e_text_input_method_context_cb_keysym,
1102 _e_text_input_method_context_cb_keyboard_grab,
1103 _e_text_input_method_context_cb_key,
1104 _e_text_input_method_context_cb_modifiers,
1105 _e_text_input_method_context_cb_language,
1106 _e_text_input_method_context_cb_text_direction,
1107 _e_text_input_method_context_cb_selection_region,
1108 _e_text_input_method_context_cb_private_command,
1109 _e_text_input_method_context_cb_input_panel_data_update,
1110 _e_text_input_method_context_cb_hide_input_panel,
1111 _e_text_input_method_context_cb_get_selection_text,
1112 _e_text_input_method_context_cb_get_surrounding_text,
1113 _e_text_input_method_context_cb_filter_key_event_done,
1114 _e_text_input_method_context_cb_update_ise_geometry,
1115 _e_text_input_method_context_cb_recapture_string,
1116 _e_text_input_method_context_cb_input_panel_event,
1117 _e_text_input_method_context_cb_commit_content,
1118 _e_text_input_method_context_cb_update_candidate_state,
1119 _e_text_input_method_context_cb_reshow_input_panel,
1123 _e_text_input_method_context_cb_resource_destroy(struct wl_resource *resource)
1125 E_Input_Method_Context *context = wl_resource_get_user_data(resource);
1129 WTI_WARNING(resource,
1130 WL_DISPLAY_ERROR_INVALID_OBJECT,
1131 "No Input Method Context For Resource");
1135 #if ENABLE_GRAB_KEYBOARD
1136 if (context->kbd.resource)
1137 wl_resource_destroy(context->kbd.resource);
1140 if ((context->input_method) &&
1141 (context->input_method->context == context))
1142 context->input_method->context = NULL;
1147 static Eina_Bool is_number_key(const char *str)
1149 if (!str) return EINA_FALSE;
1151 int result = atoi(str);
1155 if (!strcmp(str, "0"))
1165 _e_mod_ecore_key_down_cb(void *data, int type, void *event)
1167 Ecore_Event_Key *ev = (Ecore_Event_Key *)event;
1169 if (g_disable_show_panel == EINA_TRUE)
1170 return ECORE_CALLBACK_PASS_ON;
1172 /* process remote controller key exceptionally */
1173 if (((!strcmp(ev->key, "Down") ||
1174 !strcmp(ev->key, "KP_Down") ||
1175 !strcmp(ev->key, "Up") ||
1176 !strcmp(ev->key, "KP_Up") ||
1177 !strcmp(ev->key, "Right") ||
1178 !strcmp(ev->key, "KP_Right") ||
1179 !strcmp(ev->key, "Left") ||
1180 !strcmp(ev->key, "KP_Left")) && !ev->string) ||
1181 !strcmp(ev->key, "Return") ||
1182 !strcmp(ev->key, "Pause") ||
1183 !strcmp(ev->key, "NoSymbol") ||
1184 !strncmp(ev->key, "XF86", 4) ||
1185 is_number_key(ev->string))
1186 return ECORE_CALLBACK_PASS_ON;
1188 if (g_text_input && g_text_input->resource && g_client)
1189 _input_panel_hide(g_client, g_text_input->resource, EINA_FALSE);
1191 g_disable_show_panel = EINA_TRUE;
1193 return ECORE_CALLBACK_PASS_ON;
1197 _e_text_input_deactivate(E_Text_Input *text_input, E_Input_Method *input_method, Eina_Bool need_focus_in)
1199 LOGD("text_input : %p\n", text_input);
1201 if (text_input == g_text_input)
1203 g_text_input = NULL;
1207 if (input_method->input == text_input)
1209 if ((input_method->context) && (input_method->resource))
1211 #if ENABLE_GRAB_KEYBOARD
1212 _e_text_input_method_context_grab_set(input_method->context,
1215 /* TODO: finish the grab of keyboard. */
1216 wl_input_method_send_deactivate(input_method->resource,
1217 input_method->context->resource,
1221 if (ecore_key_down_handler)
1223 ecore_event_handler_del(ecore_key_down_handler);
1224 ecore_key_down_handler = NULL;
1227 LOGD("Resetting input_method->input : %p", input_method->input);
1228 input_method->input = NULL;
1229 if (input_method->context) input_method->context->input = NULL;
1230 input_method->context = NULL;
1232 text_input->input_methods = eina_list_remove(text_input->input_methods, input_method);
1234 if (text_input->resource)
1235 wl_text_input_send_leave(text_input->resource);
1238 g_disable_show_panel = EINA_FALSE;
1243 _e_text_input_cb_activate(struct wl_client *client, struct wl_resource *resource, struct wl_resource *seat, struct wl_resource *surface)
1245 E_Text_Input *text_input = NULL;
1246 E_Input_Method *input_method = NULL;
1247 E_Text_Input *old = NULL;
1248 E_Input_Method_Context *context = NULL;
1249 E_Client *ec = NULL;
1251 EINA_SAFETY_ON_NULL_GOTO(resource, err);
1252 EINA_SAFETY_ON_NULL_GOTO(seat, err);
1253 EINA_SAFETY_ON_NULL_GOTO(g_input_method, err);
1254 EINA_SAFETY_ON_NULL_GOTO(g_input_method->resource, err);
1256 /* Store application window's E_Client* value for setting transient_for information later */
1257 ec = wl_resource_get_user_data(surface);
1258 EINA_SAFETY_ON_NULL_GOTO(ec, err);
1259 EINA_SAFETY_ON_TRUE_GOTO(e_object_is_del(E_OBJECT(ec)), err);
1260 client_surface_ec = ec;
1262 text_input = wl_resource_get_user_data(resource);
1263 g_text_input = text_input;
1266 /* FIXME: should get input_method object from seat. */
1267 input_method = wl_resource_get_user_data(g_input_method->resource);
1268 EINA_SAFETY_ON_NULL_GOTO(input_method, err);
1270 old = input_method->input;
1272 LOGD("old : %p, text_input : %p, %d", old, text_input, g_input_panel_state);
1273 if (old == text_input)
1277 _e_text_input_deactivate(old, input_method, EINA_TRUE);
1279 input_method->input = text_input;
1280 text_input->input_methods = eina_list_append(text_input->input_methods, input_method);
1282 if (input_method->resource)
1284 if (!(context = E_NEW(E_Input_Method_Context, 1)))
1286 wl_client_post_no_memory(client);
1287 ERR("Could not allocate space for Input_Method_Context");
1291 if (!ecore_key_down_handler)
1292 ecore_key_down_handler = ecore_event_handler_add(ECORE_EVENT_KEY_DOWN,
1293 _e_mod_ecore_key_down_cb,
1297 wl_resource_create(wl_resource_get_client(input_method->resource),
1298 &wl_input_method_context_interface, 1, 0);
1300 if (context->resource)
1301 wl_resource_set_implementation(context->resource,
1302 &_e_text_input_method_context_implementation,
1303 context, _e_text_input_method_context_cb_resource_destroy);
1305 context->input = text_input;
1306 context->input_method = input_method;
1307 input_method->context = context;
1309 if (context->resource)
1310 wl_input_method_send_activate(input_method->resource, context->resource, text_input->id, EINA_TRUE);
1314 set_soft_keyboard_mode();
1316 if (text_input->resource)
1317 wl_text_input_send_enter(text_input->resource, surface);
1323 WTI_WARNING(resource,
1324 WL_DISPLAY_ERROR_INVALID_OBJECT,
1325 "No Text Input For Resource");
1329 WL_DISPLAY_ERROR_INVALID_OBJECT,
1330 "No Comp Data For Seat");
1334 _e_text_input_cb_deactivate(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *seat)
1337 E_Text_Input *text_input = wl_resource_get_user_data(resource);
1338 E_Input_Method *input_method = NULL;
1342 WTI_WARNING(resource,
1343 WL_DISPLAY_ERROR_INVALID_OBJECT,
1344 "No Text Input For Resource");
1348 if (text_input == g_text_input)
1350 g_text_input = NULL;
1354 /* FIXME: should get input_method object from seat. */
1355 if (g_input_method && g_input_method->resource)
1356 input_method = wl_resource_get_user_data(g_input_method->resource);
1361 WL_DISPLAY_ERROR_INVALID_OBJECT,
1362 "No Input Method For Seat");
1366 _e_text_input_deactivate(text_input, input_method, EINA_TRUE);
1370 _e_text_input_method_create_context(struct wl_client *client, E_Input_Method *input_method, E_Text_Input *text_input, Eina_Bool need_focus_out)
1372 E_Input_Method_Context *context = NULL;
1374 EINA_SAFETY_ON_NULL_RETURN_VAL(input_method, EINA_FALSE);
1375 EINA_SAFETY_ON_NULL_RETURN_VAL(input_method->resource, EINA_FALSE);
1376 EINA_SAFETY_ON_NULL_RETURN_VAL(text_input, EINA_FALSE);
1378 g_text_input = text_input;
1380 input_method->input = text_input;
1381 text_input->input_methods = eina_list_append(text_input->input_methods, input_method);
1383 if (!(context = E_NEW(E_Input_Method_Context, 1)))
1385 wl_client_post_no_memory(client);
1386 ERR("Could not allocate space for Input_Method_Context");
1391 wl_resource_create(wl_resource_get_client(input_method->resource),
1392 &wl_input_method_context_interface, 1, 0);
1394 if (context->resource)
1395 wl_resource_set_implementation(context->resource,
1396 &_e_text_input_method_context_implementation,
1397 context, _e_text_input_method_context_cb_resource_destroy);
1399 context->input = text_input;
1400 context->input_method = input_method;
1401 input_method->context = context;
1403 wl_input_method_send_activate(input_method->resource, context->resource, text_input->id, need_focus_out);
1409 _e_text_input_cb_input_panel_show(struct wl_client *client, struct wl_resource *resource)
1411 E_Text_Input *text_input = wl_resource_get_user_data(resource);
1412 E_Input_Method *input_method = NULL;
1414 LOGD("text_input : %p\n", text_input);
1418 WTI_WARNING(resource,
1419 WL_DISPLAY_ERROR_INVALID_OBJECT,
1420 "No Text Input For Resource");
1424 #ifndef SUPPORT_CANDIDATE_ONEWINDOW
1425 if (g_disable_show_panel == EINA_TRUE)
1429 if (g_input_method && g_input_method->resource)
1430 input_method = wl_resource_get_user_data(g_input_method->resource);
1432 /* If input_method->context doesn't exist, create context struct to send input_panel_show event to Input Method(IME) correctly.
1433 * Because input_panel_show event can be called before focus_in(activate) by application.
1434 * And Input Method(IME) should know the state of their own input_panel to manage their resource when the input_panel is shown. */
1435 if (input_method && (!input_method->context || !input_method->context->resource))
1436 _e_text_input_method_create_context(client, input_method, text_input, EINA_TRUE);
1438 #ifdef SUPPORT_CANDIDATE_ONEWINDOW
1439 if (g_disable_show_panel == EINA_TRUE)
1441 if (g_show_state_candidate == EINA_TRUE)
1443 g_input_panel_state = E_INPUT_PANEL_STATE_DID_SHOW;
1444 g_show_client = client;
1445 e_input_panel_visibility_change(EINA_TRUE);
1446 e_input_panel_transient_for_set(client_surface_ec);
1452 if (input_method && input_method->resource && input_method->context && input_method->context->resource)
1454 /* DO NOT show input panel surface until we get message "show complete" from input method,
1455 * in order to give a change to update UI */
1456 LOGD("IM::SHOW::WAIT_FOR_READY\n");
1458 g_show_client = client;
1459 wl_input_method_send_show_input_panel(input_method->resource, input_method->context->resource);
1461 /* we need to force update in order to release buffer
1462 * if we do not, client can't update
1463 * because they may in manual render state by frame callback mechanism,
1464 * and also don't have released buffer */
1465 e_input_panel_wait_update_set(EINA_TRUE);
1468 /* If the input panel state was WILL_HIDE, it means that the conformant area information needs to be restored */
1469 if (g_input_panel_state == E_INPUT_PANEL_STATE_WILL_HIDE)
1471 if (text_input->resource)
1472 wl_text_input_send_private_command(text_input->resource, 0, "CONFORMANT_RESTORE");
1475 text_input->input_panel_visibile = EINA_TRUE;
1476 g_input_panel_state = E_INPUT_PANEL_STATE_WILL_SHOW;
1477 g_show_text_input = text_input;
1479 g_updated_geometry = EINA_FALSE;
1481 e_input_panel_transient_for_set(client_surface_ec);
1485 _e_text_input_cb_input_panel_hide(struct wl_client *client, struct wl_resource *resource)
1487 if (g_show_client == client) {
1488 _input_panel_hide(client, resource, EINA_FALSE);
1489 g_show_text_input = NULL;
1490 g_show_client = NULL;
1495 _e_text_input_cb_reset(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
1497 E_Text_Input *text_input = wl_resource_get_user_data(resource);
1498 E_Input_Method *input_method = NULL;
1499 Eina_List *l = NULL;
1503 WTI_WARNING(resource,
1504 WL_DISPLAY_ERROR_INVALID_OBJECT,
1505 "No Text Input For Resource");
1509 EINA_LIST_FOREACH(text_input->input_methods, l, input_method)
1511 if (!input_method || !input_method->context) continue;
1512 if (input_method->context->resource)
1513 wl_input_method_context_send_reset(input_method->context->resource);
1518 _e_text_input_cb_content_type_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t hint, uint32_t purpose)
1520 E_Text_Input *text_input = wl_resource_get_user_data(resource);
1521 E_Input_Method *input_method = NULL;
1522 Eina_List *l = NULL;
1526 WTI_WARNING(resource,
1527 WL_DISPLAY_ERROR_INVALID_OBJECT,
1528 "No Text Input For Resource");
1532 EINA_LIST_FOREACH(text_input->input_methods, l, input_method)
1534 if (!input_method || !input_method->context) continue;
1536 if (input_method->context->resource)
1537 wl_input_method_context_send_content_type(input_method->context->resource,
1543 _e_text_input_cb_cursor_rectangle_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, int32_t x, int32_t y, int32_t width, int32_t height)
1545 E_Text_Input *text_input = wl_resource_get_user_data(resource);
1549 WTI_WARNING(resource,
1550 WL_DISPLAY_ERROR_INVALID_OBJECT,
1551 "No Text Input For Resource");
1555 /* TODO: issue event update input_panel */
1559 _e_text_input_cb_preferred_language_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, const char *language)
1561 E_Text_Input *text_input = wl_resource_get_user_data(resource);
1562 E_Input_Method *input_method = NULL;
1563 Eina_List *l = NULL;
1567 WTI_WARNING(resource,
1568 WL_DISPLAY_ERROR_INVALID_OBJECT,
1569 "No Text Input For Resource");
1573 EINA_LIST_FOREACH(text_input->input_methods, l, input_method)
1575 if (!input_method || !input_method->context) continue;
1577 if (input_method->context->resource)
1578 wl_input_method_context_send_preferred_language(input_method->context->resource,
1584 _e_text_input_cb_state_commit(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t serial)
1586 E_Text_Input *text_input = wl_resource_get_user_data(resource);
1587 E_Input_Method *input_method = NULL;
1588 Eina_List *l = NULL;
1592 WTI_WARNING(resource,
1593 WL_DISPLAY_ERROR_INVALID_OBJECT,
1594 "No Text Input For Resource");
1598 EINA_LIST_FOREACH(text_input->input_methods, l, input_method)
1600 if (!input_method || !input_method->context) continue;
1602 if (input_method->context->resource)
1603 wl_input_method_context_send_commit_state(input_method->context->resource, serial);
1608 _e_text_input_cb_action_invoke(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t button, uint32_t index)
1610 E_Text_Input *text_input = wl_resource_get_user_data(resource);
1611 E_Input_Method *input_method = NULL;
1612 Eina_List *l = NULL;
1616 WTI_WARNING(resource,
1617 WL_DISPLAY_ERROR_INVALID_OBJECT,
1618 "No Text Input For Resource");
1622 EINA_LIST_FOREACH(text_input->input_methods, l, input_method)
1624 if (!input_method || !input_method->context) continue;
1626 if (input_method->context->resource)
1627 wl_input_method_context_send_invoke_action(input_method->context->resource,
1633 _e_text_input_cb_return_key_type_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t return_key_type)
1635 E_Text_Input *text_input = wl_resource_get_user_data(resource);
1636 E_Input_Method *input_method = NULL;
1637 Eina_List *l = NULL;
1641 WTI_WARNING(resource,
1642 WL_DISPLAY_ERROR_INVALID_OBJECT,
1643 "No Text Input For Resource");
1647 EINA_LIST_FOREACH(text_input->input_methods, l, input_method)
1649 if (!input_method || !input_method->context) continue;
1651 if (input_method->context->resource)
1652 wl_input_method_context_send_return_key_type(input_method->context->resource,
1658 _e_text_input_cb_return_key_disabled_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t disabled)
1660 E_Text_Input *text_input = wl_resource_get_user_data(resource);
1661 E_Input_Method *input_method = NULL;
1662 Eina_List *l = NULL;
1666 WTI_WARNING(resource,
1667 WL_DISPLAY_ERROR_INVALID_OBJECT,
1668 "No Text Input For Resource");
1672 EINA_LIST_FOREACH(text_input->input_methods, l, input_method)
1674 if (!input_method || !input_method->context) continue;
1676 if (input_method->context->resource)
1677 wl_input_method_context_send_return_key_disabled(input_method->context->resource,
1683 _e_text_input_cb_input_panel_data_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, const char *data, uint32_t length)
1685 E_Text_Input *text_input = wl_resource_get_user_data(resource);
1686 E_Input_Method *input_method = NULL;
1687 Eina_List *l = NULL;
1691 WTI_WARNING(resource,
1692 WL_DISPLAY_ERROR_INVALID_OBJECT,
1693 "No Text Input For Resource");
1697 EINA_LIST_FOREACH(text_input->input_methods, l, input_method)
1699 if (!input_method || !input_method->context) continue;
1701 if (input_method->context->resource)
1702 wl_input_method_context_send_input_panel_data(input_method->context->resource,
1706 /* Temporarily receiving WILL_HIDE_ACK via input_panel_data, will need for a new wayland protocol */
1707 const char *szWillHideAck = "WILL_HIDE_ACK";
1708 if (strncmp(data, szWillHideAck, strlen(szWillHideAck)) == 0)
1710 if (g_timer_will_hide)
1712 ecore_timer_del(g_timer_will_hide);
1713 g_timer_will_hide = NULL;
1715 INF("WILL_HIDE_ACK_RECVED, %d", g_input_panel_state);
1716 if (g_input_panel_state == E_INPUT_PANEL_STATE_WILL_HIDE)
1718 e_input_panel_visibility_change(EINA_FALSE);
1719 e_input_panel_transient_for_set(NULL);
1720 g_input_panel_state = E_INPUT_PANEL_STATE_DID_HIDE;
1726 _e_text_input_cb_bidi_direction_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t bidi_direction)
1728 E_Text_Input *text_input = wl_resource_get_user_data(resource);
1729 E_Input_Method *input_method = NULL;
1730 Eina_List *l = NULL;
1734 WTI_WARNING(resource,
1735 WL_DISPLAY_ERROR_INVALID_OBJECT,
1736 "No Text Input For Resource");
1740 EINA_LIST_FOREACH(text_input->input_methods, l, input_method)
1742 if (!input_method || !input_method->context) continue;
1744 if (input_method->context->resource)
1745 wl_input_method_context_send_bidi_direction(input_method->context->resource,
1751 _e_text_input_cb_cursor_position_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t cursor_position)
1753 E_Text_Input *text_input = wl_resource_get_user_data(resource);
1754 E_Input_Method *input_method = NULL;
1755 Eina_List *l = NULL;
1759 WTI_WARNING(resource,
1760 WL_DISPLAY_ERROR_INVALID_OBJECT,
1761 "No Text Input For Resource");
1765 EINA_LIST_FOREACH(text_input->input_methods, l, input_method)
1767 if (!input_method || !input_method->context) continue;
1769 if (input_method->context->resource)
1770 wl_input_method_context_send_cursor_position(input_method->context->resource, cursor_position);
1775 _e_text_input_cb_process_input_device_event(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t type, const char *data, uint32_t length)
1777 E_Text_Input *text_input = wl_resource_get_user_data(resource);
1778 E_Input_Method *input_method = NULL;
1779 Eina_List *l = NULL;
1783 WTI_WARNING(resource,
1784 WL_DISPLAY_ERROR_INVALID_OBJECT,
1785 "No Text Input For Resource");
1789 EINA_LIST_FOREACH(text_input->input_methods, l, input_method)
1791 if (!input_method || !input_method->context) continue;
1793 if (input_method->context->resource)
1794 wl_input_method_context_send_process_input_device_event(input_method->context->resource,
1795 type, data, length);
1800 _e_text_input_cb_filter_key_event(struct wl_client *client EINA_UNUSED, struct wl_resource *resource,
1801 uint32_t serial, uint32_t time, const char *keyname, uint32_t state,
1802 uint32_t modifiers, const char *dev_name, uint32_t dev_class,
1803 uint32_t dev_subclass, uint32_t keycode)
1806 E_Text_Input *text_input = wl_resource_get_user_data(resource);
1807 E_Input_Method *input_method = NULL;
1811 WTI_WARNING(resource,
1812 WL_DISPLAY_ERROR_INVALID_OBJECT,
1813 "No Text Input For Resource");
1817 /* FIXME: should get input_method object from seat. */
1818 if (g_input_method && g_input_method->resource)
1819 input_method = wl_resource_get_user_data(g_input_method->resource);
1821 if (input_method && input_method->context && input_method->context->resource)
1823 wl_input_method_context_send_filter_key_event(input_method->context->resource,
1824 serial, time, keyname, state, modifiers,
1825 dev_name, dev_class, dev_subclass, keycode);
1829 if (text_input->resource)
1830 wl_text_input_send_filter_key_event_done(text_input->resource, serial, false);
1832 WTI_WARNING(resource,
1833 WL_DISPLAY_ERROR_INVALID_OBJECT,
1840 _e_text_input_cb_get_hide_permission(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
1842 E_Text_Input *text_input = wl_resource_get_user_data(resource);
1843 uint32_t permission = 1;
1844 E_Client *focused_ec = NULL;
1848 WTI_WARNING(resource,
1849 WL_DISPLAY_ERROR_INVALID_OBJECT,
1850 "No Text Input For Resource");
1854 focused_ec = e_client_focused_get();
1857 if (focused_ec != client_surface_ec)
1859 E_Window_Type focus_win_type = focused_ec->netwm.type;
1860 LOGD("Window ID : 0x%08x, Name : %s, type : %d\n", (unsigned int)e_client_util_win_get(focused_ec), (char *)e_client_util_name_get(focused_ec), focus_win_type);
1862 if (focus_win_type == E_WINDOW_TYPE_NOTIFICATION ||
1863 focus_win_type == E_WINDOW_TYPE_POPUP_MENU)
1869 LOGD("Can't get focus window\n");
1872 if (text_input->resource)
1873 wl_text_input_send_hide_permission(text_input->resource, permission);
1877 _e_text_input_cb_set_capital_mode(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t mode)
1879 E_Text_Input *text_input = wl_resource_get_user_data(resource);
1880 E_Input_Method *input_method = NULL;
1881 Eina_List *l = NULL;
1885 WTI_WARNING(resource,
1886 WL_DISPLAY_ERROR_INVALID_OBJECT,
1887 "No Text Input For Resource");
1891 EINA_LIST_FOREACH(text_input->input_methods, l, input_method)
1893 if (!input_method || !input_method->context) continue;
1894 if (input_method->context->resource)
1895 wl_input_method_context_send_capital_mode(input_method->context->resource, mode);
1900 _e_text_input_cb_prediction_hint_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, const char *prediction_hint)
1902 E_Text_Input *text_input = wl_resource_get_user_data(resource);
1903 E_Input_Method *input_method = NULL;
1904 Eina_List *l = NULL;
1908 WTI_WARNING(resource,
1909 WL_DISPLAY_ERROR_INVALID_OBJECT,
1910 "No Text Input For Resource");
1914 EINA_LIST_FOREACH(text_input->input_methods, l, input_method)
1916 if (!input_method || !input_method->context) continue;
1918 if (input_method->context->resource)
1919 wl_input_method_context_send_prediction_hint(input_method->context->resource, prediction_hint);
1924 _e_text_input_cb_prediction_hint_data_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, const char *key, const char *value)
1926 E_Text_Input *text_input = wl_resource_get_user_data(resource);
1927 E_Input_Method *input_method = NULL;
1928 Eina_List *l = NULL;
1932 WTI_WARNING(resource,
1933 WL_DISPLAY_ERROR_INVALID_OBJECT,
1934 "No Text Input For Resource");
1938 EINA_LIST_FOREACH(text_input->input_methods, l, input_method)
1940 if (!input_method || !input_method->context) continue;
1942 if (input_method->context->resource)
1943 wl_input_method_context_send_prediction_hint_data(input_method->context->resource, key, value);
1948 _e_text_input_cb_mime_type_accept_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, const char *mime_type)
1950 E_Text_Input *text_input = wl_resource_get_user_data(resource);
1951 E_Input_Method *input_method = NULL;
1952 Eina_List *l = NULL;
1956 WTI_WARNING(resource,
1957 WL_DISPLAY_ERROR_INVALID_OBJECT,
1958 "No Text Input For Resource");
1962 EINA_LIST_FOREACH(text_input->input_methods, l, input_method)
1964 if (!input_method || !input_method->context) continue;
1966 if (input_method->context->resource)
1967 wl_input_method_context_send_mime_type(input_method->context->resource, mime_type);
1972 _e_text_input_cb_input_panel_position_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t x, uint32_t y)
1974 E_Text_Input *text_input = wl_resource_get_user_data(resource);
1978 WTI_WARNING(resource,
1979 WL_DISPLAY_ERROR_INVALID_OBJECT,
1980 "No Text Input For Resource");
1983 e_input_panel_floating_position_set(x, y);
1987 _e_text_input_cb_finalize_content(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, const char *text, uint32_t cursor_position)
1989 E_Text_Input *text_input = wl_resource_get_user_data(resource);
1990 E_Input_Method *input_method = NULL;
1991 Eina_List *l = NULL;
1995 WTI_WARNING(resource,
1996 WL_DISPLAY_ERROR_INVALID_OBJECT,
1997 "No Text Input For Resource");
2001 EINA_LIST_FOREACH(text_input->input_methods, l, input_method)
2003 if (!input_method || !input_method->context) continue;
2005 if (input_method->context->resource)
2006 wl_input_method_context_send_finalized_content(input_method->context->resource, text, cursor_position);
2011 _e_text_input_cb_resource_destroy(struct wl_resource *resource)
2013 E_Text_Input *text_input = wl_resource_get_user_data(resource);
2014 E_Input_Method *input_method = NULL;
2018 WTI_WARNING(resource,
2019 WL_DISPLAY_ERROR_INVALID_OBJECT,
2020 "No Text Input For Resource");
2024 if (g_show_text_input == text_input)
2026 if (text_input->input_panel_visibile)
2028 _input_panel_hide(g_client, resource, EINA_TRUE);
2031 g_show_text_input = NULL;
2034 if (g_text_input == text_input)
2036 g_text_input = NULL;
2040 EINA_LIST_FREE(text_input->input_methods, input_method)
2043 _e_text_input_deactivate(text_input, input_method, EINA_TRUE);
2050 _e_text_input_cb_destroy(struct wl_client *client, struct wl_resource *resource)
2053 E_Text_Input *text_input = wl_resource_get_user_data(resource);
2054 E_Input_Method *input_method = NULL;
2055 Eina_Bool _context_created = EINA_FALSE;
2059 WTI_WARNING(resource,
2060 WL_DISPLAY_ERROR_INVALID_OBJECT,
2061 "No Text Input For Resource");
2065 if (g_input_method && g_input_method->resource)
2066 input_method = wl_resource_get_user_data(g_input_method->resource);
2070 WTI_WARNING(resource,
2071 WL_DISPLAY_ERROR_INVALID_OBJECT,
2072 "No Input Method For Seat");
2076 if ((!input_method->context) || (!input_method->context->resource))
2077 _context_created = _e_text_input_method_create_context(client, input_method, text_input, EINA_FALSE);
2079 if (input_method->resource && input_method->context && input_method->context->resource)
2080 wl_input_method_send_destroy(input_method->resource, input_method->context->resource);
2082 if (_context_created)
2083 _e_text_input_deactivate(text_input, input_method, EINA_FALSE);
2085 wl_resource_destroy(resource);
2088 static const struct wl_text_input_interface _e_text_input_implementation = {
2089 _e_text_input_cb_destroy,
2090 _e_text_input_cb_activate,
2091 _e_text_input_cb_deactivate,
2092 _e_text_input_cb_input_panel_show,
2093 _e_text_input_cb_input_panel_hide,
2094 _e_text_input_cb_reset,
2095 _e_text_input_cb_content_type_set,
2096 _e_text_input_cb_cursor_rectangle_set,
2097 _e_text_input_cb_preferred_language_set,
2098 _e_text_input_cb_state_commit,
2099 _e_text_input_cb_action_invoke,
2100 _e_text_input_cb_return_key_type_set,
2101 _e_text_input_cb_return_key_disabled_set,
2102 _e_text_input_cb_input_panel_data_set,
2103 _e_text_input_cb_bidi_direction_set,
2104 _e_text_input_cb_cursor_position_set,
2105 _e_text_input_cb_process_input_device_event,
2106 _e_text_input_cb_filter_key_event,
2107 _e_text_input_cb_get_hide_permission,
2108 _e_text_input_cb_set_capital_mode,
2109 _e_text_input_cb_prediction_hint_set,
2110 _e_text_input_cb_mime_type_accept_set,
2111 _e_text_input_cb_input_panel_position_set,
2112 _e_text_input_cb_finalize_content,
2113 _e_text_input_cb_prediction_hint_data_set
2117 _e_text_input_manager_cb_text_input_create(struct wl_client *client, struct wl_resource *resource, uint32_t id)
2119 E_Text_Input_Mgr *text_input_mgr = wl_resource_get_user_data(resource);
2120 E_Text_Input *text_input = NULL;
2122 if (!text_input_mgr)
2124 WTI_WARNING(resource,
2125 WL_DISPLAY_ERROR_INVALID_OBJECT,
2126 "No Text Input Manager For Resource");
2130 if (!(text_input = E_NEW(E_Text_Input, 1)))
2132 wl_client_post_no_memory(client);
2133 ERR("Could not allocate space for Text_Input");
2137 text_input->resource =
2138 wl_resource_create(client, &wl_text_input_interface, 1, id);
2140 if (!text_input->resource)
2142 wl_client_post_no_memory(client);
2143 ERR("Could not create the resource for text_input");
2147 text_input->id = g_text_input_count++;
2149 wl_resource_set_implementation(text_input->resource,
2150 &_e_text_input_implementation,
2151 text_input, _e_text_input_cb_resource_destroy);
2154 static const struct wl_text_input_manager_interface _e_text_input_manager_implementation = {
2155 _e_text_input_manager_cb_text_input_create
2159 _e_text_cb_bind_text_input_manager(struct wl_client *client, void *data, uint32_t version EINA_UNUSED, uint32_t id)
2161 E_Text_Input_Mgr *text_input_mgr = data;
2163 text_input_mgr->resource =
2164 wl_resource_create(client,
2165 &wl_text_input_manager_interface, 1, id);
2167 if (text_input_mgr->resource)
2168 wl_resource_set_implementation(text_input_mgr->resource,
2169 &_e_text_input_manager_implementation,
2170 text_input_mgr, NULL);
2174 _e_text_input_method_cb_unbind(struct wl_resource *resource)
2177 E_Input_Method *input_method = wl_resource_get_user_data(resource);
2181 WTI_WARNING(resource,
2182 WL_DISPLAY_ERROR_INVALID_OBJECT,
2183 "No Input Method For Resource");
2187 if (input_method->resource != resource) return;
2189 if (input_method->input)
2190 _e_text_input_deactivate(input_method->input, input_method, EINA_TRUE);
2192 input_method->resource = NULL;
2193 input_method->context = NULL;
2195 if (vconf_set_bool(VCONFKEY_ISF_BIND, 0) != 0)
2196 LOGW("failed to set isf bind\n");
2200 _e_text_input_method_cb_bind(struct wl_client *client, void *data, uint32_t version EINA_UNUSED, uint32_t id)
2203 E_Input_Method *input_method = data;
2204 struct wl_resource *resource = NULL;
2206 if (!input_method) return;
2208 if (input_method->resource)
2209 _e_text_input_method_cb_unbind(input_method->resource);
2211 if (input_method->resource)
2213 WTI_WARNING(input_method->resource, WL_DISPLAY_ERROR_INVALID_OBJECT,
2214 "input_method object already bound");
2218 resource = wl_resource_create(client, &wl_input_method_interface, 1, id);
2219 if (EINA_UNLIKELY(!resource))
2222 input_method->resource = resource;
2224 wl_resource_set_implementation(resource, NULL, input_method,
2225 _e_text_input_method_cb_unbind);
2227 if (vconf_set_bool(VCONFKEY_ISF_BIND, 1) != 0)
2228 LOGW("failed to set isf bind\n");
2232 _e_text_input_method_destroy(void *data)
2234 E_Input_Method *input_method = data;
2239 if (input_method->global)
2240 wl_global_destroy(input_method->global);
2246 _e_text_input_method_create(void)
2248 if (!(g_input_method = E_NEW(E_Input_Method, 1)))
2250 ERR("Could not allocate space for Input_Method");
2254 g_input_method->global =
2255 wl_global_create(e_comp_wl->wl.disp, &wl_input_method_interface, 1,
2256 g_input_method, _e_text_input_method_cb_bind);
2258 if (!g_input_method->global)
2260 free(g_input_method);
2261 g_input_method = NULL;
2265 _e_mod_text_input_shutdown_cb_add(_e_text_input_method_destroy, g_input_method);
2271 _e_text_input_manager_destroy(void *data)
2273 E_Text_Input_Mgr *text_input_mgr = data;
2274 if (!text_input_mgr) return;
2276 wl_global_destroy(text_input_mgr->global);
2277 free(text_input_mgr);
2281 _e_text_input_manager_create(void)
2283 E_Text_Input_Mgr *text_input_mgr;
2285 if (!(text_input_mgr = E_NEW(E_Text_Input_Mgr, 1)))
2287 ERR("Could not allocate space for Text_Input_Manager");
2291 text_input_mgr->global =
2292 wl_global_create(e_comp_wl->wl.disp,
2293 &wl_text_input_manager_interface, 1,
2294 text_input_mgr, _e_text_cb_bind_text_input_manager);
2296 if (!text_input_mgr->global)
2298 free(text_input_mgr);
2302 _e_mod_text_input_shutdown_cb_add(_e_text_input_manager_destroy, text_input_mgr);
2308 _e_mod_text_input_shutdown(void)
2310 E_Mod_Text_Input_Shutdown_Cb *cb;
2312 EINA_LIST_FREE(shutdown_list, cb)
2322 E_API E_Module_Api e_modapi = { E_MODULE_API_VERSION, "Wl_Text_Input" };
2325 set_soft_keyboard_mode()
2327 g_disable_show_panel = EINA_FALSE;
2329 /* switch to S/W keyboard mode */
2331 if (vconf_get_bool(VCONFKEY_ISF_HW_KEYBOARD_INPUT_DETECTED, &val) == 0 && val != 0)
2332 vconf_set_bool(VCONFKEY_ISF_HW_KEYBOARD_INPUT_DETECTED, 0);
2336 _e_mod_eeze_udev_watch_cb(const char *text, Eeze_Udev_Event event, void *data, Eeze_Udev_Watch *watch)
2338 if (event == EEZE_UDEV_EVENT_REMOVE)
2339 set_soft_keyboard_mode();
2343 _e_text_input_method_context_cb_client_resize(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
2348 int x = 0, y = 0, w = 0, h = 0;
2350 ev = (E_Event_Client *)event;
2351 EINA_SAFETY_ON_NULL_RETURN_VAL(ev, ECORE_CALLBACK_PASS_ON);
2354 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, ECORE_CALLBACK_PASS_ON);
2356 found = e_input_panel_client_find(ec);
2357 if (!found) return ECORE_CALLBACK_PASS_ON;
2358 if ((ec->w < 1) && (ec->h < 1)) return ECORE_CALLBACK_PASS_ON;
2360 if (g_text_input && g_text_input->resource && g_input_panel_state != E_INPUT_PANEL_STATE_WILL_HIDE && g_input_panel_state != E_INPUT_PANEL_STATE_DID_HIDE)
2362 if (e_input_panel_client_geometry_get(NULL, &x, &y, &w, &h) && !(w <= 1 || h <= 1))
2363 _e_text_input_send_input_panel_geometry(g_text_input->resource, x, y, w, h);
2366 return ECORE_CALLBACK_PASS_ON;
2370 _pol_cb_hook_client_del(void *d EINA_UNUSED, E_Client *ec)
2372 if (EINA_UNLIKELY(!ec))
2375 if (ec == client_surface_ec)
2377 LOGD("transient_for_ec deleted, hiding input panel\n");
2378 e_input_panel_visibility_change(EINA_FALSE);
2379 e_input_panel_transient_for_set(NULL);
2381 if(!e_input_panel_surface_destroy(ec))
2382 LOGE("fail to remove surface\n");
2384 g_input_panel_state = E_INPUT_PANEL_STATE_DID_HIDE;
2385 if (g_timer_will_hide)
2387 ecore_timer_del(g_timer_will_hide);
2388 g_timer_will_hide = NULL;
2390 client_surface_ec = NULL;
2391 LOGD("TRANSIENT_FOR::Reset transient_for_ec to NULL\n");
2396 e_text_input_update_input_panel_state(Eina_Bool state)
2398 if (!g_text_input || !g_text_input->resource) return;
2400 E_Text_Input *text_input = wl_resource_get_user_data(g_text_input->resource);
2404 WTI_WARNING(g_text_input->resource,
2405 WL_DISPLAY_ERROR_INVALID_OBJECT,
2406 "No Text Input For Resource");
2410 if (text_input->resource)
2412 if (!g_updated_geometry)
2414 int x = 0, y = 0, w = 0, h = 0;
2415 if (e_input_panel_client_geometry_get(NULL, &x, &y, &w, &h) && !(w <= 1 || h <= 1))
2416 _e_text_input_send_input_panel_geometry(text_input->resource, x, y, w, h);
2417 g_updated_geometry = EINA_TRUE;
2419 uint32_t input_panel_state = WL_TEXT_INPUT_INPUT_PANEL_STATE_HIDE;
2420 if (state) input_panel_state = WL_TEXT_INPUT_INPUT_PANEL_STATE_SHOW;
2421 wl_text_input_send_input_panel_state(text_input->resource, input_panel_state);
2426 e_modapi_init(E_Module *m)
2428 if (!e_comp_wl) return NULL;
2430 if (!wti_log_init())
2433 /* FIXME: create only one input method object per seat. */
2434 if (!_e_text_input_method_create())
2437 if (!e_input_panel_init())
2440 if (!_e_text_input_manager_create())
2443 E_LIST_HANDLER_APPEND(handlers, E_EVENT_CLIENT_RESIZE, _e_text_input_method_context_cb_client_resize, NULL);
2445 vconf_notify_key_changed(VCONFKEY_ISF_HW_KEYBOARD_INPUT_DETECTED, _keyboard_mode_changed_cb, NULL);
2447 eeze_udev_watch_hander = eeze_udev_watch_add(EEZE_UDEV_TYPE_KEYBOARD,
2448 EEZE_UDEV_EVENT_REMOVE,
2449 _e_mod_eeze_udev_watch_cb,
2451 if (!eeze_udev_watch_hander)
2454 E_CLIENT_HOOK_APPEND(hooks_ec, E_CLIENT_HOOK_DEL, _pol_cb_hook_client_del, NULL);
2458 _e_mod_text_input_shutdown();
2463 e_modapi_shutdown(E_Module *m EINA_UNUSED)
2465 E_FREE_LIST(handlers, ecore_event_handler_del);
2466 E_FREE_LIST(hooks_ec, e_client_hook_del);
2468 if (g_timer_will_hide)
2470 ecore_timer_del(g_timer_will_hide);
2471 g_timer_will_hide = NULL;
2474 vconf_ignore_key_changed(VCONFKEY_ISF_HW_KEYBOARD_INPUT_DETECTED, _keyboard_mode_changed_cb);
2476 if (eeze_udev_watch_hander)
2478 eeze_udev_watch_del(eeze_udev_watch_hander);
2479 eeze_udev_watch_hander = NULL;
2481 _e_mod_text_input_shutdown();
2483 e_input_panel_shutdown();
2491 e_modapi_save(E_Module *m EINA_UNUSED)