3 #include "e_mod_main.h"
4 #include "e_mod_input_method_manager.h"
5 #include <text-server-protocol.h>
6 #include <input-method-server-protocol.h>
8 #include <vconf-keys.h>
12 #include <system_info.h>
17 #define LOG_TAG "WL_TEXTINPUT"
19 #define WTI_WARNING(resource, code, msg) (_e_text_input_log_show((resource), (code), (msg), __func__))
21 tizen_profile_t _get_tizen_profile()
23 static tizen_profile_t profile = TIZEN_PROFILE_UNKNOWN;
24 if (__builtin_expect(profile != TIZEN_PROFILE_UNKNOWN, 1))
28 system_info_get_platform_string("http://tizen.org/feature/profile", &profileName);
33 profile = TIZEN_PROFILE_MOBILE;
37 profile = TIZEN_PROFILE_WEARABLE;
41 profile = TIZEN_PROFILE_TV;
45 profile = TIZEN_PROFILE_IVI;
47 default: // common or unknown ==> ALL ARE COMMON.
48 profile = TIZEN_PROFILE_COMMON;
55 static Eina_Bool _e_text_input_method_context_cb_client_resize(void *data EINA_UNUSED, int type, void *event);
56 static void set_soft_keyboard_mode();
58 typedef struct _E_Text_Input E_Text_Input;
59 typedef struct _E_Text_Input_Mgr E_Text_Input_Mgr;
60 typedef struct _E_Input_Method E_Input_Method;
61 typedef struct _E_Input_Method_Context E_Input_Method_Context;
62 typedef struct _E_Mod_Text_Input_Shutdown_Cb E_Mod_Text_Input_Shutdown_Cb;
66 struct wl_resource *resource;
68 Eina_List *input_methods;
69 Eina_Bool input_panel_visible;
70 Eina_Bool input_panel_show_requested;
74 struct _E_Text_Input_Mgr
76 struct wl_global *global;
77 struct wl_resource *resource;
79 Eina_List *text_input_list;
82 struct _E_Input_Method
84 struct wl_global *global;
85 struct wl_resource *resource;
88 E_Input_Method_Context *context;
91 static struct wl_resource *destroyed_resource = NULL;
93 struct _E_Input_Method_Context
95 struct wl_resource *resource;
98 E_Input_Method *input_method;
100 #if ENABLE_GRAB_KEYBOARD
103 struct wl_resource *resource;
106 struct xkb_keymap *keymap;
107 struct xkb_state *state;
108 xkb_mod_mask_t mod_depressed, mod_latched, mod_locked;
109 xkb_layout_index_t mod_group;
115 struct _E_Mod_Text_Input_Shutdown_Cb
117 void (*func)(void *data);
121 /* This represents the overall input panel's state including the candidate area */
122 enum _E_Input_Panel_State
124 E_INPUT_PANEL_STATE_DID_HIDE,
125 E_INPUT_PANEL_STATE_WILL_HIDE,
126 E_INPUT_PANEL_STATE_DID_SHOW,
127 E_INPUT_PANEL_STATE_WILL_SHOW,
130 static E_Input_Method *g_input_method = NULL;
131 static E_Text_Input *g_text_input = NULL;
132 static struct wl_client *g_client = NULL;
133 static Eina_List *shutdown_list = NULL;
134 static Eina_Bool g_disable_show_panel = EINA_FALSE;
135 static Eeze_Udev_Watch *eeze_udev_watch_hander = NULL;
136 static Ecore_Event_Handler *ecore_key_down_handler = NULL;
137 static Eina_List *handlers = NULL;
138 static uint32_t g_text_input_count = 1;
139 static Ecore_Timer *g_timer_will_hide = NULL;
140 static enum _E_Input_Panel_State g_input_panel_state = E_INPUT_PANEL_STATE_DID_HIDE;
141 static E_Client *client_surface_ec = NULL;
142 static E_Text_Input *g_show_text_input = NULL;
143 static struct wl_client *g_show_client = NULL;
144 static Eina_Bool g_updated_geometry = EINA_FALSE;
145 static Eina_Bool g_input_panel_enabled = EINA_TRUE;
147 /* The candidate's show state that was requested by the application or IME */
148 static Eina_Bool g_show_state_candidate = EINA_FALSE;
150 static Eina_List *hooks_ec = NULL;
152 const int WILL_HIDE_TIMER_INTERVAL = 1.0f;
154 #undef E_CLIENT_HOOK_APPEND
155 #define E_CLIENT_HOOK_APPEND(l, t, cb, d) \
159 _h = e_client_hook_add(t, cb, d); \
161 l = eina_list_append(l, _h); \
165 static void _e_text_input_cb_input_panel_show(struct wl_client *client, struct wl_resource *resource);
166 static void _e_text_input_deactivate(E_Text_Input *text_input, E_Input_Method *input_method, Eina_Bool need_focus_in);
167 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);
168 static void send_hide_input_panel(E_Input_Method *input_method);
171 e_text_input_client_surface_get(void)
173 return client_surface_ec;
177 _e_text_input_log_show(struct wl_resource *resource, uint32_t code, const char *msg, const char *warning_msg)
179 LOGE("%s() is failed. msg : %s\n", warning_msg, msg);
183 _e_text_input_send_input_panel_geometry(struct wl_resource *resource, int x, int y, int w, int h)
188 if (client_surface_ec)
190 angle = client_surface_ec->e.state.rot.ang.next < 0 ?
191 client_surface_ec->e.state.rot.ang.curr :
192 client_surface_ec->e.state.rot.ang.next;
194 LOGI("curr : %d, next : %d, angle : %d\n", client_surface_ec->e.state.rot.ang.curr,
195 client_surface_ec->e.state.rot.ang.next, angle);
198 snprintf(geometry, sizeof(geometry), "%d,%d,%d,%d", x, y, w, h);
204 vconf_set_str(VCONFKEY_ISF_IME_RECENT_LAND_GEOMETRY, geometry);
207 vconf_set_str(VCONFKEY_ISF_IME_RECENT_PORT_GEOMETRY, geometry);
211 LOGI("angle : %d, x : %d, y : %d, w : %d, h : %d\n", angle, x, y, w, h);
213 wl_text_input_send_input_panel_geometry(resource, x, y, w, h);
217 _will_hide_timer_handler(void *data)
219 INF("TIMED OUT while waiting for WILL_HIDE_ACK : %d", g_input_panel_state);
220 if (g_input_panel_state == E_INPUT_PANEL_STATE_WILL_HIDE)
222 e_input_panel_visibility_change(EINA_FALSE);
223 e_input_panel_transient_for_set(NULL);
224 g_input_panel_state = E_INPUT_PANEL_STATE_DID_HIDE;
227 if (g_timer_will_hide)
229 ecore_timer_del(g_timer_will_hide);
230 g_timer_will_hide = NULL;
233 return ECORE_CALLBACK_CANCEL;
237 _input_panel_hide(struct wl_client *client, struct wl_resource *resource, Eina_Bool force_hide)
239 E_Text_Input *text_input = wl_resource_get_user_data(resource);
240 E_Input_Method *input_method = NULL;
241 Eina_Bool _context_created = EINA_FALSE;
248 WTI_WARNING(resource,
249 WL_DISPLAY_ERROR_INVALID_OBJECT,
250 "No Text Input For Resource");
254 text_input->input_panel_visible = EINA_FALSE;
256 if (text_input->resource)
258 wl_text_input_send_input_panel_geometry(text_input->resource, 0, 0, 0, 0);
259 wl_text_input_send_input_panel_state(text_input->resource, WL_TEXT_INPUT_INPUT_PANEL_STATE_HIDE);
264 e_input_panel_visibility_change(EINA_FALSE);
265 e_input_panel_transient_for_set(NULL);
266 g_input_panel_state = E_INPUT_PANEL_STATE_DID_HIDE;
270 g_input_panel_state = E_INPUT_PANEL_STATE_WILL_HIDE;
271 /* Temporarily sending private command, will need for a new wayland protocol */
272 if (text_input->resource)
273 wl_text_input_send_private_command(text_input->resource, 0, "CONFORMANT_RESET");
275 if (g_timer_will_hide)
277 ecore_timer_del(g_timer_will_hide);
278 g_timer_will_hide = NULL;
281 zone = e_zone_current_get();
282 effect_run = e_input_panel_is_effect_running();
283 if (zone && (zone->display_state == E_ZONE_DISPLAY_STATE_OFF))
288 timeout = WILL_HIDE_TIMER_INTERVAL;
289 g_timer_will_hide = ecore_timer_add(timeout, _will_hide_timer_handler, NULL);
292 if (g_input_method && g_input_method->resource)
293 input_method = wl_resource_get_user_data(g_input_method->resource);
296 If input_method->context is already deleted, create context struct again to send input_panel_hide event to Input Method(IME) correctly.
297 Because input_panel_hide event can be called after focus_out(deactivate) by application.
298 And Input Method(IME) should know the state of their own input_panel to manage their resource when the input_panel is hidden.
301 ((!input_method->context) || (!input_method->context->resource)))
302 _context_created = _e_text_input_method_create_context(client, input_method, text_input, EINA_FALSE);
304 send_hide_input_panel(input_method);
306 if (_context_created)
307 _e_text_input_deactivate(text_input, input_method, EINA_FALSE);
309 e_input_panel_wait_update_set(EINA_FALSE);
311 /* When the input panel suface is hidden, the candidate will hide too */
312 g_show_state_candidate = EINA_FALSE;
315 static void send_hide_input_panel(E_Input_Method *input_method)
317 if (input_method && input_method->resource && input_method->context && input_method->context->resource)
319 LOGI("Request to hide IME");
320 wl_input_method_send_hide_input_panel(input_method->resource, input_method->context->resource);
325 _keyboard_mode_changed_cb(keynode_t *key, void* data)
327 bool val = vconf_keynode_get_bool(key);
328 LOGI("keyboard mode : %d\n", val);
332 if (!g_disable_show_panel && g_text_input && g_text_input->resource && g_client && g_input_panel_state == E_INPUT_PANEL_STATE_DID_HIDE && g_text_input->input_panel_show_requested)
333 _e_text_input_cb_input_panel_show(g_client, g_text_input->resource);
335 #ifdef SUPPORT_CANDIDATE_ONEWINDOW
336 /* Switching to S/W keyboard mode, hide input panel since it could be displaying candidate only */
337 if (g_disable_show_panel && g_text_input && g_text_input->resource && g_client)
338 _input_panel_hide(g_client, g_text_input->resource, EINA_FALSE);
340 g_disable_show_panel = EINA_FALSE;
344 #ifdef SUPPORT_CANDIDATE_ONEWINDOW
345 /* Switching to H/W keyboard mode, hide input panel only if there is no candidate */
346 if (!g_show_state_candidate && g_text_input && g_text_input->resource && g_client)
348 if (g_text_input && g_text_input->resource && g_client)
350 _input_panel_hide(g_client, g_text_input->resource, EINA_FALSE);
352 g_disable_show_panel = EINA_TRUE;
357 #if ENABLE_GRAB_KEYBOARD
359 _e_text_input_method_context_keyboard_grab_keyboard_state_update(E_Input_Method_Context *context, uint32_t keycode, Eina_Bool pressed)
361 enum xkb_key_direction dir;
363 if (!context->kbd.state) return;
365 if (pressed) dir = XKB_KEY_DOWN;
366 else dir = XKB_KEY_UP;
368 context->kbd.mod_changed =
369 xkb_state_update_key(context->kbd.state, keycode + 8, dir);
373 _e_text_input_method_context_keyboard_grab_keyboard_modifiers_update(E_Input_Method_Context *context, struct wl_resource *keyboard)
377 if (!context->input) return;
378 if (!context->kbd.state) return;
380 context->kbd.mod_depressed =
381 xkb_state_serialize_mods(context->kbd.state, XKB_STATE_DEPRESSED);
382 context->kbd.mod_latched =
383 xkb_state_serialize_mods(context->kbd.state, XKB_STATE_MODS_LATCHED);
384 context->kbd.mod_locked =
385 xkb_state_serialize_mods(context->kbd.state, XKB_STATE_MODS_LOCKED);
386 context->kbd.mod_group =
387 xkb_state_serialize_layout(context->kbd.state, XKB_STATE_LAYOUT_EFFECTIVE);
389 serial = wl_display_next_serial(e_comp_wl->wl.disp);
390 wl_keyboard_send_modifiers(keyboard, serial,
391 context->kbd.mod_depressed,
392 context->kbd.mod_latched,
393 context->kbd.mod_locked,
394 context->kbd.mod_group);
398 _e_text_input_method_context_key_send(E_Input_Method_Context *context, unsigned int keycode, unsigned int timestamp, enum wl_keyboard_key_state state)
402 if (!context->input) return;
405 /* update modifier state */
406 _e_text_input_method_context_keyboard_grab_keyboard_state_update(context, nk, state == WL_KEYBOARD_KEY_STATE_PRESSED);
408 serial = wl_display_next_serial(e_comp_wl->wl.disp);
410 wl_keyboard_send_key(context->kbd.resource, serial, timestamp, nk, state);
411 if (context->kbd.mod_changed)
413 _e_text_input_method_context_keyboard_grab_keyboard_modifiers_update(context, context->kbd.resource);
414 context->kbd.mod_changed = 0;
419 _e_text_input_method_context_ecore_cb_key_down(void *data, int ev_type EINA_UNUSED, Ecore_Event_Key *ev)
421 E_Input_Method_Context *context = data;
423 _e_text_input_method_context_key_send(context, ev->keycode, ev->timestamp,
424 WL_KEYBOARD_KEY_STATE_PRESSED);
426 return ECORE_CALLBACK_RENEW;
430 _e_text_input_method_context_ecore_cb_key_up(void *data, int ev_type EINA_UNUSED, Ecore_Event_Key *ev)
432 E_Input_Method_Context *context = data;
434 _e_text_input_method_context_key_send(context, ev->keycode, ev->timestamp,
435 WL_KEYBOARD_KEY_STATE_RELEASED);
437 return ECORE_CALLBACK_RENEW;
441 _e_text_input_method_context_grab_set(E_Input_Method_Context *context, Eina_Bool set)
443 if (set == context->kbd.grabbed)
449 context->kbd.grabbed = set;
453 if (context->kbd.keymap) xkb_map_unref(context->kbd.keymap);
454 if (context->kbd.state) xkb_state_unref(context->kbd.state);
455 context->kbd.keymap = xkb_map_ref(e_comp_wl->xkb.keymap);
456 context->kbd.state = xkb_state_new(e_comp_wl->xkb.keymap);
457 E_LIST_HANDLER_APPEND(context->kbd.handlers, ECORE_EVENT_KEY_DOWN,
458 _e_text_input_method_context_ecore_cb_key_down,
460 E_LIST_HANDLER_APPEND(context->kbd.handlers, ECORE_EVENT_KEY_UP,
461 _e_text_input_method_context_ecore_cb_key_up,
464 e_comp_grab_input(0, 1);
468 E_FREE_LIST(context->kbd.handlers, ecore_event_handler_del);
470 e_comp_ungrab_input(0, 1);
472 if (context->kbd.keymap)
474 xkb_map_unref(context->kbd.keymap);
475 context->kbd.keymap = NULL;
478 if (context->kbd.state)
480 xkb_state_unref(context->kbd.state);
481 context->kbd.state = NULL;
488 _e_mod_text_input_shutdown_cb_add(void (*func)(void *data), void *data)
490 E_Mod_Text_Input_Shutdown_Cb *cb;
492 if (!(cb = E_NEW(E_Mod_Text_Input_Shutdown_Cb, 1)))
494 ERR("Could not allocate space for Text Input Shutdown Callback");
501 shutdown_list = eina_list_append(shutdown_list, cb);
505 _e_text_input_method_context_cb_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
507 E_Input_Method_Context *context = wl_resource_get_user_data(resource);
509 LOGD("resource(%p), context(%p), context->input(%p), context->input_method(%p)", resource, context, context->input, context->input_method);
511 wl_resource_destroy(resource);
515 _e_text_input_method_context_cb_string_commit(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t serial, const char *text)
517 E_Input_Method_Context *context = wl_resource_get_user_data(resource);
521 WTI_WARNING(resource,
522 WL_DISPLAY_ERROR_INVALID_OBJECT,
523 "No Input Method Context For Resource");
527 if ((context->input) && (context->input->resource))
528 wl_text_input_send_commit_string(context->input->resource,
533 _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)
535 E_Input_Method_Context *context = wl_resource_get_user_data(resource);
539 WTI_WARNING(resource,
540 WL_DISPLAY_ERROR_INVALID_OBJECT,
541 "No Input Method Context For Resource");
545 if ((context->input) && (context->input->resource))
546 wl_text_input_send_preedit_string(context->input->resource,
547 serial, text, commit);
551 _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)
553 E_Input_Method_Context *context = wl_resource_get_user_data(resource);
557 WTI_WARNING(resource,
558 WL_DISPLAY_ERROR_INVALID_OBJECT,
559 "No Input Method Context For Resource");
563 if ((context->input) && (context->input->resource))
564 wl_text_input_send_recapture_string(context->input->resource,
565 serial, index, length, preedit, preedit_commit, commit);
569 _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)
571 E_Input_Method_Context *context = wl_resource_get_user_data(resource);
575 WTI_WARNING(resource,
576 WL_DISPLAY_ERROR_INVALID_OBJECT,
577 "No Input Method Context For Resource");
581 if ((context->input) && (context->input->resource))
582 wl_text_input_send_preedit_styling(context->input->resource,
583 index, length, style);
587 _e_text_input_method_context_cb_preedit_cursor(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, int32_t cursor)
589 E_Input_Method_Context *context = wl_resource_get_user_data(resource);
593 WTI_WARNING(resource,
594 WL_DISPLAY_ERROR_INVALID_OBJECT,
595 "No Input Method Context For Resource");
599 if ((context->input) && (context->input->resource))
600 wl_text_input_send_preedit_cursor(context->input->resource,
605 _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)
607 E_Input_Method_Context *context = wl_resource_get_user_data(resource);
611 WTI_WARNING(resource,
612 WL_DISPLAY_ERROR_INVALID_OBJECT,
613 "No Input Method Context For Resource");
617 if ((context->input) && (context->input->resource))
618 wl_text_input_send_delete_surrounding_text(context->input->resource,
623 _e_text_input_method_context_cb_cursor_position(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, int32_t index, int32_t anchor)
625 E_Input_Method_Context *context = wl_resource_get_user_data(resource);
629 WTI_WARNING(resource,
630 WL_DISPLAY_ERROR_INVALID_OBJECT,
631 "No Input Method Context For Resource");
635 if ((context->input) && (context->input->resource))
636 wl_text_input_send_cursor_position(context->input->resource,
641 _e_text_input_method_context_cb_modifiers_map(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_array *map)
643 E_Input_Method_Context *context = wl_resource_get_user_data(resource);
647 WTI_WARNING(resource,
648 WL_DISPLAY_ERROR_INVALID_OBJECT,
649 "No Input Method Context For Resource");
653 if ((context->input) && (context->input->resource))
654 wl_text_input_send_modifiers_map(context->input->resource, map);
658 _e_keyevent_free(void *data EINA_UNUSED, void *ev)
660 Ecore_Event_Key *e = ev;
663 eina_stringshare_del(e->keyname);
666 eina_stringshare_del(e->key);
669 eina_stringshare_del(e->compose);
672 eina_stringshare_del(e->string);
678 feed_key_event(const char *keyname, const char *key, const char *string, int keycode, int state)
680 Ecore_Event_Key *e = E_NEW(Ecore_Event_Key, 1);
683 e->keyname = (char *)eina_stringshare_add(keyname);
684 e->key = (char *)eina_stringshare_add(key);
685 e->string = (char *)eina_stringshare_add(string);
686 e->compose = (char *)eina_stringshare_add(e->string);
688 e->timestamp = 0; /* For distinguishing S/W keyboard event */
690 e->keycode = keycode;
692 ecore_event_add(state ? ECORE_EVENT_KEY_DOWN : ECORE_EVENT_KEY_UP, e, _e_keyevent_free, NULL);
696 _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)
698 E_Input_Method_Context *context = wl_resource_get_user_data(resource);
702 WTI_WARNING(resource,
703 WL_DISPLAY_ERROR_INVALID_OBJECT,
704 "No Input Method Context For Resource");
708 if ((context->input) && (context->input->resource))
710 wl_text_input_send_keysym(context->input->resource,
711 serial, time, sym, state, modifiers);
715 char string[32], key[32], keyname[32];
717 memset(keyname, 0, sizeof(keyname));
718 xkb_keysym_get_name(sym, keyname, sizeof(keyname));
719 if (keyname[0] == '\0')
720 snprintf(keyname, sizeof(keyname), "Keysym-%u", sym);
722 if (strcmp(keyname, "BackSpace") == 0)
724 /* backspace key should be supported in the multibutton entry of elementary
725 even though it losts focus */
726 memset(key, 0, sizeof(key));
727 xkb_keysym_get_name(sym, key, sizeof(key));
729 memset(string, 0, sizeof(string));
730 xkb_keysym_to_utf8(sym, string, 32);
734 /* Backspace keycode (22) */
735 feed_key_event(keyname, key, string, 22, 1); /* key down */
736 feed_key_event(keyname, key, string, 22, 0); /* key up */
742 #if ENABLE_GRAB_KEYBOARD
744 _e_text_input_method_context_keyboard_grab_cb_resource_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
746 wl_resource_destroy(resource);
749 static const struct wl_keyboard_interface _e_keyboard_grab_interface =
751 _e_text_input_method_context_keyboard_grab_cb_resource_destroy
755 _e_text_input_method_context_keyboard_grab_cb_keyboard_unbind(struct wl_resource *resource)
757 E_Input_Method_Context *context = wl_resource_get_user_data(resource);
761 WTI_WARNING(resource,
762 WL_DISPLAY_ERROR_INVALID_OBJECT,
763 "No Input Method Context For Resource");
767 _e_text_input_method_context_grab_set(context, EINA_FALSE);
769 context->kbd.resource = NULL;
774 _e_text_input_method_context_cb_keyboard_grab(struct wl_client *client, struct wl_resource *resource, uint32_t id)
776 DBG("Input Method Context - grab keyboard %d", wl_resource_get_id(resource));
777 #if ENABLE_GRAB_KEYBOARD
778 E_Input_Method_Context *context = wl_resource_get_user_data(resource);
779 struct wl_resource *keyboard = NULL;
783 WTI_WARNING(resource,
784 WL_DISPLAY_ERROR_INVALID_OBJECT,
785 "No Input Method Context For Resource");
789 keyboard = wl_resource_create(client, &wl_keyboard_interface, 1, id);
792 wl_client_post_no_memory(client);
796 wl_resource_set_implementation(keyboard, &_e_keyboard_grab_interface, context, _e_text_input_method_context_keyboard_grab_cb_keyboard_unbind);
798 /* send current keymap */
799 wl_keyboard_send_keymap(keyboard, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
800 e_comp_wl->xkb.fd, e_comp_wl->xkb.size);
802 context->kbd.resource = keyboard;
804 _e_text_input_method_context_grab_set(context, EINA_TRUE);
809 _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)
811 DBG("Input Method Context - key %d", wl_resource_get_id(resource));
822 _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)
824 DBG("Input Method Context - modifiers %d", wl_resource_get_id(resource));
829 (void)mods_depressed;
836 _e_text_input_method_context_cb_language(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t serial, const char *language)
838 E_Input_Method_Context *context = wl_resource_get_user_data(resource);
842 WTI_WARNING(resource,
843 WL_DISPLAY_ERROR_INVALID_OBJECT,
844 "No Input Method Context For Resource");
848 if ((context->input) && (context->input->resource))
849 wl_text_input_send_language(context->input->resource,
854 _e_text_input_method_context_cb_text_direction(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t serial, uint32_t direction)
856 E_Input_Method_Context *context = wl_resource_get_user_data(resource);
860 WTI_WARNING(resource,
861 WL_DISPLAY_ERROR_INVALID_OBJECT,
862 "No Input Method Context For Resource");
866 if ((context->input) && (context->input->resource))
867 wl_text_input_send_text_direction(context->input->resource,
872 _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)
874 E_Input_Method_Context *context = wl_resource_get_user_data(resource);
878 WTI_WARNING(resource,
879 WL_DISPLAY_ERROR_INVALID_OBJECT,
880 "No Input Method Context For Resource");
884 if ((context->input) && (context->input->resource))
885 wl_text_input_send_selection_region(context->input->resource,
890 _e_text_input_method_context_cb_private_command(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t serial, const char *command)
892 E_Input_Method_Context *context = wl_resource_get_user_data(resource);
896 WTI_WARNING(resource,
897 WL_DISPLAY_ERROR_INVALID_OBJECT,
898 "No Input Method Context For Resource");
902 if ((context->input) && (context->input->resource))
903 wl_text_input_send_private_command(context->input->resource,
908 _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)
910 E_Input_Method_Context *context = wl_resource_get_user_data(resource);
914 WTI_WARNING(resource,
915 WL_DISPLAY_ERROR_INVALID_OBJECT,
916 "No Input Method Context For Resource");
920 if ((context->input) && (context->input->resource))
921 wl_text_input_send_commit_content(context->input->resource,
922 serial, content, description, mime_types);
926 _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)
928 E_Input_Method_Context *context = wl_resource_get_user_data(resource);
932 WTI_WARNING(resource,
933 WL_DISPLAY_ERROR_INVALID_OBJECT,
934 "No Input Method Context For Resource");
938 if ((context->input) && (context->input->resource))
939 wl_text_input_send_input_panel_event(context->input->resource,
940 serial, event_type, value);
944 _e_text_input_method_context_cb_update_candidate_state(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t state)
946 E_Input_Method_Context *context = wl_resource_get_user_data(resource);
950 WTI_WARNING(resource,
951 WL_DISPLAY_ERROR_INVALID_OBJECT,
952 "No Input Method Context For Resource");
956 LOGI("Candidate State : %d", state);
957 Eina_Bool prev_show_state = g_show_state_candidate;
958 g_show_state_candidate = state;
959 if (g_input_panel_state == E_INPUT_PANEL_STATE_DID_HIDE)
960 prev_show_state = EINA_FALSE;
964 /* If the candidate state has been changed to OFF when panel is not in show state, */
965 if (!g_show_state_candidate && prev_show_state && g_disable_show_panel && g_client && g_text_input)
966 _input_panel_hide(g_client, g_text_input->resource, EINA_FALSE);
970 /* If the candidate state has been changed to ON when panel is not in show state */
971 if (g_show_state_candidate && !prev_show_state && g_disable_show_panel && g_client && g_text_input)
972 _e_text_input_cb_input_panel_show(g_client, g_text_input->resource);
977 _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)
979 E_Input_Method_Context *context = wl_resource_get_user_data(resource);
983 WTI_WARNING(resource,
984 WL_DISPLAY_ERROR_INVALID_OBJECT,
985 "No Input Method Context For Resource");
989 if ((context->input) && (context->input->resource))
990 wl_text_input_send_input_panel_data(context->input->resource,
991 serial, data, length);
995 _e_text_input_method_context_cb_hide_input_panel(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t serial)
997 E_Text_Input *text_input = g_text_input;
998 E_Input_Method *input_method = NULL;
1002 WTI_WARNING(resource,
1003 WL_DISPLAY_ERROR_INVALID_OBJECT,
1004 "No Text Input For Resource");
1008 text_input->input_panel_visible = EINA_FALSE;
1010 if (g_text_input && g_text_input->resource && g_client)
1011 _input_panel_hide(g_client, g_text_input->resource, EINA_FALSE);
1013 if (g_input_method && g_input_method->resource)
1014 input_method = wl_resource_get_user_data(g_input_method->resource);
1016 send_hide_input_panel(input_method);
1020 _e_text_input_method_context_cb_get_selection_text(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, int32_t fd)
1022 E_Input_Method_Context *context = wl_resource_get_user_data(resource);
1026 WTI_WARNING(resource,
1027 WL_DISPLAY_ERROR_INVALID_OBJECT,
1028 "No Input Method Context For Resource");
1033 if ((context->input) && (context->input->resource))
1034 wl_text_input_send_get_selection_text(context->input->resource, fd);
1040 _e_text_input_method_context_cb_get_surrounding_text(struct wl_client *client EINA_UNUSED, struct wl_resource *resource,
1041 uint32_t maxlen_before, uint32_t maxlen_after, int32_t fd)
1043 E_Input_Method_Context *context = wl_resource_get_user_data(resource);
1047 WTI_WARNING(resource,
1048 WL_DISPLAY_ERROR_INVALID_OBJECT,
1049 "No Input Method Context For Resource");
1054 if ((context->input) && (context->input->resource))
1055 wl_text_input_send_get_surrounding_text(context->input->resource, maxlen_before, maxlen_after, fd);
1061 _e_text_input_method_context_cb_filter_key_event_done(struct wl_client *client EINA_UNUSED, struct wl_resource *resource,
1062 uint32_t serial, uint32_t state)
1064 E_Input_Method_Context *context = wl_resource_get_user_data(resource);
1068 WTI_WARNING(resource,
1069 WL_DISPLAY_ERROR_INVALID_OBJECT,
1070 "No Input Method Context For Resource");
1074 if ((context->input) && (context->input->resource))
1075 wl_text_input_send_filter_key_event_done(context->input->resource,
1080 _e_text_input_method_context_cb_update_ise_geometry(struct wl_client *client EINA_UNUSED, struct wl_resource *resource,
1081 uint32_t serial, uint32_t x, uint32_t y, uint32_t width, uint32_t height)
1083 E_Input_Method_Context *context = wl_resource_get_user_data(resource);
1087 WTI_WARNING(resource,
1088 WL_DISPLAY_ERROR_INVALID_OBJECT,
1089 "No Input Method Context For Resource");
1093 if ((context->input) && (context->input->resource))
1095 _e_text_input_send_input_panel_geometry(context->input->resource, x, y, width, height);
1096 g_updated_geometry = EINA_TRUE;
1101 _e_text_input_method_context_cb_reshow_input_panel(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
1103 e_input_panel_transient_for_set(client_surface_ec);
1104 e_input_panel_wait_update_set(EINA_TRUE);
1107 static const struct wl_input_method_context_interface _e_text_input_method_context_implementation = {
1108 _e_text_input_method_context_cb_destroy,
1109 _e_text_input_method_context_cb_string_commit,
1110 _e_text_input_method_context_cb_preedit_string,
1111 _e_text_input_method_context_cb_preedit_styling,
1112 _e_text_input_method_context_cb_preedit_cursor,
1113 _e_text_input_method_context_cb_surrounding_text_delete,
1114 _e_text_input_method_context_cb_cursor_position,
1115 _e_text_input_method_context_cb_modifiers_map,
1116 _e_text_input_method_context_cb_keysym,
1117 _e_text_input_method_context_cb_keyboard_grab,
1118 _e_text_input_method_context_cb_key,
1119 _e_text_input_method_context_cb_modifiers,
1120 _e_text_input_method_context_cb_language,
1121 _e_text_input_method_context_cb_text_direction,
1122 _e_text_input_method_context_cb_selection_region,
1123 _e_text_input_method_context_cb_private_command,
1124 _e_text_input_method_context_cb_input_panel_data_update,
1125 _e_text_input_method_context_cb_hide_input_panel,
1126 _e_text_input_method_context_cb_get_selection_text,
1127 _e_text_input_method_context_cb_get_surrounding_text,
1128 _e_text_input_method_context_cb_filter_key_event_done,
1129 _e_text_input_method_context_cb_update_ise_geometry,
1130 _e_text_input_method_context_cb_recapture_string,
1131 _e_text_input_method_context_cb_input_panel_event,
1132 _e_text_input_method_context_cb_commit_content,
1133 _e_text_input_method_context_cb_update_candidate_state,
1134 _e_text_input_method_context_cb_reshow_input_panel,
1138 _e_text_input_method_context_cb_resource_destroy(struct wl_resource *resource)
1140 E_Input_Method_Context *context = wl_resource_get_user_data(resource);
1144 WTI_WARNING(resource,
1145 WL_DISPLAY_ERROR_INVALID_OBJECT,
1146 "No Input Method Context For Resource");
1150 #if ENABLE_GRAB_KEYBOARD
1151 if (context->kbd.resource)
1153 wl_resource_destroy(context->kbd.resource);
1154 context->kbd.resource = NULL;
1158 LOGI("resource(%p), context(%p)", resource, context);
1160 if ((context->input_method) &&
1161 (context->input_method->context == context))
1162 context->input_method->context = NULL;
1167 static Eina_Bool is_number_key(const char *str)
1169 if (!str) return EINA_FALSE;
1171 int result = atoi(str);
1175 if (!strcmp(str, "0"))
1185 _e_mod_ecore_key_down_cb(void *data, int type, void *event)
1187 Ecore_Event_Key *ev = (Ecore_Event_Key *)event;
1188 if (ev->event_flags & ECORE_EVENT_FLAG_CANCEL)
1190 SECURE_LOGI("%s key is cancelled.", ev->key);
1191 return ECORE_CALLBACK_PASS_ON;
1194 if (g_disable_show_panel == EINA_TRUE)
1195 return ECORE_CALLBACK_PASS_ON;
1197 /* process remote controller key exceptionally */
1198 if (((!strcmp(ev->key, "Down") ||
1199 !strcmp(ev->key, "KP_Down") ||
1200 !strcmp(ev->key, "Up") ||
1201 !strcmp(ev->key, "KP_Up") ||
1202 !strcmp(ev->key, "Right") ||
1203 !strcmp(ev->key, "KP_Right") ||
1204 !strcmp(ev->key, "Left") ||
1205 !strcmp(ev->key, "KP_Left")) && !ev->string) ||
1206 !strcmp(ev->key, "Return") ||
1207 !strcmp(ev->key, "Pause") ||
1208 !strcmp(ev->key, "NoSymbol") ||
1209 !strncmp(ev->key, "XF86", 4) ||
1210 !strncmp(ev->key, "Cancel", 5) ||
1211 (is_number_key(ev->string) && _TV))
1212 return ECORE_CALLBACK_PASS_ON;
1214 SECURE_LOGI("Hide IME (key : %s)", ev->key);
1216 if (g_text_input && g_text_input->resource && g_client)
1217 _input_panel_hide(g_client, g_text_input->resource, EINA_FALSE);
1219 g_disable_show_panel = EINA_TRUE;
1221 return ECORE_CALLBACK_PASS_ON;
1225 _e_text_input_deactivate(E_Text_Input *text_input, E_Input_Method *input_method, Eina_Bool need_focus_in)
1227 if (text_input == g_text_input)
1229 g_text_input = NULL;
1233 if (input_method->input == text_input)
1235 if ((input_method->context) && (input_method->resource))
1237 #if ENABLE_GRAB_KEYBOARD
1238 _e_text_input_method_context_grab_set(input_method->context,
1241 if (input_method->resource == destroyed_resource)
1243 LOGI("deactivate skipped : %p %p", input_method->resource,
1244 input_method->context->resource);
1248 /* TODO: finish the grab of keyboard. */
1249 wl_input_method_send_deactivate(input_method->resource,
1250 input_method->context->resource,
1252 LOGI("wm_map TEXTINPUT deactivate : %p %p", input_method->resource,
1253 input_method->context->resource);
1257 if (ecore_key_down_handler)
1259 ecore_event_handler_del(ecore_key_down_handler);
1260 ecore_key_down_handler = NULL;
1263 LOGI("Resetting input_method->input : %p, text_input : %p, %p %p",
1264 input_method->input, text_input,
1265 input_method->resource,
1266 (input_method->context ? input_method->context->resource : NULL));
1267 input_method->input = NULL;
1268 if (input_method->context) input_method->context->input = NULL;
1269 input_method->context = NULL;
1271 text_input->input_panel_show_requested = EINA_FALSE;
1272 text_input->input_methods = eina_list_remove(text_input->input_methods, input_method);
1274 if (text_input->resource)
1275 wl_text_input_send_leave(text_input->resource);
1277 if (_TV || _WEARABLE)
1278 g_disable_show_panel = EINA_FALSE;
1283 _e_text_input_cb_activate(struct wl_client *client, struct wl_resource *resource, struct wl_resource *seat, struct wl_resource *surface)
1285 E_Text_Input *text_input = NULL;
1286 E_Input_Method *input_method = NULL;
1287 E_Text_Input *old = NULL;
1288 E_Input_Method_Context *context = NULL;
1289 E_Client *ec = NULL;
1291 EINA_SAFETY_ON_NULL_GOTO(resource, err);
1292 EINA_SAFETY_ON_NULL_GOTO(seat, err);
1293 EINA_SAFETY_ON_NULL_GOTO(g_input_method, err);
1294 EINA_SAFETY_ON_NULL_GOTO(g_input_method->resource, err);
1296 /* Store application window's E_Client* value for setting transient_for information later */
1297 ec = wl_resource_get_user_data(surface);
1298 EINA_SAFETY_ON_NULL_GOTO(ec, err);
1299 EINA_SAFETY_ON_TRUE_GOTO(e_object_is_del(E_OBJECT(ec)), err);
1300 client_surface_ec = ec;
1302 text_input = wl_resource_get_user_data(resource);
1303 g_text_input = text_input;
1306 /* FIXME: should get input_method object from seat. */
1307 input_method = wl_resource_get_user_data(g_input_method->resource);
1308 EINA_SAFETY_ON_NULL_GOTO(input_method, err);
1310 old = input_method->input;
1312 LOGI("old : %p, text_input : %p, %d", old, text_input, g_input_panel_state);
1313 if (old == text_input)
1317 _e_text_input_deactivate(old, input_method, EINA_TRUE);
1319 input_method->input = text_input;
1320 text_input->input_methods = eina_list_append(text_input->input_methods, input_method);
1322 if (input_method->resource)
1324 if (!(context = E_NEW(E_Input_Method_Context, 1)))
1326 wl_client_post_no_memory(client);
1327 ERR("Could not allocate space for Input_Method_Context");
1331 if (!ecore_key_down_handler)
1332 ecore_key_down_handler = ecore_event_handler_prepend(ECORE_EVENT_KEY_DOWN,
1333 _e_mod_ecore_key_down_cb,
1337 wl_resource_create(wl_resource_get_client(input_method->resource),
1338 &wl_input_method_context_interface, 1, 0);
1340 if (context->resource)
1341 wl_resource_set_implementation(context->resource,
1342 &_e_text_input_method_context_implementation,
1343 context, _e_text_input_method_context_cb_resource_destroy);
1345 context->input = text_input;
1346 context->input_method = input_method;
1347 input_method->context = context;
1349 if (context->resource)
1351 wl_input_method_send_activate(input_method->resource, context->resource, text_input->id, EINA_TRUE);
1352 LOGI("wm_map TEXTINPUT activate : %p %p", input_method->resource,
1355 destroyed_resource = NULL;
1358 WRN("Failed to send activate due to no resource in context");
1361 WRN("no inputmethod resource");
1363 if (_TV || _WEARABLE)
1364 set_soft_keyboard_mode();
1366 if (text_input->resource)
1367 wl_text_input_send_enter(text_input->resource, surface);
1373 WTI_WARNING(resource,
1374 WL_DISPLAY_ERROR_INVALID_OBJECT,
1375 "No Text Input For Resource");
1379 WL_DISPLAY_ERROR_INVALID_OBJECT,
1380 "No Comp Data For Seat");
1384 _e_text_input_cb_deactivate(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *seat)
1387 E_Text_Input *text_input = wl_resource_get_user_data(resource);
1388 E_Input_Method *input_method = NULL;
1392 WTI_WARNING(resource,
1393 WL_DISPLAY_ERROR_INVALID_OBJECT,
1394 "No Text Input For Resource");
1398 if (text_input == g_text_input)
1400 g_text_input = NULL;
1404 /* FIXME: should get input_method object from seat. */
1405 if (g_input_method && g_input_method->resource)
1406 input_method = wl_resource_get_user_data(g_input_method->resource);
1411 WL_DISPLAY_ERROR_INVALID_OBJECT,
1412 "No Input Method For Seat");
1416 _e_text_input_deactivate(text_input, input_method, EINA_TRUE);
1420 _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)
1422 E_Input_Method_Context *context = NULL;
1424 EINA_SAFETY_ON_NULL_RETURN_VAL(input_method, EINA_FALSE);
1425 EINA_SAFETY_ON_NULL_RETURN_VAL(input_method->resource, EINA_FALSE);
1426 EINA_SAFETY_ON_NULL_RETURN_VAL(text_input, EINA_FALSE);
1428 g_text_input = text_input;
1430 input_method->input = text_input;
1431 text_input->input_methods = eina_list_append(text_input->input_methods, input_method);
1433 if (!(context = E_NEW(E_Input_Method_Context, 1)))
1435 wl_client_post_no_memory(client);
1436 ERR("Could not allocate space for Input_Method_Context");
1441 wl_resource_create(wl_resource_get_client(input_method->resource),
1442 &wl_input_method_context_interface, 1, 0);
1444 if (context->resource)
1445 wl_resource_set_implementation(context->resource,
1446 &_e_text_input_method_context_implementation,
1447 context, _e_text_input_method_context_cb_resource_destroy);
1449 context->input = text_input;
1450 context->input_method = input_method;
1451 input_method->context = context;
1453 wl_input_method_send_activate(input_method->resource, context->resource, text_input->id, need_focus_out);
1455 LOGI("wm_map TEXTINPUT activate : input_method->resource(%p) context->resource(%p)",
1456 input_method->resource, context->resource);
1458 destroyed_resource = NULL;
1464 _e_text_input_cb_input_panel_show(struct wl_client *client, struct wl_resource *resource)
1466 E_Text_Input *text_input = wl_resource_get_user_data(resource);
1467 E_Input_Method *input_method = NULL;
1469 LOGI("text_input : %p\n", text_input);
1473 WTI_WARNING(resource,
1474 WL_DISPLAY_ERROR_INVALID_OBJECT,
1475 "No Text Input For Resource");
1479 text_input->input_panel_show_requested = EINA_TRUE;
1481 #ifndef SUPPORT_CANDIDATE_ONEWINDOW
1482 if (g_disable_show_panel == EINA_TRUE)
1486 if (g_input_method && g_input_method->resource)
1487 input_method = wl_resource_get_user_data(g_input_method->resource);
1489 /* If input_method->context doesn't exist, create context struct to send input_panel_show event to Input Method(IME) correctly.
1490 * Because input_panel_show event can be called before focus_in(activate) by application.
1491 * And Input Method(IME) should know the state of their own input_panel to manage their resource when the input_panel is shown. */
1492 if (input_method && (!input_method->context || !input_method->context->resource))
1493 _e_text_input_method_create_context(client, input_method, text_input, EINA_TRUE);
1495 #ifdef SUPPORT_CANDIDATE_ONEWINDOW
1496 if (g_disable_show_panel == EINA_TRUE)
1498 if (g_show_state_candidate == EINA_TRUE)
1500 g_input_panel_state = E_INPUT_PANEL_STATE_DID_SHOW;
1501 g_show_client = client;
1502 e_input_panel_visibility_change(EINA_TRUE);
1503 e_input_panel_transient_for_set(client_surface_ec);
1511 if (input_method->resource && input_method->context && input_method->context->resource)
1513 /* DO NOT show input panel surface until we get message "show complete" from input method,
1514 * in order to give a change to update UI */
1515 LOGI("IM::SHOW::WAIT_FOR_READY\n");
1517 g_show_client = client;
1519 if (client_surface_ec)
1521 E_Util_Transform *transform = &client_surface_ec->transform_core.result.transform;
1522 Eina_Bool transformEnabled = e_client_transform_core_enable_get(client_surface_ec);
1524 if (transformEnabled && transform != 0)
1525 e_util_transform_rotation_round_get(transform, NULL, NULL, &angle);
1527 angle = client_surface_ec->e.state.rot.ang.curr;
1530 wl_input_method_send_show_input_panel(input_method->resource, input_method->context->resource, angle);
1532 /* we need to force update in order to release buffer
1533 * if we do not, client can't update
1534 * because they may in manual render state by frame callback mechanism,
1535 * and also don't have released buffer */
1536 e_input_panel_wait_update_set(EINA_TRUE);
1540 LOGW("Failed to send show input panel. inputmethod : %p, input_method->resource : %p, input_method->context : %p", input_method, input_method->resource, input_method->context);
1541 if (input_method->context)
1542 LOGW("Failed to send show input panel. input_method->context->resource : %p", input_method->context->resource);
1547 LOGW("No input method");
1550 /* If the input panel state was WILL_HIDE, it means that the conformant area information needs to be restored */
1551 if (g_input_panel_state == E_INPUT_PANEL_STATE_WILL_HIDE)
1553 if (text_input->resource)
1554 wl_text_input_send_private_command(text_input->resource, 0, "CONFORMANT_RESTORE");
1557 text_input->input_panel_visible = EINA_TRUE;
1558 g_input_panel_state = E_INPUT_PANEL_STATE_WILL_SHOW;
1559 g_show_text_input = text_input;
1561 g_updated_geometry = EINA_FALSE;
1563 e_input_panel_transient_for_set(client_surface_ec);
1567 _e_text_input_cb_input_panel_hide(struct wl_client *client, struct wl_resource *resource)
1569 if (g_show_client == client) {
1570 _input_panel_hide(client, resource, EINA_FALSE);
1571 g_show_text_input = NULL;
1572 g_show_client = NULL;
1577 _e_text_input_cb_reset(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
1579 E_Text_Input *text_input = wl_resource_get_user_data(resource);
1580 E_Input_Method *input_method = NULL;
1581 Eina_List *l = NULL;
1585 WTI_WARNING(resource,
1586 WL_DISPLAY_ERROR_INVALID_OBJECT,
1587 "No Text Input For Resource");
1591 EINA_LIST_FOREACH(text_input->input_methods, l, input_method)
1593 if (!input_method || !input_method->context) continue;
1594 if (input_method->context->resource)
1595 wl_input_method_context_send_reset(input_method->context->resource);
1600 _e_text_input_cb_content_type_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t hint, uint32_t purpose)
1602 E_Text_Input *text_input = wl_resource_get_user_data(resource);
1603 E_Input_Method *input_method = NULL;
1604 Eina_List *l = NULL;
1608 WTI_WARNING(resource,
1609 WL_DISPLAY_ERROR_INVALID_OBJECT,
1610 "No Text Input For Resource");
1614 EINA_LIST_FOREACH(text_input->input_methods, l, input_method)
1616 if (!input_method || !input_method->context) continue;
1618 if (input_method->context->resource)
1619 wl_input_method_context_send_content_type(input_method->context->resource,
1625 _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)
1627 E_Text_Input *text_input = wl_resource_get_user_data(resource);
1631 WTI_WARNING(resource,
1632 WL_DISPLAY_ERROR_INVALID_OBJECT,
1633 "No Text Input For Resource");
1637 /* TODO: issue event update input_panel */
1641 _e_text_input_cb_preferred_language_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, const char *language)
1643 E_Text_Input *text_input = wl_resource_get_user_data(resource);
1644 E_Input_Method *input_method = NULL;
1645 Eina_List *l = NULL;
1649 WTI_WARNING(resource,
1650 WL_DISPLAY_ERROR_INVALID_OBJECT,
1651 "No Text Input For Resource");
1655 EINA_LIST_FOREACH(text_input->input_methods, l, input_method)
1657 if (!input_method || !input_method->context) continue;
1659 if (input_method->context->resource)
1660 wl_input_method_context_send_preferred_language(input_method->context->resource,
1666 _e_text_input_cb_state_commit(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t serial)
1668 E_Text_Input *text_input = wl_resource_get_user_data(resource);
1669 E_Input_Method *input_method = NULL;
1670 Eina_List *l = NULL;
1674 WTI_WARNING(resource,
1675 WL_DISPLAY_ERROR_INVALID_OBJECT,
1676 "No Text Input For Resource");
1680 EINA_LIST_FOREACH(text_input->input_methods, l, input_method)
1682 if (!input_method || !input_method->context) continue;
1684 if (input_method->context->resource)
1685 wl_input_method_context_send_commit_state(input_method->context->resource, serial);
1690 _e_text_input_cb_action_invoke(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t button, uint32_t index)
1692 E_Text_Input *text_input = wl_resource_get_user_data(resource);
1693 E_Input_Method *input_method = NULL;
1694 Eina_List *l = NULL;
1698 WTI_WARNING(resource,
1699 WL_DISPLAY_ERROR_INVALID_OBJECT,
1700 "No Text Input For Resource");
1704 EINA_LIST_FOREACH(text_input->input_methods, l, input_method)
1706 if (!input_method || !input_method->context) continue;
1708 if (input_method->context->resource)
1709 wl_input_method_context_send_invoke_action(input_method->context->resource,
1715 _e_text_input_cb_return_key_type_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t return_key_type)
1717 E_Text_Input *text_input = wl_resource_get_user_data(resource);
1718 E_Input_Method *input_method = NULL;
1719 Eina_List *l = NULL;
1723 WTI_WARNING(resource,
1724 WL_DISPLAY_ERROR_INVALID_OBJECT,
1725 "No Text Input For Resource");
1729 EINA_LIST_FOREACH(text_input->input_methods, l, input_method)
1731 if (!input_method || !input_method->context) continue;
1733 if (input_method->context->resource)
1734 wl_input_method_context_send_return_key_type(input_method->context->resource,
1740 _e_text_input_cb_return_key_disabled_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t disabled)
1742 E_Text_Input *text_input = wl_resource_get_user_data(resource);
1743 E_Input_Method *input_method = NULL;
1744 Eina_List *l = NULL;
1748 WTI_WARNING(resource,
1749 WL_DISPLAY_ERROR_INVALID_OBJECT,
1750 "No Text Input For Resource");
1754 EINA_LIST_FOREACH(text_input->input_methods, l, input_method)
1756 if (!input_method || !input_method->context) continue;
1758 if (input_method->context->resource)
1759 wl_input_method_context_send_return_key_disabled(input_method->context->resource,
1765 _e_text_input_cb_input_panel_data_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, const char *data, uint32_t length)
1767 E_Text_Input *text_input = wl_resource_get_user_data(resource);
1768 E_Input_Method *input_method = NULL;
1769 Eina_List *l = NULL;
1773 WTI_WARNING(resource,
1774 WL_DISPLAY_ERROR_INVALID_OBJECT,
1775 "No Text Input For Resource");
1779 EINA_LIST_FOREACH(text_input->input_methods, l, input_method)
1781 if (!input_method || !input_method->context) continue;
1783 if (input_method->context->resource)
1784 wl_input_method_context_send_input_panel_data(input_method->context->resource,
1788 /* Temporarily receiving WILL_HIDE_ACK via input_panel_data, will need for a new wayland protocol */
1789 const char *szWillHideAck = "WILL_HIDE_ACK";
1790 if (strncmp(data, szWillHideAck, strlen(szWillHideAck)) == 0)
1792 if (g_timer_will_hide)
1794 ecore_timer_del(g_timer_will_hide);
1795 g_timer_will_hide = NULL;
1797 INF("WILL_HIDE_ACK_RECVED, %d", g_input_panel_state);
1798 if (g_input_panel_state == E_INPUT_PANEL_STATE_WILL_HIDE)
1800 e_input_panel_visibility_change(EINA_FALSE);
1801 e_input_panel_transient_for_set(NULL);
1802 g_input_panel_state = E_INPUT_PANEL_STATE_DID_HIDE;
1808 _e_text_input_cb_bidi_direction_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t bidi_direction)
1810 E_Text_Input *text_input = wl_resource_get_user_data(resource);
1811 E_Input_Method *input_method = NULL;
1812 Eina_List *l = NULL;
1816 WTI_WARNING(resource,
1817 WL_DISPLAY_ERROR_INVALID_OBJECT,
1818 "No Text Input For Resource");
1822 EINA_LIST_FOREACH(text_input->input_methods, l, input_method)
1824 if (!input_method || !input_method->context) continue;
1826 if (input_method->context->resource)
1827 wl_input_method_context_send_bidi_direction(input_method->context->resource,
1833 _e_text_input_cb_cursor_position_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t cursor_position)
1835 E_Text_Input *text_input = wl_resource_get_user_data(resource);
1836 E_Input_Method *input_method = NULL;
1837 Eina_List *l = NULL;
1841 WTI_WARNING(resource,
1842 WL_DISPLAY_ERROR_INVALID_OBJECT,
1843 "No Text Input For Resource");
1847 EINA_LIST_FOREACH(text_input->input_methods, l, input_method)
1849 if (!input_method || !input_method->context) continue;
1851 if (input_method->context->resource)
1852 wl_input_method_context_send_cursor_position(input_method->context->resource, cursor_position);
1857 _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)
1859 E_Text_Input *text_input = wl_resource_get_user_data(resource);
1860 E_Input_Method *input_method = NULL;
1861 Eina_List *l = NULL;
1865 WTI_WARNING(resource,
1866 WL_DISPLAY_ERROR_INVALID_OBJECT,
1867 "No Text Input For Resource");
1871 EINA_LIST_FOREACH(text_input->input_methods, l, input_method)
1873 if (!input_method || !input_method->context) continue;
1875 if (input_method->context->resource)
1876 wl_input_method_context_send_process_input_device_event(input_method->context->resource,
1877 type, data, length);
1882 _e_text_input_cb_filter_key_event(struct wl_client *client EINA_UNUSED, struct wl_resource *resource,
1883 uint32_t serial, uint32_t time, const char *keyname, uint32_t state,
1884 uint32_t modifiers, const char *dev_name, uint32_t dev_class,
1885 uint32_t dev_subclass, uint32_t keycode)
1888 E_Text_Input *text_input = wl_resource_get_user_data(resource);
1889 E_Input_Method *input_method = NULL;
1893 WTI_WARNING(resource,
1894 WL_DISPLAY_ERROR_INVALID_OBJECT,
1895 "No Text Input For Resource");
1899 /* FIXME: should get input_method object from seat. */
1900 if (g_input_method && g_input_method->resource)
1901 input_method = wl_resource_get_user_data(g_input_method->resource);
1903 if (input_method && input_method->context && input_method->context->resource)
1905 wl_input_method_context_send_filter_key_event(input_method->context->resource,
1906 serial, time, keyname, state, modifiers,
1907 dev_name, dev_class, dev_subclass, keycode);
1911 if (text_input->resource)
1912 wl_text_input_send_filter_key_event_done(text_input->resource, serial, false);
1914 WTI_WARNING(resource,
1915 WL_DISPLAY_ERROR_INVALID_OBJECT,
1922 _e_text_input_cb_get_hide_permission(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
1924 E_Text_Input *text_input = wl_resource_get_user_data(resource);
1925 uint32_t permission = 1;
1926 E_Client *focused_ec = NULL;
1930 WTI_WARNING(resource,
1931 WL_DISPLAY_ERROR_INVALID_OBJECT,
1932 "No Text Input For Resource");
1936 focused_ec = e_client_focused_get();
1939 if (focused_ec != client_surface_ec)
1941 E_Window_Type focus_win_type = focused_ec->netwm.type;
1942 LOGI("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);
1944 if (focus_win_type == E_WINDOW_TYPE_NOTIFICATION ||
1945 focus_win_type == E_WINDOW_TYPE_POPUP_MENU)
1951 LOGI("Can't get focus window\n");
1954 if (text_input->resource)
1955 wl_text_input_send_hide_permission(text_input->resource, permission);
1959 _e_text_input_cb_set_capital_mode(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t mode)
1961 E_Text_Input *text_input = wl_resource_get_user_data(resource);
1962 E_Input_Method *input_method = NULL;
1963 Eina_List *l = NULL;
1967 WTI_WARNING(resource,
1968 WL_DISPLAY_ERROR_INVALID_OBJECT,
1969 "No Text Input For Resource");
1973 EINA_LIST_FOREACH(text_input->input_methods, l, input_method)
1975 if (!input_method || !input_method->context) continue;
1976 if (input_method->context->resource)
1977 wl_input_method_context_send_capital_mode(input_method->context->resource, mode);
1982 _e_text_input_cb_prediction_hint_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, const char *prediction_hint)
1984 E_Text_Input *text_input = wl_resource_get_user_data(resource);
1985 E_Input_Method *input_method = NULL;
1986 Eina_List *l = NULL;
1990 WTI_WARNING(resource,
1991 WL_DISPLAY_ERROR_INVALID_OBJECT,
1992 "No Text Input For Resource");
1996 EINA_LIST_FOREACH(text_input->input_methods, l, input_method)
1998 if (!input_method || !input_method->context) continue;
2000 if (input_method->context->resource)
2001 wl_input_method_context_send_prediction_hint(input_method->context->resource, prediction_hint);
2006 _e_text_input_cb_prediction_hint_data_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, const char *key, const char *value)
2008 E_Text_Input *text_input = wl_resource_get_user_data(resource);
2009 E_Input_Method *input_method = NULL;
2010 Eina_List *l = NULL;
2014 WTI_WARNING(resource,
2015 WL_DISPLAY_ERROR_INVALID_OBJECT,
2016 "No Text Input For Resource");
2020 EINA_LIST_FOREACH(text_input->input_methods, l, input_method)
2022 if (!input_method || !input_method->context) continue;
2024 if (input_method->context->resource)
2025 wl_input_method_context_send_prediction_hint_data(input_method->context->resource, key, value);
2030 _e_text_input_cb_input_panel_enabled_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t enabled)
2032 E_Text_Input *text_input = wl_resource_get_user_data(resource);
2036 WTI_WARNING(resource,
2037 WL_DISPLAY_ERROR_INVALID_OBJECT,
2038 "No Text Input For Resource");
2042 g_input_panel_enabled = enabled;
2046 _e_text_input_cb_mime_type_accept_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, const char *mime_type)
2048 E_Text_Input *text_input = wl_resource_get_user_data(resource);
2049 E_Input_Method *input_method = NULL;
2050 Eina_List *l = NULL;
2054 WTI_WARNING(resource,
2055 WL_DISPLAY_ERROR_INVALID_OBJECT,
2056 "No Text Input For Resource");
2060 EINA_LIST_FOREACH(text_input->input_methods, l, input_method)
2062 if (!input_method || !input_method->context) continue;
2064 if (input_method->context->resource)
2065 wl_input_method_context_send_mime_type(input_method->context->resource, mime_type);
2070 _e_text_input_cb_input_panel_position_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t x, uint32_t y)
2072 E_Text_Input *text_input = wl_resource_get_user_data(resource);
2076 WTI_WARNING(resource,
2077 WL_DISPLAY_ERROR_INVALID_OBJECT,
2078 "No Text Input For Resource");
2081 e_input_panel_floating_position_set(x, y);
2085 _e_text_input_cb_finalize_content(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, const char *text, uint32_t cursor_position)
2087 E_Text_Input *text_input = wl_resource_get_user_data(resource);
2088 E_Input_Method *input_method = NULL;
2089 Eina_List *l = NULL;
2093 WTI_WARNING(resource,
2094 WL_DISPLAY_ERROR_INVALID_OBJECT,
2095 "No Text Input For Resource");
2099 EINA_LIST_FOREACH(text_input->input_methods, l, input_method)
2101 if (!input_method || !input_method->context) continue;
2103 if (input_method->context->resource)
2104 wl_input_method_context_send_finalized_content(input_method->context->resource, text, cursor_position);
2109 _e_text_input_cb_resource_destroy(struct wl_resource *resource)
2111 E_Text_Input *text_input = wl_resource_get_user_data(resource);
2112 E_Input_Method *input_method = NULL;
2116 WTI_WARNING(resource,
2117 WL_DISPLAY_ERROR_INVALID_OBJECT,
2118 "No Text Input For Resource");
2122 LOGI("resource : %p", resource);
2124 if (g_show_text_input == text_input)
2126 if (text_input->input_panel_visible)
2128 _input_panel_hide(g_client, resource, EINA_TRUE);
2131 g_show_text_input = NULL;
2134 if (g_text_input == text_input)
2136 g_text_input = NULL;
2140 EINA_LIST_FREE(text_input->input_methods, input_method)
2143 _e_text_input_deactivate(text_input, input_method, EINA_TRUE);
2150 _e_text_input_cb_destroy(struct wl_client *client, struct wl_resource *resource)
2152 E_Text_Input *text_input = wl_resource_get_user_data(resource);
2153 E_Input_Method *input_method = NULL;
2154 Eina_Bool _context_created = EINA_FALSE;
2158 WTI_WARNING(resource,
2159 WL_DISPLAY_ERROR_INVALID_OBJECT,
2160 "No Text Input For Resource");
2164 if (g_input_method && g_input_method->resource)
2165 input_method = wl_resource_get_user_data(g_input_method->resource);
2169 WTI_WARNING(resource,
2170 WL_DISPLAY_ERROR_INVALID_OBJECT,
2171 "No Input Method For Seat");
2175 LOGI("text_input(%p), focus(%d), input_method(%p), input_method->resource(%p), context(%p), context->resource(%p), resource(%p)",
2176 text_input, (text_input == g_text_input), input_method, input_method->resource, input_method->context,
2177 (input_method->context ? input_method->context->resource : NULL), resource);
2179 if ((!input_method->context) || (!input_method->context->resource))
2180 _context_created = _e_text_input_method_create_context(client, input_method, text_input, EINA_FALSE);
2182 if (text_input == g_text_input &&
2183 input_method->resource && input_method->context && input_method->context->resource)
2185 wl_input_method_send_destroy(input_method->resource, input_method->context->resource);
2186 LOGI("wm_map TEXTINPUT destroy : input_method->resource(%p) input_method->context->resource(%p)",
2187 input_method->resource, input_method->context->resource);
2189 destroyed_resource = input_method->resource;
2192 if (_context_created)
2193 _e_text_input_deactivate(text_input, input_method, EINA_FALSE);
2196 static const struct wl_text_input_interface _e_text_input_implementation = {
2197 _e_text_input_cb_destroy,
2198 _e_text_input_cb_activate,
2199 _e_text_input_cb_deactivate,
2200 _e_text_input_cb_input_panel_show,
2201 _e_text_input_cb_input_panel_hide,
2202 _e_text_input_cb_reset,
2203 _e_text_input_cb_content_type_set,
2204 _e_text_input_cb_cursor_rectangle_set,
2205 _e_text_input_cb_preferred_language_set,
2206 _e_text_input_cb_state_commit,
2207 _e_text_input_cb_action_invoke,
2208 _e_text_input_cb_return_key_type_set,
2209 _e_text_input_cb_return_key_disabled_set,
2210 _e_text_input_cb_input_panel_data_set,
2211 _e_text_input_cb_bidi_direction_set,
2212 _e_text_input_cb_cursor_position_set,
2213 _e_text_input_cb_process_input_device_event,
2214 _e_text_input_cb_filter_key_event,
2215 _e_text_input_cb_get_hide_permission,
2216 _e_text_input_cb_set_capital_mode,
2217 _e_text_input_cb_prediction_hint_set,
2218 _e_text_input_cb_mime_type_accept_set,
2219 _e_text_input_cb_input_panel_position_set,
2220 _e_text_input_cb_finalize_content,
2221 _e_text_input_cb_prediction_hint_data_set,
2222 _e_text_input_cb_input_panel_enabled_set
2226 _e_text_input_manager_cb_text_input_create(struct wl_client *client, struct wl_resource *resource, uint32_t id)
2228 E_Text_Input_Mgr *text_input_mgr = wl_resource_get_user_data(resource);
2229 E_Text_Input *text_input = NULL;
2231 if (!text_input_mgr)
2233 WTI_WARNING(resource,
2234 WL_DISPLAY_ERROR_INVALID_OBJECT,
2235 "No Text Input Manager For Resource");
2239 if (!(text_input = E_NEW(E_Text_Input, 1)))
2241 wl_client_post_no_memory(client);
2242 ERR("Could not allocate space for Text_Input");
2246 text_input->resource =
2247 wl_resource_create(client, &wl_text_input_interface, 1, id);
2249 if (!text_input->resource)
2251 wl_client_post_no_memory(client);
2252 ERR("Could not create the resource for text_input");
2256 text_input->id = g_text_input_count++;
2258 wl_resource_set_implementation(text_input->resource,
2259 &_e_text_input_implementation,
2260 text_input, _e_text_input_cb_resource_destroy);
2263 static const struct wl_text_input_manager_interface _e_text_input_manager_implementation = {
2264 _e_text_input_manager_cb_text_input_create
2268 _e_text_cb_bind_text_input_manager(struct wl_client *client, void *data, uint32_t version EINA_UNUSED, uint32_t id)
2270 E_Text_Input_Mgr *text_input_mgr = data;
2272 text_input_mgr->resource =
2273 wl_resource_create(client,
2274 &wl_text_input_manager_interface, 1, id);
2276 if (text_input_mgr->resource)
2277 wl_resource_set_implementation(text_input_mgr->resource,
2278 &_e_text_input_manager_implementation,
2279 text_input_mgr, NULL);
2283 _e_text_input_method_cb_unbind(struct wl_resource *resource)
2286 E_Input_Method *input_method = wl_resource_get_user_data(resource);
2290 WTI_WARNING(resource,
2291 WL_DISPLAY_ERROR_INVALID_OBJECT,
2292 "No Input Method For Resource");
2296 if (input_method->resource != resource) return;
2298 if (input_method->input)
2299 _e_text_input_deactivate(input_method->input, input_method, EINA_TRUE);
2301 input_method->resource = NULL;
2302 input_method->context = NULL;
2304 if (vconf_set_bool(VCONFKEY_ISF_BIND, 0) != 0)
2305 LOGW("failed to set isf bind\n");
2309 _e_text_input_method_cb_bind(struct wl_client *client, void *data, uint32_t version EINA_UNUSED, uint32_t id)
2312 E_Input_Method *input_method = data;
2313 struct wl_resource *resource = NULL;
2315 if (!input_method) return;
2317 if (input_method->resource)
2318 _e_text_input_method_cb_unbind(input_method->resource);
2320 if (input_method->resource)
2322 WTI_WARNING(input_method->resource, WL_DISPLAY_ERROR_INVALID_OBJECT,
2323 "input_method object already bound");
2327 resource = wl_resource_create(client, &wl_input_method_interface, 1, id);
2328 if (EINA_UNLIKELY(!resource))
2331 input_method->resource = resource;
2333 wl_resource_set_implementation(resource, NULL, input_method,
2334 _e_text_input_method_cb_unbind);
2336 if (vconf_set_bool(VCONFKEY_ISF_BIND, 1) != 0)
2337 LOGW("failed to set isf bind\n");
2341 _e_text_input_method_destroy(void *data)
2343 E_Input_Method *input_method = data;
2348 if (input_method->global)
2350 wl_global_destroy(input_method->global);
2351 input_method->global = NULL;
2358 _e_text_input_method_create(void)
2360 if (!(g_input_method = E_NEW(E_Input_Method, 1)))
2362 ERR("Could not allocate space for Input_Method");
2366 g_input_method->global =
2367 wl_global_create(e_comp_wl->wl.disp, &wl_input_method_interface, 1,
2368 g_input_method, _e_text_input_method_cb_bind);
2370 if (!g_input_method->global)
2372 free(g_input_method);
2373 g_input_method = NULL;
2377 _e_mod_text_input_shutdown_cb_add(_e_text_input_method_destroy, g_input_method);
2383 _e_text_input_manager_destroy(void *data)
2385 E_Text_Input_Mgr *text_input_mgr = data;
2386 if (!text_input_mgr) return;
2388 LOGI("input manager : %p", text_input_mgr);
2390 if (text_input_mgr->global)
2392 wl_global_destroy(text_input_mgr->global);
2393 text_input_mgr->global = NULL;
2395 free(text_input_mgr);
2399 _e_text_input_manager_create(void)
2401 E_Text_Input_Mgr *text_input_mgr;
2403 if (!(text_input_mgr = E_NEW(E_Text_Input_Mgr, 1)))
2405 ERR("Could not allocate space for Text_Input_Manager");
2409 text_input_mgr->global =
2410 wl_global_create(e_comp_wl->wl.disp,
2411 &wl_text_input_manager_interface, 1,
2412 text_input_mgr, _e_text_cb_bind_text_input_manager);
2414 if (!text_input_mgr->global)
2416 free(text_input_mgr);
2420 LOGI("input manager : %p", text_input_mgr);
2422 _e_mod_text_input_shutdown_cb_add(_e_text_input_manager_destroy, text_input_mgr);
2428 _e_mod_text_input_shutdown(void)
2430 E_Mod_Text_Input_Shutdown_Cb *cb;
2432 EINA_LIST_FREE(shutdown_list, cb)
2442 E_API E_Module_Api e_modapi = { E_MODULE_API_VERSION, "Wl_Text_Input" };
2445 set_soft_keyboard_mode()
2447 g_disable_show_panel = EINA_FALSE;
2449 /* switch to S/W keyboard mode */
2451 if (vconf_get_bool(VCONFKEY_ISF_HW_KEYBOARD_INPUT_DETECTED, &val) == 0 && val != 0)
2452 vconf_set_bool(VCONFKEY_ISF_HW_KEYBOARD_INPUT_DETECTED, 0);
2456 _e_mod_eeze_udev_watch_cb(const char *text, Eeze_Udev_Event event, void *data, Eeze_Udev_Watch *watch)
2458 if (event == EEZE_UDEV_EVENT_REMOVE)
2459 set_soft_keyboard_mode();
2463 e_client_rotation_is_progress(E_Client *ec)
2465 if (!ec) return EINA_TRUE;
2467 if (ec->e.state.rot.ang.next == -1)
2474 _e_text_input_method_context_cb_client_resize(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
2480 ev = (E_Event_Client *)event;
2481 EINA_SAFETY_ON_NULL_RETURN_VAL(ev, ECORE_CALLBACK_PASS_ON);
2484 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, ECORE_CALLBACK_PASS_ON);
2486 found = e_input_panel_client_find(ec);
2487 if (!found) return ECORE_CALLBACK_PASS_ON;
2488 if ((ec->w < 1) && (ec->h < 1)) return ECORE_CALLBACK_PASS_ON;
2490 e_text_input_update_input_panel_geometry(ec);
2492 return ECORE_CALLBACK_PASS_ON;
2496 _pol_cb_hook_client_del(void *d EINA_UNUSED, E_Client *ec)
2498 if (EINA_UNLIKELY(!ec))
2501 if (ec == client_surface_ec)
2503 LOGI("transient_for_ec deleted, hiding input panel\n");
2504 e_input_panel_visibility_change(EINA_FALSE);
2505 e_input_panel_transient_for_set(NULL);
2507 if(!e_input_panel_surface_destroy(ec))
2508 LOGE("fail to remove surface\n");
2510 g_input_panel_state = E_INPUT_PANEL_STATE_DID_HIDE;
2511 if (g_timer_will_hide)
2513 ecore_timer_del(g_timer_will_hide);
2514 g_timer_will_hide = NULL;
2516 client_surface_ec = NULL;
2517 LOGI("TRANSIENT_FOR::Reset transient_for_ec to NULL\n");
2522 e_text_input_update_input_panel_state(Eina_Bool state)
2524 if (!g_text_input || !g_text_input->resource) return;
2526 E_Text_Input *text_input = wl_resource_get_user_data(g_text_input->resource);
2530 WTI_WARNING(g_text_input->resource,
2531 WL_DISPLAY_ERROR_INVALID_OBJECT,
2532 "No Text Input For Resource");
2536 if (text_input->resource)
2538 if (!g_updated_geometry)
2540 int x = 0, y = 0, w = 0, h = 0;
2541 if (e_input_panel_client_geometry_get(NULL, &x, &y, &w, &h) && !(w <= 1 || h <= 1))
2542 _e_text_input_send_input_panel_geometry(text_input->resource, x, y, w, h);
2543 g_updated_geometry = EINA_TRUE;
2545 uint32_t input_panel_state = WL_TEXT_INPUT_INPUT_PANEL_STATE_HIDE;
2546 if (state) input_panel_state = WL_TEXT_INPUT_INPUT_PANEL_STATE_SHOW;
2547 wl_text_input_send_input_panel_state(text_input->resource, input_panel_state);
2552 e_text_input_update_input_panel_geometry(E_Client *ec)
2554 if (g_text_input && g_text_input->resource &&
2555 g_input_panel_state != E_INPUT_PANEL_STATE_WILL_HIDE && g_input_panel_state != E_INPUT_PANEL_STATE_DID_HIDE &&
2558 if (e_client_rotation_is_progress(ec))
2560 LOGI("Rotation is not finished");
2564 /* The geometry of E_Client may not be valid when IME is shown.
2565 Assume E_Client has a valid geometry when this callback is called after IME has set the size.
2567 int x = 0, y = 0, w = 0, h = 0;
2568 if (e_input_panel_client_geometry_get(NULL, &x, &y, &w, &h) && !(w <= 1 || h <= 1))
2570 LOGI("x : %d, y : %d, w : %d, h : %d", x, y, w, h);
2571 _e_text_input_send_input_panel_geometry(g_text_input->resource, x, y, w, h);
2577 e_modapi_init(E_Module *m)
2579 if (!e_comp_wl) return NULL;
2581 if (!wti_log_init())
2584 /* FIXME: create only one input method object per seat. */
2585 if (!_e_text_input_method_create())
2588 if (!e_input_panel_init())
2591 if (!_e_text_input_manager_create())
2594 if (!e_input_method_manager_create())
2597 E_LIST_HANDLER_APPEND(handlers, E_EVENT_CLIENT_RESIZE, _e_text_input_method_context_cb_client_resize, NULL);
2599 if (vconf_notify_key_changed(VCONFKEY_ISF_HW_KEYBOARD_INPUT_DETECTED, _keyboard_mode_changed_cb, NULL) != 0)
2600 LOGW ("Failed to register callback function for H/W keyboard input detection.");
2602 eeze_udev_watch_hander = eeze_udev_watch_add(EEZE_UDEV_TYPE_KEYBOARD,
2603 EEZE_UDEV_EVENT_REMOVE,
2604 _e_mod_eeze_udev_watch_cb,
2606 if (!eeze_udev_watch_hander)
2609 E_CLIENT_HOOK_APPEND(hooks_ec, E_CLIENT_HOOK_DEL, _pol_cb_hook_client_del, NULL);
2613 _e_mod_text_input_shutdown();
2618 e_modapi_shutdown(E_Module *m EINA_UNUSED)
2620 E_FREE_LIST(handlers, ecore_event_handler_del);
2621 E_FREE_LIST(hooks_ec, e_client_hook_del);
2623 if (g_timer_will_hide)
2625 ecore_timer_del(g_timer_will_hide);
2626 g_timer_will_hide = NULL;
2629 vconf_ignore_key_changed(VCONFKEY_ISF_HW_KEYBOARD_INPUT_DETECTED, _keyboard_mode_changed_cb);
2631 if (eeze_udev_watch_hander)
2633 eeze_udev_watch_del(eeze_udev_watch_hander);
2634 eeze_udev_watch_hander = NULL;
2636 _e_mod_text_input_shutdown();
2638 e_input_panel_shutdown();
2646 e_modapi_save(E_Module *m EINA_UNUSED)