2 * ISF(Input Service Framework)
4 * ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable.
5 * Copyright (c) 2013 Intel Corporation
6 * Copyright (c) 2013-2015 Samsung Electronics Co., Ltd.
8 * Contact: Jihoon Kim <jihoon48.kim@samsung.com>, Li Zhang <li2012.zhang@samsung.com>
10 * This library is free software; you can redistribute it and/or modify it under
11 * the terms of the GNU Lesser General Public License as published by the
12 * Free Software Foundation; either version 2.1 of the License, or (at your option)
15 * This library is distributed in the hope that it will be useful, but WITHOUT ANY
16 * WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
18 * License for more details.
20 * You should have received a copy of the GNU Lesser General Public License
21 * along with this library; if not, write to the Free Software Foundation, Inc., 51
22 * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
26 #define Uses_SCIM_PANEL_CLIENT
27 #define Uses_SCIM_CONFIG_PATH
28 #define Uses_SCIM_PANEL_AGENT
30 #include <sys/types.h>
33 #include <sys/times.h>
49 #define EFL_BETA_API_SUPPORT
50 #include <Ecore_Wl2.h>
51 #include <input-method-client-protocol.h>
52 #include <text-client-protocol.h>
54 #include "scim_private.h"
56 #include "isf_wsc_context.h"
57 #include "isf_wsc_control_ui.h"
58 #include "tizen_profile.h"
60 #include <linux/input.h>
62 #if ENABLE_GRAB_KEYBOARD
63 #include <xkbcommon/xkbcommon.h>
67 #include "isf_debug.h"
73 #define LOG_TAG "ISF_WAYLAND_MODULE"
77 struct _WSCContextISFImpl {
78 WSCContextISF *parent;
79 Ecore_IMF_Input_Mode input_mode;
80 WideString surrounding_text;
81 WideString preedit_string;
82 AttributeList preedit_attrlist;
83 WideString commit_string;
84 Ecore_IMF_Autocapital_Type autocapital_type;
85 Ecore_IMF_Input_Hints input_hint;
86 Ecore_IMF_BiDi_Direction bidi_direction;
87 Ecore_IMF_Input_Panel_Layout panel_layout;
88 Ecore_IMF_Input_Panel_Return_Key_Type return_key_type;
98 int return_key_disabled;
101 bool preedit_started;
102 bool need_commit_preedit;
103 bool init_remote_entry_metadata;
104 bool init_remote_surrounding_text;
105 bool block_input_resource;
106 Input_Resource input_resource;
108 WSCContextISFImpl *next;
111 _WSCContextISFImpl() : parent(NULL),
112 input_mode(ECORE_IMF_INPUT_MODE_FULL),
113 autocapital_type(ECORE_IMF_AUTOCAPITAL_TYPE_SENTENCE),
114 input_hint(ECORE_IMF_INPUT_HINT_NONE),
115 bidi_direction(ECORE_IMF_BIDI_DIRECTION_NEUTRAL),
116 panel_layout(ECORE_IMF_INPUT_PANEL_LAYOUT_NORMAL),
117 return_key_type(ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_DEFAULT),
126 return_key_disabled(0),
129 preedit_started(false),
130 need_commit_preedit(false),
131 init_remote_entry_metadata(true),
132 init_remote_surrounding_text(true),
133 block_input_resource(false),
134 input_resource(INPUT_RESOURCE_NONE),
140 static struct wl_input_method_manager *_im_manager = NULL;
142 /* private functions */
144 static void panel_slot_update_preedit_caret (int context,
146 static void panel_slot_process_key_event (int context,
147 const KeyEvent &key);
148 static void panel_slot_commit_string (int context,
149 const WideString &wstr,
151 static void panel_slot_forward_key_event (int context,
154 static void panel_slot_update_preedit_string (int context,
155 const WideString str,
156 const WideString commit,
157 const AttributeList &attrs,
160 static void _show_preedit_string (int context);
162 static void panel_req_update_bidi_direction (WSCContextISF *ic, int direction);
164 static void remote_surrounding_get (WSCContextISF *wsc_ctx);
166 static void wl_im_destroy (void);
168 /* Panel iochannel handler*/
169 static void panel_initialize (void);
170 static void panel_finalize (void);
172 /* utility functions */
174 static bool filter_keys (const char *keyname,
175 const char *config_path);
176 static void set_ic_capabilities (WSCContextISF *ic);
178 static void initialize (void);
179 static void finalize (void);
181 static void send_wl_key_event (WSCContextISF *ic, const KeyEvent &key, bool fake);
182 static void _hide_preedit_string (int context, bool update_preedit);
184 /* Local variables declaration */
185 static String _language;
186 static WSCContextISFImpl *_used_ic_impl_list = 0;
187 static WSCContextISFImpl *_free_ic_impl_list = 0;
188 static WSCContextISF *_ic_list = 0;
190 static KeyboardLayout _keyboard_layout = SCIM_KEYBOARD_Default;
191 static int _valid_key_mask = SCIM_KEY_AllMasks;
193 static ConfigPointer _config;
195 static WSCContextISF *_focused_ic = 0;
197 static bool _scim_initialized = false;
199 static int _panel_client_id = 0;
200 static uint32 _active_helper_option = 0;
202 static bool _on_the_spot = true;
203 static bool _change_keyboard_mode_by_focus_move = false;
204 static bool _support_hw_keyboard_mode = false;
206 static bool _x_key_event_is_valid = false;
208 static Ecore_Timer *_resource_check_timer = NULL;
210 static bool _need_wl_im_init = false;
211 static struct _wl_im *_wl_im_ctx = NULL;
212 static int _ecore_wl2_init_count = 0;
214 static bool _launch_ise_on_request = false;
216 #define WAYLAND_MODULE_CLIENT_ID (0)
217 #define MAX_PREEDIT_BUFSIZE 4000
219 #define MOD_SHIFT_MASK 0x01
220 #define MOD_CAPS_MASK 0x02
221 #define MOD_CONTROL_MASK 0x04
222 #define MOD_ALT_MASK 0x08
223 #define MOD_NUM_MASK 0x100
224 #define MOD_Mod5_MASK 0x80
226 #define WL_TEXT_INPUT_CONTENT_HINT_AUTOFILL_MASK 0xff0000
228 //////////////////////////////wayland_panel_agent_module begin//////////////////////////////////////////////////
230 #define scim_module_init wayland_LTX_scim_module_init
231 #define scim_module_exit wayland_LTX_scim_module_exit
232 #define scim_panel_agent_module_init wayland_LTX_scim_panel_agent_module_init
233 #define scim_panel_agent_module_get_instance wayland_LTX_scim_panel_agent_module_get_instance
235 static struct weescim _wsc = {0};
237 InfoManager* g_info_manager = NULL;
238 static scim::PanelAgentPointer instance;
241 /////////////////////////////////////////////////////////////////////////////
242 // Implementation of Wayland Input Method functions.
243 /////////////////////////////////////////////////////////////////////////////
246 _wsc_im_ctx_reset (void *data, struct wl_input_method_context *im_ctx)
248 WSCContextISF *context_scim = (WSCContextISF*)data;
250 if (context_scim && context_scim->impl && context_scim == _focused_ic) {
251 g_info_manager->socket_reset_input_context (WAYLAND_MODULE_CLIENT_ID, context_scim->id);
256 _wsc_im_ctx_content_type (void *data, struct wl_input_method_context *im_ctx, uint32_t hint, uint32_t purpose)
258 WSCContextISF *wsc_ctx = (WSCContextISF*)data;
259 if (!wsc_ctx) return;
261 LOGD ("im_context = %p hint = %04x purpose = %d", im_ctx, hint, purpose);
264 if (wsc_ctx->content_purpose != purpose || !wsc_ctx->layout_initialized) {
265 wsc_ctx->layout_initialized = EINA_TRUE;
266 wsc_ctx->content_purpose = purpose;
267 isf_wsc_context_input_panel_layout_set (wsc_ctx, wsc_context_input_panel_layout_get (wsc_ctx));
270 if (wsc_ctx->content_hint != hint) {
271 uint32_t hint_copy, old_hintbit, new_hintbit;
272 const uint32_t autocap_type = WL_TEXT_INPUT_CONTENT_HINT_AUTO_CAPITALIZATION |
273 WL_TEXT_INPUT_CONTENT_HINT_UPPERCASE |
274 WL_TEXT_INPUT_CONTENT_HINT_WORD_CAPITALIZATION;
276 hint_copy = wsc_ctx->content_hint;
277 wsc_ctx->content_hint = hint;
279 // Set prediction allow
280 old_hintbit = hint_copy & WL_TEXT_INPUT_CONTENT_HINT_AUTO_COMPLETION;
281 new_hintbit = hint & WL_TEXT_INPUT_CONTENT_HINT_AUTO_COMPLETION;
282 if (old_hintbit != new_hintbit || !wsc_ctx->prediction_allow_initialized) {
283 wsc_ctx->prediction_allow_initialized = EINA_TRUE;
284 g_info_manager->set_prediction_allow (WAYLAND_MODULE_CLIENT_ID, wsc_context_prediction_allow_get (wsc_ctx));
287 // Set autocapital type
288 old_hintbit = hint_copy & autocap_type;
289 new_hintbit = hint & autocap_type;
290 if (old_hintbit != new_hintbit || !wsc_ctx->autocapital_type_initialized) {
291 wsc_ctx->autocapital_type_initialized = EINA_TRUE;
292 isf_wsc_context_autocapital_type_set (wsc_ctx, wsc_context_autocapital_type_get (wsc_ctx));
296 old_hintbit = hint_copy & WL_TEXT_INPUT_CONTENT_HINT_LATIN;
297 new_hintbit = hint & WL_TEXT_INPUT_CONTENT_HINT_LATIN;
298 if (old_hintbit != new_hintbit || !wsc_ctx->language_initialized) {
299 wsc_ctx->language_initialized = EINA_TRUE;
300 isf_wsc_context_input_panel_language_set (wsc_ctx, wsc_context_input_panel_language_get (wsc_ctx));
303 isf_wsc_context_input_hint_set (wsc_ctx, wsc_context_input_hint_get (wsc_ctx));
307 isf_wsc_context_send_entry_metadata (wsc_ctx, wsc_context_input_hint_get (wsc_ctx), wsc_context_input_panel_layout_get (wsc_ctx),
308 wsc_context_input_panel_layout_variation_get (wsc_ctx), wsc_context_autocapital_type_get (wsc_ctx), wsc_ctx->return_key_disabled,
309 (Ecore_IMF_Input_Panel_Return_Key_Type)wsc_ctx->return_key_type);
314 _wsc_im_ctx_invoke_action (void *data, struct wl_input_method_context *im_ctx, uint32_t button, uint32_t index)
316 WSCContextISF *wsc_ctx = (WSCContextISF*)data;
317 if (!wsc_ctx) return;
319 LOGD ("invoke action. button : %d", button);
321 if (button != BTN_LEFT)
324 wsc_context_send_preedit_string (wsc_ctx);
328 _wsc_im_ctx_commit_state (void *data, struct wl_input_method_context *im_ctx, uint32_t serial)
330 WSCContextISF *wsc_ctx = (WSCContextISF*)data;
331 if (!wsc_ctx) return;
333 wsc_ctx->serial = serial;
335 if (wsc_ctx->language)
336 wl_input_method_context_language (im_ctx, wsc_ctx->serial, wsc_ctx->language);
340 _wsc_im_ctx_preferred_language (void *data, struct wl_input_method_context *im_ctx, const char *language)
342 WSCContextISF *wsc_ctx = (WSCContextISF*)data;
343 if (!wsc_ctx) return;
345 if (language && wsc_ctx->language && !strcmp (language, wsc_ctx->language))
348 if (wsc_ctx->language) {
349 free (wsc_ctx->language);
350 wsc_ctx->language = NULL;
354 wsc_ctx->language = strdup (language);
355 LOGD ("Language changed, new: '%s'", language);
360 _wsc_im_ctx_return_key_type (void *data, struct wl_input_method_context *im_ctx, uint32_t return_key_type)
362 WSCContextISF *wsc_ctx = (WSCContextISF*)data;
364 LOGD ("im_context = %p return key type = %d", im_ctx, return_key_type);
365 if (!wsc_ctx) return;
367 if (wsc_ctx->return_key_type != return_key_type) {
368 wsc_ctx->return_key_type = return_key_type;
369 isf_wsc_context_input_panel_return_key_type_set (wsc_ctx, (Ecore_IMF_Input_Panel_Return_Key_Type)wsc_ctx->return_key_type);
371 isf_wsc_context_send_entry_metadata (wsc_ctx, wsc_context_input_hint_get (wsc_ctx), wsc_context_input_panel_layout_get (wsc_ctx),
372 wsc_context_input_panel_layout_variation_get (wsc_ctx), wsc_context_autocapital_type_get (wsc_ctx), wsc_ctx->return_key_disabled,
373 (Ecore_IMF_Input_Panel_Return_Key_Type)wsc_ctx->return_key_type);
378 _wsc_im_ctx_return_key_disabled (void *data, struct wl_input_method_context *im_ctx, uint32_t disabled)
380 WSCContextISF *wsc_ctx = (WSCContextISF*)data;
381 Eina_Bool return_key_disabled = !!disabled;
383 LOGD ("im_context = %p return key disabled = %d", im_ctx, return_key_disabled);
384 if (!wsc_ctx) return;
386 if (wsc_ctx->return_key_disabled != return_key_disabled) {
387 wsc_ctx->return_key_disabled = return_key_disabled;
388 isf_wsc_context_input_panel_return_key_disabled_set (wsc_ctx, wsc_ctx->return_key_disabled);
390 isf_wsc_context_send_entry_metadata (wsc_ctx, wsc_context_input_hint_get (wsc_ctx), wsc_context_input_panel_layout_get (wsc_ctx),
391 wsc_context_input_panel_layout_variation_get (wsc_ctx), wsc_context_autocapital_type_get (wsc_ctx), wsc_ctx->return_key_disabled,
392 (Ecore_IMF_Input_Panel_Return_Key_Type)wsc_ctx->return_key_type);
397 _wsc_im_ctx_input_panel_data (void *data, struct wl_input_method_context *im_ctx, const char *input_panel_data, uint32_t input_panel_data_length)
399 WSCContextISF *wsc_ctx = (WSCContextISF*)data;
400 LOGD ("im_context = %p input panel data = %s len = %d", im_ctx, input_panel_data, input_panel_data_length);
401 if (!wsc_ctx) return;
404 if (wsc_ctx->impl->imdata) {
405 free(wsc_ctx->impl->imdata);
408 wsc_ctx->impl->imdata = calloc(1, input_panel_data_length);
409 if (wsc_ctx->impl->imdata)
410 memcpy(wsc_ctx->impl->imdata, input_panel_data, input_panel_data_length);
412 wsc_ctx->impl->imdata_size = input_panel_data_length;
415 isf_wsc_context_input_panel_imdata_set (wsc_ctx, (void *)input_panel_data, input_panel_data_length);
419 _wsc_im_ctx_bidi_direction (void *data, struct wl_input_method_context *im_ctx, uint32_t bidi_direction)
421 WSCContextISF *wsc_ctx = (WSCContextISF*)data;
423 LOGD ("im_context = %p bidi_direction = %d", im_ctx, bidi_direction);
424 if (!wsc_ctx) return;
426 if (wsc_ctx->bidi_direction != bidi_direction) {
427 wsc_ctx->bidi_direction = bidi_direction;
429 isf_wsc_context_bidi_direction_set (wsc_ctx, (Ecore_IMF_BiDi_Direction)wsc_ctx->bidi_direction);
434 _wsc_im_ctx_cursor_position (void *data, struct wl_input_method_context *im_ctx, uint32_t cursor_pos)
436 WSCContextISF *wsc_ctx = (WSCContextISF*)data;
438 LOGD ("im_context = %p cursor_pos = %d", im_ctx, cursor_pos);
439 if (!wsc_ctx || !wsc_ctx->impl) return;
440 wsc_ctx->impl->cursor_pos = cursor_pos;
441 wsc_ctx->surrounding_cursor = cursor_pos;
442 LOGD ("wsc_ctx->surrounding_cursor = %d", wsc_ctx->surrounding_cursor);
443 g_info_manager->socket_update_cursor_position (cursor_pos);
446 remote_surrounding_get (wsc_ctx);
450 _wsc_im_ctx_process_input_device_event (void *data, struct wl_input_method_context *im_ctx, uint32_t type, const char *input_data, uint32_t input_data_len)
452 WSCContextISF *wsc_ctx = (WSCContextISF*)data;
454 LOGD("im_context = %p type = %d, data = (%p) %d", im_ctx, type, input_data, input_data_len);
455 if (!wsc_ctx) return;
457 isf_wsc_context_process_input_device_event (wsc_ctx, type, input_data, input_data_len);
461 _wsc_im_ctx_filter_key_event (void *data, struct wl_input_method_context *im_ctx, uint32_t serial, uint32_t time, const char *keyname, uint32_t state, uint32_t modifiers, const char *dev_name, uint32_t dev_class, uint32_t dev_subclass, uint32_t keycode)
463 WSCContextISF *wsc_ctx = (WSCContextISF*)data;
464 if (!wsc_ctx) return;
466 #if !(ENABLE_GRAB_KEYBOARD)
467 isf_wsc_context_filter_key_event (wsc_ctx, serial, time, keyname,
468 ((wl_keyboard_key_state)state) == WL_KEYBOARD_KEY_STATE_PRESSED, modifiers, dev_name, dev_class, dev_subclass, keycode);
473 _wsc_im_ctx_capital_mode (void *data, struct wl_input_method_context *im_ctx, uint32_t mode)
475 LOGD ("capital mode %d", mode);
476 WSCContextISF *wsc_ctx = (WSCContextISF*)data;
477 if (!wsc_ctx) return;
478 wsc_ctx->caps_mode = mode;
479 isf_wsc_context_input_panel_caps_mode_set (wsc_ctx, mode);
483 _wsc_im_ctx_prediction_hint (void *data, struct wl_input_method_context *im_ctx, const char *prediction_hint)
485 WSCContextISF *wsc_ctx = (WSCContextISF*)data;
487 LOGD ("im_context = %p, prediction hint = %s", im_ctx, prediction_hint);
488 if (!wsc_ctx) return;
490 isf_wsc_context_input_panel_prediction_hint_set (wsc_ctx, prediction_hint);
494 _wsc_im_ctx_mime_type (void *data, struct wl_input_method_context *im_ctx, const char *mime_type)
496 WSCContextISF *wsc_ctx = (WSCContextISF*)data;
498 LOGD ("im_context = %p, mime_type = %s", im_ctx, mime_type);
499 if (!wsc_ctx) return;
502 wsc_ctx->impl->mime_type = String (mime_type);
505 isf_wsc_context_input_panel_mime_type_accept_set (wsc_ctx, mime_type);
509 _wsc_im_ctx_finalized_content (void *data, struct wl_input_method_context *im_ctx, const char *text, uint32_t cursor_pos)
511 WSCContextISF *wsc_ctx = (WSCContextISF*)data;
513 SECURE_LOGD ("im_context = %p, text = %s, cursor_pos = %d", im_ctx, text, cursor_pos);
514 if (!wsc_ctx) return;
516 isf_wsc_context_input_panel_finalize_content (wsc_ctx, text, cursor_pos);
520 _wsc_im_ctx_prediction_hint_data (void *data, struct wl_input_method_context *im_ctx, const char *key, const char * value)
522 WSCContextISF *wsc_ctx = (WSCContextISF*)data;
523 if (!wsc_ctx) return;
525 isf_wsc_context_input_panel_prediction_hint_data_set (wsc_ctx, key, value);
528 static const struct wl_input_method_context_listener wsc_im_context_listener = {
530 _wsc_im_ctx_content_type,
531 _wsc_im_ctx_invoke_action,
532 _wsc_im_ctx_commit_state,
533 _wsc_im_ctx_preferred_language,
534 _wsc_im_ctx_return_key_type,
535 _wsc_im_ctx_return_key_disabled,
536 _wsc_im_ctx_input_panel_data,
537 _wsc_im_ctx_bidi_direction,
538 _wsc_im_ctx_cursor_position,
539 _wsc_im_ctx_process_input_device_event,
540 _wsc_im_ctx_filter_key_event,
541 _wsc_im_ctx_capital_mode,
542 _wsc_im_ctx_prediction_hint,
543 _wsc_im_ctx_mime_type,
544 _wsc_im_ctx_finalized_content,
545 _wsc_im_ctx_prediction_hint_data
548 #if ENABLE_GRAB_KEYBOARD
550 _init_keysym2keycode (WSCContextISF *wsc_ctx)
555 const xkb_keysym_t *syms;
557 if (!wsc_ctx || !wsc_ctx->state)
560 for (i = 0; i < 256; i++) {
562 num_syms = xkb_key_get_syms (wsc_ctx->state, code, &syms);
565 wsc_ctx->_keysym2keycode[syms[0]] = i;
570 _fini_keysym2keycode (WSCContextISF *wsc_ctx)
572 wsc_ctx->_keysym2keycode.clear ();
576 _wsc_im_keyboard_keymap (void *data,
577 struct wl_keyboard *wl_keyboard,
582 WSCContextISF *wsc_ctx = (WSCContextISF*)data;
590 _fini_keysym2keycode (wsc_ctx);
592 if (wsc_ctx->state) {
593 xkb_state_unref (wsc_ctx->state);
594 wsc_ctx->state = NULL;
597 if (wsc_ctx->keymap) {
598 xkb_map_unref (wsc_ctx->keymap);
599 wsc_ctx->keymap = NULL;
602 if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) {
607 map_str = (char*)mmap (NULL, size, PROT_READ, MAP_SHARED, fd, 0);
608 if (map_str == MAP_FAILED) {
614 xkb_map_new_from_string (wsc_ctx->xkb_context,
616 XKB_KEYMAP_FORMAT_TEXT_V1,
617 (xkb_keymap_compile_flags)0);
619 munmap (map_str, size);
622 if (!wsc_ctx->keymap) {
623 LOGW ("failed to compile keymap");
627 wsc_ctx->state = xkb_state_new (wsc_ctx->keymap);
628 if (!wsc_ctx->state) {
629 LOGW ("failed to create XKB state");
630 xkb_map_unref (wsc_ctx->keymap);
634 wsc_ctx->control_mask =
635 1 << xkb_map_mod_get_index (wsc_ctx->keymap, "Control");
637 1 << xkb_map_mod_get_index (wsc_ctx->keymap, "Mod1");
638 wsc_ctx->shift_mask =
639 1 << xkb_map_mod_get_index (wsc_ctx->keymap, "Shift");
641 LOGD ("create _keysym2keycode");
642 _init_keysym2keycode (wsc_ctx);
646 _wsc_im_keyboard_key (void *data,
647 struct wl_keyboard *wl_keyboard,
653 WSCContextISF *wsc_ctx = (WSCContextISF*)data;
656 const xkb_keysym_t *syms;
658 char keyname[64] = {0};
659 enum wl_keyboard_key_state state = (wl_keyboard_key_state)state_w;
661 if (!wsc_ctx || !wsc_ctx->state)
665 num_syms = xkb_key_get_syms (wsc_ctx->state, code, &syms);
667 sym = XKB_KEY_NoSymbol;
670 xkb_keysym_get_name (sym, keyname, 64);
673 isf_wsc_context_filter_key_event (wsc_ctx, serial, time, code, sym, keyname,
678 _wsc_im_keyboard_modifiers (void *data,
679 struct wl_keyboard *wl_keyboard,
681 uint32_t mods_depressed,
682 uint32_t mods_latched,
683 uint32_t mods_locked,
686 WSCContextISF *wsc_ctx = (WSCContextISF*)data;
687 if (!wsc_ctx || !wsc_ctx->state)
690 struct wl_input_method_context *context = wsc_ctx->im_ctx;
693 xkb_state_update_mask (wsc_ctx->state, mods_depressed,
694 mods_latched, mods_locked, 0, 0, group);
695 mask = xkb_state_serialize_mods (wsc_ctx->state,
696 (xkb_state_component)(XKB_STATE_DEPRESSED | XKB_STATE_LATCHED));
698 wsc_ctx->modifiers = 0;
699 if (mask & wsc_ctx->control_mask)
700 wsc_ctx->modifiers |= SCIM_KEY_ControlMask;
701 if (mask & wsc_ctx->alt_mask)
702 wsc_ctx->modifiers |= SCIM_KEY_AltMask;
703 if (mask & wsc_ctx->shift_mask)
704 wsc_ctx->modifiers |= SCIM_KEY_ShiftMask;
706 wl_input_method_context_modifiers (context, serial,
707 mods_depressed, mods_depressed,
708 mods_latched, group);
711 static const struct wl_keyboard_listener wsc_im_keyboard_listener = {
712 _wsc_im_keyboard_keymap,
715 _wsc_im_keyboard_key,
716 _wsc_im_keyboard_modifiers
723 if (!_wl_im_ctx || !_wl_im_ctx->wsc || !_wl_im_ctx->wsc->wsc_ctx)
726 WSCContextISF *wsc_ctx = _wl_im_ctx->wsc->wsc_ctx;
728 if (_wl_im_ctx->need_focus_event)
729 isf_wsc_context_focus_out (wsc_ctx);
731 #if ENABLE_GRAB_KEYBOARD
732 if (wsc_ctx->keyboard) {
733 wl_keyboard_destroy (wsc_ctx->keyboard);
734 wsc_ctx->keyboard = NULL;
737 _fini_keysym2keycode (wsc_ctx);
739 if (wsc_ctx->state) {
740 xkb_state_unref (wsc_ctx->state);
741 wsc_ctx->state = NULL;
744 if (wsc_ctx->keymap) {
745 xkb_map_unref (wsc_ctx->keymap);
746 wsc_ctx->keymap = NULL;
749 if (wsc_ctx->xkb_context) {
750 xkb_context_unref (wsc_ctx->xkb_context);
751 wsc_ctx->xkb_context = NULL;
755 if (wsc_ctx->im_ctx) {
756 LOGD("destroy wl_input_method_context : %p", wsc_ctx->im_ctx);
757 wl_input_method_context_destroy (wsc_ctx->im_ctx);
758 wsc_ctx->im_ctx = NULL;
761 if (wsc_ctx->preedit_str) {
762 free (wsc_ctx->preedit_str);
763 wsc_ctx->preedit_str = NULL;
766 if (wsc_ctx->surrounding_text) {
767 free (wsc_ctx->surrounding_text);
768 wsc_ctx->surrounding_text = NULL;
771 if (wsc_ctx->remote_surrounding_text) {
772 free (wsc_ctx->remote_surrounding_text);
773 wsc_ctx->remote_surrounding_text = NULL;
776 if (wsc_ctx->language) {
777 free (wsc_ctx->language);
778 wsc_ctx->language = NULL;
781 wsc_ctx->layout_initialized = EINA_FALSE;
782 wsc_ctx->prediction_allow_initialized = EINA_FALSE;
783 wsc_ctx->autocapital_type_initialized = EINA_FALSE;
784 wsc_ctx->language_initialized = EINA_FALSE;
786 if (_resource_check_timer)
787 ecore_timer_del (_resource_check_timer);
788 _resource_check_timer = NULL;
790 isf_wsc_context_del (wsc_ctx);
792 _wl_im_ctx->wsc->wsc_ctx = NULL;
793 _wl_im_ctx->input_method = NULL;
794 _wl_im_ctx->im_ctx = NULL;
795 _wl_im_ctx->need_focus_event = EINA_FALSE;
796 _need_wl_im_init = false;
800 _wsc_im_activate (void *data, struct wl_input_method *input_method, struct wl_input_method_context *im_ctx, uint32_t text_input_id, uint32_t focus_in_event)
802 struct weescim *wsc = (weescim*)data;
805 WSCContextISF *wsc_ctx = new WSCContextISF;
810 if (_need_wl_im_init) {
811 LOGD("destroy wl_input_method_context");
815 #if ENABLE_GRAB_KEYBOARD
816 wsc_ctx->xkb_context = xkb_context_new ((xkb_context_flags)0);
817 if (wsc_ctx->xkb_context == NULL) {
818 LOGW ("Failed to create XKB context");
822 wsc_ctx->state = NULL;
823 wsc_ctx->keymap = NULL;
824 wsc_ctx->modifiers = 0;
827 wsc_ctx->id = text_input_id;
828 wsc->wsc_ctx = wsc_ctx;
830 wsc_ctx->surrounding_text = NULL;
831 wsc_ctx->remote_surrounding_text = NULL;
832 wsc_ctx->surrounding_cursor = 0;
833 LOGD("inputmethod : %p, im context : %p, surrounding_cursor = %d", input_method, im_ctx, wsc_ctx->surrounding_cursor);
835 wsc_ctx->preedit_str = strdup ("");
836 wsc_ctx->content_hint = WL_TEXT_INPUT_CONTENT_HINT_NONE;
837 wsc_ctx->content_purpose = WL_TEXT_INPUT_CONTENT_PURPOSE_NORMAL;
839 wsc_ctx->im_ctx = im_ctx;
840 wl_input_method_context_add_listener (im_ctx, &wsc_im_context_listener, wsc_ctx);
842 #if ENABLE_GRAB_KEYBOARD
843 wsc_ctx->keyboard = wl_input_method_context_grab_keyboard (im_ctx);
844 if (wsc_ctx->keyboard)
845 wl_keyboard_add_listener (wsc_ctx->keyboard, &wsc_im_keyboard_listener, wsc_ctx);
848 if (wsc_ctx->language)
849 wl_input_method_context_language (im_ctx, wsc_ctx->serial, wsc_ctx->language);
851 isf_wsc_context_add (wsc_ctx);
853 if (focus_in_event) {
854 isf_wsc_context_focus_in (wsc_ctx);
855 _wl_im_ctx->need_focus_event = EINA_TRUE;
860 _wsc_im_deactivate (void *data, struct wl_input_method *input_method, struct wl_input_method_context *im_ctx, uint32_t focus_out_event)
862 struct weescim *wsc = (weescim*)data;
863 if (!wsc || !wsc->wsc_ctx) return;
865 LOGD("inputmethod : %p, im ctx : %p, focus out : %d", input_method, im_ctx, focus_out_event);
867 /* When the focus_in/input_panel_shutdown event is called,
868 * it is not possible to know the information of wl_input_method to destroy */
869 _wl_im_ctx->wsc = wsc;
870 _wl_im_ctx->input_method = input_method;
871 _wl_im_ctx->im_ctx = im_ctx;
872 _need_wl_im_init = true;
874 if (focus_out_event) {
875 isf_wsc_context_focus_out (wsc->wsc_ctx);
876 _wl_im_ctx->need_focus_event = EINA_FALSE;
878 wsc->wsc_ctx->input_panel_shown_once = EINA_FALSE;
882 _wsc_im_destroy (void *data, struct wl_input_method *input_method, struct wl_input_method_context *im_ctx)
884 struct weescim *wsc = (weescim*)data;
885 if (!wsc || !wsc->wsc_ctx) return;
887 LOGD("inputmethod : %p, im ctx : %p", input_method, im_ctx);
889 _wl_im_ctx->wsc = wsc;
890 _wl_im_ctx->input_method = input_method;
891 _wl_im_ctx->im_ctx = im_ctx;
894 g_info_manager->request_ise_terminate();
898 _wsc_im_show_input_panel (void *data, struct wl_input_method *input_method, struct wl_input_method_context *im_ctx, uint32_t angle)
900 struct weescim *wsc = (weescim*)data;
901 if (!wsc || !wsc->wsc_ctx) return;
903 wsc->wsc_ctx->angle = angle;
904 isf_wsc_context_input_panel_show (wsc->wsc_ctx);
905 wsc->wsc_ctx->input_panel_shown_once = EINA_TRUE;
908 remote_surrounding_get (wsc->wsc_ctx);
912 _wsc_im_hide_input_panel (void *data, struct wl_input_method *input_method, struct wl_input_method_context *im_ctx)
914 struct weescim *wsc = (weescim*)data;
915 if (!wsc || !wsc->wsc_ctx) return;
917 LOGD("inputmethod : %p, im ctx : %p", input_method, im_ctx);
919 isf_wsc_context_input_panel_hide (wsc->wsc_ctx);
922 static const struct wl_input_method_listener wsc_im_listener = {
926 _wsc_im_show_input_panel,
927 _wsc_im_hide_input_panel
931 _wsc_setup (struct weescim *wsc)
933 Eina_Iterator *globals = NULL;
934 struct wl_registry *registry = NULL;
935 Ecore_Wl2_Global *global = NULL;
937 if (!wsc) return false;
939 Ecore_Wl2_Display *wl2_display = ecore_wl2_display_connect (NULL);
941 LOGW ("failed to connect");
945 if (!(registry = ecore_wl2_display_registry_get (wl2_display))) {
946 LOGW ("failed to get wl_registry");
950 if (!(globals = ecore_wl2_display_globals_get (wl2_display))) {
951 LOGW ("failed to get wl_globals");
955 EINA_ITERATOR_FOREACH(globals, global) {
956 if (strcmp (global->interface, "wl_input_method") == 0)
957 wsc->im = (wl_input_method*)wl_registry_bind (registry, global->id, &wl_input_method_interface, 1);
958 else if (strcmp (global->interface, "wl_input_method_manager") == 0)
959 _im_manager = (wl_input_method_manager*)wl_registry_bind (registry, global->id, &wl_input_method_manager_interface, 1);
961 eina_iterator_free (globals);
963 if (wsc->im == NULL) {
964 LOGW ("Failed because wl_input_method is null");
968 /* Input method listener */
969 LOGD ("Adding wl_input_method listener");
972 wl_input_method_add_listener (wsc->im, &wsc_im_listener, wsc);
974 LOGW ("Couldn't get wayland input method interface");
982 //////////////////////////////wayland_panel_agent_module end//////////////////////////////////////////////////
991 get_panel_client_id (void)
993 return _panel_client_id;
997 get_language (char **language)
999 *language = strdup (_language.c_str ());
1007 struct timezone tz; /* is not used since ages */
1008 gettimeofday (&tv, &tz);
1009 tint = (unsigned int)(tv.tv_sec * 1000);
1010 tint = tint / 1000 * 1000;
1011 tint = (unsigned int)(tint + tv.tv_usec / 1000);
1015 /* Function Implementations */
1016 static WSCContextISFImpl *
1017 new_ic_impl (WSCContextISF *parent)
1019 WSCContextISFImpl *impl = NULL;
1021 if (_free_ic_impl_list != NULL) {
1022 impl = _free_ic_impl_list;
1023 _free_ic_impl_list = _free_ic_impl_list->next;
1025 impl = new WSCContextISFImpl;
1030 impl->next = _used_ic_impl_list;
1031 _used_ic_impl_list = impl;
1033 impl->parent = parent;
1039 delete_ic_impl (WSCContextISFImpl *impl)
1041 WSCContextISFImpl *rec = _used_ic_impl_list, *last = 0;
1043 for (; rec != 0; last = rec, rec = rec->next) {
1046 last->next = rec->next;
1048 _used_ic_impl_list = rec->next;
1050 rec->next = _free_ic_impl_list;
1051 _free_ic_impl_list = rec;
1058 rec->imdata_size = 0;
1060 rec->mime_type = String ();
1061 rec->surrounding_text = WideString ();
1062 rec->preedit_string = WideString ();
1063 rec->preedit_attrlist.clear ();
1064 rec->commit_string = WideString ();
1065 rec->block_input_resource = true;
1072 delete_all_ic_impl (void)
1074 WSCContextISFImpl *it = _used_ic_impl_list;
1077 _used_ic_impl_list = it->next;
1079 it = _used_ic_impl_list;
1082 it = _free_ic_impl_list;
1084 _free_ic_impl_list = it->next;
1086 it = _free_ic_impl_list;
1090 static WSCContextISF *
1093 WSCContextISFImpl *rec = _used_ic_impl_list;
1096 if (rec->parent && rec->parent->id == id)
1105 check_valid_ic (WSCContextISF *ic)
1107 if (ic && ic->impl && ic->ctx)
1113 void context_scim_imdata_get (WSCContextISF *wsc_ctx, void *data, int *length, int max_len)
1115 WSCContextISF* context_scim = wsc_ctx;
1117 SCIM_DEBUG_FRONTEND (1) << __FUNCTION__ << "...\n";
1122 if (context_scim && context_scim->impl && context_scim->impl->imdata && data && length) {
1123 if (max_len > context_scim->impl->imdata_size)
1124 max_len = context_scim->impl->imdata_size;
1126 memcpy (data, context_scim->impl->imdata, max_len);
1132 void context_scim_mime_type_get (WSCContextISF *wsc_ctx, char *mime_types, int max_len)
1134 WSCContextISF* context_scim = wsc_ctx;
1136 SCIM_DEBUG_FRONTEND (1) << __FUNCTION__ << "...\n";
1138 if (mime_types && max_len > 0) {
1139 /* Initialize mime_types to have an empty string */
1140 mime_types[0] = '\0';
1141 if (context_scim && context_scim->impl) {
1142 if (!(context_scim->impl->mime_type).empty ()) {
1143 int length = (context_scim->impl->mime_type).length ();
1144 if (max_len > length)
1146 memcpy ((void*)mime_types, (context_scim->impl->mime_type).c_str (), max_len);
1153 insert_text (const char *text, uint32_t offset, const char *insert)
1155 uint32_t tlen = strlen (text), ilen = strlen (insert);
1156 char *new_text = (char*)malloc (tlen + ilen + 1);
1158 if ((unsigned int) tlen < offset)
1160 memcpy (new_text, text, offset);
1161 memcpy (new_text + offset, insert, ilen);
1162 memcpy (new_text + offset + ilen, text + offset, tlen - offset);
1163 new_text[tlen + ilen] = '\0';
1170 change_block_status_timer_cb (void *data)
1172 WSCContextISF* context_scim = static_cast<WSCContextISF*>(data);
1173 if (context_scim && context_scim->impl)
1174 context_scim->impl->block_input_resource = false;
1176 _resource_check_timer = NULL;
1178 return ECORE_CALLBACK_CANCEL;
1182 check_input_resource (WSCContextISF *wsc_ctx, Input_Resource input_res)
1184 WSCContextISF* context_scim = wsc_ctx;
1185 LOGD ("Input resource : %d", input_res);
1186 SCIM_DEBUG_FRONTEND (1) << __FUNCTION__ << "...\n";
1188 if (context_scim && context_scim->impl) {
1189 if (context_scim->impl->input_resource == input_res)
1193 if (context_scim->impl->input_resource != input_res && input_res != INPUT_RESOURCE_NONE)
1194 g_info_manager->remoteinput_callback_input_resource (input_res);
1196 if (context_scim->impl->input_resource == INPUT_RESOURCE_REMOTE && input_res == INPUT_RESOURCE_LOCAL) {
1197 if (context_scim->impl->need_commit_preedit) {
1198 WideString wstr = context_scim->impl->preedit_string;
1199 _hide_preedit_string (context_scim->id, false);
1200 wsc_context_commit_string (context_scim, utf8_wcstombs (wstr).c_str ());
1202 context_scim->impl->need_commit_preedit = false;
1203 context_scim->impl->preedit_string.clear ();
1206 if (_resource_check_timer)
1207 ecore_timer_del (_resource_check_timer);
1208 _resource_check_timer = ecore_timer_add (2.0, change_block_status_timer_cb, context_scim);
1209 context_scim->impl->block_input_resource = true;
1211 context_scim->impl->input_resource = input_res;
1215 /* Public functions */
1217 isf_wsc_context_init (void)
1219 SCIM_DEBUG_FRONTEND (1) << __FUNCTION__ << "...\n";
1222 if (!_scim_initialized) {
1223 _ecore_wl2_init_count = ecore_wl2_init ();
1224 if (_ecore_wl2_init_count > 0) {
1226 _scim_initialized = true;
1227 isf_wsc_input_panel_init ();
1228 //isf_wsc_context_set_hardware_keyboard_mode(context_scim);
1231 LOGE("Failed to initialize Ecore_Wl");
1236 isf_wsc_context_shutdown (void)
1239 SCIM_DEBUG_FRONTEND (1) << __FUNCTION__ << "...\n";
1241 if (_scim_initialized) {
1242 _scim_initialized = false;
1244 isf_wsc_input_panel_shutdown ();
1247 if (_ecore_wl2_init_count > 0) {
1248 Ecore_Wl2_Display *wl2_display = ecore_wl2_connected_display_get (NULL);
1250 ecore_wl2_display_disconnect (wl2_display);
1252 ecore_wl2_shutdown ();
1253 _ecore_wl2_init_count = 0;
1259 isf_wsc_context_add (WSCContextISF *wsc_ctx)
1261 SCIM_DEBUG_FRONTEND (1) << __FUNCTION__ << "...\n";
1263 WSCContextISF* context_scim = wsc_ctx;
1265 if (!context_scim) return;
1266 context_scim->surrounding_text_fd_read_handler = NULL;
1267 context_scim->selection_text_fd_read_handler = NULL;
1268 context_scim->remote_surrounding_text_fd_read_handler = NULL;
1269 context_scim->surrounding_text = NULL;
1270 context_scim->remote_surrounding_text = NULL;
1271 context_scim->selection_text = NULL;
1273 context_scim->impl = new_ic_impl (context_scim);
1274 if (context_scim->impl == NULL) {
1275 std::cerr << "memory allocation failed in " << __FUNCTION__ << "\n";
1279 LOGD ("ctx impl : %p", context_scim->impl);
1281 context_scim->impl->preedit_caret = 0;
1282 context_scim->impl->cursor_x = 0;
1283 context_scim->impl->cursor_y = 0;
1284 context_scim->impl->cursor_pos = -1;
1285 context_scim->impl->cursor_top_y = 0;
1286 context_scim->impl->is_on = true;
1287 context_scim->impl->use_preedit = _on_the_spot;
1288 context_scim->impl->preedit_started = false;
1289 context_scim->impl->need_commit_preedit = false;
1292 context_scim->next = NULL;
1294 context_scim->next = _ic_list;
1295 _ic_list = context_scim;
1297 context_scim->impl->is_on = _config->read (String (SCIM_CONFIG_FRONTEND_IM_OPENED_BY_DEFAULT), context_scim->impl->is_on);
1299 g_info_manager->register_input_context (WAYLAND_MODULE_CLIENT_ID, context_scim->id, "");
1300 set_ic_capabilities (context_scim);
1301 SCIM_DEBUG_FRONTEND (2) << "input context created: id = " << context_scim->id << "\n";
1305 isf_wsc_context_del (WSCContextISF *wsc_ctx)
1307 SCIM_DEBUG_FRONTEND (1) << __FUNCTION__ << "...\n";
1308 if (!_ic_list) return;
1310 WSCContextISF *context_scim = wsc_ctx;
1311 if (!context_scim) return;
1313 LOGD ("ctx impl : %p", context_scim->impl);
1315 if (context_scim->selection_text_fd_read_handler) {
1316 int fd = ecore_main_fd_handler_fd_get (context_scim->selection_text_fd_read_handler);
1319 ecore_main_fd_handler_del (context_scim->selection_text_fd_read_handler);
1320 context_scim->selection_text_fd_read_handler = NULL;
1323 if (context_scim->selection_text) {
1324 free (context_scim->selection_text);
1325 context_scim->selection_text = NULL;
1328 if (context_scim->surrounding_text_fd_read_handler) {
1329 int fd = ecore_main_fd_handler_fd_get (context_scim->surrounding_text_fd_read_handler);
1332 ecore_main_fd_handler_del (context_scim->surrounding_text_fd_read_handler);
1333 context_scim->surrounding_text_fd_read_handler = NULL;
1336 if (context_scim->remote_surrounding_text_fd_read_handler) {
1337 int fd = ecore_main_fd_handler_fd_get (context_scim->remote_surrounding_text_fd_read_handler);
1340 ecore_main_fd_handler_del (context_scim->remote_surrounding_text_fd_read_handler);
1341 context_scim->remote_surrounding_text_fd_read_handler = NULL;
1344 if (context_scim->surrounding_text) {
1345 free (context_scim->surrounding_text);
1346 context_scim->surrounding_text = NULL;
1349 if (context_scim->remote_surrounding_text) {
1350 free (context_scim->remote_surrounding_text);
1351 context_scim->remote_surrounding_text = NULL;
1354 if (context_scim->id != _ic_list->id) {
1355 WSCContextISF * pre = _ic_list;
1356 WSCContextISF * cur = _ic_list->next;
1357 while (cur != NULL) {
1358 if (cur->id == context_scim->id) {
1359 pre->next = cur->next;
1366 _ic_list = _ic_list->next;
1369 if (context_scim->impl) {
1370 if (context_scim == _focused_ic) {
1371 g_info_manager->socket_turn_off ();
1372 g_info_manager->focus_out (WAYLAND_MODULE_CLIENT_ID, context_scim->id);
1375 g_info_manager->remove_input_context (WAYLAND_MODULE_CLIENT_ID, context_scim->id);
1377 if (context_scim->impl) {
1378 delete_ic_impl (context_scim->impl);
1379 context_scim->impl = 0;
1383 if (context_scim == _focused_ic)
1388 isf_wsc_context_focus_in (WSCContextISF *wsc_ctx)
1390 WSCContextISF* context_scim = wsc_ctx;
1394 SCIM_DEBUG_FRONTEND(1) << __FUNCTION__<< "(" << context_scim->id << ")...\n";
1397 if (_focused_ic == context_scim) {
1398 SCIM_DEBUG_FRONTEND(1) << "It's already focused.\n";
1401 SCIM_DEBUG_FRONTEND(1) << "Focus out previous IC first: " << _focused_ic->id << "\n";
1402 isf_wsc_context_focus_out (_focused_ic);
1405 if (_change_keyboard_mode_by_focus_move) {
1406 //if h/w keyboard mode, keyboard mode will be changed to s/w mode when the entry get the focus.
1407 LOGD ("Keyboard mode is changed H/W->S/W because of focus_in.");
1408 isf_wsc_context_set_keyboard_mode (wsc_ctx, TOOLBAR_HELPER_MODE);
1411 if (context_scim && context_scim->impl) {
1412 _focused_ic = context_scim;
1414 context_scim->impl->is_on = _config->read (String (SCIM_CONFIG_FRONTEND_IM_OPENED_BY_DEFAULT), context_scim->impl->is_on);
1415 context_scim->impl->surrounding_text.clear ();
1416 context_scim->impl->preedit_string.clear ();
1417 context_scim->impl->preedit_attrlist.clear ();
1418 context_scim->impl->commit_string.clear ();
1419 context_scim->impl->preedit_caret = 0;
1420 context_scim->impl->preedit_started = false;
1422 g_info_manager->register_input_context (WAYLAND_MODULE_CLIENT_ID, context_scim->id, "");
1424 set_ic_capabilities (context_scim);
1426 //FIXME: modify the parameter ic->impl->si->get_factory_uuid ()
1427 g_info_manager->focus_in (WAYLAND_MODULE_CLIENT_ID, context_scim->id, "");
1428 if (context_scim->impl->is_on) {
1429 g_info_manager->socket_turn_on ();
1430 // _panel_client.hide_preedit_string (context_scim->id);
1431 // _panel_client.hide_aux_string (context_scim->id);
1432 // _panel_client.hide_lookup_table (context_scim->id);
1434 #if 0 //REMOVE_SCIM_LAUNCHER
1435 context_scim->impl->si->set_layout (wsc_context_input_panel_layout_get (wsc_ctx));
1436 context_scim->impl->si->set_prediction_allow (context_scim->impl->prediction_allow);
1438 if (context_scim->impl->imdata)
1439 context_scim->impl->si->set_imdata ((const char*)context_scim->impl->imdata, context_scim->impl->imdata_size);
1441 LOGD ("set autocapital type : %d, ctx : %p", context_scim->impl->autocapital_type, wsc_ctx);
1442 g_info_manager->set_autocapital_type ((int)context_scim->impl->autocapital_type);
1444 g_info_manager->socket_turn_off ();
1447 g_info_manager->get_active_helper_option (WAYLAND_MODULE_CLIENT_ID, _active_helper_option);
1450 g_info_manager->remoteinput_callback_focus_in ();
1452 context_scim->impl->init_remote_entry_metadata = false;
1453 context_scim->impl->init_remote_surrounding_text = false;
1454 context_scim->impl->block_input_resource = false;
1455 context_scim->impl->input_resource = INPUT_RESOURCE_NONE;
1460 isf_wsc_context_focus_out (WSCContextISF *wsc_ctx)
1462 WSCContextISF* context_scim = wsc_ctx;
1464 if (!context_scim) return;
1466 SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "(" << context_scim->id << ")...\n";
1468 if (context_scim && context_scim->impl && context_scim == _focused_ic) {
1469 LOGD ("ctx : %p", wsc_ctx);
1471 if (context_scim->impl->need_commit_preedit) {
1472 _hide_preedit_string (context_scim->id, false);
1474 wsc_context_commit_preedit_string (context_scim);
1475 g_info_manager->socket_reset_input_context (WAYLAND_MODULE_CLIENT_ID, context_scim->id);
1478 context_scim->impl->cursor_pos = -1;
1479 // if (context_scim->impl->shared_si) context_scim->impl->si->reset ();
1480 g_info_manager->focus_out (WAYLAND_MODULE_CLIENT_ID, context_scim->id);
1485 g_info_manager->remoteinput_callback_focus_out ();
1487 context_scim->impl->surrounding_text.clear ();
1488 context_scim->impl->preedit_string.clear ();
1489 context_scim->impl->preedit_attrlist.clear ();
1490 context_scim->impl->commit_string.clear ();
1491 context_scim->impl->preedit_caret = 0;
1492 context_scim->impl->preedit_started = false;
1493 context_scim->impl->need_commit_preedit = false;
1495 context_scim->impl->init_remote_entry_metadata = true;
1496 context_scim->impl->init_remote_surrounding_text = true;
1497 context_scim->impl->block_input_resource = true;
1498 context_scim->impl->input_resource = INPUT_RESOURCE_NONE;
1500 _x_key_event_is_valid = false;
1504 isf_wsc_context_preedit_string_get (WSCContextISF *wsc_ctx, char** str, int *cursor_pos)
1506 SCIM_DEBUG_FRONTEND (1) << __FUNCTION__ << "...\n";
1508 WSCContextISF* context_scim = wsc_ctx;
1510 if (context_scim && context_scim->impl && context_scim->impl->is_on) {
1511 String mbs = utf8_wcstombs (context_scim->impl->preedit_string);
1515 *str = strdup (mbs.c_str ());
1521 //*cursor_pos = context_scim->impl->preedit_caret;
1522 mbs = utf8_wcstombs (
1523 context_scim->impl->preedit_string.substr (0, context_scim->impl->preedit_caret));
1524 *cursor_pos = mbs.length ();
1536 isf_wsc_context_autocapital_type_set (WSCContextISF* wsc_ctx, Ecore_IMF_Autocapital_Type autocapital_type)
1538 SCIM_DEBUG_FRONTEND (1) << __FUNCTION__ << " = " << autocapital_type << "...\n";
1539 WSCContextISF* context_scim = wsc_ctx;
1541 if (context_scim && context_scim->impl && context_scim->impl->autocapital_type != autocapital_type) {
1542 context_scim->impl->autocapital_type = autocapital_type;
1543 if (context_scim == _focused_ic) {
1544 LOGD ("ctx : %p. set autocapital type : %d", wsc_ctx, autocapital_type);
1545 g_info_manager->set_autocapital_type ((int)autocapital_type);
1551 isf_wsc_context_bidi_direction_set (WSCContextISF* wsc_ctx, Ecore_IMF_BiDi_Direction direction)
1553 SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
1555 WSCContextISF *context_scim = wsc_ctx;
1557 if (context_scim && context_scim->impl) {
1558 if (context_scim->impl->bidi_direction != direction) {
1559 context_scim->impl->bidi_direction = direction;
1561 if (context_scim == _focused_ic) {
1562 LOGD ("ctx : %p, bidi direction : %#x", wsc_ctx, direction);
1563 panel_req_update_bidi_direction (context_scim, direction);
1570 isf_wsc_context_send_surrounding_text (WSCContextISF* wsc_ctx, const char *text, int cursor)
1572 SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
1574 WSCContextISF *context_scim = wsc_ctx;
1576 if (!context_scim || !context_scim->impl || !text)
1579 char *conv_text = strdup (utf8_wcstombs (context_scim->impl->surrounding_text).c_str ());
1583 if (!context_scim->impl->init_remote_surrounding_text || strcmp (conv_text, text) != 0 || context_scim->impl->cursor_pos != cursor) {
1584 SECURE_LOGD("remote surrounding text : \"%s\"", text);
1585 context_scim->impl->surrounding_text = utf8_mbstowcs (String (text));
1586 context_scim->impl->cursor_pos = cursor;
1589 if (context_scim->input_panel_shown_once && context_scim->impl->input_resource != INPUT_RESOURCE_REMOTE) {
1590 context_scim->impl->init_remote_surrounding_text = true;
1591 if (context_scim->impl->panel_layout == ECORE_IMF_INPUT_PANEL_LAYOUT_PASSWORD) {
1592 g_info_manager->remoteinput_callback_surrounding_text (String (""), 0);
1595 g_info_manager->remoteinput_callback_surrounding_text (String (text), context_scim->impl->cursor_pos);
1604 isf_wsc_context_send_entry_metadata (WSCContextISF* wsc_ctx, Ecore_IMF_Input_Hints hint,
1605 Ecore_IMF_Input_Panel_Layout layout, int variation,
1606 Ecore_IMF_Autocapital_Type type, int return_key_disabled,
1607 Ecore_IMF_Input_Panel_Return_Key_Type return_key_type)
1609 SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
1611 WSCContextISF *context_scim = wsc_ctx;
1613 if (context_scim && context_scim->impl) {
1614 if (!context_scim->impl->init_remote_entry_metadata || (context_scim->impl->input_hint != hint || context_scim->impl->panel_layout != layout ||
1615 context_scim->impl->variation != variation || context_scim->impl->autocapital_type != type ||
1616 context_scim->impl->return_key_disabled != return_key_disabled || context_scim->impl->return_key_type != return_key_type)) {
1617 if (context_scim->impl->panel_layout != layout || context_scim->impl->variation != variation) {
1618 if (context_scim->impl->input_resource == INPUT_RESOURCE_REMOTE)
1619 context_scim->impl->input_resource = INPUT_RESOURCE_NONE;
1622 context_scim->impl->input_hint = hint;
1623 context_scim->impl->panel_layout = layout;
1624 context_scim->impl->variation = variation;
1625 context_scim->impl->autocapital_type = type;
1626 context_scim->impl->return_key_disabled = return_key_disabled;
1627 context_scim->impl->return_key_type = return_key_type;
1630 g_info_manager->remoteinput_callback_entry_metadata (context_scim->impl->input_hint, context_scim->impl->panel_layout,
1631 context_scim->impl->variation, context_scim->impl->autocapital_type, context_scim->impl->return_key_disabled,
1632 context_scim->impl->return_key_type);
1634 context_scim->impl->init_remote_entry_metadata = true;
1637 remote_surrounding_get (wsc_ctx);
1642 #if ENABLE_GRAB_KEYBOARD
1644 bool is_number_key (const char *str)
1646 if (!str) return false;
1648 int result = atoi (str);
1651 if (!strcmp (str, "0"))
1661 isf_wsc_context_filter_key_event (WSCContextISF* wsc_ctx,
1663 uint32_t timestamp, uint32_t keycode, uint32_t symcode,
1665 enum wl_keyboard_key_state state)
1668 SCIM_DEBUG_FRONTEND (1) << __FUNCTION__ << "...\n";
1671 if (!wsc_ctx) return;
1673 KeyEvent key(symcode, wsc_ctx->modifiers);
1675 bool ignore_key = filter_keys (keyname, SCIM_CONFIG_HOTKEYS_FRONTEND_IGNORE_KEY);
1677 if (state == WL_KEYBOARD_KEY_STATE_RELEASED) {
1678 key.mask = SCIM_KEY_ReleaseMask;
1679 } else if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
1681 /* Hardware input detect code */
1682 if (get_keyboard_mode () == TOOLBAR_HELPER_MODE &&
1684 _support_hw_keyboard_mode &&
1685 strncmp (keyname, "XF86", 4)) {
1686 bool hw_key_detect = false;
1689 if (strcmp (keyname, "Down") &&
1690 strcmp (keyname, "KP_Down") &&
1691 strcmp (keyname, "Up") &&
1692 strcmp (keyname, "KP_Up") &&
1693 strcmp (keyname, "Right") &&
1694 strcmp (keyname, "KP_Right") &&
1695 strcmp (keyname, "Left") &&
1696 strcmp (keyname, "KP_Left") &&
1697 strcmp (keyname, "Return") &&
1698 strcmp (keyname, "Pause") &&
1699 strcmp (keyname, "NoSymbol") &&
1700 !is_number_key (keyname)) {
1701 hw_key_detect = true;
1704 if (key.code != 0x1008ff26 && key.code != 0xFF69) {
1705 /* XF86back, Cancel (Power + Volume down) key */
1706 hw_key_detect = true;
1710 if (hw_key_detect) {
1711 isf_wsc_context_set_keyboard_mode (wsc_ctx, TOOLBAR_KEYBOARD_MODE);
1712 ISF_SAVE_LOG ("Changed keyboard mode from S/W to H/W (code: %x, name: %s)", key.code, keyname);
1713 LOGD ("Hardware keyboard mode, active helper option: %d", _active_helper_option);
1720 if (!_focused_ic || !_focused_ic->impl || !_focused_ic->impl->is_on) {
1723 static uint32 _serial = 0;
1724 g_info_manager->process_key_event (key, ++_serial);
1727 send_wl_key_event (wsc_ctx, key, false);
1732 isf_wsc_context_filter_key_event (WSCContextISF* wsc_ctx,
1734 uint32_t timestamp, const char *keysym,
1735 bool press, uint32_t modifiers,
1736 const char *dev_name, uint32_t dev_class, uint32_t dev_subclass, uint32_t keycode)
1738 SCIM_DEBUG_FRONTEND (1) << __FUNCTION__ << "...\n";
1741 if (!wsc_ctx) return;
1744 LOGD("key is NULL");
1748 String _key(keysym);
1751 if (!scim_string_to_key (key, _key)) {
1752 xkb_keysym_t code = xkb_keysym_from_name(keysym, XKB_KEYSYM_NO_FLAGS);
1753 if (code == XKB_KEY_NoSymbol) {
1754 code = xkb_keysym_from_name(keysym, XKB_KEYSYM_CASE_INSENSITIVE);
1758 scim_set_device_info (key, dev_name ? dev_name : "", dev_class, dev_subclass);
1760 bool ignore_key = filter_keys (keysym, SCIM_CONFIG_HOTKEYS_FRONTEND_IGNORE_KEY);
1762 if (modifiers & MOD_SHIFT_MASK)
1763 key.mask |= SCIM_KEY_ShiftMask;
1764 if (modifiers & MOD_ALT_MASK)
1765 key.mask |= SCIM_KEY_AltMask;
1766 if (modifiers & MOD_CONTROL_MASK)
1767 key.mask |= SCIM_KEY_ControlMask;
1769 if (modifiers & MOD_CAPS_MASK)
1770 key.mask |= SCIM_KEY_CapsLockMask;
1771 if (modifiers & MOD_NUM_MASK)
1772 key.mask |= SCIM_KEY_NumLockMask;
1775 key.mask |= SCIM_KEY_ReleaseMask;
1778 /* Hardware input detect code */
1779 if (get_keyboard_mode () == TOOLBAR_HELPER_MODE &&
1781 _support_hw_keyboard_mode &&
1782 strncmp (keysym, "XF86", 4)) {
1783 bool hw_key_detect = false;
1786 if (strcmp (keysym, "Down") &&
1787 strcmp (keysym, "KP_Down") &&
1788 strcmp (keysym, "Up") &&
1789 strcmp (keysym, "KP_Up") &&
1790 strcmp (keysym, "Right") &&
1791 strcmp (keysym, "KP_Right") &&
1792 strcmp (keysym, "Left") &&
1793 strcmp (keysym, "KP_Left") &&
1794 strcmp (keysym, "Return") &&
1795 strcmp (keysym, "KP_Enter") &&
1796 strcmp (keysym, "Pause") &&
1797 strcmp (keysym, "NoSymbol") &&
1798 key.dev_subclass != ECORE_DEVICE_SUBCLASS_REMOCON) {
1799 hw_key_detect = true;
1802 if (key.code != 0x1008ff26 && key.code != 0xFF69) {
1803 /* XF86back, Cancel (Power + Volume down) key */
1804 hw_key_detect = true;
1808 if (hw_key_detect) {
1809 isf_wsc_context_set_keyboard_mode (wsc_ctx, TOOLBAR_KEYBOARD_MODE);
1810 ISF_SAVE_LOG ("Changed keyboard mode from S/W to H/W (code: %x, key : %s)", key.code, keysym);
1811 LOGD ("Hardware keyboard mode, active helper option: %d", _active_helper_option);
1818 if (!_focused_ic || !_focused_ic->impl || !_focused_ic->impl->is_on) {
1820 } else if (g_info_manager->process_key_event (key, serial, keycode)){
1825 if (!instance.null ())
1826 instance->process_key_event_done (WAYLAND_MODULE_CLIENT_ID, wsc_ctx->id, key, EINA_FALSE, serial);
1831 wsc_commit_preedit (WSCContextISF* wsc_ctx)
1833 char* surrounding_text;
1835 if (!wsc_ctx || !wsc_ctx->preedit_str ||
1836 strlen (wsc_ctx->preedit_str) == 0)
1839 wl_input_method_context_cursor_position (wsc_ctx->im_ctx,
1842 if (strlen (wsc_ctx->preedit_str) > MAX_PREEDIT_BUFSIZE) {
1843 char str_buffer[MAX_PREEDIT_BUFSIZE];
1845 memcpy (str_buffer, wsc_ctx->preedit_str, MAX_PREEDIT_BUFSIZE - 1);
1846 str_buffer[MAX_PREEDIT_BUFSIZE - 1] = '\0';
1847 char *old_preedit_str = wsc_ctx->preedit_str;
1848 wsc_ctx->preedit_str = (char*)realloc (wsc_ctx->preedit_str, sizeof(char) * MAX_PREEDIT_BUFSIZE);
1849 if (wsc_ctx->preedit_str) {
1850 memcpy (wsc_ctx->preedit_str, str_buffer, strlen(str_buffer));
1851 wsc_ctx->preedit_str[MAX_PREEDIT_BUFSIZE - 1] = '\0';
1853 free (old_preedit_str);
1854 LOGE ("realloc failed");
1859 wl_input_method_context_commit_string (wsc_ctx->im_ctx,
1861 wsc_ctx->preedit_str);
1863 if (wsc_ctx->surrounding_text) {
1864 surrounding_text = insert_text (wsc_ctx->surrounding_text,
1865 wsc_ctx->surrounding_cursor,
1866 wsc_ctx->preedit_str);
1868 free (wsc_ctx->surrounding_text);
1869 wsc_ctx->surrounding_text = surrounding_text;
1870 wsc_ctx->surrounding_cursor += strlen (wsc_ctx->preedit_str);
1871 LOGD ("wsc_ctx->surrounding_cursor = %d", wsc_ctx->surrounding_cursor);
1873 wsc_ctx->surrounding_text = strdup (wsc_ctx->preedit_str);
1874 wsc_ctx->surrounding_cursor = strlen (wsc_ctx->preedit_str);
1875 LOGD ("wsc_ctx->surrounding_cursor = %d", wsc_ctx->surrounding_cursor);
1878 if (wsc_ctx->preedit_str)
1879 free (wsc_ctx->preedit_str);
1881 wsc_ctx->preedit_str = strdup ("");
1885 wsc_send_preedit_style (WSCContextISF* wsc_ctx)
1887 if (!wsc_ctx) return;
1888 if (wsc_ctx->impl && wsc_ctx->impl->is_on) {
1889 String mbs = utf8_wcstombs (wsc_ctx->impl->preedit_string);
1891 if (!wsc_ctx->impl->preedit_attrlist.empty ()) {
1892 if (mbs.length ()) {
1893 uint32_t preedit_style = WL_TEXT_INPUT_PREEDIT_STYLE_DEFAULT;
1894 int start_index, end_index;
1895 int wlen = wsc_ctx->impl->preedit_string.length ();
1896 AttributeList::const_iterator i;
1897 bool *attrs_flag = new bool [mbs.length ()];
1899 memset (attrs_flag, 0, mbs.length () * sizeof (bool));
1900 for (i = wsc_ctx->impl->preedit_attrlist.begin ();
1901 i != wsc_ctx->impl->preedit_attrlist.end (); ++i) {
1902 start_index = i->get_start ();
1903 end_index = i->get_end ();
1904 if (end_index <= wlen && start_index < end_index) {
1905 start_index = g_utf8_offset_to_pointer (mbs.c_str (), i->get_start ()) - mbs.c_str ();
1906 end_index = g_utf8_offset_to_pointer (mbs.c_str (), i->get_end ()) - mbs.c_str ();
1907 if (i->get_type () == SCIM_ATTR_DECORATE) {
1908 switch (i->get_value ())
1910 case SCIM_ATTR_DECORATE_UNDERLINE:
1911 preedit_style = WL_TEXT_INPUT_PREEDIT_STYLE_UNDERLINE;
1913 case SCIM_ATTR_DECORATE_REVERSE:
1914 preedit_style = WL_TEXT_INPUT_PREEDIT_STYLE_REVERSE;
1916 case SCIM_ATTR_DECORATE_HIGHLIGHT:
1917 preedit_style = WL_TEXT_INPUT_PREEDIT_STYLE_HIGHLIGHT;
1919 case SCIM_ATTR_DECORATE_BGCOLOR1:
1920 preedit_style = WL_TEXT_INPUT_PREEDIT_STYLE_BGCOLOR1;
1922 case SCIM_ATTR_DECORATE_BGCOLOR2:
1923 preedit_style = WL_TEXT_INPUT_PREEDIT_STYLE_BGCOLOR2;
1925 case SCIM_ATTR_DECORATE_BGCOLOR3:
1926 preedit_style = WL_TEXT_INPUT_PREEDIT_STYLE_BGCOLOR3;
1928 case SCIM_ATTR_DECORATE_BGCOLOR4:
1929 preedit_style = WL_TEXT_INPUT_PREEDIT_STYLE_BGCOLOR4;
1932 preedit_style = WL_TEXT_INPUT_PREEDIT_STYLE_DEFAULT;
1936 wl_input_method_context_preedit_styling (wsc_ctx->im_ctx,
1938 end_index - start_index,
1941 switch (i->get_value ())
1943 case SCIM_ATTR_DECORATE_NONE:
1944 case SCIM_ATTR_DECORATE_UNDERLINE:
1945 case SCIM_ATTR_DECORATE_REVERSE:
1946 case SCIM_ATTR_DECORATE_HIGHLIGHT:
1947 case SCIM_ATTR_DECORATE_BGCOLOR1:
1948 case SCIM_ATTR_DECORATE_BGCOLOR2:
1949 case SCIM_ATTR_DECORATE_BGCOLOR3:
1950 case SCIM_ATTR_DECORATE_BGCOLOR4:
1951 // Record which character has attribute.
1952 for (int pos = start_index; pos < end_index; ++pos)
1953 attrs_flag [pos] = 1;
1958 } else if (i->get_type () == SCIM_ATTR_FOREGROUND) {
1959 SCIM_DEBUG_FRONTEND(4) << "SCIM_ATTR_FOREGROUND\n";
1960 } else if (i->get_type () == SCIM_ATTR_BACKGROUND) {
1961 SCIM_DEBUG_FRONTEND(4) << "SCIM_ATTR_BACKGROUND\n";
1965 // Setting default style for all characters which don't have attribute.
1966 for (unsigned int pos = 0; pos < mbs.length (); ++pos) {
1967 if (!attrs_flag [pos]) {
1968 int begin_pos = pos;
1969 while (pos < mbs.length () && !attrs_flag [pos])
1972 preedit_style = WL_TEXT_INPUT_PREEDIT_STYLE_DEFAULT;
1973 start_index = begin_pos;
1976 wl_input_method_context_preedit_styling (wsc_ctx->im_ctx,
1978 end_index - start_index,
1982 delete [] attrs_flag;
1987 if (wsc_ctx->impl && !wsc_ctx->impl->preedit_attrlist.empty ())
1988 wsc_ctx->impl->preedit_attrlist.clear ();
1993 wsc_send_preedit (WSCContextISF* wsc_ctx, int32_t cursor)
1997 if (!wsc_ctx) return;
1999 uint32_t index = strlen (wsc_ctx->preedit_str);
2004 /* Note : Since the current wayland_immodule implementation does not call
2005 * PREEDIT_CHANGED callback even when preedit_cursor or preedit_style gets updated, for now
2006 * we must update preedit_string also whenever preedit_cursor or preedit_style is updated.
2007 * So the below 3 lines cannot be called separately. */
2008 wsc_send_preedit_style (wsc_ctx);
2009 wl_input_method_context_preedit_cursor (wsc_ctx->im_ctx, index);
2010 wl_input_method_context_preedit_string (wsc_ctx->im_ctx,
2012 wsc_ctx->preedit_str,
2013 utf8_wcstombs (wsc_ctx->impl->commit_string).c_str ());
2016 bool wsc_context_surrounding_get (WSCContextISF *wsc_ctx, char **text, int *cursor_pos)
2022 if (wsc_ctx->surrounding_text)
2023 *text = strdup (wsc_ctx->surrounding_text);
2025 *text = strdup ("");
2029 *cursor_pos = wsc_ctx->surrounding_cursor;
2035 remote_surrounding_text_fd_read_func (void* data, Ecore_Fd_Handler* fd_handler) {
2036 if (fd_handler == NULL || data == NULL)
2037 return ECORE_CALLBACK_RENEW;
2039 WSCContextISF* wsc_ctx = (WSCContextISF*)data;
2041 int fd = ecore_main_fd_handler_fd_get (fd_handler);
2043 return ECORE_CALLBACK_RENEW;
2046 int len = read (fd, buff, sizeof (buff) - 1);
2049 SECURE_LOGD ("remote_surrounding_text : %s, surrounding_cursor : %d", wsc_ctx->remote_surrounding_text, wsc_ctx->surrounding_cursor);
2050 isf_wsc_context_send_surrounding_text (wsc_ctx, wsc_ctx->remote_surrounding_text ? wsc_ctx->remote_surrounding_text : "", wsc_ctx->surrounding_cursor);
2051 } else if (len < 0) {
2055 if (wsc_ctx->remote_surrounding_text == NULL) {
2056 if (len >= (int)sizeof(int)) {
2057 /* Add one byte for terminating NULL character and subtract <int> byte for cursor position */
2058 wsc_ctx->remote_surrounding_text = (char*)malloc (len + 1 - sizeof(int));
2059 if (wsc_ctx->remote_surrounding_text) {
2060 memcpy(&(wsc_ctx->surrounding_cursor), buff, sizeof(int));
2061 memcpy (wsc_ctx->remote_surrounding_text, buff + sizeof(int), len - sizeof(int));
2062 wsc_ctx->remote_surrounding_text[len - sizeof(int)] = '\0';
2063 return ECORE_CALLBACK_RENEW;
2065 LOGE ("malloc failed");
2069 int old_len = strlen (wsc_ctx->remote_surrounding_text);
2070 void * _new = realloc (wsc_ctx->remote_surrounding_text, len + old_len + 1);
2072 wsc_ctx->remote_surrounding_text = (char*)_new;
2073 memcpy (wsc_ctx->remote_surrounding_text + old_len, buff, len);
2074 wsc_ctx->remote_surrounding_text[old_len + len] = '\0';
2075 return ECORE_CALLBACK_RENEW;
2077 LOGE ("realloc failed");
2082 if (wsc_ctx->remote_surrounding_text_fd_read_handler) {
2084 ecore_main_fd_handler_del (wsc_ctx->remote_surrounding_text_fd_read_handler);
2085 wsc_ctx->remote_surrounding_text_fd_read_handler = NULL;
2088 if (wsc_ctx->remote_surrounding_text) {
2089 free (wsc_ctx->remote_surrounding_text);
2090 wsc_ctx->remote_surrounding_text = NULL;
2093 return ECORE_CALLBACK_CANCEL;
2097 remote_surrounding_get (WSCContextISF *wsc_ctx)
2099 if (wsc_ctx && wsc_ctx->im_ctx && wsc_ctx->remote_surrounding_text_fd_read_handler)
2103 if (pipe2(filedes, O_CLOEXEC | O_NONBLOCK) == -1) {
2104 LOGW ("create pipe failed");
2107 LOGD("%d,%d", filedes[0], filedes[1]);
2108 if (wsc_ctx && wsc_ctx->im_ctx) {
2109 wl_input_method_context_get_surrounding_text (wsc_ctx->im_ctx, UINT_MAX, UINT_MAX, filedes[1]);
2110 Ecore_Wl2_Display *wl2_display = ecore_wl2_connected_display_get (NULL);
2112 ecore_wl2_display_flush (wl2_display);
2116 if (wsc_ctx && wsc_ctx->im_ctx) {
2117 if (wsc_ctx->remote_surrounding_text) {
2118 free (wsc_ctx->remote_surrounding_text);
2119 wsc_ctx->remote_surrounding_text = NULL;
2122 wsc_ctx->remote_surrounding_text_fd_read_handler = ecore_main_fd_handler_add (filedes[0], ECORE_FD_READ, remote_surrounding_text_fd_read_func, wsc_ctx, NULL, NULL);
2127 Ecore_IMF_Input_Panel_Layout wsc_context_input_panel_layout_get (WSCContextISF *wsc_ctx)
2129 Ecore_IMF_Input_Panel_Layout layout = ECORE_IMF_INPUT_PANEL_LAYOUT_NORMAL;
2134 switch (wsc_ctx->content_purpose) {
2135 case WL_TEXT_INPUT_CONTENT_PURPOSE_DIGITS:
2136 case WL_TEXT_INPUT_CONTENT_PURPOSE_DIGITS_SIGNED:
2137 case WL_TEXT_INPUT_CONTENT_PURPOSE_DIGITS_DECIMAL:
2138 case WL_TEXT_INPUT_CONTENT_PURPOSE_DIGITS_SIGNEDDECIMAL:
2139 layout = ECORE_IMF_INPUT_PANEL_LAYOUT_NUMBERONLY;
2141 case WL_TEXT_INPUT_CONTENT_PURPOSE_NUMBER:
2142 layout = ECORE_IMF_INPUT_PANEL_LAYOUT_NUMBER;
2144 case WL_TEXT_INPUT_CONTENT_PURPOSE_DATE:
2145 layout = ECORE_IMF_INPUT_PANEL_LAYOUT_MONTH;
2147 case WL_TEXT_INPUT_CONTENT_PURPOSE_TIME:
2148 case WL_TEXT_INPUT_CONTENT_PURPOSE_DATETIME:
2149 layout = ECORE_IMF_INPUT_PANEL_LAYOUT_DATETIME;
2151 case WL_TEXT_INPUT_CONTENT_PURPOSE_PHONE:
2152 layout = ECORE_IMF_INPUT_PANEL_LAYOUT_PHONENUMBER;
2154 case WL_TEXT_INPUT_CONTENT_PURPOSE_URL:
2155 layout = ECORE_IMF_INPUT_PANEL_LAYOUT_URL;
2157 case WL_TEXT_INPUT_CONTENT_PURPOSE_EMAIL:
2158 layout = ECORE_IMF_INPUT_PANEL_LAYOUT_EMAIL;
2160 case WL_TEXT_INPUT_CONTENT_PURPOSE_PASSWORD:
2161 case WL_TEXT_INPUT_CONTENT_PURPOSE_PASSWORD_DIGITS:
2162 layout = ECORE_IMF_INPUT_PANEL_LAYOUT_PASSWORD;
2164 case WL_TEXT_INPUT_CONTENT_PURPOSE_HEX:
2165 layout = ECORE_IMF_INPUT_PANEL_LAYOUT_HEX;
2167 case WL_TEXT_INPUT_CONTENT_PURPOSE_TERMINAL:
2168 layout = ECORE_IMF_INPUT_PANEL_LAYOUT_TERMINAL;
2170 case WL_TEXT_INPUT_CONTENT_PURPOSE_IP:
2171 layout = ECORE_IMF_INPUT_PANEL_LAYOUT_IP;
2173 case WL_TEXT_INPUT_CONTENT_PURPOSE_EMOTICON:
2174 layout = ECORE_IMF_INPUT_PANEL_LAYOUT_EMOTICON;
2176 case WL_TEXT_INPUT_CONTENT_PURPOSE_VOICE:
2177 layout = ECORE_IMF_INPUT_PANEL_LAYOUT_VOICE;
2179 case WL_TEXT_INPUT_CONTENT_PURPOSE_NORMAL:
2180 case WL_TEXT_INPUT_CONTENT_PURPOSE_FILENAME:
2181 case WL_TEXT_INPUT_CONTENT_PURPOSE_NAME:
2183 layout = ECORE_IMF_INPUT_PANEL_LAYOUT_NORMAL;
2190 int wsc_context_input_panel_layout_variation_get (WSCContextISF *wsc_ctx)
2192 int layout_variation = 0;
2195 return layout_variation;
2197 switch (wsc_ctx->content_purpose) {
2198 case WL_TEXT_INPUT_CONTENT_PURPOSE_DIGITS:
2199 layout_variation = ECORE_IMF_INPUT_PANEL_LAYOUT_NUMBERONLY_VARIATION_NORMAL;
2201 case WL_TEXT_INPUT_CONTENT_PURPOSE_DIGITS_SIGNED:
2202 layout_variation = ECORE_IMF_INPUT_PANEL_LAYOUT_NUMBERONLY_VARIATION_SIGNED;
2204 case WL_TEXT_INPUT_CONTENT_PURPOSE_DIGITS_DECIMAL:
2205 layout_variation = ECORE_IMF_INPUT_PANEL_LAYOUT_NUMBERONLY_VARIATION_DECIMAL;
2207 case WL_TEXT_INPUT_CONTENT_PURPOSE_DIGITS_SIGNEDDECIMAL:
2208 layout_variation = ECORE_IMF_INPUT_PANEL_LAYOUT_NUMBERONLY_VARIATION_SIGNED_AND_DECIMAL;
2210 case WL_TEXT_INPUT_CONTENT_PURPOSE_PASSWORD:
2211 layout_variation = ECORE_IMF_INPUT_PANEL_LAYOUT_PASSWORD_VARIATION_NORMAL;
2213 case WL_TEXT_INPUT_CONTENT_PURPOSE_PASSWORD_DIGITS:
2214 layout_variation = ECORE_IMF_INPUT_PANEL_LAYOUT_PASSWORD_VARIATION_NUMBERONLY;
2216 case WL_TEXT_INPUT_CONTENT_PURPOSE_NORMAL:
2217 layout_variation = ECORE_IMF_INPUT_PANEL_LAYOUT_NORMAL_VARIATION_NORMAL;
2219 case WL_TEXT_INPUT_CONTENT_PURPOSE_FILENAME:
2220 layout_variation = ECORE_IMF_INPUT_PANEL_LAYOUT_NORMAL_VARIATION_FILENAME;
2222 case WL_TEXT_INPUT_CONTENT_PURPOSE_NAME:
2223 layout_variation = ECORE_IMF_INPUT_PANEL_LAYOUT_NORMAL_VARIATION_PERSON_NAME;
2226 layout_variation = 0;
2230 return layout_variation;
2233 Ecore_IMF_Autocapital_Type wsc_context_autocapital_type_get (WSCContextISF *wsc_ctx)
2235 Ecore_IMF_Autocapital_Type autocapital_type = ECORE_IMF_AUTOCAPITAL_TYPE_NONE;
2238 return autocapital_type;
2240 if (wsc_ctx->content_hint & WL_TEXT_INPUT_CONTENT_HINT_AUTO_CAPITALIZATION)
2241 autocapital_type = ECORE_IMF_AUTOCAPITAL_TYPE_SENTENCE;
2242 else if (wsc_ctx->content_hint & WL_TEXT_INPUT_CONTENT_HINT_WORD_CAPITALIZATION)
2243 autocapital_type = ECORE_IMF_AUTOCAPITAL_TYPE_WORD;
2244 else if (wsc_ctx->content_hint & WL_TEXT_INPUT_CONTENT_HINT_UPPERCASE)
2245 autocapital_type = ECORE_IMF_AUTOCAPITAL_TYPE_ALLCHARACTER;
2247 autocapital_type = ECORE_IMF_AUTOCAPITAL_TYPE_NONE;
2249 return autocapital_type;
2252 bool wsc_context_input_panel_caps_lock_mode_get (WSCContextISF *wsc_ctx)
2257 if (wsc_ctx->content_hint & WL_TEXT_INPUT_CONTENT_HINT_UPPERCASE)
2263 Ecore_IMF_Input_Panel_Lang wsc_context_input_panel_language_get (WSCContextISF *wsc_ctx)
2265 Ecore_IMF_Input_Panel_Lang language = ECORE_IMF_INPUT_PANEL_LANG_AUTOMATIC;
2270 if (wsc_ctx->content_hint & WL_TEXT_INPUT_CONTENT_HINT_LATIN)
2271 language = ECORE_IMF_INPUT_PANEL_LANG_ALPHABET;
2273 language = ECORE_IMF_INPUT_PANEL_LANG_AUTOMATIC;
2278 bool wsc_context_input_panel_password_mode_get (WSCContextISF *wsc_ctx)
2280 if (wsc_ctx->content_hint & WL_TEXT_INPUT_CONTENT_HINT_PASSWORD)
2283 if (wsc_context_input_panel_layout_get (wsc_ctx) == ECORE_IMF_INPUT_PANEL_LAYOUT_PASSWORD)
2289 Ecore_IMF_Input_Hints wsc_context_input_hint_get (WSCContextISF *wsc_ctx)
2291 int input_hint = ECORE_IMF_INPUT_HINT_NONE;
2294 return (Ecore_IMF_Input_Hints)input_hint;
2296 if (wsc_ctx->content_hint & WL_TEXT_INPUT_CONTENT_HINT_SENSITIVE_DATA)
2297 input_hint |= ECORE_IMF_INPUT_HINT_SENSITIVE_DATA;
2299 input_hint &= ~ECORE_IMF_INPUT_HINT_SENSITIVE_DATA;
2301 if (wsc_ctx->content_hint & WL_TEXT_INPUT_CONTENT_HINT_AUTO_COMPLETION)
2302 input_hint |= ECORE_IMF_INPUT_HINT_AUTO_COMPLETE;
2304 input_hint &= ~ECORE_IMF_INPUT_HINT_AUTO_COMPLETE;
2306 if (wsc_ctx->content_hint & WL_TEXT_INPUT_CONTENT_HINT_MULTILINE)
2307 input_hint |= ECORE_IMF_INPUT_HINT_MULTILINE;
2309 input_hint &= ~ECORE_IMF_INPUT_HINT_MULTILINE;
2312 switch (wsc_ctx->content_hint & WL_TEXT_INPUT_CONTENT_HINT_AUTOFILL_MASK)
2314 case WL_TEXT_INPUT_CONTENT_HINT_AUTOFILL_CREDIT_CARD_EXPIRATION_DATE:
2315 input_hint |= ECORE_IMF_INPUT_HINT_AUTOFILL_CREDIT_CARD_EXPIRATION_DATE;
2317 case WL_TEXT_INPUT_CONTENT_HINT_AUTOFILL_CREDIT_CARD_EXPIRATION_DAY:
2318 input_hint |= ECORE_IMF_INPUT_HINT_AUTOFILL_CREDIT_CARD_EXPIRATION_DAY;
2320 case WL_TEXT_INPUT_CONTENT_HINT_AUTOFILL_CREDIT_CARD_EXPIRATION_MONTH:
2321 input_hint |= ECORE_IMF_INPUT_HINT_AUTOFILL_CREDIT_CARD_EXPIRATION_MONTH;
2323 case WL_TEXT_INPUT_CONTENT_HINT_AUTOFILL_CREDIT_CARD_EXPIRATION_YEAR:
2324 input_hint |= ECORE_IMF_INPUT_HINT_AUTOFILL_CREDIT_CARD_EXPIRATION_YEAR;
2326 case WL_TEXT_INPUT_CONTENT_HINT_AUTOFILL_CREDIT_CARD_NUMBER:
2327 input_hint |= ECORE_IMF_INPUT_HINT_AUTOFILL_CREDIT_CARD_NUMBER;
2329 case WL_TEXT_INPUT_CONTENT_HINT_AUTOFILL_EMAIL_ADDRESS:
2330 input_hint |= ECORE_IMF_INPUT_HINT_AUTOFILL_EMAIL_ADDRESS;
2332 case WL_TEXT_INPUT_CONTENT_HINT_AUTOFILL_PHONE:
2333 input_hint |= ECORE_IMF_INPUT_HINT_AUTOFILL_PHONE;
2335 case WL_TEXT_INPUT_CONTENT_HINT_AUTOFILL_POSTAL_ADDRESS:
2336 input_hint |= ECORE_IMF_INPUT_HINT_AUTOFILL_POSTAL_ADDRESS;
2338 case WL_TEXT_INPUT_CONTENT_HINT_AUTOFILL_POSTAL_CODE:
2339 input_hint |= ECORE_IMF_INPUT_HINT_AUTOFILL_POSTAL_CODE;
2341 case WL_TEXT_INPUT_CONTENT_HINT_AUTOFILL_ID:
2342 input_hint |= ECORE_IMF_INPUT_HINT_AUTOFILL_ID;
2344 case WL_TEXT_INPUT_CONTENT_HINT_AUTOFILL_NAME:
2345 input_hint |= ECORE_IMF_INPUT_HINT_AUTOFILL_NAME;
2349 return (Ecore_IMF_Input_Hints)input_hint;
2352 Eina_Bool wsc_context_prediction_allow_get (WSCContextISF *wsc_ctx)
2357 if (wsc_ctx->content_hint & WL_TEXT_INPUT_CONTENT_HINT_AUTO_COMPLETION)
2363 Ecore_IMF_BiDi_Direction wsc_context_bidi_direction_get (WSCContextISF *wsc_ctx)
2365 return (Ecore_IMF_BiDi_Direction)wsc_ctx->bidi_direction;
2368 void wsc_context_delete_surrounding (WSCContextISF *wsc_ctx, int offset, int len)
2370 LOGD ("offset = %d, len = %d", offset, len);
2375 wl_input_method_context_delete_surrounding_text (wsc_ctx->im_ctx, offset, len);
2378 void wsc_context_set_selection (WSCContextISF *wsc_ctx, int start, int end)
2383 wl_input_method_context_selection_region (wsc_ctx->im_ctx, wsc_ctx->serial, start, end);
2386 void wsc_context_commit_string (WSCContextISF *wsc_ctx, const char *str)
2391 if (wsc_ctx->preedit_str) {
2392 free (wsc_ctx->preedit_str);
2393 wsc_ctx->preedit_str = NULL;
2396 wsc_ctx->preedit_str = strdup (str);
2397 wsc_commit_preedit (wsc_ctx);
2400 void wsc_context_commit_preedit_string (WSCContextISF *wsc_ctx)
2402 char* preedit_str = NULL;
2408 isf_wsc_context_preedit_string_get (wsc_ctx, &preedit_str, &cursor_pos);
2410 if (wsc_ctx->preedit_str) {
2411 free (wsc_ctx->preedit_str);
2412 wsc_ctx->preedit_str = NULL;
2415 wsc_ctx->preedit_str = preedit_str;
2416 wsc_commit_preedit (wsc_ctx);
2419 void wsc_context_send_preedit_string (WSCContextISF *wsc_ctx)
2421 char* preedit_str = NULL;
2427 isf_wsc_context_preedit_string_get (wsc_ctx, &preedit_str, &cursor_pos);
2429 if (wsc_ctx->preedit_str) {
2430 free (wsc_ctx->preedit_str);
2431 wsc_ctx->preedit_str = NULL;
2434 wsc_ctx->preedit_str = preedit_str;
2435 wsc_send_preedit (wsc_ctx, cursor_pos);
2438 void wsc_context_send_key (WSCContextISF *wsc_ctx, uint32_t keysym, uint32_t modifiers, uint32_t time, bool press)
2440 if (!wsc_ctx || !wsc_ctx->im_ctx)
2443 wl_input_method_context_keysym (wsc_ctx->im_ctx, wsc_ctx->serial, time,
2444 keysym, press ? WL_KEYBOARD_KEY_STATE_PRESSED : WL_KEYBOARD_KEY_STATE_RELEASED, modifiers);
2448 set_ic_capabilities (WSCContextISF *ic)
2450 SCIM_DEBUG_FRONTEND (1) << __FUNCTION__ << "...\n";
2452 if (ic && ic->impl) {
2453 unsigned int cap = SCIM_CLIENT_CAP_ALL_CAPABILITIES;
2455 if (!_on_the_spot || !ic->impl->use_preedit)
2456 cap -= SCIM_CLIENT_CAP_ONTHESPOT_PREEDIT;
2458 //FIXME:add this interface
2459 //_info_manager->update_client_capabilities (cap);
2466 /* Panel Request functions. */
2468 panel_req_show_help (WSCContextISF *ic)
2470 SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
2474 help = String (_("Smart Common Input Method platform ")) +
2475 String (SCIM_VERSION) +
2476 String (_("\n(C) 2002-2005 James Su <suzhe@tsinghua.org.cn>\n\n"));
2478 if (ic && ic->impl && ic->impl->si) {
2479 IMEngineFactoryPointer sf = _backend->get_factory (ic->impl->si->get_factory_uuid ());
2481 help += utf8_wcstombs (sf->get_name ());
2482 help += String (_(":\n\n"));
2484 help += utf8_wcstombs (sf->get_help ());
2485 help += String (_("\n\n"));
2487 help += utf8_wcstombs (sf->get_credits ());
2490 g_info_manager->socket_show_help (help);
2493 g_info_manager->remoteinput_callback_focus_out ();
2494 LOGD("Remote control button click");
2499 panel_req_update_bidi_direction (WSCContextISF *ic, int direction)
2501 SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
2504 g_info_manager->update_ise_bidi_direction (WAYLAND_MODULE_CLIENT_ID, direction);
2508 filter_keys (const char *keyname, const char *config_path)
2510 SCIM_DEBUG_FRONTEND (1) << __FUNCTION__ << "...\n";
2514 std::vector <String> keys;
2515 scim_split_string_list (keys, _config->read (String (config_path), String ("")), ',');
2517 for (unsigned int i = 0; i < keys.size (); ++i) {
2518 if (!strcmp (keyname, keys [i].c_str ())) {
2527 panel_initialize (void)
2529 SCIM_DEBUG_FRONTEND (1) << __FUNCTION__ << "...\n";
2530 String display_name;
2532 const char *p = getenv ("DISPLAY");
2533 if (p) display_name = String (p);
2535 g_info_manager->add_client (WAYLAND_MODULE_CLIENT_ID, 2, FRONTEND_CLIENT);
2536 _panel_client_id = WAYLAND_MODULE_CLIENT_ID;
2537 g_info_manager->register_panel_client (_panel_client_id, _panel_client_id);
2538 WSCContextISF* context_scim = _ic_list;
2539 _launch_ise_on_request = scim_global_config_read (String (SCIM_GLOBAL_CONFIG_LAUNCH_ISE_ON_REQUEST), false);
2541 while (context_scim != NULL) {
2542 //FIXME:modify the parameter
2543 g_info_manager->register_input_context (WAYLAND_MODULE_CLIENT_ID, context_scim->id, "");
2545 context_scim = context_scim->next;
2554 panel_finalize (void)
2556 SCIM_DEBUG_FRONTEND (1) << __FUNCTION__ << "...\n";
2558 g_info_manager->del_client (WAYLAND_MODULE_CLIENT_ID);
2562 panel_slot_update_preedit_caret (int context, int caret)
2565 WSCContextISF* ic = find_ic (context);
2566 SCIM_DEBUG_FRONTEND (1) << __FUNCTION__ << " context=" << context << " caret=" << caret << " ic=" << ic << "\n";
2568 if (ic && ic->impl && _focused_ic == ic && ic->impl->preedit_caret != caret) {
2569 ic->impl->preedit_caret = caret;
2570 if (ic->impl->use_preedit) {
2571 if (!ic->impl->preedit_started) {
2572 if (check_valid_ic (ic))
2573 ic->impl->preedit_started = true;
2575 wsc_send_preedit (ic, caret);
2577 g_info_manager->socket_update_preedit_caret (caret);
2583 panel_slot_process_key_event (int context, const KeyEvent &key)
2585 WSCContextISF* ic = find_ic (context);
2586 SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " key=" << key.get_key_string () << " ic=" << ic << "\n";
2588 if (!(ic && ic->impl))
2591 if ((_focused_ic != NULL) && (_focused_ic != ic))
2594 send_wl_key_event (ic, key, false);
2598 panel_slot_commit_string (int context, const WideString &wstr, bool remote_mode)
2601 WSCContextISF* ic = find_ic (context);
2602 SCIM_DEBUG_FRONTEND (1) << __FUNCTION__ << " context=" << context << " str=" << utf8_wcstombs (wstr) << " ic=" << ic << "\n";
2604 if (ic && ic->impl) {
2605 if (_focused_ic != ic)
2609 if (ic->impl->block_input_resource) {
2610 LOGW ("block remote input");
2613 check_input_resource (ic, INPUT_RESOURCE_REMOTE);
2615 if (ic->impl->panel_layout == ECORE_IMF_INPUT_PANEL_LAYOUT_URL)
2616 wsc_context_delete_surrounding (ic, INT_MIN/2, INT_MAX);
2618 wsc_context_commit_string (ic, utf8_wcstombs (wstr).c_str ());
2619 ic->impl->need_commit_preedit = false;
2620 ic->impl->preedit_string.clear ();
2622 check_input_resource (ic, INPUT_RESOURCE_LOCAL);
2623 wsc_context_commit_string (ic, utf8_wcstombs (wstr).c_str ());
2629 panel_slot_forward_key_event (int context, const KeyEvent &key, bool remote_mode)
2632 WSCContextISF* ic = find_ic (context);
2633 SCIM_DEBUG_FRONTEND (1) << __FUNCTION__ << " context=" << context << " key=" << key.get_key_string () << " ic=" << ic << "\n";
2635 if (!(ic && ic->impl))
2638 if ((_focused_ic != NULL) && (_focused_ic != ic))
2642 if (ic->impl->block_input_resource) {
2643 LOGW ("block remote input");
2646 check_input_resource (ic, INPUT_RESOURCE_REMOTE);
2648 check_input_resource (ic, INPUT_RESOURCE_LOCAL);
2651 if (key.get_key_string ().length () >= 116)
2654 send_wl_key_event (ic, key, true);
2658 panel_slot_update_preedit_string (int context, const WideString str, const WideString commit, const AttributeList &attrs, int caret, bool remote_mode)
2661 WSCContextISF* ic = find_ic (context);
2662 SCIM_DEBUG_FRONTEND (1) << __FUNCTION__ << " context=" << context << " caret=" << caret << " ic=" << ic << "\n";
2664 if (ic && ic->impl && _focused_ic == ic) {
2666 if (ic->impl->block_input_resource) {
2667 LOGW ("block remote input");
2670 check_input_resource (ic, INPUT_RESOURCE_REMOTE);
2673 if (!ic->impl->is_on)
2674 ic->impl->is_on = true;
2676 if (ic->impl->preedit_string != str || str.length ()) {
2677 ic->impl->preedit_string = str;
2678 ic->impl->preedit_attrlist = attrs;
2679 ic->impl->commit_string = commit;
2681 if (ic->impl->use_preedit) {
2682 if (!ic->impl->preedit_started) {
2683 if (!check_valid_ic (ic))
2686 ic->impl->preedit_started = true;
2687 ic->impl->need_commit_preedit = true;
2689 if (caret >= 0 && caret <= (int)str.length ())
2690 ic->impl->preedit_caret = caret;
2692 ic->impl->preedit_caret = str.length ();
2694 if (ic->impl->panel_layout == ECORE_IMF_INPUT_PANEL_LAYOUT_URL)
2695 wsc_context_delete_surrounding (ic, INT_MIN/2, INT_MAX);
2697 wsc_context_send_preedit_string (ic);
2699 String _str = utf8_wcstombs (str);
2700 g_info_manager->socket_update_preedit_string (_str, attrs, (uint32)caret);
2707 _show_preedit_string (int context)
2710 WSCContextISF* ic = find_ic (context);
2711 SCIM_DEBUG_FRONTEND (1) << __FUNCTION__ << " context=" << context << "\n";
2713 if (ic && ic->impl && _focused_ic == ic) {
2714 if (!ic->impl->is_on)
2715 ic->impl->is_on = true;
2717 if (ic->impl->use_preedit) {
2718 if (!ic->impl->preedit_started) {
2719 if (check_valid_ic (ic)) {
2720 ic->impl->preedit_started = true;
2721 ic->impl->need_commit_preedit = true;
2725 g_info_manager->socket_show_preedit_string ();
2731 _hide_preedit_string (int context, bool update_preedit)
2733 SCIM_DEBUG_FRONTEND (1) << __FUNCTION__ << "...\n";
2735 WSCContextISF* ic = find_ic (context);
2737 if (ic && ic->impl && _focused_ic == ic) {
2738 if (!ic->impl->is_on)
2739 ic->impl->is_on = true;
2742 if (ic->impl->preedit_string.length ()) {
2743 ic->impl->preedit_string = WideString ();
2744 ic->impl->preedit_caret = 0;
2745 ic->impl->preedit_attrlist.clear ();
2748 ic->impl->commit_string = WideString ();
2749 if (ic->impl->use_preedit) {
2750 if (update_preedit && emit) {
2751 if (!check_valid_ic (ic))
2754 if (ic->impl->preedit_started) {
2755 if (check_valid_ic (ic)) {
2756 ic->impl->preedit_started = false;
2757 ic->impl->need_commit_preedit = false;
2760 wsc_context_send_preedit_string (ic);
2762 g_info_manager->socket_hide_preedit_string ();
2770 LOGD ("Initializing Wayland ISF IMModule...");
2772 // Get system language.
2773 _language = scim_get_locale_language (scim_get_current_locale ());
2775 panel_initialize ();
2781 LOGD ("Finalizing Ecore ISF IMModule...");
2783 SCIM_DEBUG_FRONTEND(2) << "Finalize all IC partially.\n";
2784 while (_used_ic_impl_list) {
2785 // In case in "shared input method" mode,
2786 // all contexts share only one instance,
2787 // so we need point the reference pointer correctly before finalizing.
2789 if (_used_ic_impl_list->si) {
2790 _used_ic_impl_list->si->set_frontend_data (static_cast <void*> (_used_ic_impl_list->parent));
2793 if (_used_ic_impl_list->parent && _used_ic_impl_list->parent->ctx) {
2794 isf_wsc_context_del (_used_ic_impl_list->parent);
2798 delete_all_ic_impl ();
2800 SCIM_DEBUG_FRONTEND(2) << " Releasing Config...\n";
2805 _scim_initialized = false;
2809 static uint32_t _keyname_to_keysym (uint32_t keyname, uint32_t *modifiers)
2814 if ((keyname >= '0' && keyname <= '9') ||
2815 (keyname >= 'a' && keyname <= 'z')) {
2817 } else if (keyname >= 'A' && keyname <= 'Z') {
2818 *modifiers |= MOD_SHIFT_MASK;
2819 return keyname + 32;
2824 *modifiers |= MOD_SHIFT_MASK;
2827 *modifiers |= MOD_SHIFT_MASK;
2830 *modifiers |= MOD_SHIFT_MASK;
2833 *modifiers |= MOD_SHIFT_MASK;
2836 *modifiers |= MOD_SHIFT_MASK;
2839 *modifiers |= MOD_SHIFT_MASK;
2842 *modifiers |= MOD_SHIFT_MASK;
2845 *modifiers |= MOD_SHIFT_MASK;
2848 *modifiers |= MOD_SHIFT_MASK;
2851 *modifiers |= MOD_SHIFT_MASK;
2854 *modifiers |= MOD_SHIFT_MASK;
2857 *modifiers |= MOD_SHIFT_MASK;
2860 *modifiers |= MOD_SHIFT_MASK;
2863 *modifiers |= MOD_SHIFT_MASK;
2866 *modifiers |= MOD_SHIFT_MASK;
2869 *modifiers |= MOD_SHIFT_MASK;
2872 *modifiers |= MOD_SHIFT_MASK;
2875 *modifiers |= MOD_SHIFT_MASK;
2878 *modifiers |= MOD_SHIFT_MASK;
2881 *modifiers |= MOD_SHIFT_MASK;
2888 static bool _check_remote_input_finished (const uint32 keycode, const bool pressed, const bool fake)
2890 if (pressed == false && fake == true && (keycode == SCIM_KEY_Select || keycode == SCIM_KEY_Cancel)) {
2896 static void send_wl_key_event (WSCContextISF *ic, const KeyEvent &key, bool fake)
2898 SCIM_DEBUG_FRONTEND (1) << __FUNCTION__ << "...\n";
2901 uint32_t modifiers = 0;
2906 modifiers |= MOD_Mod5_MASK;
2909 if (key.is_shift_down ())
2910 modifiers |= MOD_SHIFT_MASK;
2911 if (key.is_alt_down ())
2912 modifiers |= MOD_ALT_MASK;
2913 if (key.is_control_down ())
2914 modifiers |= MOD_CONTROL_MASK;
2916 _keyname_to_keysym (key.code, &modifiers);
2919 wsc_context_send_key (ic, key.code, modifiers, time, key.is_key_press ());
2920 if (_check_remote_input_finished (key.code, key.is_key_press (), fake))
2921 ic->impl->input_resource = INPUT_RESOURCE_NONE;
2926 reload_config_callback (const ConfigPointer &config)
2928 SCIM_DEBUG_FRONTEND (1) << __FUNCTION__ << "...\n";
2930 //FIXME:_frontend_hotkey_matcher and _imengine_hotkey_matcher should be added
2931 //_frontend_hotkey_matcher.load_hotkeys (config);
2932 //_imengine_hotkey_matcher.load_hotkeys (config);
2935 scim_string_to_key (key,
2936 config->read (String (SCIM_CONFIG_HOTKEYS_FRONTEND_VALID_KEY_MASK),
2937 String ("Shift+Control+Alt+Lock")));
2939 _valid_key_mask = (key.mask > 0) ? (key.mask) : 0xFFFF;
2940 _valid_key_mask |= SCIM_KEY_ReleaseMask;
2941 // Special treatment for two backslash keys on jp106 keyboard.
2942 _valid_key_mask |= SCIM_KEY_QuirkKanaRoMask;
2944 _on_the_spot = config->read (String (SCIM_CONFIG_FRONTEND_ON_THE_SPOT), _on_the_spot);
2945 //_shared_input_method = config->read (String (SCIM_CONFIG_FRONTEND_SHARED_INPUT_METHOD), _shared_input_method);
2946 _change_keyboard_mode_by_focus_move = scim_global_config_read (String (SCIM_GLOBAL_CONFIG_CHANGE_KEYBOARD_MODE_BY_FOCUS_MOVE), _change_keyboard_mode_by_focus_move);
2947 _support_hw_keyboard_mode = scim_global_config_read (String (SCIM_GLOBAL_CONFIG_SUPPORT_HW_KEYBOARD_MODE), _support_hw_keyboard_mode);
2949 // Get keyboard layout setting
2950 // Flush the global config first, in order to load the new configs from disk.
2951 scim_global_config_flush ();
2953 _keyboard_layout = scim_get_default_keyboard_layout ();
2956 class WaylandPanelAgent: public PanelAgentBase
2958 Connection _config_connection;
2961 WaylandPanelAgent ()
2962 : PanelAgentBase ("wayland") {
2964 ~WaylandPanelAgent () {
2967 bool initialize (InfoManager* info_manager, const String& display, bool resident) {
2969 g_info_manager = info_manager;
2970 isf_wsc_context_init ();
2972 if (!_wsc_setup (&_wsc)) {
2976 _config_connection = _config->signal_connect_reload (slot (reload_config_callback));
2978 _wl_im_ctx = new _wl_im;
2980 LOGW ("Can not create wl_im_ctx");
2986 bool valid (void) const {
2991 if (_need_wl_im_init) {
2992 LOGD("destroy wl_input_method_context");
3001 _config_connection.disconnect ();
3002 isf_wsc_context_shutdown ();
3007 exit (int id, uint32 contextid) {
3008 LOGD ("client id:%d", id);
3013 update_preedit_caret (int id, uint32 context_id, uint32 caret) {
3014 LOGD ("client id:%d", id);
3015 panel_slot_update_preedit_caret (context_id, caret);
3019 socket_helper_key_event (int id, uint32 context_id, int cmd , KeyEvent& key) {
3020 LOGD ("client id:%d", id);
3022 if (cmd == SCIM_TRANS_CMD_PROCESS_KEY_EVENT)
3023 panel_slot_process_key_event (context_id, key);
3025 panel_slot_forward_key_event (context_id, key, false);
3029 commit_string (int id, uint32 context_id, const WideString& wstr) {
3030 LOGD ("client id:%d", id);
3031 panel_slot_commit_string (context_id, wstr, false);
3035 forward_key_event (int id, uint32 context_id, const KeyEvent &key) {
3036 LOGD ("client id:%d", id);
3037 panel_slot_forward_key_event (context_id, key, false);
3041 remote_commit_string (int id, uint32 context_id, const WideString& wstr) {
3042 LOGD ("client id:%d", id);
3043 panel_slot_commit_string (context_id, wstr, true);
3047 remote_update_preedit_string (int id, uint32 context_id, const WideString str, const WideString commit, const AttributeList &attrs, uint32 caret) {
3048 LOGD ("client id:%d", id);
3049 panel_slot_update_preedit_string (context_id, str, commit, attrs, caret, true);
3053 remote_forward_key_event (int id, uint32 context_id, const KeyEvent &key) {
3054 LOGD ("client id:%d", id);
3055 panel_slot_forward_key_event (context_id, key, true);
3059 remote_delete_surrounding_text (int id, uint32 context_id, uint32 offset, uint32 len) {
3060 LOGD ("client id:%d", id);
3063 if (_focused_ic->impl->block_input_resource)
3066 check_input_resource (_focused_ic, INPUT_RESOURCE_REMOTE);
3067 wsc_context_delete_surrounding (_focused_ic, offset, len);
3072 update_ise_input_context (int client, uint32 context, uint32 type, uint32 value) {
3073 if (!_focused_ic || !_focused_ic->im_ctx)
3076 if (type == ECORE_IMF_INPUT_PANEL_LANGUAGE_EVENT) {
3077 WSCContextISF* ic = find_ic (context);
3078 if (ic && ic->language) {
3079 wl_input_method_context_language (_focused_ic->im_ctx, _focused_ic->serial, ic->language);
3082 LOGE("language locale query failed : %p %s", ic, (ic ? ic->language : "NULL"));
3083 wl_input_method_context_language (_focused_ic->im_ctx, _focused_ic->serial, "");
3086 wl_input_method_context_input_panel_event (_focused_ic->im_ctx, _focused_ic->serial, type, value);
3090 update_ise_language_locale (int client, uint32 context, String locale) {
3091 if (!_focused_ic || !_focused_ic->im_ctx)
3094 WSCContextISF* ic = find_ic (context);
3095 if (ic && locale.length() > 0) {
3098 ic->language = NULL;
3100 ic->language = strdup(locale.c_str());
3106 request_help (int id, uint32 context_id) {
3107 LOGD ("client id:%d", id);
3108 panel_slot_request_help (context_id);
3113 request_factory_menu (int id, uint32 context_id) {
3114 LOGD ("client id:%d", id);
3115 panel_slot_request_factory_menu (context_id);
3119 change_factory (int id, uint32 context_id, const String& uuid) {
3120 LOGD ("client id:%d", id);
3121 panel_slot_change_factory (context_id, uuid);
3126 reset_keyboard_ise (int id, uint32 context_id) {
3127 LOGD ("client id:%d", id);
3128 panel_slot_reset_keyboard_ise (context_id);
3133 update_keyboard_ise (int id, uint32 context_id) {
3134 LOGD ("client id:%d", id);
3135 panel_slot_update_keyboard_ise (context_id);
3140 show_preedit_string (int id, uint32 context_id) {
3141 LOGD ("client id:%d", id);
3142 _show_preedit_string (context_id);
3146 hide_preedit_string (int id, uint32 context_id) {
3147 LOGD ("client id:%d", id);
3148 _hide_preedit_string (context_id, true);
3152 update_preedit_string (int id, uint32 context_id, WideString preedit, WideString commit, AttributeList& attrs, uint32 caret) {
3153 LOGD ("client id:%d", id);
3154 SCIM_DEBUG_FRONTEND (1) << __FUNCTION__ << "...\n";
3155 WSCContextISF* ic = find_ic (context_id);
3157 if (ic && ic->impl && _focused_ic == ic) {
3158 if (!ic->impl->is_on)
3159 ic->impl->is_on = true;
3161 check_input_resource (ic, INPUT_RESOURCE_LOCAL);
3163 ic->impl->preedit_string = preedit;
3164 ic->impl->preedit_attrlist = attrs;
3165 ic->impl->commit_string = commit;
3167 if (ic->impl->use_preedit) {
3168 if (!ic->impl->preedit_started) {
3169 if (!check_valid_ic (ic))
3172 ic->impl->preedit_started = true;
3173 ic->impl->need_commit_preedit = true;
3175 if (caret <= preedit.length ())
3176 ic->impl->preedit_caret = caret;
3178 ic->impl->preedit_caret = preedit.length ();
3179 wsc_context_send_preedit_string (ic);
3181 String _str = utf8_wcstombs (preedit);
3182 g_info_manager->socket_update_preedit_string (_str, attrs, (uint32)caret);
3188 recapture_string (int id, uint32 context_id, int offset, int len, WideString preedit, WideString commit, AttributeList& attrs) {
3189 LOGD ("client id:%d", id);
3190 SCIM_DEBUG_FRONTEND (1) << __FUNCTION__ << "...\n";
3191 WSCContextISF* ic = find_ic (context_id);
3192 String preedit_str = utf8_wcstombs (preedit);
3193 String commit_str = utf8_wcstombs (commit);
3195 if (ic && ic->impl && _focused_ic == ic) {
3196 if (!ic->impl->is_on)
3197 ic->impl->is_on = true;
3199 check_input_resource (ic, INPUT_RESOURCE_LOCAL);
3201 ic->impl->preedit_string = preedit;
3202 ic->impl->preedit_attrlist = attrs;
3203 ic->impl->commit_string = commit;
3205 if (ic->impl->use_preedit) {
3206 if (!ic->impl->preedit_started) {
3207 if (!check_valid_ic (ic))
3210 ic->impl->preedit_started = true;
3211 ic->impl->need_commit_preedit = true;
3213 ic->impl->preedit_caret = preedit.length ();
3215 wl_input_method_context_preedit_cursor (ic->im_ctx, strlen(preedit_str.c_str()));
3216 wsc_send_preedit_style (ic);
3218 wl_input_method_context_recapture_string (ic->im_ctx, ic->serial,
3219 offset, len, preedit_str.c_str(), preedit_str.c_str(), commit_str.c_str());
3221 g_info_manager->socket_recapture_string (offset, len, preedit_str, commit_str, attrs);
3227 surrounding_text_fd_read_func (void* data, Ecore_Fd_Handler* fd_handler) {
3228 if (fd_handler == NULL || data == NULL)
3229 return ECORE_CALLBACK_RENEW;
3231 WSCContextISF* wsc_ctx = (WSCContextISF*)data;
3233 int fd = ecore_main_fd_handler_fd_get (fd_handler);
3235 return ECORE_CALLBACK_RENEW;
3238 int len = read (fd, buff, sizeof (buff) - 1);
3240 LOGD ("update, wsc_ctx->surrounding_cursor = %d", wsc_ctx->surrounding_cursor);
3241 g_info_manager->socket_update_surrounding_text (wsc_ctx->surrounding_text ? wsc_ctx->surrounding_text : "", wsc_ctx->surrounding_cursor);
3242 } else if (len < 0) {
3246 if (wsc_ctx->surrounding_text == NULL) {
3247 if (len >= (int)sizeof(int)) {
3248 /* Add one byte for terminating NULL character and subtract <int> byte for cursor position */
3249 wsc_ctx->surrounding_text = (char*)malloc (len + 1 - sizeof(int));
3250 if (wsc_ctx->surrounding_text) {
3251 memcpy(&(wsc_ctx->surrounding_cursor), buff, sizeof(int));
3252 memcpy (wsc_ctx->surrounding_text, buff + sizeof(int), len - sizeof(int));
3253 wsc_ctx->surrounding_text[len - sizeof(int)] = '\0';
3254 return ECORE_CALLBACK_RENEW;
3256 LOGE ("malloc failed");
3260 int old_len = strlen (wsc_ctx->surrounding_text);
3261 void * _new = realloc (wsc_ctx->surrounding_text, len + old_len + 1);
3263 wsc_ctx->surrounding_text = (char*)_new;
3264 memcpy (wsc_ctx->surrounding_text + old_len, buff, len);
3265 wsc_ctx->surrounding_text[old_len + len] = '\0';
3266 return ECORE_CALLBACK_RENEW;
3268 LOGE ("realloc failed");
3273 if (wsc_ctx->surrounding_text_fd_read_handler) {
3275 ecore_main_fd_handler_del (wsc_ctx->surrounding_text_fd_read_handler);
3276 wsc_ctx->surrounding_text_fd_read_handler = NULL;
3279 if (wsc_ctx->surrounding_text) {
3280 free (wsc_ctx->surrounding_text);
3281 wsc_ctx->surrounding_text = NULL;
3284 return ECORE_CALLBACK_RENEW;
3288 socket_helper_get_surrounding_text (int id, uint32 context_id, uint32 maxlen_before, uint32 maxlen_after) {
3289 LOGD ("client id:%d", id);
3292 if (pipe2(filedes, O_CLOEXEC | O_NONBLOCK) == -1) {
3293 LOGW ("create pipe failed");
3296 LOGD("%d,%d", filedes[0], filedes[1]);
3297 WSCContextISF* ic = find_ic (context_id);
3301 wl_input_method_context_get_surrounding_text (ic->im_ctx, maxlen_before, maxlen_after, filedes[1]);
3303 Ecore_Wl2_Display *wl2_display = ecore_wl2_connected_display_get (NULL);
3305 ecore_wl2_display_flush (wl2_display);
3308 if (ic->surrounding_text_fd_read_handler) {
3309 int fd = ecore_main_fd_handler_fd_get (ic->surrounding_text_fd_read_handler);
3312 ecore_main_fd_handler_del (ic->surrounding_text_fd_read_handler);
3313 ic->surrounding_text_fd_read_handler = NULL;
3316 if (ic->surrounding_text) {
3317 free (ic->surrounding_text);
3318 ic->surrounding_text = NULL;
3321 ic->surrounding_text_fd_read_handler = ecore_main_fd_handler_add (filedes[0], ECORE_FD_READ, surrounding_text_fd_read_func, ic, NULL, NULL);
3325 socket_helper_delete_surrounding_text (int id, uint32 context_id, uint32 offset, uint32 len) {
3326 LOGD ("client id:%d", id);
3327 //panel_slot_delete_surrounding_text (context_id, offset, len);
3329 check_input_resource (_focused_ic, INPUT_RESOURCE_LOCAL);
3330 wsc_context_delete_surrounding (_focused_ic, offset, len);
3335 socket_helper_set_selection (int id, uint32 context_id, uint32 start, uint32 end) {
3336 LOGD ("client id:%d", id);
3338 wsc_context_set_selection (_focused_ic, start, end);
3342 send_private_command (int id, uint32 context_id, const String& command) {
3343 LOGD ("client id:%d", id);
3344 //panel_slot_send_private_command (context_id, command);
3345 if (_focused_ic && _focused_ic->im_ctx)
3346 wl_input_method_context_private_command (_focused_ic->im_ctx, _focused_ic->serial, command.c_str ());
3350 commit_content (int id, uint32 context_id, const String& content, const String& description, const String& mime_types) {
3351 LOGD ("client id:%d", id);
3352 if (_focused_ic && _focused_ic->im_ctx)
3353 wl_input_method_context_commit_content (_focused_ic->im_ctx, _focused_ic->serial, content.c_str (), description.c_str (), mime_types.c_str ());
3357 hide_helper_ise (int id, uint32 context_id)
3359 LOGD ("client id:%d", id);
3360 WSCContextISF* ic = find_ic (context_id);
3363 wl_input_method_context_hide_input_panel (ic->im_ctx, ic->serial);
3368 selection_text_fd_read_func (void* data, Ecore_Fd_Handler* fd_handler) {
3369 if (fd_handler == NULL || data == NULL)
3370 return ECORE_CALLBACK_RENEW;
3372 WSCContextISF* wsc_ctx = (WSCContextISF*)data;
3373 int fd = ecore_main_fd_handler_fd_get (fd_handler);
3375 return ECORE_CALLBACK_RENEW;
3378 int len = read (fd, buff, sizeof (buff) - 1);
3381 g_info_manager->socket_update_selection (wsc_ctx->selection_text ? wsc_ctx->selection_text : "");
3382 } else if (len < 0) {
3386 if (wsc_ctx->selection_text == NULL) {
3387 wsc_ctx->selection_text = (char*)malloc (len + 1);
3388 if (wsc_ctx->selection_text) {
3389 memcpy (wsc_ctx->selection_text, buff, len);
3390 wsc_ctx->selection_text[len] = '\0';
3391 return ECORE_CALLBACK_RENEW;
3393 LOGE ("malloc failed");
3396 int old_len = strlen (wsc_ctx->selection_text);
3397 void * _new = realloc (wsc_ctx->selection_text, len + old_len + 1);
3399 wsc_ctx->selection_text = (char*)_new;
3400 memcpy (wsc_ctx->selection_text + old_len, buff, len);
3401 wsc_ctx->selection_text[old_len + len] = '\0';
3402 return ECORE_CALLBACK_RENEW;
3404 LOGE ("realloc failed");
3409 if (wsc_ctx->selection_text_fd_read_handler) {
3411 ecore_main_fd_handler_del (wsc_ctx->selection_text_fd_read_handler);
3412 wsc_ctx->selection_text_fd_read_handler = NULL;
3415 if (wsc_ctx->selection_text) {
3416 free (wsc_ctx->selection_text);
3417 wsc_ctx->selection_text = NULL;
3420 return ECORE_CALLBACK_RENEW;
3424 socket_helper_get_selection (int id, uint32 context_id) {
3425 LOGD ("client id:%d", id);
3428 if (pipe2(filedes, O_CLOEXEC | O_NONBLOCK) ==-1 ) {
3429 LOGW ("create pipe failed");
3432 LOGD("%d,%d", filedes[0], filedes[1]);
3434 WSCContextISF* ic = find_ic (context_id);
3437 wl_input_method_context_get_selection_text (ic->im_ctx, filedes[1]);
3438 Ecore_Wl2_Display *wl2_display = ecore_wl2_connected_display_get (NULL);
3440 ecore_wl2_display_flush (wl2_display);
3443 if (ic->selection_text_fd_read_handler) {
3444 int fd = ecore_main_fd_handler_fd_get (ic->selection_text_fd_read_handler);
3448 ecore_main_fd_handler_del (ic->selection_text_fd_read_handler);
3449 ic->selection_text_fd_read_handler = NULL;
3452 if (ic->selection_text) {
3453 free (ic->selection_text);
3454 ic->selection_text = NULL;
3457 ic->selection_text_fd_read_handler = ecore_main_fd_handler_add (filedes[0], ECORE_FD_READ, selection_text_fd_read_func, ic, NULL, NULL);
3460 void process_key_event_done (int id, uint32 context_id, KeyEvent &key, uint32 ret, uint32 serial) {
3461 LOGD ("client id:%d", id);
3462 WSCContextISF* ic = find_ic (context_id);
3465 #if ENABLE_GRAB_KEYBOARD
3466 if (ret == EINA_FALSE) {
3467 send_wl_key_event (ic, key, false);
3470 wl_input_method_context_filter_key_event_done (ic->im_ctx, serial, ret);
3474 void request_ise_hide (int id, uint32 context_id) {
3475 LOGD ("client id:%d", id);
3476 WSCContextISF* ic = find_ic (context_id);
3479 wl_input_method_context_hide_input_panel (ic->im_ctx, ic->serial);
3483 update_ise_geometry (int id, uint32 context_id, uint32 x, uint32 y, uint32 width, uint32 height) {
3484 LOGD ("client id:%d", id);
3486 if (_focused_ic && _focused_ic->im_ctx) {
3487 wl_input_method_context_update_ise_geometry (_focused_ic->im_ctx, _focused_ic->serial, x, y, width, height);
3491 void helper_candidate_show(int id, uint32 context_id, const String& uuid)
3493 WSCContextISF* ic = find_ic(context_id);
3497 wl_input_method_context_update_candidate_state(ic->im_ctx, 1);
3501 void helper_candidate_hide(int id, uint32 context_id, const String& uuid)
3503 WSCContextISF* ic = find_ic(context_id);
3507 wl_input_method_context_update_candidate_state(ic->im_ctx, 0);
3511 void update_entry_metadata (int id, uint32 context_id) {
3512 LOGD ("client id:%d", id);
3513 WSCContextISF* ic = find_ic(context_id);
3514 if (!ic || !ic->im_ctx) return;
3516 Ecore_IMF_Input_Panel_Layout input_panel_layout = wsc_context_input_panel_layout_get (ic);
3518 if (ic->layout_initialized)
3519 isf_wsc_context_input_panel_layout_set (ic, input_panel_layout);
3521 if (ic->prediction_allow_initialized) {
3522 Eina_Bool prediction_allow = wsc_context_prediction_allow_get (ic);
3523 if (input_panel_layout == ECORE_IMF_INPUT_PANEL_LAYOUT_PASSWORD) {
3524 LOGI ("set prediction allow : FALSE in password layout");
3525 prediction_allow = EINA_FALSE;
3528 g_info_manager->set_prediction_allow (WAYLAND_MODULE_CLIENT_ID, prediction_allow);
3531 if (ic->autocapital_type_initialized)
3532 isf_wsc_context_autocapital_type_set (ic, wsc_context_autocapital_type_get (ic));
3534 if (ic->language_initialized)
3535 isf_wsc_context_input_panel_language_set (ic, wsc_context_input_panel_language_get (ic));
3537 g_info_manager->socket_update_cursor_position (ic->surrounding_cursor);
3538 isf_wsc_context_input_panel_return_key_type_set (ic, (Ecore_IMF_Input_Panel_Return_Key_Type)ic->return_key_type);
3539 isf_wsc_context_input_panel_return_key_disabled_set (ic, ic->return_key_disabled);
3542 isf_wsc_context_input_panel_imdata_set (ic, (void *)ic->impl->imdata, ic->impl->imdata_size);
3544 isf_wsc_context_bidi_direction_set (ic, (Ecore_IMF_BiDi_Direction)ic->bidi_direction);
3545 isf_wsc_context_input_panel_caps_mode_set (ic, ic->caps_mode);
3548 isf_wsc_context_input_panel_mime_type_accept_set (ic, ic->impl->mime_type.c_str ());
3551 isf_wsc_context_send_entry_metadata (ic, wsc_context_input_hint_get (ic), wsc_context_input_panel_layout_get (ic),
3552 wsc_context_input_panel_layout_variation_get (ic), wsc_context_autocapital_type_get (ic), ic->return_key_disabled,
3553 (Ecore_IMF_Input_Panel_Return_Key_Type)ic->return_key_type);
3557 void request_ise_reshow (int id, uint32 context_id) {
3558 LOGD ("client id:%d", id);
3559 WSCContextISF* ic = find_ic (context_id);
3562 wl_input_method_context_reshow_input_panel (ic->im_ctx);
3565 void set_transient_for (uint32 caller_pid, uint32 ime_pid)
3567 LOGI ("caller pid : %u, ime pid : %u", caller_pid, ime_pid);
3570 wl_input_method_manager_set_transient_for (_im_manager, caller_pid, ime_pid);
3572 LOGW ("Failed to get input method manager interface");
3575 void set_floating_mode (int id, uint32 context_id, uint32 floating_mode)
3577 LOGD ("client id:%d", id);
3578 WSCContextISF* ic = find_ic (context_id);
3582 wl_input_method_context_set_floating_panel (ic->im_ctx, floating_mode);
3585 void set_floating_drag_enabled (int id, uint32 context_id, uint32 enabled)
3587 WSCContextISF* ic = find_ic (context_id);
3591 wl_input_method_context_set_floating_drag_enabled (ic->im_ctx, enabled);
3597 EXAPI void scim_module_init (void)
3602 EXAPI void scim_module_exit (void)
3608 EXAPI void scim_panel_agent_module_init (const scim::ConfigPointer& config)
3614 EXAPI scim::PanelAgentPointer scim_panel_agent_module_get_instance ()
3616 scim::PanelAgentBase* _instance = NULL;
3617 if (instance.null ()) {
3619 _instance = new WaylandPanelAgent ();
3626 instance = _instance;
3633 vi:ts=4:nowrap:expandtab