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>
13 #include <xkbcommon/xkbcommon.h>
18 #define LOG_TAG "WL_TEXTINPUT"
20 #define WTI_WARNING(resource, code, msg) (_e_text_input_log_show((resource), (code), (msg), __func__))
22 tizen_profile_t _get_tizen_profile()
24 static tizen_profile_t profile = TIZEN_PROFILE_UNKNOWN;
25 if (__builtin_expect(profile != TIZEN_PROFILE_UNKNOWN, 1))
29 system_info_get_platform_string("http://tizen.org/feature/profile", &profileName);
34 profile = TIZEN_PROFILE_MOBILE;
38 profile = TIZEN_PROFILE_WEARABLE;
42 profile = TIZEN_PROFILE_TV;
46 profile = TIZEN_PROFILE_IVI;
48 default: // common or unknown ==> ALL ARE COMMON.
49 profile = TIZEN_PROFILE_COMMON;
56 static Eina_Bool _e_text_input_method_context_cb_client_resize(void *data EINA_UNUSED, int type, void *event);
57 static void set_soft_keyboard_mode();
59 typedef struct _E_Text_Input E_Text_Input;
60 typedef struct _E_Text_Input_Mgr E_Text_Input_Mgr;
61 typedef struct _E_Input_Method E_Input_Method;
62 typedef struct _E_Input_Method_Context E_Input_Method_Context;
63 typedef struct _E_Mod_Text_Input_Shutdown_Cb E_Mod_Text_Input_Shutdown_Cb;
67 struct wl_resource *resource;
69 Eina_List *input_methods;
70 Eina_Bool input_panel_visible;
71 Eina_Bool input_panel_show_requested;
75 struct _E_Text_Input_Mgr
77 struct wl_global *global;
78 struct wl_resource *resource;
80 Eina_List *text_input_list;
83 struct _E_Input_Method
85 struct wl_global *global;
86 struct wl_resource *resource;
89 E_Input_Method_Context *context;
92 static struct wl_resource *destroyed_resource = NULL;
94 struct _E_Input_Method_Context
96 struct wl_resource *resource;
99 E_Input_Method *input_method;
101 #if ENABLE_GRAB_KEYBOARD
104 struct wl_resource *resource;
107 struct xkb_keymap *keymap;
108 struct xkb_state *state;
109 xkb_mod_mask_t mod_depressed, mod_latched, mod_locked;
110 xkb_layout_index_t mod_group;
116 struct _E_Mod_Text_Input_Shutdown_Cb
118 void (*func)(void *data);
122 /* This represents the overall input panel's state including the candidate area */
123 enum _E_Input_Panel_State
125 E_INPUT_PANEL_STATE_DID_HIDE,
126 E_INPUT_PANEL_STATE_WILL_HIDE,
127 E_INPUT_PANEL_STATE_DID_SHOW,
128 E_INPUT_PANEL_STATE_WILL_SHOW,
131 static E_Input_Method *g_input_method = NULL;
132 static E_Text_Input *g_text_input = NULL;
133 static struct wl_client *g_client = NULL;
134 static Eina_List *shutdown_list = NULL;
135 static Eina_Bool g_disable_show_panel = EINA_FALSE;
136 static Eeze_Udev_Watch *eeze_udev_watch_hander = NULL;
137 static Ecore_Event_Handler *ecore_key_down_handler = NULL;
138 static Eina_List *handlers = NULL;
139 static uint32_t g_text_input_count = 1;
140 static Ecore_Timer *g_timer_will_hide = NULL;
141 static enum _E_Input_Panel_State g_input_panel_state = E_INPUT_PANEL_STATE_DID_HIDE;
142 static E_Client *client_surface_ec = NULL;
143 static E_Text_Input *g_show_text_input = NULL;
144 static struct wl_client *g_show_client = NULL;
145 static Eina_Bool g_updated_geometry = EINA_FALSE;
146 static Eina_Bool g_input_panel_enabled = EINA_TRUE;
148 /* The candidate's show state that was requested by the application or IME */
149 static Eina_Bool g_show_state_candidate = EINA_FALSE;
151 static Eina_List *hooks_ec = NULL;
153 const int WILL_HIDE_TIMER_INTERVAL = 1.0f;
155 #undef E_CLIENT_HOOK_APPEND
156 #define E_CLIENT_HOOK_APPEND(l, t, cb, d) \
160 _h = e_client_hook_add(t, cb, d); \
162 l = eina_list_append(l, _h); \
166 static void _e_text_input_cb_input_panel_show(struct wl_client *client, struct wl_resource *resource);
167 static void _e_text_input_deactivate(E_Text_Input *text_input, E_Input_Method *input_method, Eina_Bool need_focus_in);
168 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);
169 static void send_hide_input_panel(E_Input_Method *input_method);
172 e_text_input_client_surface_get(void)
174 return client_surface_ec;
178 _e_text_input_log_show(struct wl_resource *resource, uint32_t code, const char *msg, const char *warning_msg)
180 LOGE("%s() is failed. msg : %s\n", warning_msg, msg);
184 _e_text_input_send_input_panel_geometry(struct wl_resource *resource, int x, int y, int w, int h)
189 if (client_surface_ec)
191 angle = client_surface_ec->e.state.rot.ang.next < 0 ?
192 client_surface_ec->e.state.rot.ang.curr :
193 client_surface_ec->e.state.rot.ang.next;
195 LOGI("curr : %d, next : %d, angle : %d\n", client_surface_ec->e.state.rot.ang.curr,
196 client_surface_ec->e.state.rot.ang.next, angle);
199 snprintf(geometry, sizeof(geometry), "%d,%d,%d,%d", x, y, w, h);
205 vconf_set_str(VCONFKEY_ISF_IME_RECENT_LAND_GEOMETRY, geometry);
208 vconf_set_str(VCONFKEY_ISF_IME_RECENT_PORT_GEOMETRY, geometry);
212 LOGI("angle : %d, x : %d, y : %d, w : %d, h : %d\n", angle, x, y, w, h);
214 wl_text_input_send_input_panel_geometry(resource, x, y, w, h);
218 _will_hide_timer_handler(void *data)
220 INF("TIMED OUT while waiting for WILL_HIDE_ACK : %d", g_input_panel_state);
221 if (g_input_panel_state == E_INPUT_PANEL_STATE_WILL_HIDE)
223 e_input_panel_visibility_change(EINA_FALSE);
224 e_input_panel_transient_for_set(NULL);
225 g_input_panel_state = E_INPUT_PANEL_STATE_DID_HIDE;
228 if (g_timer_will_hide)
230 ecore_timer_del(g_timer_will_hide);
231 g_timer_will_hide = NULL;
234 return ECORE_CALLBACK_CANCEL;
238 _input_panel_hide(struct wl_client *client, struct wl_resource *resource, Eina_Bool force_hide)
240 E_Text_Input *text_input = wl_resource_get_user_data(resource);
241 E_Input_Method *input_method = NULL;
242 Eina_Bool _context_created = EINA_FALSE;
249 WTI_WARNING(resource,
250 WL_DISPLAY_ERROR_INVALID_OBJECT,
251 "No Text Input For Resource");
255 text_input->input_panel_visible = EINA_FALSE;
257 if (text_input->resource)
259 wl_text_input_send_input_panel_geometry(text_input->resource, 0, 0, 0, 0);
260 wl_text_input_send_input_panel_state(text_input->resource, WL_TEXT_INPUT_INPUT_PANEL_STATE_HIDE);
265 e_input_panel_visibility_change(EINA_FALSE);
266 e_input_panel_transient_for_set(NULL);
267 g_input_panel_state = E_INPUT_PANEL_STATE_DID_HIDE;
271 g_input_panel_state = E_INPUT_PANEL_STATE_WILL_HIDE;
272 /* Temporarily sending private command, will need for a new wayland protocol */
273 if (text_input->resource)
274 wl_text_input_send_private_command(text_input->resource, 0, "CONFORMANT_RESET");
276 if (g_timer_will_hide)
278 ecore_timer_del(g_timer_will_hide);
279 g_timer_will_hide = NULL;
282 zone = e_zone_current_get();
283 effect_run = e_input_panel_is_effect_running();
284 if (zone && (zone->display_state == E_ZONE_DISPLAY_STATE_OFF))
289 timeout = WILL_HIDE_TIMER_INTERVAL;
290 g_timer_will_hide = ecore_timer_add(timeout, _will_hide_timer_handler, NULL);
293 if (g_input_method && g_input_method->resource)
294 input_method = wl_resource_get_user_data(g_input_method->resource);
297 If input_method->context is already deleted, create context struct again to send input_panel_hide event to Input Method(IME) correctly.
298 Because input_panel_hide event can be called after focus_out(deactivate) by application.
299 And Input Method(IME) should know the state of their own input_panel to manage their resource when the input_panel is hidden.
302 ((!input_method->context) || (!input_method->context->resource)))
303 _context_created = _e_text_input_method_create_context(client, input_method, text_input, EINA_FALSE);
305 send_hide_input_panel(input_method);
307 if (_context_created)
308 _e_text_input_deactivate(text_input, input_method, EINA_FALSE);
310 e_input_panel_wait_update_set(EINA_FALSE);
312 /* When the input panel suface is hidden, the candidate will hide too */
313 g_show_state_candidate = EINA_FALSE;
316 static void send_hide_input_panel(E_Input_Method *input_method)
318 if (input_method && input_method->resource && input_method->context && input_method->context->resource)
320 LOGI("Request to hide IME");
321 wl_input_method_send_hide_input_panel(input_method->resource, input_method->context->resource);
326 _keyboard_mode_changed_cb(keynode_t *key, void* data)
328 bool val = vconf_keynode_get_bool(key);
329 LOGI("keyboard mode : %d\n", val);
333 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)
334 _e_text_input_cb_input_panel_show(g_client, g_text_input->resource);
336 #ifdef SUPPORT_CANDIDATE_ONEWINDOW
337 /* Switching to S/W keyboard mode, hide input panel since it could be displaying candidate only */
338 if (g_disable_show_panel && g_text_input && g_text_input->resource && g_client)
339 _input_panel_hide(g_client, g_text_input->resource, EINA_FALSE);
341 g_disable_show_panel = EINA_FALSE;
345 #ifdef SUPPORT_CANDIDATE_ONEWINDOW
346 /* Switching to H/W keyboard mode, hide input panel only if there is no candidate */
347 if (!g_show_state_candidate && g_text_input && g_text_input->resource && g_client)
349 if (g_text_input && g_text_input->resource && g_client)
351 _input_panel_hide(g_client, g_text_input->resource, EINA_FALSE);
353 g_disable_show_panel = EINA_TRUE;
358 #if ENABLE_GRAB_KEYBOARD
360 _e_text_input_method_context_keyboard_grab_keyboard_state_update(E_Input_Method_Context *context, uint32_t keycode, Eina_Bool pressed)
362 enum xkb_key_direction dir;
364 if (!context->kbd.state) return;
366 if (pressed) dir = XKB_KEY_DOWN;
367 else dir = XKB_KEY_UP;
369 context->kbd.mod_changed =
370 xkb_state_update_key(context->kbd.state, keycode + 8, dir);
374 _e_text_input_method_context_keyboard_grab_keyboard_modifiers_update(E_Input_Method_Context *context, struct wl_resource *keyboard)
378 if (!context->input) return;
379 if (!context->kbd.state) return;
381 context->kbd.mod_depressed =
382 xkb_state_serialize_mods(context->kbd.state, XKB_STATE_DEPRESSED);
383 context->kbd.mod_latched =
384 xkb_state_serialize_mods(context->kbd.state, XKB_STATE_MODS_LATCHED);
385 context->kbd.mod_locked =
386 xkb_state_serialize_mods(context->kbd.state, XKB_STATE_MODS_LOCKED);
387 context->kbd.mod_group =
388 xkb_state_serialize_layout(context->kbd.state, XKB_STATE_LAYOUT_EFFECTIVE);
390 serial = wl_display_next_serial(e_comp_wl->wl.disp);
391 wl_keyboard_send_modifiers(keyboard, serial,
392 context->kbd.mod_depressed,
393 context->kbd.mod_latched,
394 context->kbd.mod_locked,
395 context->kbd.mod_group);
399 _e_text_input_method_context_key_send(E_Input_Method_Context *context, unsigned int keycode, unsigned int timestamp, enum wl_keyboard_key_state state)
403 if (!context->input) return;
406 /* update modifier state */
407 _e_text_input_method_context_keyboard_grab_keyboard_state_update(context, nk, state == WL_KEYBOARD_KEY_STATE_PRESSED);
409 serial = wl_display_next_serial(e_comp_wl->wl.disp);
411 wl_keyboard_send_key(context->kbd.resource, serial, timestamp, nk, state);
412 if (context->kbd.mod_changed)
414 _e_text_input_method_context_keyboard_grab_keyboard_modifiers_update(context, context->kbd.resource);
415 context->kbd.mod_changed = 0;
420 _e_text_input_method_context_ecore_cb_key_down(void *data, int ev_type EINA_UNUSED, Ecore_Event_Key *ev)
422 E_Input_Method_Context *context = data;
424 _e_text_input_method_context_key_send(context, ev->keycode, ev->timestamp,
425 WL_KEYBOARD_KEY_STATE_PRESSED);
427 return ECORE_CALLBACK_RENEW;
431 _e_text_input_method_context_ecore_cb_key_up(void *data, int ev_type EINA_UNUSED, Ecore_Event_Key *ev)
433 E_Input_Method_Context *context = data;
435 _e_text_input_method_context_key_send(context, ev->keycode, ev->timestamp,
436 WL_KEYBOARD_KEY_STATE_RELEASED);
438 return ECORE_CALLBACK_RENEW;
442 _e_text_input_method_context_grab_set(E_Input_Method_Context *context, Eina_Bool set)
444 if (set == context->kbd.grabbed)
450 context->kbd.grabbed = set;
454 if (context->kbd.keymap) xkb_map_unref(context->kbd.keymap);
455 if (context->kbd.state) xkb_state_unref(context->kbd.state);
456 context->kbd.keymap = xkb_map_ref(e_comp_wl->xkb.keymap);
457 context->kbd.state = xkb_state_new(e_comp_wl->xkb.keymap);
458 E_LIST_HANDLER_APPEND(context->kbd.handlers, ECORE_EVENT_KEY_DOWN,
459 _e_text_input_method_context_ecore_cb_key_down,
461 E_LIST_HANDLER_APPEND(context->kbd.handlers, ECORE_EVENT_KEY_UP,
462 _e_text_input_method_context_ecore_cb_key_up,
465 e_comp_grab_input(0, 1);
469 E_FREE_LIST(context->kbd.handlers, ecore_event_handler_del);
471 e_comp_ungrab_input(0, 1);
473 if (context->kbd.keymap)
475 xkb_map_unref(context->kbd.keymap);
476 context->kbd.keymap = NULL;
479 if (context->kbd.state)
481 xkb_state_unref(context->kbd.state);
482 context->kbd.state = NULL;
489 _e_mod_text_input_shutdown_cb_add(void (*func)(void *data), void *data)
491 E_Mod_Text_Input_Shutdown_Cb *cb;
493 if (!(cb = E_NEW(E_Mod_Text_Input_Shutdown_Cb, 1)))
495 ERR("Could not allocate space for Text Input Shutdown Callback");
502 shutdown_list = eina_list_append(shutdown_list, cb);
506 _e_text_input_method_context_cb_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
508 E_Input_Method_Context *context = wl_resource_get_user_data(resource);
510 LOGD("resource(%p), context(%p), context->input(%p), context->input_method(%p)", resource, context, context->input, context->input_method);
512 wl_resource_destroy(resource);
516 _e_text_input_method_context_cb_string_commit(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t serial, const char *text)
518 E_Input_Method_Context *context = wl_resource_get_user_data(resource);
522 WTI_WARNING(resource,
523 WL_DISPLAY_ERROR_INVALID_OBJECT,
524 "No Input Method Context For Resource");
528 if ((context->input) && (context->input->resource))
529 wl_text_input_send_commit_string(context->input->resource,
534 _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)
536 E_Input_Method_Context *context = wl_resource_get_user_data(resource);
540 WTI_WARNING(resource,
541 WL_DISPLAY_ERROR_INVALID_OBJECT,
542 "No Input Method Context For Resource");
546 if ((context->input) && (context->input->resource))
547 wl_text_input_send_preedit_string(context->input->resource,
548 serial, text, commit);
552 _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)
554 E_Input_Method_Context *context = wl_resource_get_user_data(resource);
558 WTI_WARNING(resource,
559 WL_DISPLAY_ERROR_INVALID_OBJECT,
560 "No Input Method Context For Resource");
564 if ((context->input) && (context->input->resource))
565 wl_text_input_send_recapture_string(context->input->resource,
566 serial, index, length, preedit, preedit_commit, commit);
570 _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)
572 E_Input_Method_Context *context = wl_resource_get_user_data(resource);
576 WTI_WARNING(resource,
577 WL_DISPLAY_ERROR_INVALID_OBJECT,
578 "No Input Method Context For Resource");
582 if ((context->input) && (context->input->resource))
583 wl_text_input_send_preedit_styling(context->input->resource,
584 index, length, style);
588 _e_text_input_method_context_cb_preedit_cursor(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, int32_t cursor)
590 E_Input_Method_Context *context = wl_resource_get_user_data(resource);
594 WTI_WARNING(resource,
595 WL_DISPLAY_ERROR_INVALID_OBJECT,
596 "No Input Method Context For Resource");
600 if ((context->input) && (context->input->resource))
601 wl_text_input_send_preedit_cursor(context->input->resource,
606 _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)
608 E_Input_Method_Context *context = wl_resource_get_user_data(resource);
612 WTI_WARNING(resource,
613 WL_DISPLAY_ERROR_INVALID_OBJECT,
614 "No Input Method Context For Resource");
618 if ((context->input) && (context->input->resource))
619 wl_text_input_send_delete_surrounding_text(context->input->resource,
624 _e_text_input_method_context_cb_cursor_position(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, int32_t index, int32_t anchor)
626 E_Input_Method_Context *context = wl_resource_get_user_data(resource);
630 WTI_WARNING(resource,
631 WL_DISPLAY_ERROR_INVALID_OBJECT,
632 "No Input Method Context For Resource");
636 if ((context->input) && (context->input->resource))
637 wl_text_input_send_cursor_position(context->input->resource,
642 _e_text_input_method_context_cb_modifiers_map(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_array *map)
644 E_Input_Method_Context *context = wl_resource_get_user_data(resource);
648 WTI_WARNING(resource,
649 WL_DISPLAY_ERROR_INVALID_OBJECT,
650 "No Input Method Context For Resource");
654 if ((context->input) && (context->input->resource))
655 wl_text_input_send_modifiers_map(context->input->resource, map);
659 _e_keyevent_free(void *data EINA_UNUSED, void *ev)
661 Ecore_Event_Key *e = ev;
664 eina_stringshare_del(e->keyname);
667 eina_stringshare_del(e->key);
670 eina_stringshare_del(e->compose);
673 eina_stringshare_del(e->string);
679 feed_key_event(const char *keyname, const char *key, const char *string, int keycode, int state)
681 Ecore_Event_Key *e = E_NEW(Ecore_Event_Key, 1);
684 e->keyname = (char *)eina_stringshare_add(keyname);
685 e->key = (char *)eina_stringshare_add(key);
686 e->string = (char *)eina_stringshare_add(string);
687 e->compose = (char *)eina_stringshare_add(e->string);
689 e->timestamp = 0; /* For distinguishing S/W keyboard event */
691 e->keycode = keycode;
693 ecore_event_add(state ? ECORE_EVENT_KEY_DOWN : ECORE_EVENT_KEY_UP, e, _e_keyevent_free, NULL);
697 _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)
699 E_Input_Method_Context *context = wl_resource_get_user_data(resource);
703 WTI_WARNING(resource,
704 WL_DISPLAY_ERROR_INVALID_OBJECT,
705 "No Input Method Context For Resource");
709 if ((context->input) && (context->input->resource))
711 wl_text_input_send_keysym(context->input->resource,
712 serial, time, sym, state, modifiers);
716 char string[32], key[32], keyname[32];
718 memset(keyname, 0, sizeof(keyname));
719 xkb_keysym_get_name(sym, keyname, sizeof(keyname));
720 if (keyname[0] == '\0')
721 snprintf(keyname, sizeof(keyname), "Keysym-%u", sym);
723 if (strcmp(keyname, "BackSpace") == 0)
725 /* backspace key should be supported in the multibutton entry of elementary
726 even though it losts focus */
727 memset(key, 0, sizeof(key));
728 xkb_keysym_get_name(sym, key, sizeof(key));
730 memset(string, 0, sizeof(string));
731 xkb_keysym_to_utf8(sym, string, 32);
735 /* Backspace keycode (22) */
736 feed_key_event(keyname, key, string, 22, 1); /* key down */
737 feed_key_event(keyname, key, string, 22, 0); /* key up */
743 #if ENABLE_GRAB_KEYBOARD
745 _e_text_input_method_context_keyboard_grab_cb_resource_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
747 wl_resource_destroy(resource);
750 static const struct wl_keyboard_interface _e_keyboard_grab_interface =
752 _e_text_input_method_context_keyboard_grab_cb_resource_destroy
756 _e_text_input_method_context_keyboard_grab_cb_keyboard_unbind(struct wl_resource *resource)
758 E_Input_Method_Context *context = wl_resource_get_user_data(resource);
762 WTI_WARNING(resource,
763 WL_DISPLAY_ERROR_INVALID_OBJECT,
764 "No Input Method Context For Resource");
768 _e_text_input_method_context_grab_set(context, EINA_FALSE);
770 context->kbd.resource = NULL;
775 _e_text_input_method_context_cb_keyboard_grab(struct wl_client *client, struct wl_resource *resource, uint32_t id)
777 DBG("Input Method Context - grab keyboard %d", wl_resource_get_id(resource));
778 #if ENABLE_GRAB_KEYBOARD
779 E_Input_Method_Context *context = wl_resource_get_user_data(resource);
780 struct wl_resource *keyboard = NULL;
784 WTI_WARNING(resource,
785 WL_DISPLAY_ERROR_INVALID_OBJECT,
786 "No Input Method Context For Resource");
790 keyboard = wl_resource_create(client, &wl_keyboard_interface, 1, id);
793 wl_client_post_no_memory(client);
797 wl_resource_set_implementation(keyboard, &_e_keyboard_grab_interface, context, _e_text_input_method_context_keyboard_grab_cb_keyboard_unbind);
799 /* send current keymap */
800 wl_keyboard_send_keymap(keyboard, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
801 e_comp_wl->xkb.fd, e_comp_wl->xkb.size);
803 context->kbd.resource = keyboard;
805 _e_text_input_method_context_grab_set(context, EINA_TRUE);
810 _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)
812 DBG("Input Method Context - key %d", wl_resource_get_id(resource));
823 _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)
825 DBG("Input Method Context - modifiers %d", wl_resource_get_id(resource));
830 (void)mods_depressed;
837 _e_text_input_method_context_cb_language(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t serial, const char *language)
839 E_Input_Method_Context *context = wl_resource_get_user_data(resource);
843 WTI_WARNING(resource,
844 WL_DISPLAY_ERROR_INVALID_OBJECT,
845 "No Input Method Context For Resource");
849 if ((context->input) && (context->input->resource))
850 wl_text_input_send_language(context->input->resource,
855 _e_text_input_method_context_cb_text_direction(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t serial, uint32_t direction)
857 E_Input_Method_Context *context = wl_resource_get_user_data(resource);
861 WTI_WARNING(resource,
862 WL_DISPLAY_ERROR_INVALID_OBJECT,
863 "No Input Method Context For Resource");
867 if ((context->input) && (context->input->resource))
868 wl_text_input_send_text_direction(context->input->resource,
873 _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)
875 E_Input_Method_Context *context = wl_resource_get_user_data(resource);
879 WTI_WARNING(resource,
880 WL_DISPLAY_ERROR_INVALID_OBJECT,
881 "No Input Method Context For Resource");
885 if ((context->input) && (context->input->resource))
886 wl_text_input_send_selection_region(context->input->resource,
891 _e_text_input_method_context_cb_private_command(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t serial, const char *command)
893 E_Input_Method_Context *context = wl_resource_get_user_data(resource);
897 WTI_WARNING(resource,
898 WL_DISPLAY_ERROR_INVALID_OBJECT,
899 "No Input Method Context For Resource");
903 if ((context->input) && (context->input->resource))
904 wl_text_input_send_private_command(context->input->resource,
909 _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)
911 E_Input_Method_Context *context = wl_resource_get_user_data(resource);
915 WTI_WARNING(resource,
916 WL_DISPLAY_ERROR_INVALID_OBJECT,
917 "No Input Method Context For Resource");
921 if ((context->input) && (context->input->resource))
922 wl_text_input_send_commit_content(context->input->resource,
923 serial, content, description, mime_types);
927 _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)
929 E_Input_Method_Context *context = wl_resource_get_user_data(resource);
933 WTI_WARNING(resource,
934 WL_DISPLAY_ERROR_INVALID_OBJECT,
935 "No Input Method Context For Resource");
939 if ((context->input) && (context->input->resource))
940 wl_text_input_send_input_panel_event(context->input->resource,
941 serial, event_type, value);
945 _e_text_input_method_context_cb_update_candidate_state(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t state)
947 E_Input_Method_Context *context = wl_resource_get_user_data(resource);
951 WTI_WARNING(resource,
952 WL_DISPLAY_ERROR_INVALID_OBJECT,
953 "No Input Method Context For Resource");
957 LOGI("Candidate State : %d", state);
958 Eina_Bool prev_show_state = g_show_state_candidate;
959 g_show_state_candidate = state;
960 if (g_input_panel_state == E_INPUT_PANEL_STATE_DID_HIDE)
961 prev_show_state = EINA_FALSE;
965 /* If the candidate state has been changed to OFF when panel is not in show state, */
966 if (!g_show_state_candidate && prev_show_state && g_disable_show_panel && g_client && g_text_input)
967 _input_panel_hide(g_client, g_text_input->resource, EINA_FALSE);
971 /* If the candidate state has been changed to ON when panel is not in show state */
972 if (g_show_state_candidate && !prev_show_state && g_disable_show_panel && g_client && g_text_input)
973 _e_text_input_cb_input_panel_show(g_client, g_text_input->resource);
978 _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)
980 E_Input_Method_Context *context = wl_resource_get_user_data(resource);
984 WTI_WARNING(resource,
985 WL_DISPLAY_ERROR_INVALID_OBJECT,
986 "No Input Method Context For Resource");
990 if ((context->input) && (context->input->resource))
991 wl_text_input_send_input_panel_data(context->input->resource,
992 serial, data, length);
996 _e_text_input_method_context_cb_hide_input_panel(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t serial)
998 E_Text_Input *text_input = g_text_input;
999 E_Input_Method *input_method = NULL;
1003 WTI_WARNING(resource,
1004 WL_DISPLAY_ERROR_INVALID_OBJECT,
1005 "No Text Input For Resource");
1009 text_input->input_panel_visible = EINA_FALSE;
1011 if (g_text_input && g_text_input->resource && g_client)
1012 _input_panel_hide(g_client, g_text_input->resource, EINA_FALSE);
1014 if (g_input_method && g_input_method->resource)
1015 input_method = wl_resource_get_user_data(g_input_method->resource);
1017 send_hide_input_panel(input_method);
1021 _e_text_input_method_context_cb_get_selection_text(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, int32_t fd)
1023 E_Input_Method_Context *context = wl_resource_get_user_data(resource);
1027 WTI_WARNING(resource,
1028 WL_DISPLAY_ERROR_INVALID_OBJECT,
1029 "No Input Method Context For Resource");
1034 if ((context->input) && (context->input->resource))
1035 wl_text_input_send_get_selection_text(context->input->resource, fd);
1041 _e_text_input_method_context_cb_get_surrounding_text(struct wl_client *client EINA_UNUSED, struct wl_resource *resource,
1042 uint32_t maxlen_before, uint32_t maxlen_after, int32_t fd)
1044 E_Input_Method_Context *context = wl_resource_get_user_data(resource);
1048 WTI_WARNING(resource,
1049 WL_DISPLAY_ERROR_INVALID_OBJECT,
1050 "No Input Method Context For Resource");
1055 if ((context->input) && (context->input->resource))
1056 wl_text_input_send_get_surrounding_text(context->input->resource, maxlen_before, maxlen_after, fd);
1062 _e_text_input_method_context_cb_filter_key_event_done(struct wl_client *client EINA_UNUSED, struct wl_resource *resource,
1063 uint32_t serial, uint32_t state)
1065 E_Input_Method_Context *context = wl_resource_get_user_data(resource);
1069 WTI_WARNING(resource,
1070 WL_DISPLAY_ERROR_INVALID_OBJECT,
1071 "No Input Method Context For Resource");
1075 if ((context->input) && (context->input->resource))
1076 wl_text_input_send_filter_key_event_done(context->input->resource,
1081 _e_text_input_method_context_cb_update_ise_geometry(struct wl_client *client EINA_UNUSED, struct wl_resource *resource,
1082 uint32_t serial, uint32_t x, uint32_t y, uint32_t width, uint32_t height)
1084 E_Input_Method_Context *context = wl_resource_get_user_data(resource);
1088 WTI_WARNING(resource,
1089 WL_DISPLAY_ERROR_INVALID_OBJECT,
1090 "No Input Method Context For Resource");
1094 if ((context->input) && (context->input->resource))
1096 _e_text_input_send_input_panel_geometry(context->input->resource, x, y, width, height);
1097 g_updated_geometry = EINA_TRUE;
1102 _e_text_input_method_context_cb_reshow_input_panel(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
1104 e_input_panel_transient_for_set(client_surface_ec);
1105 e_input_panel_wait_update_set(EINA_TRUE);
1109 _e_text_input_method_context_cb_set_floating_panel(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t state)
1111 e_input_panel_floating_panel_set(state ? EINA_TRUE : EINA_FALSE);
1115 _e_text_input_method_context_cb_set_floating_drag_enabled(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t enabled)
1117 e_input_panel_floating_drag_enabled(enabled ? EINA_TRUE : EINA_FALSE);
1120 static const struct wl_input_method_context_interface _e_text_input_method_context_implementation = {
1121 _e_text_input_method_context_cb_destroy,
1122 _e_text_input_method_context_cb_string_commit,
1123 _e_text_input_method_context_cb_preedit_string,
1124 _e_text_input_method_context_cb_preedit_styling,
1125 _e_text_input_method_context_cb_preedit_cursor,
1126 _e_text_input_method_context_cb_surrounding_text_delete,
1127 _e_text_input_method_context_cb_cursor_position,
1128 _e_text_input_method_context_cb_modifiers_map,
1129 _e_text_input_method_context_cb_keysym,
1130 _e_text_input_method_context_cb_keyboard_grab,
1131 _e_text_input_method_context_cb_key,
1132 _e_text_input_method_context_cb_modifiers,
1133 _e_text_input_method_context_cb_language,
1134 _e_text_input_method_context_cb_text_direction,
1135 _e_text_input_method_context_cb_selection_region,
1136 _e_text_input_method_context_cb_private_command,
1137 _e_text_input_method_context_cb_input_panel_data_update,
1138 _e_text_input_method_context_cb_hide_input_panel,
1139 _e_text_input_method_context_cb_get_selection_text,
1140 _e_text_input_method_context_cb_get_surrounding_text,
1141 _e_text_input_method_context_cb_filter_key_event_done,
1142 _e_text_input_method_context_cb_update_ise_geometry,
1143 _e_text_input_method_context_cb_recapture_string,
1144 _e_text_input_method_context_cb_input_panel_event,
1145 _e_text_input_method_context_cb_commit_content,
1146 _e_text_input_method_context_cb_update_candidate_state,
1147 _e_text_input_method_context_cb_reshow_input_panel,
1148 _e_text_input_method_context_cb_set_floating_panel,
1149 _e_text_input_method_context_cb_set_floating_drag_enabled,
1153 _e_text_input_method_context_cb_resource_destroy(struct wl_resource *resource)
1155 E_Input_Method_Context *context = wl_resource_get_user_data(resource);
1159 WTI_WARNING(resource,
1160 WL_DISPLAY_ERROR_INVALID_OBJECT,
1161 "No Input Method Context For Resource");
1165 #if ENABLE_GRAB_KEYBOARD
1166 if (context->kbd.resource)
1168 wl_resource_destroy(context->kbd.resource);
1169 context->kbd.resource = NULL;
1173 LOGI("resource(%p), context(%p)", resource, context);
1175 if ((context->input_method) &&
1176 (context->input_method->context == context))
1177 context->input_method->context = NULL;
1182 static Eina_Bool is_number_key(const char *str)
1184 if (!str) return EINA_FALSE;
1186 int result = atoi(str);
1190 if (!strcmp(str, "0"))
1200 _e_mod_ecore_key_down_cb(void *data, int type, void *event)
1202 Ecore_Event_Key *ev = (Ecore_Event_Key *)event;
1203 if (ev->event_flags & ECORE_EVENT_FLAG_CANCEL)
1205 SECURE_LOGI("%s key is cancelled.", ev->key);
1206 return ECORE_CALLBACK_PASS_ON;
1209 if (g_disable_show_panel == EINA_TRUE)
1210 return ECORE_CALLBACK_PASS_ON;
1212 /* process remote controller key exceptionally */
1213 if (((!strcmp(ev->key, "Down") ||
1214 !strcmp(ev->key, "KP_Down") ||
1215 !strcmp(ev->key, "Up") ||
1216 !strcmp(ev->key, "KP_Up") ||
1217 !strcmp(ev->key, "Right") ||
1218 !strcmp(ev->key, "KP_Right") ||
1219 !strcmp(ev->key, "Left") ||
1220 !strcmp(ev->key, "KP_Left")) && !ev->string) ||
1221 !strcmp(ev->key, "Return") ||
1222 !strcmp(ev->key, "Pause") ||
1223 !strcmp(ev->key, "NoSymbol") ||
1224 !strncmp(ev->key, "XF86", 4) ||
1225 !strncmp(ev->key, "Cancel", 5) ||
1226 (is_number_key(ev->string) && _TV))
1227 return ECORE_CALLBACK_PASS_ON;
1229 SECURE_LOGI("Hide IME (key : %s)", ev->key);
1231 if (g_text_input && g_text_input->resource && g_client)
1232 _input_panel_hide(g_client, g_text_input->resource, EINA_FALSE);
1234 g_disable_show_panel = EINA_TRUE;
1236 return ECORE_CALLBACK_PASS_ON;
1240 _e_text_input_deactivate(E_Text_Input *text_input, E_Input_Method *input_method, Eina_Bool need_focus_in)
1242 if (text_input == g_text_input)
1244 g_text_input = NULL;
1248 if (input_method->input == text_input)
1250 if ((input_method->context) && (input_method->resource))
1252 #if ENABLE_GRAB_KEYBOARD
1253 _e_text_input_method_context_grab_set(input_method->context,
1256 if (input_method->resource == destroyed_resource)
1258 LOGI("deactivate skipped : %p %p", input_method->resource,
1259 input_method->context->resource);
1263 /* TODO: finish the grab of keyboard. */
1264 wl_input_method_send_deactivate(input_method->resource,
1265 input_method->context->resource,
1267 LOGI("wm_map TEXTINPUT deactivate : %p %p", input_method->resource,
1268 input_method->context->resource);
1272 if (ecore_key_down_handler)
1274 ecore_event_handler_del(ecore_key_down_handler);
1275 ecore_key_down_handler = NULL;
1278 LOGI("Resetting input_method->input : %p, text_input : %p, %p %p",
1279 input_method->input, text_input,
1280 input_method->resource,
1281 (input_method->context ? input_method->context->resource : NULL));
1282 input_method->input = NULL;
1283 if (input_method->context) input_method->context->input = NULL;
1284 input_method->context = NULL;
1286 text_input->input_panel_show_requested = EINA_FALSE;
1287 text_input->input_methods = eina_list_remove(text_input->input_methods, input_method);
1289 if (text_input->resource)
1290 wl_text_input_send_leave(text_input->resource);
1292 if (_TV || _WEARABLE)
1293 g_disable_show_panel = EINA_FALSE;
1298 _e_text_input_cb_activate(struct wl_client *client, struct wl_resource *resource, struct wl_resource *seat, struct wl_resource *surface)
1300 E_Text_Input *text_input = NULL;
1301 E_Input_Method *input_method = NULL;
1302 E_Text_Input *old = NULL;
1303 E_Input_Method_Context *context = NULL;
1304 E_Client *ec = NULL;
1306 EINA_SAFETY_ON_NULL_GOTO(resource, err);
1307 EINA_SAFETY_ON_NULL_GOTO(seat, err);
1308 EINA_SAFETY_ON_NULL_GOTO(g_input_method, err);
1309 EINA_SAFETY_ON_NULL_GOTO(g_input_method->resource, err);
1311 /* Store application window's E_Client* value for setting transient_for information later */
1312 ec = wl_resource_get_user_data(surface);
1313 EINA_SAFETY_ON_NULL_GOTO(ec, err);
1314 EINA_SAFETY_ON_TRUE_GOTO(e_object_is_del(E_OBJECT(ec)), err);
1315 client_surface_ec = ec;
1317 text_input = wl_resource_get_user_data(resource);
1318 g_text_input = text_input;
1321 /* FIXME: should get input_method object from seat. */
1322 input_method = wl_resource_get_user_data(g_input_method->resource);
1323 EINA_SAFETY_ON_NULL_GOTO(input_method, err);
1325 old = input_method->input;
1327 LOGI("old : %p, text_input : %p, %d", old, text_input, g_input_panel_state);
1328 if (old == text_input)
1332 _e_text_input_deactivate(old, input_method, EINA_TRUE);
1334 input_method->input = text_input;
1335 text_input->input_methods = eina_list_append(text_input->input_methods, input_method);
1337 if (input_method->resource)
1339 if (!(context = E_NEW(E_Input_Method_Context, 1)))
1341 wl_client_post_no_memory(client);
1342 ERR("Could not allocate space for Input_Method_Context");
1346 if (!ecore_key_down_handler)
1347 ecore_key_down_handler = ecore_event_handler_prepend(ECORE_EVENT_KEY_DOWN,
1348 _e_mod_ecore_key_down_cb,
1352 wl_resource_create(wl_resource_get_client(input_method->resource),
1353 &wl_input_method_context_interface, 1, 0);
1355 if (context->resource)
1356 wl_resource_set_implementation(context->resource,
1357 &_e_text_input_method_context_implementation,
1358 context, _e_text_input_method_context_cb_resource_destroy);
1360 context->input = text_input;
1361 context->input_method = input_method;
1362 input_method->context = context;
1364 if (context->resource)
1366 wl_input_method_send_activate(input_method->resource, context->resource, text_input->id, EINA_TRUE);
1367 LOGI("wm_map TEXTINPUT activate : %p %p", input_method->resource,
1370 destroyed_resource = NULL;
1373 WRN("Failed to send activate due to no resource in context");
1376 WRN("no inputmethod resource");
1378 if (_TV || _WEARABLE)
1379 set_soft_keyboard_mode();
1381 if (text_input->resource)
1382 wl_text_input_send_enter(text_input->resource, surface);
1388 WTI_WARNING(resource,
1389 WL_DISPLAY_ERROR_INVALID_OBJECT,
1390 "No Text Input For Resource");
1394 WL_DISPLAY_ERROR_INVALID_OBJECT,
1395 "No Comp Data For Seat");
1399 _e_text_input_cb_deactivate(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *seat)
1402 E_Text_Input *text_input = wl_resource_get_user_data(resource);
1403 E_Input_Method *input_method = NULL;
1407 WTI_WARNING(resource,
1408 WL_DISPLAY_ERROR_INVALID_OBJECT,
1409 "No Text Input For Resource");
1413 if (text_input == g_text_input)
1415 g_text_input = NULL;
1419 /* FIXME: should get input_method object from seat. */
1420 if (g_input_method && g_input_method->resource)
1421 input_method = wl_resource_get_user_data(g_input_method->resource);
1426 WL_DISPLAY_ERROR_INVALID_OBJECT,
1427 "No Input Method For Seat");
1431 _e_text_input_deactivate(text_input, input_method, EINA_TRUE);
1435 _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)
1437 E_Input_Method_Context *context = NULL;
1439 EINA_SAFETY_ON_NULL_RETURN_VAL(input_method, EINA_FALSE);
1440 EINA_SAFETY_ON_NULL_RETURN_VAL(input_method->resource, EINA_FALSE);
1441 EINA_SAFETY_ON_NULL_RETURN_VAL(text_input, EINA_FALSE);
1443 g_text_input = text_input;
1445 input_method->input = text_input;
1446 text_input->input_methods = eina_list_append(text_input->input_methods, input_method);
1448 if (!(context = E_NEW(E_Input_Method_Context, 1)))
1450 wl_client_post_no_memory(client);
1451 ERR("Could not allocate space for Input_Method_Context");
1456 wl_resource_create(wl_resource_get_client(input_method->resource),
1457 &wl_input_method_context_interface, 1, 0);
1459 if (context->resource)
1460 wl_resource_set_implementation(context->resource,
1461 &_e_text_input_method_context_implementation,
1462 context, _e_text_input_method_context_cb_resource_destroy);
1464 context->input = text_input;
1465 context->input_method = input_method;
1466 input_method->context = context;
1468 wl_input_method_send_activate(input_method->resource, context->resource, text_input->id, need_focus_out);
1470 LOGI("wm_map TEXTINPUT activate : input_method->resource(%p) context->resource(%p)",
1471 input_method->resource, context->resource);
1473 destroyed_resource = NULL;
1479 _e_text_input_cb_input_panel_show(struct wl_client *client, struct wl_resource *resource)
1481 E_Text_Input *text_input = wl_resource_get_user_data(resource);
1482 E_Input_Method *input_method = NULL;
1484 LOGI("text_input : %p\n", text_input);
1488 WTI_WARNING(resource,
1489 WL_DISPLAY_ERROR_INVALID_OBJECT,
1490 "No Text Input For Resource");
1494 text_input->input_panel_show_requested = EINA_TRUE;
1496 #ifndef SUPPORT_CANDIDATE_ONEWINDOW
1497 if (g_disable_show_panel == EINA_TRUE)
1501 if (g_input_method && g_input_method->resource)
1502 input_method = wl_resource_get_user_data(g_input_method->resource);
1504 /* If input_method->context doesn't exist, create context struct to send input_panel_show event to Input Method(IME) correctly.
1505 * Because input_panel_show event can be called before focus_in(activate) by application.
1506 * And Input Method(IME) should know the state of their own input_panel to manage their resource when the input_panel is shown. */
1507 if (input_method && (!input_method->context || !input_method->context->resource))
1508 _e_text_input_method_create_context(client, input_method, text_input, EINA_TRUE);
1510 #ifdef SUPPORT_CANDIDATE_ONEWINDOW
1511 if (g_disable_show_panel == EINA_TRUE)
1513 if (g_show_state_candidate == EINA_TRUE)
1515 g_input_panel_state = E_INPUT_PANEL_STATE_DID_SHOW;
1516 g_show_client = client;
1517 e_input_panel_visibility_change(EINA_TRUE);
1518 e_input_panel_transient_for_set(client_surface_ec);
1526 if (input_method->resource && input_method->context && input_method->context->resource)
1528 /* DO NOT show input panel surface until we get message "show complete" from input method,
1529 * in order to give a change to update UI */
1530 LOGI("IM::SHOW::WAIT_FOR_READY\n");
1532 g_show_client = client;
1534 if (client_surface_ec)
1536 E_Util_Transform *transform = &client_surface_ec->transform_core.result.transform;
1537 Eina_Bool transformEnabled = e_client_transform_core_enable_get(client_surface_ec);
1539 if (transformEnabled && transform != 0)
1541 e_util_transform_rotation_round_get(transform, NULL, NULL, &angle);
1542 /* transformed angle and window rotation angle are diametrically opposite
1543 * when they're showing on display. so, adjust transformed angle to window rotation angle */
1544 angle = (360 - angle) % 360;
1546 angle += client_surface_ec->e.state.rot.ang.curr;
1549 wl_input_method_send_show_input_panel(input_method->resource, input_method->context->resource, angle);
1551 /* we need to force update in order to release buffer
1552 * if we do not, client can't update
1553 * because they may in manual render state by frame callback mechanism,
1554 * and also don't have released buffer */
1555 e_input_panel_wait_update_set(EINA_TRUE);
1559 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);
1560 if (input_method->context)
1561 LOGW("Failed to send show input panel. input_method->context->resource : %p", input_method->context->resource);
1566 LOGW("No input method");
1569 /* If the input panel state was WILL_HIDE, it means that the conformant area information needs to be restored */
1570 if (g_input_panel_state == E_INPUT_PANEL_STATE_WILL_HIDE)
1572 if (text_input->resource)
1573 wl_text_input_send_private_command(text_input->resource, 0, "CONFORMANT_RESTORE");
1576 text_input->input_panel_visible = EINA_TRUE;
1577 g_input_panel_state = E_INPUT_PANEL_STATE_WILL_SHOW;
1578 g_show_text_input = text_input;
1580 g_updated_geometry = EINA_FALSE;
1582 e_input_panel_transient_for_set(client_surface_ec);
1586 _e_text_input_cb_input_panel_hide(struct wl_client *client, struct wl_resource *resource)
1588 if (g_show_client == client) {
1589 _input_panel_hide(client, resource, EINA_FALSE);
1590 g_show_text_input = NULL;
1591 g_show_client = NULL;
1596 _e_text_input_cb_reset(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
1598 E_Text_Input *text_input = wl_resource_get_user_data(resource);
1599 E_Input_Method *input_method = NULL;
1600 Eina_List *l = NULL;
1604 WTI_WARNING(resource,
1605 WL_DISPLAY_ERROR_INVALID_OBJECT,
1606 "No Text Input For Resource");
1610 EINA_LIST_FOREACH(text_input->input_methods, l, input_method)
1612 if (!input_method || !input_method->context) continue;
1613 if (input_method->context->resource)
1614 wl_input_method_context_send_reset(input_method->context->resource);
1619 _e_text_input_cb_content_type_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t hint, uint32_t purpose)
1621 E_Text_Input *text_input = wl_resource_get_user_data(resource);
1622 E_Input_Method *input_method = NULL;
1623 Eina_List *l = NULL;
1627 WTI_WARNING(resource,
1628 WL_DISPLAY_ERROR_INVALID_OBJECT,
1629 "No Text Input For Resource");
1633 EINA_LIST_FOREACH(text_input->input_methods, l, input_method)
1635 if (!input_method || !input_method->context) continue;
1637 if (input_method->context->resource)
1638 wl_input_method_context_send_content_type(input_method->context->resource,
1644 _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)
1646 E_Text_Input *text_input = wl_resource_get_user_data(resource);
1650 WTI_WARNING(resource,
1651 WL_DISPLAY_ERROR_INVALID_OBJECT,
1652 "No Text Input For Resource");
1656 /* TODO: issue event update input_panel */
1660 _e_text_input_cb_preferred_language_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, const char *language)
1662 E_Text_Input *text_input = wl_resource_get_user_data(resource);
1663 E_Input_Method *input_method = NULL;
1664 Eina_List *l = NULL;
1668 WTI_WARNING(resource,
1669 WL_DISPLAY_ERROR_INVALID_OBJECT,
1670 "No Text Input For Resource");
1674 EINA_LIST_FOREACH(text_input->input_methods, l, input_method)
1676 if (!input_method || !input_method->context) continue;
1678 if (input_method->context->resource)
1679 wl_input_method_context_send_preferred_language(input_method->context->resource,
1685 _e_text_input_cb_state_commit(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t serial)
1687 E_Text_Input *text_input = wl_resource_get_user_data(resource);
1688 E_Input_Method *input_method = NULL;
1689 Eina_List *l = NULL;
1693 WTI_WARNING(resource,
1694 WL_DISPLAY_ERROR_INVALID_OBJECT,
1695 "No Text Input For Resource");
1699 EINA_LIST_FOREACH(text_input->input_methods, l, input_method)
1701 if (!input_method || !input_method->context) continue;
1703 if (input_method->context->resource)
1704 wl_input_method_context_send_commit_state(input_method->context->resource, serial);
1709 _e_text_input_cb_action_invoke(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t button, uint32_t index)
1711 E_Text_Input *text_input = wl_resource_get_user_data(resource);
1712 E_Input_Method *input_method = NULL;
1713 Eina_List *l = NULL;
1717 WTI_WARNING(resource,
1718 WL_DISPLAY_ERROR_INVALID_OBJECT,
1719 "No Text Input For Resource");
1723 EINA_LIST_FOREACH(text_input->input_methods, l, input_method)
1725 if (!input_method || !input_method->context) continue;
1727 if (input_method->context->resource)
1728 wl_input_method_context_send_invoke_action(input_method->context->resource,
1734 _e_text_input_cb_return_key_type_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t return_key_type)
1736 E_Text_Input *text_input = wl_resource_get_user_data(resource);
1737 E_Input_Method *input_method = NULL;
1738 Eina_List *l = NULL;
1742 WTI_WARNING(resource,
1743 WL_DISPLAY_ERROR_INVALID_OBJECT,
1744 "No Text Input For Resource");
1748 EINA_LIST_FOREACH(text_input->input_methods, l, input_method)
1750 if (!input_method || !input_method->context) continue;
1752 if (input_method->context->resource)
1753 wl_input_method_context_send_return_key_type(input_method->context->resource,
1759 _e_text_input_cb_return_key_disabled_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t disabled)
1761 E_Text_Input *text_input = wl_resource_get_user_data(resource);
1762 E_Input_Method *input_method = NULL;
1763 Eina_List *l = NULL;
1767 WTI_WARNING(resource,
1768 WL_DISPLAY_ERROR_INVALID_OBJECT,
1769 "No Text Input For Resource");
1773 EINA_LIST_FOREACH(text_input->input_methods, l, input_method)
1775 if (!input_method || !input_method->context) continue;
1777 if (input_method->context->resource)
1778 wl_input_method_context_send_return_key_disabled(input_method->context->resource,
1784 _e_text_input_cb_input_panel_data_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, const char *data, uint32_t length)
1786 E_Text_Input *text_input = wl_resource_get_user_data(resource);
1787 E_Input_Method *input_method = NULL;
1788 Eina_List *l = NULL;
1792 WTI_WARNING(resource,
1793 WL_DISPLAY_ERROR_INVALID_OBJECT,
1794 "No Text Input For Resource");
1798 EINA_LIST_FOREACH(text_input->input_methods, l, input_method)
1800 if (!input_method || !input_method->context) continue;
1802 if (input_method->context->resource)
1803 wl_input_method_context_send_input_panel_data(input_method->context->resource,
1807 /* Temporarily receiving WILL_HIDE_ACK via input_panel_data, will need for a new wayland protocol */
1808 const char *szWillHideAck = "WILL_HIDE_ACK";
1809 if (strncmp(data, szWillHideAck, strlen(szWillHideAck)) == 0)
1811 if (g_timer_will_hide)
1813 ecore_timer_del(g_timer_will_hide);
1814 g_timer_will_hide = NULL;
1816 INF("WILL_HIDE_ACK_RECVED, %d", g_input_panel_state);
1817 if (g_input_panel_state == E_INPUT_PANEL_STATE_WILL_HIDE)
1819 e_input_panel_visibility_change(EINA_FALSE);
1820 e_input_panel_transient_for_set(NULL);
1821 g_input_panel_state = E_INPUT_PANEL_STATE_DID_HIDE;
1827 _e_text_input_cb_bidi_direction_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t bidi_direction)
1829 E_Text_Input *text_input = wl_resource_get_user_data(resource);
1830 E_Input_Method *input_method = NULL;
1831 Eina_List *l = NULL;
1835 WTI_WARNING(resource,
1836 WL_DISPLAY_ERROR_INVALID_OBJECT,
1837 "No Text Input For Resource");
1841 EINA_LIST_FOREACH(text_input->input_methods, l, input_method)
1843 if (!input_method || !input_method->context) continue;
1845 if (input_method->context->resource)
1846 wl_input_method_context_send_bidi_direction(input_method->context->resource,
1852 _e_text_input_cb_cursor_position_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t cursor_position)
1854 E_Text_Input *text_input = wl_resource_get_user_data(resource);
1855 E_Input_Method *input_method = NULL;
1856 Eina_List *l = NULL;
1860 WTI_WARNING(resource,
1861 WL_DISPLAY_ERROR_INVALID_OBJECT,
1862 "No Text Input For Resource");
1866 EINA_LIST_FOREACH(text_input->input_methods, l, input_method)
1868 if (!input_method || !input_method->context) continue;
1870 if (input_method->context->resource)
1871 wl_input_method_context_send_cursor_position(input_method->context->resource, cursor_position);
1876 _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)
1878 E_Text_Input *text_input = wl_resource_get_user_data(resource);
1879 E_Input_Method *input_method = NULL;
1880 Eina_List *l = NULL;
1884 WTI_WARNING(resource,
1885 WL_DISPLAY_ERROR_INVALID_OBJECT,
1886 "No Text Input For Resource");
1890 EINA_LIST_FOREACH(text_input->input_methods, l, input_method)
1892 if (!input_method || !input_method->context) continue;
1894 if (input_method->context->resource)
1895 wl_input_method_context_send_process_input_device_event(input_method->context->resource,
1896 type, data, length);
1901 _e_text_input_cb_filter_key_event(struct wl_client *client EINA_UNUSED, struct wl_resource *resource,
1902 uint32_t serial, uint32_t time, const char *keyname, uint32_t state,
1903 uint32_t modifiers, const char *dev_name, uint32_t dev_class,
1904 uint32_t dev_subclass, uint32_t keycode)
1907 E_Text_Input *text_input = wl_resource_get_user_data(resource);
1908 E_Input_Method *input_method = NULL;
1912 WTI_WARNING(resource,
1913 WL_DISPLAY_ERROR_INVALID_OBJECT,
1914 "No Text Input For Resource");
1918 /* FIXME: should get input_method object from seat. */
1919 if (g_input_method && g_input_method->resource)
1920 input_method = wl_resource_get_user_data(g_input_method->resource);
1922 if (input_method && input_method->context && input_method->context->resource)
1924 wl_input_method_context_send_filter_key_event(input_method->context->resource,
1925 serial, time, keyname, state, modifiers,
1926 dev_name, dev_class, dev_subclass, keycode);
1930 if (text_input->resource)
1931 wl_text_input_send_filter_key_event_done(text_input->resource, serial, false);
1933 WTI_WARNING(resource,
1934 WL_DISPLAY_ERROR_INVALID_OBJECT,
1941 _e_text_input_cb_get_hide_permission(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
1943 E_Text_Input *text_input = wl_resource_get_user_data(resource);
1944 uint32_t permission = 1;
1945 E_Client *focused_ec = NULL;
1949 WTI_WARNING(resource,
1950 WL_DISPLAY_ERROR_INVALID_OBJECT,
1951 "No Text Input For Resource");
1955 focused_ec = e_client_focused_get();
1958 if (focused_ec != client_surface_ec)
1960 E_Window_Type focus_win_type = focused_ec->netwm.type;
1961 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);
1963 if (focus_win_type == E_WINDOW_TYPE_NOTIFICATION ||
1964 focus_win_type == E_WINDOW_TYPE_POPUP_MENU)
1970 LOGI("Can't get focus window\n");
1973 if (text_input->resource)
1974 wl_text_input_send_hide_permission(text_input->resource, permission);
1978 _e_text_input_cb_set_capital_mode(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t mode)
1980 E_Text_Input *text_input = wl_resource_get_user_data(resource);
1981 E_Input_Method *input_method = NULL;
1982 Eina_List *l = NULL;
1986 WTI_WARNING(resource,
1987 WL_DISPLAY_ERROR_INVALID_OBJECT,
1988 "No Text Input For Resource");
1992 EINA_LIST_FOREACH(text_input->input_methods, l, input_method)
1994 if (!input_method || !input_method->context) continue;
1995 if (input_method->context->resource)
1996 wl_input_method_context_send_capital_mode(input_method->context->resource, mode);
2001 _e_text_input_cb_prediction_hint_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, const char *prediction_hint)
2003 E_Text_Input *text_input = wl_resource_get_user_data(resource);
2004 E_Input_Method *input_method = NULL;
2005 Eina_List *l = NULL;
2009 WTI_WARNING(resource,
2010 WL_DISPLAY_ERROR_INVALID_OBJECT,
2011 "No Text Input For Resource");
2015 EINA_LIST_FOREACH(text_input->input_methods, l, input_method)
2017 if (!input_method || !input_method->context) continue;
2019 if (input_method->context->resource)
2020 wl_input_method_context_send_prediction_hint(input_method->context->resource, prediction_hint);
2025 _e_text_input_cb_prediction_hint_data_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, const char *key, const char *value)
2027 E_Text_Input *text_input = wl_resource_get_user_data(resource);
2028 E_Input_Method *input_method = NULL;
2029 Eina_List *l = NULL;
2033 WTI_WARNING(resource,
2034 WL_DISPLAY_ERROR_INVALID_OBJECT,
2035 "No Text Input For Resource");
2039 EINA_LIST_FOREACH(text_input->input_methods, l, input_method)
2041 if (!input_method || !input_method->context) continue;
2043 if (input_method->context->resource)
2044 wl_input_method_context_send_prediction_hint_data(input_method->context->resource, key, value);
2049 _e_text_input_cb_input_panel_enabled_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t enabled)
2051 E_Text_Input *text_input = wl_resource_get_user_data(resource);
2055 WTI_WARNING(resource,
2056 WL_DISPLAY_ERROR_INVALID_OBJECT,
2057 "No Text Input For Resource");
2061 g_input_panel_enabled = enabled;
2065 _e_text_input_cb_mime_type_accept_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, const char *mime_type)
2067 E_Text_Input *text_input = wl_resource_get_user_data(resource);
2068 E_Input_Method *input_method = NULL;
2069 Eina_List *l = NULL;
2073 WTI_WARNING(resource,
2074 WL_DISPLAY_ERROR_INVALID_OBJECT,
2075 "No Text Input For Resource");
2079 EINA_LIST_FOREACH(text_input->input_methods, l, input_method)
2081 if (!input_method || !input_method->context) continue;
2083 if (input_method->context->resource)
2084 wl_input_method_context_send_mime_type(input_method->context->resource, mime_type);
2089 _e_text_input_cb_input_panel_position_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t x, uint32_t y)
2091 E_Text_Input *text_input = wl_resource_get_user_data(resource);
2095 WTI_WARNING(resource,
2096 WL_DISPLAY_ERROR_INVALID_OBJECT,
2097 "No Text Input For Resource");
2100 e_input_panel_floating_position_set(x, y);
2104 _e_text_input_cb_finalize_content(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, const char *text, uint32_t cursor_position)
2106 E_Text_Input *text_input = wl_resource_get_user_data(resource);
2107 E_Input_Method *input_method = NULL;
2108 Eina_List *l = NULL;
2112 WTI_WARNING(resource,
2113 WL_DISPLAY_ERROR_INVALID_OBJECT,
2114 "No Text Input For Resource");
2118 EINA_LIST_FOREACH(text_input->input_methods, l, input_method)
2120 if (!input_method || !input_method->context) continue;
2122 if (input_method->context->resource)
2123 wl_input_method_context_send_finalized_content(input_method->context->resource, text, cursor_position);
2128 _e_text_input_cb_resource_destroy(struct wl_resource *resource)
2130 E_Text_Input *text_input = wl_resource_get_user_data(resource);
2131 E_Input_Method *input_method = NULL;
2135 WTI_WARNING(resource,
2136 WL_DISPLAY_ERROR_INVALID_OBJECT,
2137 "No Text Input For Resource");
2141 LOGI("resource : %p", resource);
2143 if (g_show_text_input == text_input)
2145 if (text_input->input_panel_visible)
2147 _input_panel_hide(g_client, resource, EINA_TRUE);
2150 g_show_text_input = NULL;
2153 if (g_text_input == text_input)
2155 g_text_input = NULL;
2159 EINA_LIST_FREE(text_input->input_methods, input_method)
2162 _e_text_input_deactivate(text_input, input_method, EINA_TRUE);
2169 _e_text_input_cb_destroy(struct wl_client *client, struct wl_resource *resource)
2171 E_Text_Input *text_input = wl_resource_get_user_data(resource);
2172 E_Input_Method *input_method = NULL;
2173 Eina_Bool _context_created = EINA_FALSE;
2177 WTI_WARNING(resource,
2178 WL_DISPLAY_ERROR_INVALID_OBJECT,
2179 "No Text Input For Resource");
2183 if (g_input_method && g_input_method->resource)
2184 input_method = wl_resource_get_user_data(g_input_method->resource);
2188 WTI_WARNING(resource,
2189 WL_DISPLAY_ERROR_INVALID_OBJECT,
2190 "No Input Method For Seat");
2194 LOGI("text_input(%p), focus(%d), input_method(%p), input_method->resource(%p), context(%p), context->resource(%p), resource(%p)",
2195 text_input, (text_input == g_text_input), input_method, input_method->resource, input_method->context,
2196 (input_method->context ? input_method->context->resource : NULL), resource);
2198 if ((!input_method->context) || (!input_method->context->resource))
2199 _context_created = _e_text_input_method_create_context(client, input_method, text_input, EINA_FALSE);
2201 if (text_input == g_text_input &&
2202 input_method->resource && input_method->context && input_method->context->resource)
2204 wl_input_method_send_destroy(input_method->resource, input_method->context->resource);
2205 LOGI("wm_map TEXTINPUT destroy : input_method->resource(%p) input_method->context->resource(%p)",
2206 input_method->resource, input_method->context->resource);
2208 destroyed_resource = input_method->resource;
2211 if (_context_created)
2212 _e_text_input_deactivate(text_input, input_method, EINA_FALSE);
2215 static const struct wl_text_input_interface _e_text_input_implementation = {
2216 _e_text_input_cb_destroy,
2217 _e_text_input_cb_activate,
2218 _e_text_input_cb_deactivate,
2219 _e_text_input_cb_input_panel_show,
2220 _e_text_input_cb_input_panel_hide,
2221 _e_text_input_cb_reset,
2222 _e_text_input_cb_content_type_set,
2223 _e_text_input_cb_cursor_rectangle_set,
2224 _e_text_input_cb_preferred_language_set,
2225 _e_text_input_cb_state_commit,
2226 _e_text_input_cb_action_invoke,
2227 _e_text_input_cb_return_key_type_set,
2228 _e_text_input_cb_return_key_disabled_set,
2229 _e_text_input_cb_input_panel_data_set,
2230 _e_text_input_cb_bidi_direction_set,
2231 _e_text_input_cb_cursor_position_set,
2232 _e_text_input_cb_process_input_device_event,
2233 _e_text_input_cb_filter_key_event,
2234 _e_text_input_cb_get_hide_permission,
2235 _e_text_input_cb_set_capital_mode,
2236 _e_text_input_cb_prediction_hint_set,
2237 _e_text_input_cb_mime_type_accept_set,
2238 _e_text_input_cb_input_panel_position_set,
2239 _e_text_input_cb_finalize_content,
2240 _e_text_input_cb_prediction_hint_data_set,
2241 _e_text_input_cb_input_panel_enabled_set
2245 _e_text_input_manager_cb_text_input_create(struct wl_client *client, struct wl_resource *resource, uint32_t id)
2247 E_Text_Input_Mgr *text_input_mgr = wl_resource_get_user_data(resource);
2248 E_Text_Input *text_input = NULL;
2250 if (!text_input_mgr)
2252 WTI_WARNING(resource,
2253 WL_DISPLAY_ERROR_INVALID_OBJECT,
2254 "No Text Input Manager For Resource");
2258 if (!(text_input = E_NEW(E_Text_Input, 1)))
2260 wl_client_post_no_memory(client);
2261 ERR("Could not allocate space for Text_Input");
2265 text_input->resource =
2266 wl_resource_create(client, &wl_text_input_interface, 1, id);
2268 if (!text_input->resource)
2270 wl_client_post_no_memory(client);
2271 ERR("Could not create the resource for text_input");
2275 text_input->id = g_text_input_count++;
2277 wl_resource_set_implementation(text_input->resource,
2278 &_e_text_input_implementation,
2279 text_input, _e_text_input_cb_resource_destroy);
2282 static const struct wl_text_input_manager_interface _e_text_input_manager_implementation = {
2283 _e_text_input_manager_cb_text_input_create
2287 _e_text_cb_bind_text_input_manager(struct wl_client *client, void *data, uint32_t version EINA_UNUSED, uint32_t id)
2289 E_Text_Input_Mgr *text_input_mgr = data;
2291 text_input_mgr->resource =
2292 wl_resource_create(client,
2293 &wl_text_input_manager_interface, 1, id);
2295 if (text_input_mgr->resource)
2296 wl_resource_set_implementation(text_input_mgr->resource,
2297 &_e_text_input_manager_implementation,
2298 text_input_mgr, NULL);
2302 _e_text_input_method_cb_unbind(struct wl_resource *resource)
2305 E_Input_Method *input_method = wl_resource_get_user_data(resource);
2309 WTI_WARNING(resource,
2310 WL_DISPLAY_ERROR_INVALID_OBJECT,
2311 "No Input Method For Resource");
2315 if (input_method->resource != resource) return;
2317 if (input_method->input)
2318 _e_text_input_deactivate(input_method->input, input_method, EINA_TRUE);
2320 input_method->resource = NULL;
2321 input_method->context = NULL;
2323 if (vconf_set_bool(VCONFKEY_ISF_BIND, 0) != 0)
2324 LOGW("failed to set isf bind\n");
2328 _e_text_input_method_cb_bind(struct wl_client *client, void *data, uint32_t version EINA_UNUSED, uint32_t id)
2331 E_Input_Method *input_method = data;
2332 struct wl_resource *resource = NULL;
2334 if (!input_method) return;
2336 if (input_method->resource)
2337 _e_text_input_method_cb_unbind(input_method->resource);
2339 if (input_method->resource)
2341 WTI_WARNING(input_method->resource, WL_DISPLAY_ERROR_INVALID_OBJECT,
2342 "input_method object already bound");
2346 resource = wl_resource_create(client, &wl_input_method_interface, 1, id);
2347 if (EINA_UNLIKELY(!resource))
2350 input_method->resource = resource;
2352 wl_resource_set_implementation(resource, NULL, input_method,
2353 _e_text_input_method_cb_unbind);
2355 if (vconf_set_bool(VCONFKEY_ISF_BIND, 1) != 0)
2356 LOGW("failed to set isf bind\n");
2360 _e_text_input_method_destroy(void *data)
2362 E_Input_Method *input_method = data;
2367 if (input_method->global)
2369 wl_global_destroy(input_method->global);
2370 input_method->global = NULL;
2377 _e_text_input_method_create(void)
2379 if (!(g_input_method = E_NEW(E_Input_Method, 1)))
2381 ERR("Could not allocate space for Input_Method");
2385 g_input_method->global =
2386 wl_global_create(e_comp_wl->wl.disp, &wl_input_method_interface, 1,
2387 g_input_method, _e_text_input_method_cb_bind);
2389 if (!g_input_method->global)
2391 free(g_input_method);
2392 g_input_method = NULL;
2396 _e_mod_text_input_shutdown_cb_add(_e_text_input_method_destroy, g_input_method);
2402 _e_text_input_manager_destroy(void *data)
2404 E_Text_Input_Mgr *text_input_mgr = data;
2405 if (!text_input_mgr) return;
2407 LOGI("input manager : %p", text_input_mgr);
2409 if (text_input_mgr->global)
2411 wl_global_destroy(text_input_mgr->global);
2412 text_input_mgr->global = NULL;
2414 free(text_input_mgr);
2418 _e_text_input_manager_create(void)
2420 E_Text_Input_Mgr *text_input_mgr;
2422 if (!(text_input_mgr = E_NEW(E_Text_Input_Mgr, 1)))
2424 ERR("Could not allocate space for Text_Input_Manager");
2428 text_input_mgr->global =
2429 wl_global_create(e_comp_wl->wl.disp,
2430 &wl_text_input_manager_interface, 1,
2431 text_input_mgr, _e_text_cb_bind_text_input_manager);
2433 if (!text_input_mgr->global)
2435 free(text_input_mgr);
2439 LOGI("input manager : %p", text_input_mgr);
2441 _e_mod_text_input_shutdown_cb_add(_e_text_input_manager_destroy, text_input_mgr);
2447 _e_mod_text_input_shutdown(void)
2449 E_Mod_Text_Input_Shutdown_Cb *cb;
2451 EINA_LIST_FREE(shutdown_list, cb)
2461 E_API E_Module_Api e_modapi = { E_MODULE_API_VERSION, "Wl_Text_Input" };
2464 set_soft_keyboard_mode()
2466 g_disable_show_panel = EINA_FALSE;
2468 /* switch to S/W keyboard mode */
2470 if (vconf_get_bool(VCONFKEY_ISF_HW_KEYBOARD_INPUT_DETECTED, &val) == 0 && val != 0)
2471 vconf_set_bool(VCONFKEY_ISF_HW_KEYBOARD_INPUT_DETECTED, 0);
2475 _e_mod_eeze_udev_watch_cb(const char *text, Eeze_Udev_Event event, void *data, Eeze_Udev_Watch *watch)
2477 if (event == EEZE_UDEV_EVENT_REMOVE)
2478 set_soft_keyboard_mode();
2482 e_client_rotation_is_progress(E_Client *ec)
2484 if (!ec) return EINA_TRUE;
2486 if (ec->e.state.rot.ang.next == -1)
2493 _e_text_input_method_context_cb_client_resize(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
2499 ev = (E_Event_Client *)event;
2500 EINA_SAFETY_ON_NULL_RETURN_VAL(ev, ECORE_CALLBACK_PASS_ON);
2503 EINA_SAFETY_ON_NULL_RETURN_VAL(ec, ECORE_CALLBACK_PASS_ON);
2505 found = e_input_panel_client_find(ec);
2506 if (!found) return ECORE_CALLBACK_PASS_ON;
2507 if ((ec->w < 1) && (ec->h < 1)) return ECORE_CALLBACK_PASS_ON;
2509 e_text_input_update_input_panel_geometry(ec);
2511 return ECORE_CALLBACK_PASS_ON;
2515 _pol_cb_hook_client_del(void *d EINA_UNUSED, E_Client *ec)
2517 if (EINA_UNLIKELY(!ec))
2520 if (ec == client_surface_ec)
2522 LOGI("transient_for_ec deleted, hiding input panel\n");
2523 e_input_panel_visibility_change(EINA_FALSE);
2524 e_input_panel_transient_for_set(NULL);
2526 if(!e_input_panel_surface_destroy(ec))
2527 LOGE("fail to remove surface\n");
2529 g_input_panel_state = E_INPUT_PANEL_STATE_DID_HIDE;
2530 if (g_timer_will_hide)
2532 ecore_timer_del(g_timer_will_hide);
2533 g_timer_will_hide = NULL;
2535 client_surface_ec = NULL;
2536 LOGI("TRANSIENT_FOR::Reset transient_for_ec to NULL\n");
2541 e_text_input_update_input_panel_state(Eina_Bool state)
2543 if (!g_text_input || !g_text_input->resource) return;
2545 E_Text_Input *text_input = wl_resource_get_user_data(g_text_input->resource);
2549 WTI_WARNING(g_text_input->resource,
2550 WL_DISPLAY_ERROR_INVALID_OBJECT,
2551 "No Text Input For Resource");
2555 if (text_input->resource)
2557 if (!g_updated_geometry)
2559 int x = 0, y = 0, w = 0, h = 0;
2560 if (e_input_panel_client_geometry_get(NULL, &x, &y, &w, &h) && !(w <= 1 || h <= 1))
2561 _e_text_input_send_input_panel_geometry(text_input->resource, x, y, w, h);
2562 g_updated_geometry = EINA_TRUE;
2564 uint32_t input_panel_state = WL_TEXT_INPUT_INPUT_PANEL_STATE_HIDE;
2565 if (state) input_panel_state = WL_TEXT_INPUT_INPUT_PANEL_STATE_SHOW;
2566 wl_text_input_send_input_panel_state(text_input->resource, input_panel_state);
2571 e_text_input_update_input_panel_geometry(E_Client *ec)
2573 if (g_text_input && g_text_input->resource &&
2574 g_input_panel_state != E_INPUT_PANEL_STATE_WILL_HIDE && g_input_panel_state != E_INPUT_PANEL_STATE_DID_HIDE &&
2577 if (e_client_rotation_is_progress(ec))
2579 LOGI("Rotation is not finished");
2583 /* The geometry of E_Client may not be valid when IME is shown.
2584 Assume E_Client has a valid geometry when this callback is called after IME has set the size.
2586 int x = 0, y = 0, w = 0, h = 0;
2587 if (e_input_panel_client_geometry_get(NULL, &x, &y, &w, &h) && !(w <= 1 || h <= 1))
2589 LOGI("x : %d, y : %d, w : %d, h : %d", x, y, w, h);
2590 _e_text_input_send_input_panel_geometry(g_text_input->resource, x, y, w, h);
2596 e_modapi_init(E_Module *m)
2598 if (!e_comp_wl) return NULL;
2600 if (!wti_log_init())
2603 /* FIXME: create only one input method object per seat. */
2604 if (!_e_text_input_method_create())
2607 if (!e_input_panel_init())
2610 if (!_e_text_input_manager_create())
2613 if (!e_input_method_manager_create())
2616 E_LIST_HANDLER_APPEND(handlers, E_EVENT_CLIENT_RESIZE, _e_text_input_method_context_cb_client_resize, NULL);
2618 if (vconf_notify_key_changed(VCONFKEY_ISF_HW_KEYBOARD_INPUT_DETECTED, _keyboard_mode_changed_cb, NULL) != 0)
2619 LOGW ("Failed to register callback function for H/W keyboard input detection.");
2621 eeze_udev_watch_hander = eeze_udev_watch_add(EEZE_UDEV_TYPE_KEYBOARD,
2622 EEZE_UDEV_EVENT_REMOVE,
2623 _e_mod_eeze_udev_watch_cb,
2625 if (!eeze_udev_watch_hander)
2628 E_CLIENT_HOOK_APPEND(hooks_ec, E_CLIENT_HOOK_DEL, _pol_cb_hook_client_del, NULL);
2632 _e_mod_text_input_shutdown();
2637 e_modapi_shutdown(E_Module *m EINA_UNUSED)
2639 E_FREE_LIST(handlers, ecore_event_handler_del);
2640 E_FREE_LIST(hooks_ec, e_client_hook_del);
2642 if (g_timer_will_hide)
2644 ecore_timer_del(g_timer_will_hide);
2645 g_timer_will_hide = NULL;
2648 vconf_ignore_key_changed(VCONFKEY_ISF_HW_KEYBOARD_INPUT_DETECTED, _keyboard_mode_changed_cb);
2650 if (eeze_udev_watch_hander)
2652 eeze_udev_watch_del(eeze_udev_watch_hander);
2653 eeze_udev_watch_hander = NULL;
2655 _e_mod_text_input_shutdown();
2657 e_input_panel_shutdown();
2665 e_modapi_save(E_Module *m EINA_UNUSED)