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_SUPER_MASK 0x20
224 #define MOD_NUM_MASK 0x100
225 #define MOD_Mod5_MASK 0x80
227 #define WL_TEXT_INPUT_CONTENT_HINT_AUTOFILL_MASK 0xff0000
229 //////////////////////////////wayland_panel_agent_module begin//////////////////////////////////////////////////
231 #define scim_module_init wayland_LTX_scim_module_init
232 #define scim_module_exit wayland_LTX_scim_module_exit
233 #define scim_panel_agent_module_init wayland_LTX_scim_panel_agent_module_init
234 #define scim_panel_agent_module_get_instance wayland_LTX_scim_panel_agent_module_get_instance
236 static struct weescim _wsc = {0};
238 InfoManager* g_info_manager = NULL;
239 static scim::PanelAgentPointer instance;
242 /////////////////////////////////////////////////////////////////////////////
243 // Implementation of Wayland Input Method functions.
244 /////////////////////////////////////////////////////////////////////////////
247 _wsc_im_ctx_reset (void *data, struct wl_input_method_context *im_ctx)
249 WSCContextISF *context_scim = (WSCContextISF*)data;
251 if (context_scim && context_scim->impl && context_scim == _focused_ic) {
252 g_info_manager->socket_reset_input_context (WAYLAND_MODULE_CLIENT_ID, context_scim->id);
257 _wsc_im_ctx_content_type (void *data, struct wl_input_method_context *im_ctx, uint32_t hint, uint32_t purpose)
259 WSCContextISF *wsc_ctx = (WSCContextISF*)data;
260 if (!wsc_ctx) return;
262 LOGD ("im_context = %p hint = %04x purpose = %d", im_ctx, hint, purpose);
265 if (wsc_ctx->content_purpose != purpose || !wsc_ctx->layout_initialized) {
266 wsc_ctx->layout_initialized = EINA_TRUE;
267 wsc_ctx->content_purpose = purpose;
268 isf_wsc_context_input_panel_layout_set (wsc_ctx, wsc_context_input_panel_layout_get (wsc_ctx));
271 if (wsc_ctx->content_hint != hint) {
272 uint32_t hint_copy, old_hintbit, new_hintbit;
273 const uint32_t autocap_type = WL_TEXT_INPUT_CONTENT_HINT_AUTO_CAPITALIZATION |
274 WL_TEXT_INPUT_CONTENT_HINT_UPPERCASE |
275 WL_TEXT_INPUT_CONTENT_HINT_WORD_CAPITALIZATION;
277 hint_copy = wsc_ctx->content_hint;
278 wsc_ctx->content_hint = hint;
280 // Set prediction allow
281 old_hintbit = hint_copy & WL_TEXT_INPUT_CONTENT_HINT_AUTO_COMPLETION;
282 new_hintbit = hint & WL_TEXT_INPUT_CONTENT_HINT_AUTO_COMPLETION;
283 if (old_hintbit != new_hintbit || !wsc_ctx->prediction_allow_initialized) {
284 wsc_ctx->prediction_allow_initialized = EINA_TRUE;
285 g_info_manager->set_prediction_allow (WAYLAND_MODULE_CLIENT_ID, wsc_context_prediction_allow_get (wsc_ctx));
288 // Set autocapital type
289 old_hintbit = hint_copy & autocap_type;
290 new_hintbit = hint & autocap_type;
291 if (old_hintbit != new_hintbit || !wsc_ctx->autocapital_type_initialized) {
292 wsc_ctx->autocapital_type_initialized = EINA_TRUE;
293 isf_wsc_context_autocapital_type_set (wsc_ctx, wsc_context_autocapital_type_get (wsc_ctx));
297 old_hintbit = hint_copy & WL_TEXT_INPUT_CONTENT_HINT_LATIN;
298 new_hintbit = hint & WL_TEXT_INPUT_CONTENT_HINT_LATIN;
299 if (old_hintbit != new_hintbit || !wsc_ctx->language_initialized) {
300 wsc_ctx->language_initialized = EINA_TRUE;
301 isf_wsc_context_input_panel_language_set (wsc_ctx, wsc_context_input_panel_language_get (wsc_ctx));
304 isf_wsc_context_input_hint_set (wsc_ctx, wsc_context_input_hint_get (wsc_ctx));
308 isf_wsc_context_send_entry_metadata (wsc_ctx, wsc_context_input_hint_get (wsc_ctx), wsc_context_input_panel_layout_get (wsc_ctx),
309 wsc_context_input_panel_layout_variation_get (wsc_ctx), wsc_context_autocapital_type_get (wsc_ctx), wsc_ctx->return_key_disabled,
310 (Ecore_IMF_Input_Panel_Return_Key_Type)wsc_ctx->return_key_type);
315 _wsc_im_ctx_invoke_action (void *data, struct wl_input_method_context *im_ctx, uint32_t button, uint32_t index)
317 WSCContextISF *wsc_ctx = (WSCContextISF*)data;
318 if (!wsc_ctx) return;
320 LOGD ("invoke action. button : %d", button);
322 if (button != BTN_LEFT)
325 wsc_context_send_preedit_string (wsc_ctx);
329 _wsc_im_ctx_commit_state (void *data, struct wl_input_method_context *im_ctx, uint32_t serial)
331 WSCContextISF *wsc_ctx = (WSCContextISF*)data;
332 if (!wsc_ctx) return;
334 wsc_ctx->serial = serial;
336 if (wsc_ctx->language)
337 wl_input_method_context_language (im_ctx, wsc_ctx->serial, wsc_ctx->language);
341 _wsc_im_ctx_preferred_language (void *data, struct wl_input_method_context *im_ctx, const char *language)
343 WSCContextISF *wsc_ctx = (WSCContextISF*)data;
344 if (!wsc_ctx) return;
346 if (language && wsc_ctx->language && !strcmp (language, wsc_ctx->language))
349 if (wsc_ctx->language) {
350 free (wsc_ctx->language);
351 wsc_ctx->language = NULL;
355 wsc_ctx->language = strdup (language);
356 LOGD ("Language changed, new: '%s'", language);
361 _wsc_im_ctx_return_key_type (void *data, struct wl_input_method_context *im_ctx, uint32_t return_key_type)
363 WSCContextISF *wsc_ctx = (WSCContextISF*)data;
365 LOGD ("im_context = %p return key type = %d", im_ctx, return_key_type);
366 if (!wsc_ctx) return;
368 if (wsc_ctx->return_key_type != return_key_type) {
369 wsc_ctx->return_key_type = return_key_type;
370 isf_wsc_context_input_panel_return_key_type_set (wsc_ctx, (Ecore_IMF_Input_Panel_Return_Key_Type)wsc_ctx->return_key_type);
372 isf_wsc_context_send_entry_metadata (wsc_ctx, wsc_context_input_hint_get (wsc_ctx), wsc_context_input_panel_layout_get (wsc_ctx),
373 wsc_context_input_panel_layout_variation_get (wsc_ctx), wsc_context_autocapital_type_get (wsc_ctx), wsc_ctx->return_key_disabled,
374 (Ecore_IMF_Input_Panel_Return_Key_Type)wsc_ctx->return_key_type);
379 _wsc_im_ctx_return_key_disabled (void *data, struct wl_input_method_context *im_ctx, uint32_t disabled)
381 WSCContextISF *wsc_ctx = (WSCContextISF*)data;
382 Eina_Bool return_key_disabled = !!disabled;
384 LOGD ("im_context = %p return key disabled = %d", im_ctx, return_key_disabled);
385 if (!wsc_ctx) return;
387 if (wsc_ctx->return_key_disabled != return_key_disabled) {
388 wsc_ctx->return_key_disabled = return_key_disabled;
389 isf_wsc_context_input_panel_return_key_disabled_set (wsc_ctx, wsc_ctx->return_key_disabled);
391 isf_wsc_context_send_entry_metadata (wsc_ctx, wsc_context_input_hint_get (wsc_ctx), wsc_context_input_panel_layout_get (wsc_ctx),
392 wsc_context_input_panel_layout_variation_get (wsc_ctx), wsc_context_autocapital_type_get (wsc_ctx), wsc_ctx->return_key_disabled,
393 (Ecore_IMF_Input_Panel_Return_Key_Type)wsc_ctx->return_key_type);
398 _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)
400 WSCContextISF *wsc_ctx = (WSCContextISF*)data;
401 LOGD ("im_context = %p input panel data = %s len = %d", im_ctx, input_panel_data, input_panel_data_length);
402 if (!wsc_ctx) return;
405 if (wsc_ctx->impl->imdata) {
406 free(wsc_ctx->impl->imdata);
409 wsc_ctx->impl->imdata = calloc(1, input_panel_data_length);
410 if (wsc_ctx->impl->imdata)
411 memcpy(wsc_ctx->impl->imdata, input_panel_data, input_panel_data_length);
413 wsc_ctx->impl->imdata_size = input_panel_data_length;
416 isf_wsc_context_input_panel_imdata_set (wsc_ctx, (void *)input_panel_data, input_panel_data_length);
420 _wsc_im_ctx_bidi_direction (void *data, struct wl_input_method_context *im_ctx, uint32_t bidi_direction)
422 WSCContextISF *wsc_ctx = (WSCContextISF*)data;
424 LOGD ("im_context = %p bidi_direction = %d", im_ctx, bidi_direction);
425 if (!wsc_ctx) return;
427 if (wsc_ctx->bidi_direction != bidi_direction) {
428 wsc_ctx->bidi_direction = bidi_direction;
430 isf_wsc_context_bidi_direction_set (wsc_ctx, (Ecore_IMF_BiDi_Direction)wsc_ctx->bidi_direction);
435 _wsc_im_ctx_cursor_position (void *data, struct wl_input_method_context *im_ctx, uint32_t cursor_pos)
437 WSCContextISF *wsc_ctx = (WSCContextISF*)data;
439 LOGD ("im_context = %p cursor_pos = %d", im_ctx, cursor_pos);
440 if (!wsc_ctx || !wsc_ctx->impl) return;
441 wsc_ctx->impl->cursor_pos = cursor_pos;
442 wsc_ctx->surrounding_cursor = cursor_pos;
443 LOGD ("wsc_ctx->surrounding_cursor = %d", wsc_ctx->surrounding_cursor);
444 g_info_manager->socket_update_cursor_position (cursor_pos);
447 remote_surrounding_get (wsc_ctx);
451 _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)
453 WSCContextISF *wsc_ctx = (WSCContextISF*)data;
455 LOGD("im_context = %p type = %d, data = (%p) %d", im_ctx, type, input_data, input_data_len);
456 if (!wsc_ctx) return;
458 isf_wsc_context_process_input_device_event (wsc_ctx, type, input_data, input_data_len);
462 _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)
464 WSCContextISF *wsc_ctx = (WSCContextISF*)data;
465 if (!wsc_ctx) return;
467 #if !(ENABLE_GRAB_KEYBOARD)
468 isf_wsc_context_filter_key_event (wsc_ctx, serial, time, keyname,
469 ((wl_keyboard_key_state)state) == WL_KEYBOARD_KEY_STATE_PRESSED, modifiers, dev_name, dev_class, dev_subclass, keycode);
474 _wsc_im_ctx_capital_mode (void *data, struct wl_input_method_context *im_ctx, uint32_t mode)
476 LOGD ("capital mode %d", mode);
477 WSCContextISF *wsc_ctx = (WSCContextISF*)data;
478 if (!wsc_ctx) return;
479 wsc_ctx->caps_mode = mode;
480 isf_wsc_context_input_panel_caps_mode_set (wsc_ctx, mode);
484 _wsc_im_ctx_prediction_hint (void *data, struct wl_input_method_context *im_ctx, const char *prediction_hint)
486 WSCContextISF *wsc_ctx = (WSCContextISF*)data;
488 LOGD ("im_context = %p, prediction hint = %s", im_ctx, prediction_hint);
489 if (!wsc_ctx) return;
491 isf_wsc_context_input_panel_prediction_hint_set (wsc_ctx, prediction_hint);
495 _wsc_im_ctx_mime_type (void *data, struct wl_input_method_context *im_ctx, const char *mime_type)
497 WSCContextISF *wsc_ctx = (WSCContextISF*)data;
499 LOGD ("im_context = %p, mime_type = %s", im_ctx, mime_type);
500 if (!wsc_ctx) return;
503 wsc_ctx->impl->mime_type = String (mime_type);
506 isf_wsc_context_input_panel_mime_type_accept_set (wsc_ctx, mime_type);
510 _wsc_im_ctx_finalized_content (void *data, struct wl_input_method_context *im_ctx, const char *text, uint32_t cursor_pos)
512 WSCContextISF *wsc_ctx = (WSCContextISF*)data;
514 SECURE_LOGD ("im_context = %p, text = %s, cursor_pos = %d", im_ctx, text, cursor_pos);
515 if (!wsc_ctx) return;
517 isf_wsc_context_input_panel_finalize_content (wsc_ctx, text, cursor_pos);
521 _wsc_im_ctx_prediction_hint_data (void *data, struct wl_input_method_context *im_ctx, const char *key, const char * value)
523 WSCContextISF *wsc_ctx = (WSCContextISF*)data;
524 if (!wsc_ctx) return;
526 isf_wsc_context_input_panel_prediction_hint_data_set (wsc_ctx, key, value);
529 static const struct wl_input_method_context_listener wsc_im_context_listener = {
531 _wsc_im_ctx_content_type,
532 _wsc_im_ctx_invoke_action,
533 _wsc_im_ctx_commit_state,
534 _wsc_im_ctx_preferred_language,
535 _wsc_im_ctx_return_key_type,
536 _wsc_im_ctx_return_key_disabled,
537 _wsc_im_ctx_input_panel_data,
538 _wsc_im_ctx_bidi_direction,
539 _wsc_im_ctx_cursor_position,
540 _wsc_im_ctx_process_input_device_event,
541 _wsc_im_ctx_filter_key_event,
542 _wsc_im_ctx_capital_mode,
543 _wsc_im_ctx_prediction_hint,
544 _wsc_im_ctx_mime_type,
545 _wsc_im_ctx_finalized_content,
546 _wsc_im_ctx_prediction_hint_data
549 #if ENABLE_GRAB_KEYBOARD
551 _init_keysym2keycode (WSCContextISF *wsc_ctx)
556 const xkb_keysym_t *syms;
558 if (!wsc_ctx || !wsc_ctx->state)
561 for (i = 0; i < 256; i++) {
563 num_syms = xkb_key_get_syms (wsc_ctx->state, code, &syms);
566 wsc_ctx->_keysym2keycode[syms[0]] = i;
571 _fini_keysym2keycode (WSCContextISF *wsc_ctx)
573 wsc_ctx->_keysym2keycode.clear ();
577 _wsc_im_keyboard_keymap (void *data,
578 struct wl_keyboard *wl_keyboard,
583 WSCContextISF *wsc_ctx = (WSCContextISF*)data;
591 _fini_keysym2keycode (wsc_ctx);
593 if (wsc_ctx->state) {
594 xkb_state_unref (wsc_ctx->state);
595 wsc_ctx->state = NULL;
598 if (wsc_ctx->keymap) {
599 xkb_map_unref (wsc_ctx->keymap);
600 wsc_ctx->keymap = NULL;
603 if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) {
608 map_str = (char*)mmap (NULL, size, PROT_READ, MAP_SHARED, fd, 0);
609 if (map_str == MAP_FAILED) {
615 xkb_map_new_from_string (wsc_ctx->xkb_context,
617 XKB_KEYMAP_FORMAT_TEXT_V1,
618 (xkb_keymap_compile_flags)0);
620 munmap (map_str, size);
623 if (!wsc_ctx->keymap) {
624 LOGW ("failed to compile keymap");
628 wsc_ctx->state = xkb_state_new (wsc_ctx->keymap);
629 if (!wsc_ctx->state) {
630 LOGW ("failed to create XKB state");
631 xkb_map_unref (wsc_ctx->keymap);
635 wsc_ctx->control_mask =
636 1 << xkb_map_mod_get_index (wsc_ctx->keymap, "Control");
638 1 << xkb_map_mod_get_index (wsc_ctx->keymap, "Mod1");
639 wsc_ctx->shift_mask =
640 1 << xkb_map_mod_get_index (wsc_ctx->keymap, "Shift");
641 wsc_ctx->super_mask =
642 1 << xkb_map_mod_get_index (wsc_ctx->keymap, "Super");
644 LOGD ("create _keysym2keycode");
645 _init_keysym2keycode (wsc_ctx);
649 _wsc_im_keyboard_key (void *data,
650 struct wl_keyboard *wl_keyboard,
656 WSCContextISF *wsc_ctx = (WSCContextISF*)data;
659 const xkb_keysym_t *syms;
661 char keyname[64] = {0};
662 enum wl_keyboard_key_state state = (wl_keyboard_key_state)state_w;
664 if (!wsc_ctx || !wsc_ctx->state)
668 num_syms = xkb_key_get_syms (wsc_ctx->state, code, &syms);
670 sym = XKB_KEY_NoSymbol;
673 xkb_keysym_get_name (sym, keyname, 64);
676 isf_wsc_context_filter_key_event (wsc_ctx, serial, time, code, sym, keyname,
681 _wsc_im_keyboard_modifiers (void *data,
682 struct wl_keyboard *wl_keyboard,
684 uint32_t mods_depressed,
685 uint32_t mods_latched,
686 uint32_t mods_locked,
689 WSCContextISF *wsc_ctx = (WSCContextISF*)data;
690 if (!wsc_ctx || !wsc_ctx->state)
693 struct wl_input_method_context *context = wsc_ctx->im_ctx;
696 xkb_state_update_mask (wsc_ctx->state, mods_depressed,
697 mods_latched, mods_locked, 0, 0, group);
698 mask = xkb_state_serialize_mods (wsc_ctx->state,
699 (xkb_state_component)(XKB_STATE_DEPRESSED | XKB_STATE_LATCHED));
701 wsc_ctx->modifiers = 0;
702 if (mask & wsc_ctx->control_mask)
703 wsc_ctx->modifiers |= SCIM_KEY_ControlMask;
704 if (mask & wsc_ctx->alt_mask)
705 wsc_ctx->modifiers |= SCIM_KEY_AltMask;
706 if (mask & wsc_ctx->shift_mask)
707 wsc_ctx->modifiers |= SCIM_KEY_ShiftMask;
708 if (mask & wsc_ctx->super_mask)
709 wsc_ctx->modifiers |= SCIM_KEY_SuperMask;
711 wl_input_method_context_modifiers (context, serial,
712 mods_depressed, mods_depressed,
713 mods_latched, group);
716 static const struct wl_keyboard_listener wsc_im_keyboard_listener = {
717 _wsc_im_keyboard_keymap,
720 _wsc_im_keyboard_key,
721 _wsc_im_keyboard_modifiers
728 if (!_wl_im_ctx || !_wl_im_ctx->wsc || !_wl_im_ctx->wsc->wsc_ctx)
731 WSCContextISF *wsc_ctx = _wl_im_ctx->wsc->wsc_ctx;
733 if (_wl_im_ctx->need_focus_event)
734 isf_wsc_context_focus_out (wsc_ctx);
736 #if ENABLE_GRAB_KEYBOARD
737 if (wsc_ctx->keyboard) {
738 wl_keyboard_destroy (wsc_ctx->keyboard);
739 wsc_ctx->keyboard = NULL;
742 _fini_keysym2keycode (wsc_ctx);
744 if (wsc_ctx->state) {
745 xkb_state_unref (wsc_ctx->state);
746 wsc_ctx->state = NULL;
749 if (wsc_ctx->keymap) {
750 xkb_map_unref (wsc_ctx->keymap);
751 wsc_ctx->keymap = NULL;
754 if (wsc_ctx->xkb_context) {
755 xkb_context_unref (wsc_ctx->xkb_context);
756 wsc_ctx->xkb_context = NULL;
760 if (wsc_ctx->im_ctx) {
761 LOGD("destroy wl_input_method_context : %p", wsc_ctx->im_ctx);
762 wl_input_method_context_destroy (wsc_ctx->im_ctx);
763 wsc_ctx->im_ctx = NULL;
766 if (wsc_ctx->preedit_str) {
767 free (wsc_ctx->preedit_str);
768 wsc_ctx->preedit_str = NULL;
771 if (wsc_ctx->surrounding_text) {
772 free (wsc_ctx->surrounding_text);
773 wsc_ctx->surrounding_text = NULL;
776 if (wsc_ctx->remote_surrounding_text) {
777 free (wsc_ctx->remote_surrounding_text);
778 wsc_ctx->remote_surrounding_text = NULL;
781 if (wsc_ctx->language) {
782 free (wsc_ctx->language);
783 wsc_ctx->language = NULL;
786 wsc_ctx->layout_initialized = EINA_FALSE;
787 wsc_ctx->prediction_allow_initialized = EINA_FALSE;
788 wsc_ctx->autocapital_type_initialized = EINA_FALSE;
789 wsc_ctx->language_initialized = EINA_FALSE;
791 if (_resource_check_timer)
792 ecore_timer_del (_resource_check_timer);
793 _resource_check_timer = NULL;
795 isf_wsc_context_del (wsc_ctx);
797 _wl_im_ctx->wsc->wsc_ctx = NULL;
798 _wl_im_ctx->input_method = NULL;
799 _wl_im_ctx->im_ctx = NULL;
800 _wl_im_ctx->need_focus_event = EINA_FALSE;
801 _need_wl_im_init = false;
805 _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)
807 struct weescim *wsc = (weescim*)data;
810 WSCContextISF *wsc_ctx = new WSCContextISF;
815 if (_need_wl_im_init) {
816 LOGD("destroy wl_input_method_context");
820 #if ENABLE_GRAB_KEYBOARD
821 wsc_ctx->xkb_context = xkb_context_new ((xkb_context_flags)0);
822 if (wsc_ctx->xkb_context == NULL) {
823 LOGW ("Failed to create XKB context");
827 wsc_ctx->state = NULL;
828 wsc_ctx->keymap = NULL;
829 wsc_ctx->modifiers = 0;
832 wsc_ctx->id = text_input_id;
833 wsc->wsc_ctx = wsc_ctx;
835 wsc_ctx->surrounding_text = NULL;
836 wsc_ctx->remote_surrounding_text = NULL;
837 wsc_ctx->surrounding_cursor = 0;
838 LOGD("inputmethod : %p, im context : %p, surrounding_cursor = %d", input_method, im_ctx, wsc_ctx->surrounding_cursor);
840 wsc_ctx->preedit_str = strdup ("");
841 wsc_ctx->content_hint = WL_TEXT_INPUT_CONTENT_HINT_NONE;
842 wsc_ctx->content_purpose = WL_TEXT_INPUT_CONTENT_PURPOSE_NORMAL;
844 wsc_ctx->im_ctx = im_ctx;
845 wl_input_method_context_add_listener (im_ctx, &wsc_im_context_listener, wsc_ctx);
847 #if ENABLE_GRAB_KEYBOARD
848 wsc_ctx->keyboard = wl_input_method_context_grab_keyboard (im_ctx);
849 if (wsc_ctx->keyboard)
850 wl_keyboard_add_listener (wsc_ctx->keyboard, &wsc_im_keyboard_listener, wsc_ctx);
853 if (wsc_ctx->language)
854 wl_input_method_context_language (im_ctx, wsc_ctx->serial, wsc_ctx->language);
856 isf_wsc_context_add (wsc_ctx);
858 if (focus_in_event) {
859 isf_wsc_context_focus_in (wsc_ctx);
860 _wl_im_ctx->need_focus_event = EINA_TRUE;
865 _wsc_im_deactivate (void *data, struct wl_input_method *input_method, struct wl_input_method_context *im_ctx, uint32_t focus_out_event)
867 struct weescim *wsc = (weescim*)data;
868 if (!wsc || !wsc->wsc_ctx) return;
870 LOGD("inputmethod : %p, im ctx : %p, focus out : %d", input_method, im_ctx, focus_out_event);
872 /* When the focus_in/input_panel_shutdown event is called,
873 * it is not possible to know the information of wl_input_method to destroy */
874 _wl_im_ctx->wsc = wsc;
875 _wl_im_ctx->input_method = input_method;
876 _wl_im_ctx->im_ctx = im_ctx;
877 _need_wl_im_init = true;
879 if (focus_out_event) {
880 isf_wsc_context_focus_out (wsc->wsc_ctx);
881 _wl_im_ctx->need_focus_event = EINA_FALSE;
883 wsc->wsc_ctx->input_panel_shown_once = EINA_FALSE;
887 _wsc_im_destroy (void *data, struct wl_input_method *input_method, struct wl_input_method_context *im_ctx)
889 struct weescim *wsc = (weescim*)data;
890 if (!wsc || !wsc->wsc_ctx) return;
892 LOGD("inputmethod : %p, im ctx : %p", input_method, im_ctx);
894 _wl_im_ctx->wsc = wsc;
895 _wl_im_ctx->input_method = input_method;
896 _wl_im_ctx->im_ctx = im_ctx;
899 g_info_manager->request_ise_terminate();
903 _wsc_im_show_input_panel (void *data, struct wl_input_method *input_method, struct wl_input_method_context *im_ctx, uint32_t angle)
905 struct weescim *wsc = (weescim*)data;
906 if (!wsc || !wsc->wsc_ctx) return;
908 wsc->wsc_ctx->angle = angle;
909 isf_wsc_context_input_panel_show (wsc->wsc_ctx);
910 wsc->wsc_ctx->input_panel_shown_once = EINA_TRUE;
913 remote_surrounding_get (wsc->wsc_ctx);
917 _wsc_im_hide_input_panel (void *data, struct wl_input_method *input_method, struct wl_input_method_context *im_ctx)
919 struct weescim *wsc = (weescim*)data;
920 if (!wsc || !wsc->wsc_ctx) return;
922 LOGD("inputmethod : %p, im ctx : %p", input_method, im_ctx);
924 isf_wsc_context_input_panel_hide (wsc->wsc_ctx);
927 static const struct wl_input_method_listener wsc_im_listener = {
931 _wsc_im_show_input_panel,
932 _wsc_im_hide_input_panel
936 _wsc_setup (struct weescim *wsc)
938 Eina_Iterator *globals = NULL;
939 struct wl_registry *registry = NULL;
940 Ecore_Wl2_Global *global = NULL;
942 if (!wsc) return false;
944 Ecore_Wl2_Display *wl2_display = ecore_wl2_display_connect (NULL);
946 LOGW ("failed to connect");
950 if (!(registry = ecore_wl2_display_registry_get (wl2_display))) {
951 LOGW ("failed to get wl_registry");
955 if (!(globals = ecore_wl2_display_globals_get (wl2_display))) {
956 LOGW ("failed to get wl_globals");
960 EINA_ITERATOR_FOREACH(globals, global) {
961 if (strcmp (global->interface, "wl_input_method") == 0)
962 wsc->im = (wl_input_method*)wl_registry_bind (registry, global->id, &wl_input_method_interface, 1);
963 else if (strcmp (global->interface, "wl_input_method_manager") == 0)
964 _im_manager = (wl_input_method_manager*)wl_registry_bind (registry, global->id, &wl_input_method_manager_interface, 1);
966 eina_iterator_free (globals);
968 if (wsc->im == NULL) {
969 LOGW ("Failed because wl_input_method is null");
973 /* Input method listener */
974 LOGD ("Adding wl_input_method listener");
977 wl_input_method_add_listener (wsc->im, &wsc_im_listener, wsc);
979 LOGW ("Couldn't get wayland input method interface");
987 //////////////////////////////wayland_panel_agent_module end//////////////////////////////////////////////////
996 get_panel_client_id (void)
998 return _panel_client_id;
1002 get_language (char **language)
1004 *language = strdup (_language.c_str ());
1012 struct timezone tz; /* is not used since ages */
1013 gettimeofday (&tv, &tz);
1014 tint = (unsigned int)(tv.tv_sec * 1000);
1015 tint = tint / 1000 * 1000;
1016 tint = (unsigned int)(tint + tv.tv_usec / 1000);
1020 /* Function Implementations */
1021 static WSCContextISFImpl *
1022 new_ic_impl (WSCContextISF *parent)
1024 WSCContextISFImpl *impl = NULL;
1026 if (_free_ic_impl_list != NULL) {
1027 impl = _free_ic_impl_list;
1028 _free_ic_impl_list = _free_ic_impl_list->next;
1030 impl = new WSCContextISFImpl;
1035 impl->next = _used_ic_impl_list;
1036 _used_ic_impl_list = impl;
1038 impl->parent = parent;
1044 delete_ic_impl (WSCContextISFImpl *impl)
1046 WSCContextISFImpl *rec = _used_ic_impl_list, *last = 0;
1048 for (; rec != 0; last = rec, rec = rec->next) {
1051 last->next = rec->next;
1053 _used_ic_impl_list = rec->next;
1055 rec->next = _free_ic_impl_list;
1056 _free_ic_impl_list = rec;
1063 rec->imdata_size = 0;
1065 rec->mime_type = String ();
1066 rec->surrounding_text = WideString ();
1067 rec->preedit_string = WideString ();
1068 rec->preedit_attrlist.clear ();
1069 rec->commit_string = WideString ();
1070 rec->block_input_resource = true;
1077 delete_all_ic_impl (void)
1079 WSCContextISFImpl *it = _used_ic_impl_list;
1082 _used_ic_impl_list = it->next;
1084 it = _used_ic_impl_list;
1087 it = _free_ic_impl_list;
1089 _free_ic_impl_list = it->next;
1091 it = _free_ic_impl_list;
1095 static WSCContextISF *
1098 WSCContextISFImpl *rec = _used_ic_impl_list;
1101 if (rec->parent && rec->parent->id == id)
1110 check_valid_ic (WSCContextISF *ic)
1112 if (ic && ic->impl && ic->ctx)
1118 void context_scim_imdata_get (WSCContextISF *wsc_ctx, void *data, int *length, int max_len)
1120 WSCContextISF* context_scim = wsc_ctx;
1122 SCIM_DEBUG_FRONTEND (1) << __FUNCTION__ << "...\n";
1127 if (context_scim && context_scim->impl && context_scim->impl->imdata && data && length) {
1128 if (max_len > context_scim->impl->imdata_size)
1129 max_len = context_scim->impl->imdata_size;
1131 memcpy (data, context_scim->impl->imdata, max_len);
1137 void context_scim_mime_type_get (WSCContextISF *wsc_ctx, char *mime_types, int max_len)
1139 WSCContextISF* context_scim = wsc_ctx;
1141 SCIM_DEBUG_FRONTEND (1) << __FUNCTION__ << "...\n";
1143 if (mime_types && max_len > 0) {
1144 /* Initialize mime_types to have an empty string */
1145 mime_types[0] = '\0';
1146 if (context_scim && context_scim->impl) {
1147 if (!(context_scim->impl->mime_type).empty ()) {
1148 int length = (context_scim->impl->mime_type).length ();
1149 if (max_len > length)
1151 memcpy ((void*)mime_types, (context_scim->impl->mime_type).c_str (), max_len);
1158 insert_text (const char *text, uint32_t offset, const char *insert)
1160 uint32_t tlen = strlen (text), ilen = strlen (insert);
1161 char *new_text = (char*)malloc (tlen + ilen + 1);
1163 if ((unsigned int) tlen < offset)
1165 memcpy (new_text, text, offset);
1166 memcpy (new_text + offset, insert, ilen);
1167 memcpy (new_text + offset + ilen, text + offset, tlen - offset);
1168 new_text[tlen + ilen] = '\0';
1175 change_block_status_timer_cb (void *data)
1177 WSCContextISF* context_scim = static_cast<WSCContextISF*>(data);
1178 if (context_scim && context_scim->impl)
1179 context_scim->impl->block_input_resource = false;
1181 _resource_check_timer = NULL;
1183 return ECORE_CALLBACK_CANCEL;
1187 check_input_resource (WSCContextISF *wsc_ctx, Input_Resource input_res)
1189 WSCContextISF* context_scim = wsc_ctx;
1190 LOGD ("Input resource : %d", input_res);
1191 SCIM_DEBUG_FRONTEND (1) << __FUNCTION__ << "...\n";
1193 if (context_scim && context_scim->impl) {
1194 if (context_scim->impl->input_resource == input_res)
1198 if (context_scim->impl->input_resource != input_res && input_res != INPUT_RESOURCE_NONE)
1199 g_info_manager->remoteinput_callback_input_resource (input_res);
1201 if (context_scim->impl->input_resource == INPUT_RESOURCE_REMOTE && input_res == INPUT_RESOURCE_LOCAL) {
1202 if (context_scim->impl->need_commit_preedit) {
1203 WideString wstr = context_scim->impl->preedit_string;
1204 _hide_preedit_string (context_scim->id, false);
1205 wsc_context_commit_string (context_scim, utf8_wcstombs (wstr).c_str ());
1207 context_scim->impl->need_commit_preedit = false;
1208 context_scim->impl->preedit_string.clear ();
1211 if (_resource_check_timer)
1212 ecore_timer_del (_resource_check_timer);
1213 _resource_check_timer = ecore_timer_add (2.0, change_block_status_timer_cb, context_scim);
1214 context_scim->impl->block_input_resource = true;
1216 context_scim->impl->input_resource = input_res;
1220 /* Public functions */
1222 isf_wsc_context_init (void)
1224 SCIM_DEBUG_FRONTEND (1) << __FUNCTION__ << "...\n";
1227 if (!_scim_initialized) {
1228 _ecore_wl2_init_count = ecore_wl2_init ();
1229 if (_ecore_wl2_init_count > 0) {
1231 _scim_initialized = true;
1232 isf_wsc_input_panel_init ();
1233 //isf_wsc_context_set_hardware_keyboard_mode(context_scim);
1236 LOGE("Failed to initialize Ecore_Wl");
1241 isf_wsc_context_shutdown (void)
1244 SCIM_DEBUG_FRONTEND (1) << __FUNCTION__ << "...\n";
1246 if (_scim_initialized) {
1247 _scim_initialized = false;
1249 isf_wsc_input_panel_shutdown ();
1252 if (_ecore_wl2_init_count > 0) {
1253 Ecore_Wl2_Display *wl2_display = ecore_wl2_connected_display_get (NULL);
1255 ecore_wl2_display_disconnect (wl2_display);
1257 ecore_wl2_shutdown ();
1258 _ecore_wl2_init_count = 0;
1264 isf_wsc_context_add (WSCContextISF *wsc_ctx)
1266 SCIM_DEBUG_FRONTEND (1) << __FUNCTION__ << "...\n";
1268 WSCContextISF* context_scim = wsc_ctx;
1270 if (!context_scim) return;
1271 context_scim->surrounding_text_fd_read_handler = NULL;
1272 context_scim->selection_text_fd_read_handler = NULL;
1273 context_scim->remote_surrounding_text_fd_read_handler = NULL;
1274 context_scim->surrounding_text = NULL;
1275 context_scim->remote_surrounding_text = NULL;
1276 context_scim->selection_text = NULL;
1278 context_scim->impl = new_ic_impl (context_scim);
1279 if (context_scim->impl == NULL) {
1280 std::cerr << "memory allocation failed in " << __FUNCTION__ << "\n";
1284 LOGD ("ctx impl : %p", context_scim->impl);
1286 context_scim->impl->preedit_caret = 0;
1287 context_scim->impl->cursor_x = 0;
1288 context_scim->impl->cursor_y = 0;
1289 context_scim->impl->cursor_pos = -1;
1290 context_scim->impl->cursor_top_y = 0;
1291 context_scim->impl->is_on = true;
1292 context_scim->impl->use_preedit = _on_the_spot;
1293 context_scim->impl->preedit_started = false;
1294 context_scim->impl->need_commit_preedit = false;
1297 context_scim->next = NULL;
1299 context_scim->next = _ic_list;
1300 _ic_list = context_scim;
1302 context_scim->impl->is_on = _config->read (String (SCIM_CONFIG_FRONTEND_IM_OPENED_BY_DEFAULT), context_scim->impl->is_on);
1304 g_info_manager->register_input_context (WAYLAND_MODULE_CLIENT_ID, context_scim->id, "");
1305 set_ic_capabilities (context_scim);
1306 SCIM_DEBUG_FRONTEND (2) << "input context created: id = " << context_scim->id << "\n";
1310 isf_wsc_context_del (WSCContextISF *wsc_ctx)
1312 SCIM_DEBUG_FRONTEND (1) << __FUNCTION__ << "...\n";
1313 if (!_ic_list) return;
1315 WSCContextISF *context_scim = wsc_ctx;
1316 if (!context_scim) return;
1318 LOGD ("ctx impl : %p", context_scim->impl);
1320 if (context_scim->selection_text_fd_read_handler) {
1321 int fd = ecore_main_fd_handler_fd_get (context_scim->selection_text_fd_read_handler);
1324 ecore_main_fd_handler_del (context_scim->selection_text_fd_read_handler);
1325 context_scim->selection_text_fd_read_handler = NULL;
1328 if (context_scim->selection_text) {
1329 free (context_scim->selection_text);
1330 context_scim->selection_text = NULL;
1333 if (context_scim->surrounding_text_fd_read_handler) {
1334 int fd = ecore_main_fd_handler_fd_get (context_scim->surrounding_text_fd_read_handler);
1337 ecore_main_fd_handler_del (context_scim->surrounding_text_fd_read_handler);
1338 context_scim->surrounding_text_fd_read_handler = NULL;
1341 if (context_scim->remote_surrounding_text_fd_read_handler) {
1342 int fd = ecore_main_fd_handler_fd_get (context_scim->remote_surrounding_text_fd_read_handler);
1345 ecore_main_fd_handler_del (context_scim->remote_surrounding_text_fd_read_handler);
1346 context_scim->remote_surrounding_text_fd_read_handler = NULL;
1349 if (context_scim->surrounding_text) {
1350 free (context_scim->surrounding_text);
1351 context_scim->surrounding_text = NULL;
1354 if (context_scim->remote_surrounding_text) {
1355 free (context_scim->remote_surrounding_text);
1356 context_scim->remote_surrounding_text = NULL;
1359 if (context_scim->id != _ic_list->id) {
1360 WSCContextISF * pre = _ic_list;
1361 WSCContextISF * cur = _ic_list->next;
1362 while (cur != NULL) {
1363 if (cur->id == context_scim->id) {
1364 pre->next = cur->next;
1371 _ic_list = _ic_list->next;
1374 if (context_scim->impl) {
1375 if (context_scim == _focused_ic) {
1376 g_info_manager->socket_turn_off ();
1377 g_info_manager->focus_out (WAYLAND_MODULE_CLIENT_ID, context_scim->id);
1380 g_info_manager->remove_input_context (WAYLAND_MODULE_CLIENT_ID, context_scim->id);
1382 if (context_scim->impl) {
1383 delete_ic_impl (context_scim->impl);
1384 context_scim->impl = 0;
1388 if (context_scim == _focused_ic)
1393 isf_wsc_context_focus_in (WSCContextISF *wsc_ctx)
1395 WSCContextISF* context_scim = wsc_ctx;
1399 SCIM_DEBUG_FRONTEND(1) << __FUNCTION__<< "(" << context_scim->id << ")...\n";
1402 if (_focused_ic == context_scim) {
1403 SCIM_DEBUG_FRONTEND(1) << "It's already focused.\n";
1406 SCIM_DEBUG_FRONTEND(1) << "Focus out previous IC first: " << _focused_ic->id << "\n";
1407 isf_wsc_context_focus_out (_focused_ic);
1410 if (_change_keyboard_mode_by_focus_move) {
1411 //if h/w keyboard mode, keyboard mode will be changed to s/w mode when the entry get the focus.
1412 LOGD ("Keyboard mode is changed H/W->S/W because of focus_in.");
1413 isf_wsc_context_set_keyboard_mode (wsc_ctx, TOOLBAR_HELPER_MODE);
1416 if (context_scim && context_scim->impl) {
1417 _focused_ic = context_scim;
1419 context_scim->impl->is_on = _config->read (String (SCIM_CONFIG_FRONTEND_IM_OPENED_BY_DEFAULT), context_scim->impl->is_on);
1420 context_scim->impl->surrounding_text.clear ();
1421 context_scim->impl->preedit_string.clear ();
1422 context_scim->impl->preedit_attrlist.clear ();
1423 context_scim->impl->commit_string.clear ();
1424 context_scim->impl->preedit_caret = 0;
1425 context_scim->impl->preedit_started = false;
1427 g_info_manager->register_input_context (WAYLAND_MODULE_CLIENT_ID, context_scim->id, "");
1429 set_ic_capabilities (context_scim);
1431 //FIXME: modify the parameter ic->impl->si->get_factory_uuid ()
1432 g_info_manager->focus_in (WAYLAND_MODULE_CLIENT_ID, context_scim->id, "");
1433 if (context_scim->impl->is_on) {
1434 g_info_manager->socket_turn_on ();
1435 // _panel_client.hide_preedit_string (context_scim->id);
1436 // _panel_client.hide_aux_string (context_scim->id);
1437 // _panel_client.hide_lookup_table (context_scim->id);
1439 #if 0 //REMOVE_SCIM_LAUNCHER
1440 context_scim->impl->si->set_layout (wsc_context_input_panel_layout_get (wsc_ctx));
1441 context_scim->impl->si->set_prediction_allow (context_scim->impl->prediction_allow);
1443 if (context_scim->impl->imdata)
1444 context_scim->impl->si->set_imdata ((const char*)context_scim->impl->imdata, context_scim->impl->imdata_size);
1446 LOGD ("set autocapital type : %d, ctx : %p", context_scim->impl->autocapital_type, wsc_ctx);
1447 g_info_manager->set_autocapital_type ((int)context_scim->impl->autocapital_type);
1449 g_info_manager->socket_turn_off ();
1452 g_info_manager->get_active_helper_option (WAYLAND_MODULE_CLIENT_ID, _active_helper_option);
1455 g_info_manager->remoteinput_callback_focus_in ();
1457 context_scim->impl->init_remote_entry_metadata = false;
1458 context_scim->impl->init_remote_surrounding_text = false;
1459 context_scim->impl->block_input_resource = false;
1460 context_scim->impl->input_resource = INPUT_RESOURCE_NONE;
1465 isf_wsc_context_focus_out (WSCContextISF *wsc_ctx)
1467 WSCContextISF* context_scim = wsc_ctx;
1469 if (!context_scim) return;
1471 SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "(" << context_scim->id << ")...\n";
1473 if (context_scim && context_scim->impl && context_scim == _focused_ic) {
1474 LOGD ("ctx : %p", wsc_ctx);
1476 if (context_scim->impl->need_commit_preedit) {
1477 _hide_preedit_string (context_scim->id, false);
1479 wsc_context_commit_preedit_string (context_scim);
1480 g_info_manager->socket_reset_input_context (WAYLAND_MODULE_CLIENT_ID, context_scim->id);
1483 context_scim->impl->cursor_pos = -1;
1484 // if (context_scim->impl->shared_si) context_scim->impl->si->reset ();
1485 g_info_manager->focus_out (WAYLAND_MODULE_CLIENT_ID, context_scim->id);
1490 g_info_manager->remoteinput_callback_focus_out ();
1492 context_scim->impl->surrounding_text.clear ();
1493 context_scim->impl->preedit_string.clear ();
1494 context_scim->impl->preedit_attrlist.clear ();
1495 context_scim->impl->commit_string.clear ();
1496 context_scim->impl->preedit_caret = 0;
1497 context_scim->impl->preedit_started = false;
1498 context_scim->impl->need_commit_preedit = false;
1500 context_scim->impl->init_remote_entry_metadata = true;
1501 context_scim->impl->init_remote_surrounding_text = true;
1502 context_scim->impl->block_input_resource = true;
1503 context_scim->impl->input_resource = INPUT_RESOURCE_NONE;
1505 _x_key_event_is_valid = false;
1509 isf_wsc_context_preedit_string_get (WSCContextISF *wsc_ctx, char** str, int *cursor_pos)
1511 SCIM_DEBUG_FRONTEND (1) << __FUNCTION__ << "...\n";
1513 WSCContextISF* context_scim = wsc_ctx;
1515 if (context_scim && context_scim->impl && context_scim->impl->is_on) {
1516 String mbs = utf8_wcstombs (context_scim->impl->preedit_string);
1520 *str = strdup (mbs.c_str ());
1526 //*cursor_pos = context_scim->impl->preedit_caret;
1527 mbs = utf8_wcstombs (
1528 context_scim->impl->preedit_string.substr (0, context_scim->impl->preedit_caret));
1529 *cursor_pos = mbs.length ();
1541 isf_wsc_context_autocapital_type_set (WSCContextISF* wsc_ctx, Ecore_IMF_Autocapital_Type autocapital_type)
1543 SCIM_DEBUG_FRONTEND (1) << __FUNCTION__ << " = " << autocapital_type << "...\n";
1544 WSCContextISF* context_scim = wsc_ctx;
1546 if (context_scim && context_scim->impl && context_scim->impl->autocapital_type != autocapital_type) {
1547 context_scim->impl->autocapital_type = autocapital_type;
1548 if (context_scim == _focused_ic) {
1549 LOGD ("ctx : %p. set autocapital type : %d", wsc_ctx, autocapital_type);
1550 g_info_manager->set_autocapital_type ((int)autocapital_type);
1556 isf_wsc_context_bidi_direction_set (WSCContextISF* wsc_ctx, Ecore_IMF_BiDi_Direction direction)
1558 SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
1560 WSCContextISF *context_scim = wsc_ctx;
1562 if (context_scim && context_scim->impl) {
1563 if (context_scim->impl->bidi_direction != direction) {
1564 context_scim->impl->bidi_direction = direction;
1566 if (context_scim == _focused_ic) {
1567 LOGD ("ctx : %p, bidi direction : %#x", wsc_ctx, direction);
1568 panel_req_update_bidi_direction (context_scim, direction);
1575 isf_wsc_context_send_surrounding_text (WSCContextISF* wsc_ctx, const char *text, int cursor)
1577 SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
1579 WSCContextISF *context_scim = wsc_ctx;
1581 if (!context_scim || !context_scim->impl || !text)
1584 char *conv_text = strdup (utf8_wcstombs (context_scim->impl->surrounding_text).c_str ());
1588 if (!context_scim->impl->init_remote_surrounding_text || strcmp (conv_text, text) != 0 || context_scim->impl->cursor_pos != cursor) {
1589 SECURE_LOGD("remote surrounding text : \"%s\"", text);
1590 context_scim->impl->surrounding_text = utf8_mbstowcs (String (text));
1591 context_scim->impl->cursor_pos = cursor;
1594 if (context_scim->input_panel_shown_once && context_scim->impl->input_resource != INPUT_RESOURCE_REMOTE) {
1595 context_scim->impl->init_remote_surrounding_text = true;
1596 if (context_scim->impl->panel_layout == ECORE_IMF_INPUT_PANEL_LAYOUT_PASSWORD) {
1597 g_info_manager->remoteinput_callback_surrounding_text (String (""), 0);
1600 g_info_manager->remoteinput_callback_surrounding_text (String (text), context_scim->impl->cursor_pos);
1609 isf_wsc_context_send_entry_metadata (WSCContextISF* wsc_ctx, Ecore_IMF_Input_Hints hint,
1610 Ecore_IMF_Input_Panel_Layout layout, int variation,
1611 Ecore_IMF_Autocapital_Type type, int return_key_disabled,
1612 Ecore_IMF_Input_Panel_Return_Key_Type return_key_type)
1614 SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
1616 WSCContextISF *context_scim = wsc_ctx;
1618 if (context_scim && context_scim->impl) {
1619 if (!context_scim->impl->init_remote_entry_metadata || (context_scim->impl->input_hint != hint || context_scim->impl->panel_layout != layout ||
1620 context_scim->impl->variation != variation || context_scim->impl->autocapital_type != type ||
1621 context_scim->impl->return_key_disabled != return_key_disabled || context_scim->impl->return_key_type != return_key_type)) {
1622 if (context_scim->impl->panel_layout != layout || context_scim->impl->variation != variation) {
1623 if (context_scim->impl->input_resource == INPUT_RESOURCE_REMOTE)
1624 context_scim->impl->input_resource = INPUT_RESOURCE_NONE;
1627 context_scim->impl->input_hint = hint;
1628 context_scim->impl->panel_layout = layout;
1629 context_scim->impl->variation = variation;
1630 context_scim->impl->autocapital_type = type;
1631 context_scim->impl->return_key_disabled = return_key_disabled;
1632 context_scim->impl->return_key_type = return_key_type;
1635 g_info_manager->remoteinput_callback_entry_metadata (context_scim->impl->input_hint, context_scim->impl->panel_layout,
1636 context_scim->impl->variation, context_scim->impl->autocapital_type, context_scim->impl->return_key_disabled,
1637 context_scim->impl->return_key_type);
1639 context_scim->impl->init_remote_entry_metadata = true;
1642 remote_surrounding_get (wsc_ctx);
1647 #if ENABLE_GRAB_KEYBOARD
1649 bool is_number_key (const char *str)
1651 if (!str) return false;
1653 int result = atoi (str);
1656 if (!strcmp (str, "0"))
1666 isf_wsc_context_filter_key_event (WSCContextISF* wsc_ctx,
1668 uint32_t timestamp, uint32_t keycode, uint32_t symcode,
1670 enum wl_keyboard_key_state state)
1673 SCIM_DEBUG_FRONTEND (1) << __FUNCTION__ << "...\n";
1676 if (!wsc_ctx) return;
1678 KeyEvent key(symcode, wsc_ctx->modifiers);
1680 bool ignore_key = filter_keys (keyname, SCIM_CONFIG_HOTKEYS_FRONTEND_IGNORE_KEY);
1682 if (state == WL_KEYBOARD_KEY_STATE_RELEASED) {
1683 key.mask = SCIM_KEY_ReleaseMask;
1684 } else if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {
1686 /* Hardware input detect code */
1687 if (get_keyboard_mode () == TOOLBAR_HELPER_MODE &&
1689 _support_hw_keyboard_mode &&
1690 strncmp (keyname, "XF86", 4)) {
1691 bool hw_key_detect = false;
1694 if (strcmp (keyname, "Down") &&
1695 strcmp (keyname, "KP_Down") &&
1696 strcmp (keyname, "Up") &&
1697 strcmp (keyname, "KP_Up") &&
1698 strcmp (keyname, "Right") &&
1699 strcmp (keyname, "KP_Right") &&
1700 strcmp (keyname, "Left") &&
1701 strcmp (keyname, "KP_Left") &&
1702 strcmp (keyname, "Return") &&
1703 strcmp (keyname, "Pause") &&
1704 strcmp (keyname, "NoSymbol") &&
1705 !is_number_key (keyname)) {
1706 hw_key_detect = true;
1709 if (key.code != 0x1008ff26 && key.code != 0xFF69) {
1710 /* XF86back, Cancel (Power + Volume down) key */
1711 hw_key_detect = true;
1715 if (hw_key_detect) {
1716 isf_wsc_context_set_keyboard_mode (wsc_ctx, TOOLBAR_KEYBOARD_MODE);
1717 ISF_SAVE_LOG ("Changed keyboard mode from S/W to H/W (code: %x, name: %s)", key.code, keyname);
1718 LOGD ("Hardware keyboard mode, active helper option: %d", _active_helper_option);
1725 if (!_focused_ic || !_focused_ic->impl || !_focused_ic->impl->is_on) {
1728 static uint32 _serial = 0;
1729 g_info_manager->process_key_event (key, ++_serial);
1732 send_wl_key_event (wsc_ctx, key, false);
1737 isf_wsc_context_filter_key_event (WSCContextISF* wsc_ctx,
1739 uint32_t timestamp, const char *keysym,
1740 bool press, uint32_t modifiers,
1741 const char *dev_name, uint32_t dev_class, uint32_t dev_subclass, uint32_t keycode)
1743 SCIM_DEBUG_FRONTEND (1) << __FUNCTION__ << "...\n";
1746 if (!wsc_ctx) return;
1749 LOGD("key is NULL");
1753 String _key(keysym);
1756 if (!scim_string_to_key (key, _key)) {
1757 xkb_keysym_t code = xkb_keysym_from_name(keysym, XKB_KEYSYM_NO_FLAGS);
1758 if (code == XKB_KEY_NoSymbol) {
1759 code = xkb_keysym_from_name(keysym, XKB_KEYSYM_CASE_INSENSITIVE);
1763 scim_set_device_info (key, dev_name ? dev_name : "", dev_class, dev_subclass);
1765 bool ignore_key = filter_keys (keysym, SCIM_CONFIG_HOTKEYS_FRONTEND_IGNORE_KEY);
1767 if (modifiers & MOD_SHIFT_MASK)
1768 key.mask |= SCIM_KEY_ShiftMask;
1769 if (modifiers & MOD_ALT_MASK)
1770 key.mask |= SCIM_KEY_AltMask;
1771 if (modifiers & MOD_CONTROL_MASK)
1772 key.mask |= SCIM_KEY_ControlMask;
1773 if (modifiers & MOD_SUPER_MASK)
1774 key.mask |= SCIM_KEY_SuperMask;
1776 if (modifiers & MOD_CAPS_MASK)
1777 key.mask |= SCIM_KEY_CapsLockMask;
1778 if (modifiers & MOD_NUM_MASK)
1779 key.mask |= SCIM_KEY_NumLockMask;
1782 key.mask |= SCIM_KEY_ReleaseMask;
1785 /* Hardware input detect code */
1786 if (get_keyboard_mode () == TOOLBAR_HELPER_MODE &&
1788 _support_hw_keyboard_mode &&
1789 strncmp (keysym, "XF86", 4)) {
1790 bool hw_key_detect = false;
1793 if (strcmp (keysym, "Down") &&
1794 strcmp (keysym, "KP_Down") &&
1795 strcmp (keysym, "Up") &&
1796 strcmp (keysym, "KP_Up") &&
1797 strcmp (keysym, "Right") &&
1798 strcmp (keysym, "KP_Right") &&
1799 strcmp (keysym, "Left") &&
1800 strcmp (keysym, "KP_Left") &&
1801 strcmp (keysym, "Return") &&
1802 strcmp (keysym, "KP_Enter") &&
1803 strcmp (keysym, "Pause") &&
1804 strcmp (keysym, "NoSymbol") &&
1805 key.dev_subclass != ECORE_DEVICE_SUBCLASS_REMOCON) {
1806 hw_key_detect = true;
1809 if (key.code != 0x1008ff26 && key.code != 0xFF69) {
1810 /* XF86back, Cancel (Power + Volume down) key */
1811 hw_key_detect = true;
1815 if (hw_key_detect) {
1816 isf_wsc_context_set_keyboard_mode (wsc_ctx, TOOLBAR_KEYBOARD_MODE);
1817 ISF_SAVE_LOG ("Changed keyboard mode from S/W to H/W (code: %x, key : %s)", key.code, keysym);
1818 LOGD ("Hardware keyboard mode, active helper option: %d", _active_helper_option);
1825 if (!_focused_ic || !_focused_ic->impl || !_focused_ic->impl->is_on) {
1827 } else if (g_info_manager->process_key_event (key, serial, keycode)){
1832 if (!instance.null ())
1833 instance->process_key_event_done (WAYLAND_MODULE_CLIENT_ID, wsc_ctx->id, key, EINA_FALSE, serial);
1838 wsc_commit_preedit (WSCContextISF* wsc_ctx)
1840 char* surrounding_text;
1842 if (!wsc_ctx || !wsc_ctx->preedit_str ||
1843 strlen (wsc_ctx->preedit_str) == 0)
1846 wl_input_method_context_cursor_position (wsc_ctx->im_ctx,
1849 if (strlen (wsc_ctx->preedit_str) > MAX_PREEDIT_BUFSIZE) {
1850 char str_buffer[MAX_PREEDIT_BUFSIZE];
1852 memcpy (str_buffer, wsc_ctx->preedit_str, MAX_PREEDIT_BUFSIZE - 1);
1853 str_buffer[MAX_PREEDIT_BUFSIZE - 1] = '\0';
1854 char *old_preedit_str = wsc_ctx->preedit_str;
1855 wsc_ctx->preedit_str = (char*)realloc (wsc_ctx->preedit_str, sizeof(char) * MAX_PREEDIT_BUFSIZE);
1856 if (wsc_ctx->preedit_str) {
1857 memcpy (wsc_ctx->preedit_str, str_buffer, strlen(str_buffer));
1858 wsc_ctx->preedit_str[MAX_PREEDIT_BUFSIZE - 1] = '\0';
1860 free (old_preedit_str);
1861 LOGE ("realloc failed");
1866 wl_input_method_context_commit_string (wsc_ctx->im_ctx,
1868 wsc_ctx->preedit_str);
1870 if (wsc_ctx->surrounding_text) {
1871 surrounding_text = insert_text (wsc_ctx->surrounding_text,
1872 wsc_ctx->surrounding_cursor,
1873 wsc_ctx->preedit_str);
1875 free (wsc_ctx->surrounding_text);
1876 wsc_ctx->surrounding_text = surrounding_text;
1877 wsc_ctx->surrounding_cursor += strlen (wsc_ctx->preedit_str);
1878 LOGD ("wsc_ctx->surrounding_cursor = %d", wsc_ctx->surrounding_cursor);
1880 wsc_ctx->surrounding_text = strdup (wsc_ctx->preedit_str);
1881 wsc_ctx->surrounding_cursor = strlen (wsc_ctx->preedit_str);
1882 LOGD ("wsc_ctx->surrounding_cursor = %d", wsc_ctx->surrounding_cursor);
1885 if (wsc_ctx->preedit_str)
1886 free (wsc_ctx->preedit_str);
1888 wsc_ctx->preedit_str = strdup ("");
1892 wsc_send_preedit_style (WSCContextISF* wsc_ctx)
1894 if (!wsc_ctx) return;
1895 if (wsc_ctx->impl && wsc_ctx->impl->is_on) {
1896 String mbs = utf8_wcstombs (wsc_ctx->impl->preedit_string);
1898 if (!wsc_ctx->impl->preedit_attrlist.empty ()) {
1899 if (mbs.length ()) {
1900 uint32_t preedit_style = WL_TEXT_INPUT_PREEDIT_STYLE_DEFAULT;
1901 int start_index, end_index;
1902 int wlen = wsc_ctx->impl->preedit_string.length ();
1903 AttributeList::const_iterator i;
1904 bool *attrs_flag = new bool [mbs.length ()];
1906 memset (attrs_flag, 0, mbs.length () * sizeof (bool));
1907 for (i = wsc_ctx->impl->preedit_attrlist.begin ();
1908 i != wsc_ctx->impl->preedit_attrlist.end (); ++i) {
1909 start_index = i->get_start ();
1910 end_index = i->get_end ();
1911 if (end_index <= wlen && start_index < end_index) {
1912 start_index = g_utf8_offset_to_pointer (mbs.c_str (), i->get_start ()) - mbs.c_str ();
1913 end_index = g_utf8_offset_to_pointer (mbs.c_str (), i->get_end ()) - mbs.c_str ();
1914 if (i->get_type () == SCIM_ATTR_DECORATE) {
1915 switch (i->get_value ())
1917 case SCIM_ATTR_DECORATE_UNDERLINE:
1918 preedit_style = WL_TEXT_INPUT_PREEDIT_STYLE_UNDERLINE;
1920 case SCIM_ATTR_DECORATE_REVERSE:
1921 preedit_style = WL_TEXT_INPUT_PREEDIT_STYLE_REVERSE;
1923 case SCIM_ATTR_DECORATE_HIGHLIGHT:
1924 preedit_style = WL_TEXT_INPUT_PREEDIT_STYLE_HIGHLIGHT;
1926 case SCIM_ATTR_DECORATE_BGCOLOR1:
1927 preedit_style = WL_TEXT_INPUT_PREEDIT_STYLE_BGCOLOR1;
1929 case SCIM_ATTR_DECORATE_BGCOLOR2:
1930 preedit_style = WL_TEXT_INPUT_PREEDIT_STYLE_BGCOLOR2;
1932 case SCIM_ATTR_DECORATE_BGCOLOR3:
1933 preedit_style = WL_TEXT_INPUT_PREEDIT_STYLE_BGCOLOR3;
1935 case SCIM_ATTR_DECORATE_BGCOLOR4:
1936 preedit_style = WL_TEXT_INPUT_PREEDIT_STYLE_BGCOLOR4;
1939 preedit_style = WL_TEXT_INPUT_PREEDIT_STYLE_DEFAULT;
1943 wl_input_method_context_preedit_styling (wsc_ctx->im_ctx,
1945 end_index - start_index,
1948 switch (i->get_value ())
1950 case SCIM_ATTR_DECORATE_NONE:
1951 case SCIM_ATTR_DECORATE_UNDERLINE:
1952 case SCIM_ATTR_DECORATE_REVERSE:
1953 case SCIM_ATTR_DECORATE_HIGHLIGHT:
1954 case SCIM_ATTR_DECORATE_BGCOLOR1:
1955 case SCIM_ATTR_DECORATE_BGCOLOR2:
1956 case SCIM_ATTR_DECORATE_BGCOLOR3:
1957 case SCIM_ATTR_DECORATE_BGCOLOR4:
1958 // Record which character has attribute.
1959 for (int pos = start_index; pos < end_index; ++pos)
1960 attrs_flag [pos] = 1;
1965 } else if (i->get_type () == SCIM_ATTR_FOREGROUND) {
1966 SCIM_DEBUG_FRONTEND(4) << "SCIM_ATTR_FOREGROUND\n";
1967 } else if (i->get_type () == SCIM_ATTR_BACKGROUND) {
1968 SCIM_DEBUG_FRONTEND(4) << "SCIM_ATTR_BACKGROUND\n";
1972 // Setting default style for all characters which don't have attribute.
1973 for (unsigned int pos = 0; pos < mbs.length (); ++pos) {
1974 if (!attrs_flag [pos]) {
1975 int begin_pos = pos;
1976 while (pos < mbs.length () && !attrs_flag [pos])
1979 preedit_style = WL_TEXT_INPUT_PREEDIT_STYLE_DEFAULT;
1980 start_index = begin_pos;
1983 wl_input_method_context_preedit_styling (wsc_ctx->im_ctx,
1985 end_index - start_index,
1989 delete [] attrs_flag;
1994 if (wsc_ctx->impl && !wsc_ctx->impl->preedit_attrlist.empty ())
1995 wsc_ctx->impl->preedit_attrlist.clear ();
2000 wsc_send_preedit (WSCContextISF* wsc_ctx, int32_t cursor)
2004 if (!wsc_ctx) return;
2006 uint32_t index = strlen (wsc_ctx->preedit_str);
2011 /* Note : Since the current wayland_immodule implementation does not call
2012 * PREEDIT_CHANGED callback even when preedit_cursor or preedit_style gets updated, for now
2013 * we must update preedit_string also whenever preedit_cursor or preedit_style is updated.
2014 * So the below 3 lines cannot be called separately. */
2015 wsc_send_preedit_style (wsc_ctx);
2016 wl_input_method_context_preedit_cursor (wsc_ctx->im_ctx, index);
2017 wl_input_method_context_preedit_string (wsc_ctx->im_ctx,
2019 wsc_ctx->preedit_str,
2020 utf8_wcstombs (wsc_ctx->impl->commit_string).c_str ());
2023 bool wsc_context_surrounding_get (WSCContextISF *wsc_ctx, char **text, int *cursor_pos)
2029 if (wsc_ctx->surrounding_text)
2030 *text = strdup (wsc_ctx->surrounding_text);
2032 *text = strdup ("");
2036 *cursor_pos = wsc_ctx->surrounding_cursor;
2042 remote_surrounding_text_fd_read_func (void* data, Ecore_Fd_Handler* fd_handler) {
2043 if (fd_handler == NULL || data == NULL)
2044 return ECORE_CALLBACK_RENEW;
2046 WSCContextISF* wsc_ctx = (WSCContextISF*)data;
2048 int fd = ecore_main_fd_handler_fd_get (fd_handler);
2050 return ECORE_CALLBACK_RENEW;
2053 int len = read (fd, buff, sizeof (buff) - 1);
2056 SECURE_LOGD ("remote_surrounding_text : %s, surrounding_cursor : %d", wsc_ctx->remote_surrounding_text, wsc_ctx->surrounding_cursor);
2057 isf_wsc_context_send_surrounding_text (wsc_ctx, wsc_ctx->remote_surrounding_text ? wsc_ctx->remote_surrounding_text : "", wsc_ctx->surrounding_cursor);
2058 } else if (len < 0) {
2062 if (wsc_ctx->remote_surrounding_text == NULL) {
2063 if (len >= (int)sizeof(int)) {
2064 /* Add one byte for terminating NULL character and subtract <int> byte for cursor position */
2065 wsc_ctx->remote_surrounding_text = (char*)malloc (len + 1 - sizeof(int));
2066 if (wsc_ctx->remote_surrounding_text) {
2067 memcpy(&(wsc_ctx->surrounding_cursor), buff, sizeof(int));
2068 memcpy (wsc_ctx->remote_surrounding_text, buff + sizeof(int), len - sizeof(int));
2069 wsc_ctx->remote_surrounding_text[len - sizeof(int)] = '\0';
2070 return ECORE_CALLBACK_RENEW;
2072 LOGE ("malloc failed");
2076 int old_len = strlen (wsc_ctx->remote_surrounding_text);
2077 void * _new = realloc (wsc_ctx->remote_surrounding_text, len + old_len + 1);
2079 wsc_ctx->remote_surrounding_text = (char*)_new;
2080 memcpy (wsc_ctx->remote_surrounding_text + old_len, buff, len);
2081 wsc_ctx->remote_surrounding_text[old_len + len] = '\0';
2082 return ECORE_CALLBACK_RENEW;
2084 LOGE ("realloc failed");
2089 if (wsc_ctx->remote_surrounding_text_fd_read_handler) {
2091 ecore_main_fd_handler_del (wsc_ctx->remote_surrounding_text_fd_read_handler);
2092 wsc_ctx->remote_surrounding_text_fd_read_handler = NULL;
2095 if (wsc_ctx->remote_surrounding_text) {
2096 free (wsc_ctx->remote_surrounding_text);
2097 wsc_ctx->remote_surrounding_text = NULL;
2100 return ECORE_CALLBACK_CANCEL;
2104 remote_surrounding_get (WSCContextISF *wsc_ctx)
2106 if (wsc_ctx && wsc_ctx->im_ctx && wsc_ctx->remote_surrounding_text_fd_read_handler)
2110 if (pipe2(filedes, O_CLOEXEC | O_NONBLOCK) == -1) {
2111 LOGW ("create pipe failed");
2114 LOGD("%d,%d", filedes[0], filedes[1]);
2115 if (wsc_ctx && wsc_ctx->im_ctx) {
2116 wl_input_method_context_get_surrounding_text (wsc_ctx->im_ctx, UINT_MAX, UINT_MAX, filedes[1]);
2117 Ecore_Wl2_Display *wl2_display = ecore_wl2_connected_display_get (NULL);
2119 ecore_wl2_display_flush (wl2_display);
2123 if (wsc_ctx && wsc_ctx->im_ctx) {
2124 if (wsc_ctx->remote_surrounding_text) {
2125 free (wsc_ctx->remote_surrounding_text);
2126 wsc_ctx->remote_surrounding_text = NULL;
2129 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);
2134 Ecore_IMF_Input_Panel_Layout wsc_context_input_panel_layout_get (WSCContextISF *wsc_ctx)
2136 Ecore_IMF_Input_Panel_Layout layout = ECORE_IMF_INPUT_PANEL_LAYOUT_NORMAL;
2141 switch (wsc_ctx->content_purpose) {
2142 case WL_TEXT_INPUT_CONTENT_PURPOSE_DIGITS:
2143 case WL_TEXT_INPUT_CONTENT_PURPOSE_DIGITS_SIGNED:
2144 case WL_TEXT_INPUT_CONTENT_PURPOSE_DIGITS_DECIMAL:
2145 case WL_TEXT_INPUT_CONTENT_PURPOSE_DIGITS_SIGNEDDECIMAL:
2146 layout = ECORE_IMF_INPUT_PANEL_LAYOUT_NUMBERONLY;
2148 case WL_TEXT_INPUT_CONTENT_PURPOSE_NUMBER:
2149 layout = ECORE_IMF_INPUT_PANEL_LAYOUT_NUMBER;
2151 case WL_TEXT_INPUT_CONTENT_PURPOSE_DATE:
2152 layout = ECORE_IMF_INPUT_PANEL_LAYOUT_MONTH;
2154 case WL_TEXT_INPUT_CONTENT_PURPOSE_TIME:
2155 case WL_TEXT_INPUT_CONTENT_PURPOSE_DATETIME:
2156 layout = ECORE_IMF_INPUT_PANEL_LAYOUT_DATETIME;
2158 case WL_TEXT_INPUT_CONTENT_PURPOSE_PHONE:
2159 layout = ECORE_IMF_INPUT_PANEL_LAYOUT_PHONENUMBER;
2161 case WL_TEXT_INPUT_CONTENT_PURPOSE_URL:
2162 layout = ECORE_IMF_INPUT_PANEL_LAYOUT_URL;
2164 case WL_TEXT_INPUT_CONTENT_PURPOSE_EMAIL:
2165 layout = ECORE_IMF_INPUT_PANEL_LAYOUT_EMAIL;
2167 case WL_TEXT_INPUT_CONTENT_PURPOSE_PASSWORD:
2168 case WL_TEXT_INPUT_CONTENT_PURPOSE_PASSWORD_DIGITS:
2169 layout = ECORE_IMF_INPUT_PANEL_LAYOUT_PASSWORD;
2171 case WL_TEXT_INPUT_CONTENT_PURPOSE_HEX:
2172 layout = ECORE_IMF_INPUT_PANEL_LAYOUT_HEX;
2174 case WL_TEXT_INPUT_CONTENT_PURPOSE_TERMINAL:
2175 layout = ECORE_IMF_INPUT_PANEL_LAYOUT_TERMINAL;
2177 case WL_TEXT_INPUT_CONTENT_PURPOSE_IP:
2178 layout = ECORE_IMF_INPUT_PANEL_LAYOUT_IP;
2180 case WL_TEXT_INPUT_CONTENT_PURPOSE_EMOTICON:
2181 layout = ECORE_IMF_INPUT_PANEL_LAYOUT_EMOTICON;
2183 case WL_TEXT_INPUT_CONTENT_PURPOSE_VOICE:
2184 layout = ECORE_IMF_INPUT_PANEL_LAYOUT_VOICE;
2186 case WL_TEXT_INPUT_CONTENT_PURPOSE_NORMAL:
2187 case WL_TEXT_INPUT_CONTENT_PURPOSE_FILENAME:
2188 case WL_TEXT_INPUT_CONTENT_PURPOSE_NAME:
2190 layout = ECORE_IMF_INPUT_PANEL_LAYOUT_NORMAL;
2197 int wsc_context_input_panel_layout_variation_get (WSCContextISF *wsc_ctx)
2199 int layout_variation = 0;
2202 return layout_variation;
2204 switch (wsc_ctx->content_purpose) {
2205 case WL_TEXT_INPUT_CONTENT_PURPOSE_DIGITS:
2206 layout_variation = ECORE_IMF_INPUT_PANEL_LAYOUT_NUMBERONLY_VARIATION_NORMAL;
2208 case WL_TEXT_INPUT_CONTENT_PURPOSE_DIGITS_SIGNED:
2209 layout_variation = ECORE_IMF_INPUT_PANEL_LAYOUT_NUMBERONLY_VARIATION_SIGNED;
2211 case WL_TEXT_INPUT_CONTENT_PURPOSE_DIGITS_DECIMAL:
2212 layout_variation = ECORE_IMF_INPUT_PANEL_LAYOUT_NUMBERONLY_VARIATION_DECIMAL;
2214 case WL_TEXT_INPUT_CONTENT_PURPOSE_DIGITS_SIGNEDDECIMAL:
2215 layout_variation = ECORE_IMF_INPUT_PANEL_LAYOUT_NUMBERONLY_VARIATION_SIGNED_AND_DECIMAL;
2217 case WL_TEXT_INPUT_CONTENT_PURPOSE_PASSWORD:
2218 layout_variation = ECORE_IMF_INPUT_PANEL_LAYOUT_PASSWORD_VARIATION_NORMAL;
2220 case WL_TEXT_INPUT_CONTENT_PURPOSE_PASSWORD_DIGITS:
2221 layout_variation = ECORE_IMF_INPUT_PANEL_LAYOUT_PASSWORD_VARIATION_NUMBERONLY;
2223 case WL_TEXT_INPUT_CONTENT_PURPOSE_NORMAL:
2224 layout_variation = ECORE_IMF_INPUT_PANEL_LAYOUT_NORMAL_VARIATION_NORMAL;
2226 case WL_TEXT_INPUT_CONTENT_PURPOSE_FILENAME:
2227 layout_variation = ECORE_IMF_INPUT_PANEL_LAYOUT_NORMAL_VARIATION_FILENAME;
2229 case WL_TEXT_INPUT_CONTENT_PURPOSE_NAME:
2230 layout_variation = ECORE_IMF_INPUT_PANEL_LAYOUT_NORMAL_VARIATION_PERSON_NAME;
2233 layout_variation = 0;
2237 return layout_variation;
2240 Ecore_IMF_Autocapital_Type wsc_context_autocapital_type_get (WSCContextISF *wsc_ctx)
2242 Ecore_IMF_Autocapital_Type autocapital_type = ECORE_IMF_AUTOCAPITAL_TYPE_NONE;
2245 return autocapital_type;
2247 if (wsc_ctx->content_hint & WL_TEXT_INPUT_CONTENT_HINT_AUTO_CAPITALIZATION)
2248 autocapital_type = ECORE_IMF_AUTOCAPITAL_TYPE_SENTENCE;
2249 else if (wsc_ctx->content_hint & WL_TEXT_INPUT_CONTENT_HINT_WORD_CAPITALIZATION)
2250 autocapital_type = ECORE_IMF_AUTOCAPITAL_TYPE_WORD;
2251 else if (wsc_ctx->content_hint & WL_TEXT_INPUT_CONTENT_HINT_UPPERCASE)
2252 autocapital_type = ECORE_IMF_AUTOCAPITAL_TYPE_ALLCHARACTER;
2254 autocapital_type = ECORE_IMF_AUTOCAPITAL_TYPE_NONE;
2256 return autocapital_type;
2259 bool wsc_context_input_panel_caps_lock_mode_get (WSCContextISF *wsc_ctx)
2264 if (wsc_ctx->content_hint & WL_TEXT_INPUT_CONTENT_HINT_UPPERCASE)
2270 Ecore_IMF_Input_Panel_Lang wsc_context_input_panel_language_get (WSCContextISF *wsc_ctx)
2272 Ecore_IMF_Input_Panel_Lang language = ECORE_IMF_INPUT_PANEL_LANG_AUTOMATIC;
2277 if (wsc_ctx->content_hint & WL_TEXT_INPUT_CONTENT_HINT_LATIN)
2278 language = ECORE_IMF_INPUT_PANEL_LANG_ALPHABET;
2280 language = ECORE_IMF_INPUT_PANEL_LANG_AUTOMATIC;
2285 bool wsc_context_input_panel_password_mode_get (WSCContextISF *wsc_ctx)
2287 if (wsc_ctx->content_hint & WL_TEXT_INPUT_CONTENT_HINT_PASSWORD)
2290 if (wsc_context_input_panel_layout_get (wsc_ctx) == ECORE_IMF_INPUT_PANEL_LAYOUT_PASSWORD)
2296 Ecore_IMF_Input_Hints wsc_context_input_hint_get (WSCContextISF *wsc_ctx)
2298 int input_hint = ECORE_IMF_INPUT_HINT_NONE;
2301 return (Ecore_IMF_Input_Hints)input_hint;
2303 if (wsc_ctx->content_hint & WL_TEXT_INPUT_CONTENT_HINT_SENSITIVE_DATA)
2304 input_hint |= ECORE_IMF_INPUT_HINT_SENSITIVE_DATA;
2306 input_hint &= ~ECORE_IMF_INPUT_HINT_SENSITIVE_DATA;
2308 if (wsc_ctx->content_hint & WL_TEXT_INPUT_CONTENT_HINT_AUTO_COMPLETION)
2309 input_hint |= ECORE_IMF_INPUT_HINT_AUTO_COMPLETE;
2311 input_hint &= ~ECORE_IMF_INPUT_HINT_AUTO_COMPLETE;
2313 if (wsc_ctx->content_hint & WL_TEXT_INPUT_CONTENT_HINT_MULTILINE)
2314 input_hint |= ECORE_IMF_INPUT_HINT_MULTILINE;
2316 input_hint &= ~ECORE_IMF_INPUT_HINT_MULTILINE;
2319 switch (wsc_ctx->content_hint & WL_TEXT_INPUT_CONTENT_HINT_AUTOFILL_MASK)
2321 case WL_TEXT_INPUT_CONTENT_HINT_AUTOFILL_CREDIT_CARD_EXPIRATION_DATE:
2322 input_hint |= ECORE_IMF_INPUT_HINT_AUTOFILL_CREDIT_CARD_EXPIRATION_DATE;
2324 case WL_TEXT_INPUT_CONTENT_HINT_AUTOFILL_CREDIT_CARD_EXPIRATION_DAY:
2325 input_hint |= ECORE_IMF_INPUT_HINT_AUTOFILL_CREDIT_CARD_EXPIRATION_DAY;
2327 case WL_TEXT_INPUT_CONTENT_HINT_AUTOFILL_CREDIT_CARD_EXPIRATION_MONTH:
2328 input_hint |= ECORE_IMF_INPUT_HINT_AUTOFILL_CREDIT_CARD_EXPIRATION_MONTH;
2330 case WL_TEXT_INPUT_CONTENT_HINT_AUTOFILL_CREDIT_CARD_EXPIRATION_YEAR:
2331 input_hint |= ECORE_IMF_INPUT_HINT_AUTOFILL_CREDIT_CARD_EXPIRATION_YEAR;
2333 case WL_TEXT_INPUT_CONTENT_HINT_AUTOFILL_CREDIT_CARD_NUMBER:
2334 input_hint |= ECORE_IMF_INPUT_HINT_AUTOFILL_CREDIT_CARD_NUMBER;
2336 case WL_TEXT_INPUT_CONTENT_HINT_AUTOFILL_EMAIL_ADDRESS:
2337 input_hint |= ECORE_IMF_INPUT_HINT_AUTOFILL_EMAIL_ADDRESS;
2339 case WL_TEXT_INPUT_CONTENT_HINT_AUTOFILL_PHONE:
2340 input_hint |= ECORE_IMF_INPUT_HINT_AUTOFILL_PHONE;
2342 case WL_TEXT_INPUT_CONTENT_HINT_AUTOFILL_POSTAL_ADDRESS:
2343 input_hint |= ECORE_IMF_INPUT_HINT_AUTOFILL_POSTAL_ADDRESS;
2345 case WL_TEXT_INPUT_CONTENT_HINT_AUTOFILL_POSTAL_CODE:
2346 input_hint |= ECORE_IMF_INPUT_HINT_AUTOFILL_POSTAL_CODE;
2348 case WL_TEXT_INPUT_CONTENT_HINT_AUTOFILL_ID:
2349 input_hint |= ECORE_IMF_INPUT_HINT_AUTOFILL_ID;
2351 case WL_TEXT_INPUT_CONTENT_HINT_AUTOFILL_NAME:
2352 input_hint |= ECORE_IMF_INPUT_HINT_AUTOFILL_NAME;
2356 return (Ecore_IMF_Input_Hints)input_hint;
2359 Eina_Bool wsc_context_prediction_allow_get (WSCContextISF *wsc_ctx)
2364 if (wsc_ctx->content_hint & WL_TEXT_INPUT_CONTENT_HINT_AUTO_COMPLETION)
2370 Ecore_IMF_BiDi_Direction wsc_context_bidi_direction_get (WSCContextISF *wsc_ctx)
2372 return (Ecore_IMF_BiDi_Direction)wsc_ctx->bidi_direction;
2375 void wsc_context_delete_surrounding (WSCContextISF *wsc_ctx, int offset, int len)
2377 LOGD ("offset = %d, len = %d", offset, len);
2382 wl_input_method_context_delete_surrounding_text (wsc_ctx->im_ctx, offset, len);
2385 void wsc_context_set_selection (WSCContextISF *wsc_ctx, int start, int end)
2390 wl_input_method_context_selection_region (wsc_ctx->im_ctx, wsc_ctx->serial, start, end);
2393 void wsc_context_commit_string (WSCContextISF *wsc_ctx, const char *str)
2398 if (wsc_ctx->preedit_str) {
2399 free (wsc_ctx->preedit_str);
2400 wsc_ctx->preedit_str = NULL;
2403 wsc_ctx->preedit_str = strdup (str);
2404 wsc_commit_preedit (wsc_ctx);
2407 void wsc_context_commit_preedit_string (WSCContextISF *wsc_ctx)
2409 char* preedit_str = NULL;
2415 isf_wsc_context_preedit_string_get (wsc_ctx, &preedit_str, &cursor_pos);
2417 if (wsc_ctx->preedit_str) {
2418 free (wsc_ctx->preedit_str);
2419 wsc_ctx->preedit_str = NULL;
2422 wsc_ctx->preedit_str = preedit_str;
2423 wsc_commit_preedit (wsc_ctx);
2426 void wsc_context_send_preedit_string (WSCContextISF *wsc_ctx)
2428 char* preedit_str = NULL;
2434 isf_wsc_context_preedit_string_get (wsc_ctx, &preedit_str, &cursor_pos);
2436 if (wsc_ctx->preedit_str) {
2437 free (wsc_ctx->preedit_str);
2438 wsc_ctx->preedit_str = NULL;
2441 wsc_ctx->preedit_str = preedit_str;
2442 wsc_send_preedit (wsc_ctx, cursor_pos);
2445 void wsc_context_send_key (WSCContextISF *wsc_ctx, uint32_t keysym, uint32_t modifiers, uint32_t time, bool press)
2447 if (!wsc_ctx || !wsc_ctx->im_ctx)
2450 wl_input_method_context_keysym (wsc_ctx->im_ctx, wsc_ctx->serial, time,
2451 keysym, press ? WL_KEYBOARD_KEY_STATE_PRESSED : WL_KEYBOARD_KEY_STATE_RELEASED, modifiers);
2455 set_ic_capabilities (WSCContextISF *ic)
2457 SCIM_DEBUG_FRONTEND (1) << __FUNCTION__ << "...\n";
2459 if (ic && ic->impl) {
2460 unsigned int cap = SCIM_CLIENT_CAP_ALL_CAPABILITIES;
2462 if (!_on_the_spot || !ic->impl->use_preedit)
2463 cap -= SCIM_CLIENT_CAP_ONTHESPOT_PREEDIT;
2465 //FIXME:add this interface
2466 //_info_manager->update_client_capabilities (cap);
2473 /* Panel Request functions. */
2475 panel_req_show_help (WSCContextISF *ic)
2477 SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
2481 help = String (_("Smart Common Input Method platform ")) +
2482 String (SCIM_VERSION) +
2483 String (_("\n(C) 2002-2005 James Su <suzhe@tsinghua.org.cn>\n\n"));
2485 if (ic && ic->impl && ic->impl->si) {
2486 IMEngineFactoryPointer sf = _backend->get_factory (ic->impl->si->get_factory_uuid ());
2488 help += utf8_wcstombs (sf->get_name ());
2489 help += String (_(":\n\n"));
2491 help += utf8_wcstombs (sf->get_help ());
2492 help += String (_("\n\n"));
2494 help += utf8_wcstombs (sf->get_credits ());
2497 g_info_manager->socket_show_help (help);
2500 g_info_manager->remoteinput_callback_focus_out ();
2501 LOGD("Remote control button click");
2506 panel_req_update_bidi_direction (WSCContextISF *ic, int direction)
2508 SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
2511 g_info_manager->update_ise_bidi_direction (WAYLAND_MODULE_CLIENT_ID, direction);
2515 filter_keys (const char *keyname, const char *config_path)
2517 SCIM_DEBUG_FRONTEND (1) << __FUNCTION__ << "...\n";
2521 std::vector <String> keys;
2522 scim_split_string_list (keys, _config->read (String (config_path), String ("")), ',');
2524 for (unsigned int i = 0; i < keys.size (); ++i) {
2525 if (!strcmp (keyname, keys [i].c_str ())) {
2534 panel_initialize (void)
2536 SCIM_DEBUG_FRONTEND (1) << __FUNCTION__ << "...\n";
2537 String display_name;
2539 const char *p = getenv ("DISPLAY");
2540 if (p) display_name = String (p);
2542 g_info_manager->add_client (WAYLAND_MODULE_CLIENT_ID, 2, FRONTEND_CLIENT);
2543 _panel_client_id = WAYLAND_MODULE_CLIENT_ID;
2544 g_info_manager->register_panel_client (_panel_client_id, _panel_client_id);
2545 WSCContextISF* context_scim = _ic_list;
2546 _launch_ise_on_request = scim_global_config_read (String (SCIM_GLOBAL_CONFIG_LAUNCH_ISE_ON_REQUEST), false);
2548 while (context_scim != NULL) {
2549 //FIXME:modify the parameter
2550 g_info_manager->register_input_context (WAYLAND_MODULE_CLIENT_ID, context_scim->id, "");
2552 context_scim = context_scim->next;
2561 panel_finalize (void)
2563 SCIM_DEBUG_FRONTEND (1) << __FUNCTION__ << "...\n";
2565 g_info_manager->del_client (WAYLAND_MODULE_CLIENT_ID);
2569 panel_slot_update_preedit_caret (int context, int caret)
2572 WSCContextISF* ic = find_ic (context);
2573 SCIM_DEBUG_FRONTEND (1) << __FUNCTION__ << " context=" << context << " caret=" << caret << " ic=" << ic << "\n";
2575 if (ic && ic->impl && _focused_ic == ic && ic->impl->preedit_caret != caret) {
2576 ic->impl->preedit_caret = caret;
2577 if (ic->impl->use_preedit) {
2578 if (!ic->impl->preedit_started) {
2579 if (check_valid_ic (ic))
2580 ic->impl->preedit_started = true;
2582 wsc_send_preedit (ic, caret);
2584 g_info_manager->socket_update_preedit_caret (caret);
2590 panel_slot_process_key_event (int context, const KeyEvent &key)
2592 WSCContextISF* ic = find_ic (context);
2593 SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << " context=" << context << " key=" << key.get_key_string () << " ic=" << ic << "\n";
2595 if (!(ic && ic->impl))
2598 if ((_focused_ic != NULL) && (_focused_ic != ic))
2601 send_wl_key_event (ic, key, false);
2605 panel_slot_commit_string (int context, const WideString &wstr, bool remote_mode)
2608 WSCContextISF* ic = find_ic (context);
2609 SCIM_DEBUG_FRONTEND (1) << __FUNCTION__ << " context=" << context << " str=" << utf8_wcstombs (wstr) << " ic=" << ic << "\n";
2611 if (ic && ic->impl) {
2612 if (_focused_ic != ic)
2616 if (ic->impl->block_input_resource) {
2617 LOGW ("block remote input");
2620 check_input_resource (ic, INPUT_RESOURCE_REMOTE);
2622 if (ic->impl->panel_layout == ECORE_IMF_INPUT_PANEL_LAYOUT_URL)
2623 wsc_context_delete_surrounding (ic, INT_MIN/2, INT_MAX);
2625 wsc_context_commit_string (ic, utf8_wcstombs (wstr).c_str ());
2626 ic->impl->need_commit_preedit = false;
2627 ic->impl->preedit_string.clear ();
2629 check_input_resource (ic, INPUT_RESOURCE_LOCAL);
2630 wsc_context_commit_string (ic, utf8_wcstombs (wstr).c_str ());
2636 panel_slot_forward_key_event (int context, const KeyEvent &key, bool remote_mode)
2639 WSCContextISF* ic = find_ic (context);
2640 SCIM_DEBUG_FRONTEND (1) << __FUNCTION__ << " context=" << context << " key=" << key.get_key_string () << " ic=" << ic << "\n";
2642 if (!(ic && ic->impl))
2645 if ((_focused_ic != NULL) && (_focused_ic != ic))
2649 if (ic->impl->block_input_resource) {
2650 LOGW ("block remote input");
2653 check_input_resource (ic, INPUT_RESOURCE_REMOTE);
2655 check_input_resource (ic, INPUT_RESOURCE_LOCAL);
2658 if (key.get_key_string ().length () >= 116)
2661 send_wl_key_event (ic, key, true);
2665 panel_slot_update_preedit_string (int context, const WideString str, const WideString commit, const AttributeList &attrs, int caret, bool remote_mode)
2668 WSCContextISF* ic = find_ic (context);
2669 SCIM_DEBUG_FRONTEND (1) << __FUNCTION__ << " context=" << context << " caret=" << caret << " ic=" << ic << "\n";
2671 if (ic && ic->impl && _focused_ic == ic) {
2673 if (ic->impl->block_input_resource) {
2674 LOGW ("block remote input");
2677 check_input_resource (ic, INPUT_RESOURCE_REMOTE);
2680 if (!ic->impl->is_on)
2681 ic->impl->is_on = true;
2683 if (ic->impl->preedit_string != str || str.length ()) {
2684 ic->impl->preedit_string = str;
2685 ic->impl->preedit_attrlist = attrs;
2686 ic->impl->commit_string = commit;
2688 if (ic->impl->use_preedit) {
2689 if (!ic->impl->preedit_started) {
2690 if (!check_valid_ic (ic))
2693 ic->impl->preedit_started = true;
2694 ic->impl->need_commit_preedit = true;
2696 if (caret >= 0 && caret <= (int)str.length ())
2697 ic->impl->preedit_caret = caret;
2699 ic->impl->preedit_caret = str.length ();
2701 if (ic->impl->panel_layout == ECORE_IMF_INPUT_PANEL_LAYOUT_URL)
2702 wsc_context_delete_surrounding (ic, INT_MIN/2, INT_MAX);
2704 wsc_context_send_preedit_string (ic);
2706 String _str = utf8_wcstombs (str);
2707 g_info_manager->socket_update_preedit_string (_str, attrs, (uint32)caret);
2714 _show_preedit_string (int context)
2717 WSCContextISF* ic = find_ic (context);
2718 SCIM_DEBUG_FRONTEND (1) << __FUNCTION__ << " context=" << context << "\n";
2720 if (ic && ic->impl && _focused_ic == ic) {
2721 if (!ic->impl->is_on)
2722 ic->impl->is_on = true;
2724 if (ic->impl->use_preedit) {
2725 if (!ic->impl->preedit_started) {
2726 if (check_valid_ic (ic)) {
2727 ic->impl->preedit_started = true;
2728 ic->impl->need_commit_preedit = true;
2732 g_info_manager->socket_show_preedit_string ();
2738 _hide_preedit_string (int context, bool update_preedit)
2740 SCIM_DEBUG_FRONTEND (1) << __FUNCTION__ << "...\n";
2742 WSCContextISF* ic = find_ic (context);
2744 if (ic && ic->impl && _focused_ic == ic) {
2745 if (!ic->impl->is_on)
2746 ic->impl->is_on = true;
2749 if (ic->impl->preedit_string.length ()) {
2750 ic->impl->preedit_string = WideString ();
2751 ic->impl->preedit_caret = 0;
2752 ic->impl->preedit_attrlist.clear ();
2755 ic->impl->commit_string = WideString ();
2756 if (ic->impl->use_preedit) {
2757 if (update_preedit && emit) {
2758 if (!check_valid_ic (ic))
2761 if (ic->impl->preedit_started) {
2762 if (check_valid_ic (ic)) {
2763 ic->impl->preedit_started = false;
2764 ic->impl->need_commit_preedit = false;
2767 wsc_context_send_preedit_string (ic);
2769 g_info_manager->socket_hide_preedit_string ();
2777 LOGD ("Initializing Wayland ISF IMModule...");
2779 // Get system language.
2780 _language = scim_get_locale_language (scim_get_current_locale ());
2782 panel_initialize ();
2788 LOGD ("Finalizing Ecore ISF IMModule...");
2790 SCIM_DEBUG_FRONTEND(2) << "Finalize all IC partially.\n";
2791 while (_used_ic_impl_list) {
2792 // In case in "shared input method" mode,
2793 // all contexts share only one instance,
2794 // so we need point the reference pointer correctly before finalizing.
2796 if (_used_ic_impl_list->si) {
2797 _used_ic_impl_list->si->set_frontend_data (static_cast <void*> (_used_ic_impl_list->parent));
2800 if (_used_ic_impl_list->parent && _used_ic_impl_list->parent->ctx) {
2801 isf_wsc_context_del (_used_ic_impl_list->parent);
2805 delete_all_ic_impl ();
2807 SCIM_DEBUG_FRONTEND(2) << " Releasing Config...\n";
2812 _scim_initialized = false;
2816 static uint32_t _keyname_to_keysym (uint32_t keyname, uint32_t *modifiers)
2821 if ((keyname >= '0' && keyname <= '9') ||
2822 (keyname >= 'a' && keyname <= 'z')) {
2824 } else if (keyname >= 'A' && keyname <= 'Z') {
2825 *modifiers |= MOD_SHIFT_MASK;
2826 return keyname + 32;
2831 *modifiers |= MOD_SHIFT_MASK;
2834 *modifiers |= MOD_SHIFT_MASK;
2837 *modifiers |= MOD_SHIFT_MASK;
2840 *modifiers |= MOD_SHIFT_MASK;
2843 *modifiers |= MOD_SHIFT_MASK;
2846 *modifiers |= MOD_SHIFT_MASK;
2849 *modifiers |= MOD_SHIFT_MASK;
2852 *modifiers |= MOD_SHIFT_MASK;
2855 *modifiers |= MOD_SHIFT_MASK;
2858 *modifiers |= MOD_SHIFT_MASK;
2861 *modifiers |= MOD_SHIFT_MASK;
2864 *modifiers |= MOD_SHIFT_MASK;
2867 *modifiers |= MOD_SHIFT_MASK;
2870 *modifiers |= MOD_SHIFT_MASK;
2873 *modifiers |= MOD_SHIFT_MASK;
2876 *modifiers |= MOD_SHIFT_MASK;
2879 *modifiers |= MOD_SHIFT_MASK;
2882 *modifiers |= MOD_SHIFT_MASK;
2885 *modifiers |= MOD_SHIFT_MASK;
2888 *modifiers |= MOD_SHIFT_MASK;
2895 static bool _check_remote_input_finished (const uint32 keycode, const bool pressed, const bool fake)
2897 if (pressed == false && fake == true && (keycode == SCIM_KEY_Select || keycode == SCIM_KEY_Cancel)) {
2903 static void send_wl_key_event (WSCContextISF *ic, const KeyEvent &key, bool fake)
2905 SCIM_DEBUG_FRONTEND (1) << __FUNCTION__ << "...\n";
2908 uint32_t modifiers = 0;
2913 modifiers |= MOD_Mod5_MASK;
2916 if (key.is_shift_down ())
2917 modifiers |= MOD_SHIFT_MASK;
2918 if (key.is_alt_down ())
2919 modifiers |= MOD_ALT_MASK;
2920 if (key.is_control_down ())
2921 modifiers |= MOD_CONTROL_MASK;
2922 if (key.is_super_down ())
2923 modifiers |= MOD_SUPER_MASK;
2925 _keyname_to_keysym (key.code, &modifiers);
2928 wsc_context_send_key (ic, key.code, modifiers, time, key.is_key_press ());
2929 if (_check_remote_input_finished (key.code, key.is_key_press (), fake))
2930 ic->impl->input_resource = INPUT_RESOURCE_NONE;
2935 reload_config_callback (const ConfigPointer &config)
2937 SCIM_DEBUG_FRONTEND (1) << __FUNCTION__ << "...\n";
2939 //FIXME:_frontend_hotkey_matcher and _imengine_hotkey_matcher should be added
2940 //_frontend_hotkey_matcher.load_hotkeys (config);
2941 //_imengine_hotkey_matcher.load_hotkeys (config);
2944 scim_string_to_key (key,
2945 config->read (String (SCIM_CONFIG_HOTKEYS_FRONTEND_VALID_KEY_MASK),
2946 String ("Shift+Control+Alt+Lock")));
2948 _valid_key_mask = (key.mask > 0) ? (key.mask) : 0xFFFF;
2949 _valid_key_mask |= SCIM_KEY_ReleaseMask;
2950 // Special treatment for two backslash keys on jp106 keyboard.
2951 _valid_key_mask |= SCIM_KEY_QuirkKanaRoMask;
2953 _on_the_spot = config->read (String (SCIM_CONFIG_FRONTEND_ON_THE_SPOT), _on_the_spot);
2954 //_shared_input_method = config->read (String (SCIM_CONFIG_FRONTEND_SHARED_INPUT_METHOD), _shared_input_method);
2955 _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);
2956 _support_hw_keyboard_mode = scim_global_config_read (String (SCIM_GLOBAL_CONFIG_SUPPORT_HW_KEYBOARD_MODE), _support_hw_keyboard_mode);
2958 // Get keyboard layout setting
2959 // Flush the global config first, in order to load the new configs from disk.
2960 scim_global_config_flush ();
2962 _keyboard_layout = scim_get_default_keyboard_layout ();
2965 class WaylandPanelAgent: public PanelAgentBase
2967 Connection _config_connection;
2970 WaylandPanelAgent ()
2971 : PanelAgentBase ("wayland") {
2973 ~WaylandPanelAgent () {
2976 bool initialize (InfoManager* info_manager, const String& display, bool resident) {
2978 g_info_manager = info_manager;
2979 isf_wsc_context_init ();
2981 if (!_wsc_setup (&_wsc)) {
2985 _config_connection = _config->signal_connect_reload (slot (reload_config_callback));
2987 _wl_im_ctx = new _wl_im;
2989 LOGW ("Can not create wl_im_ctx");
2995 bool valid (void) const {
3000 if (_need_wl_im_init) {
3001 LOGD("destroy wl_input_method_context");
3010 _config_connection.disconnect ();
3011 isf_wsc_context_shutdown ();
3016 exit (int id, uint32 contextid) {
3017 LOGD ("client id:%d", id);
3022 update_preedit_caret (int id, uint32 context_id, uint32 caret) {
3023 LOGD ("client id:%d", id);
3024 panel_slot_update_preedit_caret (context_id, caret);
3028 socket_helper_key_event (int id, uint32 context_id, int cmd , KeyEvent& key) {
3029 LOGD ("client id:%d", id);
3031 if (cmd == SCIM_TRANS_CMD_PROCESS_KEY_EVENT)
3032 panel_slot_process_key_event (context_id, key);
3034 panel_slot_forward_key_event (context_id, key, false);
3038 commit_string (int id, uint32 context_id, const WideString& wstr) {
3039 LOGD ("client id:%d", id);
3040 panel_slot_commit_string (context_id, wstr, false);
3044 forward_key_event (int id, uint32 context_id, const KeyEvent &key) {
3045 LOGD ("client id:%d", id);
3046 panel_slot_forward_key_event (context_id, key, false);
3050 remote_commit_string (int id, uint32 context_id, const WideString& wstr) {
3051 LOGD ("client id:%d", id);
3052 panel_slot_commit_string (context_id, wstr, true);
3056 remote_update_preedit_string (int id, uint32 context_id, const WideString str, const WideString commit, const AttributeList &attrs, uint32 caret) {
3057 LOGD ("client id:%d", id);
3058 panel_slot_update_preedit_string (context_id, str, commit, attrs, caret, true);
3062 remote_forward_key_event (int id, uint32 context_id, const KeyEvent &key) {
3063 LOGD ("client id:%d", id);
3064 panel_slot_forward_key_event (context_id, key, true);
3068 remote_delete_surrounding_text (int id, uint32 context_id, uint32 offset, uint32 len) {
3069 LOGD ("client id:%d", id);
3072 if (_focused_ic->impl->block_input_resource)
3075 check_input_resource (_focused_ic, INPUT_RESOURCE_REMOTE);
3076 wsc_context_delete_surrounding (_focused_ic, offset, len);
3081 update_ise_input_context (int client, uint32 context, uint32 type, uint32 value) {
3082 if (!_focused_ic || !_focused_ic->im_ctx)
3085 if (type == ECORE_IMF_INPUT_PANEL_LANGUAGE_EVENT) {
3086 WSCContextISF* ic = find_ic (context);
3087 if (ic && ic->language) {
3088 wl_input_method_context_language (_focused_ic->im_ctx, _focused_ic->serial, ic->language);
3091 LOGE("language locale query failed : %p %s", ic, (ic ? ic->language : "NULL"));
3092 wl_input_method_context_language (_focused_ic->im_ctx, _focused_ic->serial, "");
3095 wl_input_method_context_input_panel_event (_focused_ic->im_ctx, _focused_ic->serial, type, value);
3099 update_ise_language_locale (int client, uint32 context, String locale) {
3100 if (!_focused_ic || !_focused_ic->im_ctx)
3103 WSCContextISF* ic = find_ic (context);
3104 if (ic && locale.length() > 0) {
3107 ic->language = NULL;
3109 ic->language = strdup(locale.c_str());
3115 request_help (int id, uint32 context_id) {
3116 LOGD ("client id:%d", id);
3117 panel_slot_request_help (context_id);
3122 request_factory_menu (int id, uint32 context_id) {
3123 LOGD ("client id:%d", id);
3124 panel_slot_request_factory_menu (context_id);
3128 change_factory (int id, uint32 context_id, const String& uuid) {
3129 LOGD ("client id:%d", id);
3130 panel_slot_change_factory (context_id, uuid);
3135 reset_keyboard_ise (int id, uint32 context_id) {
3136 LOGD ("client id:%d", id);
3137 panel_slot_reset_keyboard_ise (context_id);
3142 update_keyboard_ise (int id, uint32 context_id) {
3143 LOGD ("client id:%d", id);
3144 panel_slot_update_keyboard_ise (context_id);
3149 show_preedit_string (int id, uint32 context_id) {
3150 LOGD ("client id:%d", id);
3151 _show_preedit_string (context_id);
3155 hide_preedit_string (int id, uint32 context_id) {
3156 LOGD ("client id:%d", id);
3157 _hide_preedit_string (context_id, true);
3161 update_preedit_string (int id, uint32 context_id, WideString preedit, WideString commit, AttributeList& attrs, uint32 caret) {
3162 LOGD ("client id:%d", id);
3163 SCIM_DEBUG_FRONTEND (1) << __FUNCTION__ << "...\n";
3164 WSCContextISF* ic = find_ic (context_id);
3166 if (ic && ic->impl && _focused_ic == ic) {
3167 if (!ic->impl->is_on)
3168 ic->impl->is_on = true;
3170 check_input_resource (ic, INPUT_RESOURCE_LOCAL);
3172 ic->impl->preedit_string = preedit;
3173 ic->impl->preedit_attrlist = attrs;
3174 ic->impl->commit_string = commit;
3176 if (ic->impl->use_preedit) {
3177 if (!ic->impl->preedit_started) {
3178 if (!check_valid_ic (ic))
3181 ic->impl->preedit_started = true;
3182 ic->impl->need_commit_preedit = true;
3184 if (caret <= preedit.length ())
3185 ic->impl->preedit_caret = caret;
3187 ic->impl->preedit_caret = preedit.length ();
3188 wsc_context_send_preedit_string (ic);
3190 String _str = utf8_wcstombs (preedit);
3191 g_info_manager->socket_update_preedit_string (_str, attrs, (uint32)caret);
3197 recapture_string (int id, uint32 context_id, int offset, int len, WideString preedit, WideString commit, AttributeList& attrs) {
3198 LOGD ("client id:%d", id);
3199 SCIM_DEBUG_FRONTEND (1) << __FUNCTION__ << "...\n";
3200 WSCContextISF* ic = find_ic (context_id);
3201 String preedit_str = utf8_wcstombs (preedit);
3202 String commit_str = utf8_wcstombs (commit);
3204 if (ic && ic->impl && _focused_ic == ic) {
3205 if (!ic->impl->is_on)
3206 ic->impl->is_on = true;
3208 check_input_resource (ic, INPUT_RESOURCE_LOCAL);
3210 ic->impl->preedit_string = preedit;
3211 ic->impl->preedit_attrlist = attrs;
3212 ic->impl->commit_string = commit;
3214 if (ic->impl->use_preedit) {
3215 if (!ic->impl->preedit_started) {
3216 if (!check_valid_ic (ic))
3219 ic->impl->preedit_started = true;
3220 ic->impl->need_commit_preedit = true;
3222 ic->impl->preedit_caret = preedit.length ();
3224 wl_input_method_context_preedit_cursor (ic->im_ctx, strlen(preedit_str.c_str()));
3225 wsc_send_preedit_style (ic);
3227 wl_input_method_context_recapture_string (ic->im_ctx, ic->serial,
3228 offset, len, preedit_str.c_str(), preedit_str.c_str(), commit_str.c_str());
3230 g_info_manager->socket_recapture_string (offset, len, preedit_str, commit_str, attrs);
3236 surrounding_text_fd_read_func (void* data, Ecore_Fd_Handler* fd_handler) {
3237 if (fd_handler == NULL || data == NULL)
3238 return ECORE_CALLBACK_RENEW;
3240 WSCContextISF* wsc_ctx = (WSCContextISF*)data;
3242 int fd = ecore_main_fd_handler_fd_get (fd_handler);
3244 return ECORE_CALLBACK_RENEW;
3247 int len = read (fd, buff, sizeof (buff) - 1);
3249 LOGD ("update, wsc_ctx->surrounding_cursor = %d", wsc_ctx->surrounding_cursor);
3250 g_info_manager->socket_update_surrounding_text (wsc_ctx->surrounding_text ? wsc_ctx->surrounding_text : "", wsc_ctx->surrounding_cursor);
3251 } else if (len < 0) {
3255 if (wsc_ctx->surrounding_text == NULL) {
3256 if (len >= (int)sizeof(int)) {
3257 /* Add one byte for terminating NULL character and subtract <int> byte for cursor position */
3258 wsc_ctx->surrounding_text = (char*)malloc (len + 1 - sizeof(int));
3259 if (wsc_ctx->surrounding_text) {
3260 memcpy(&(wsc_ctx->surrounding_cursor), buff, sizeof(int));
3261 memcpy (wsc_ctx->surrounding_text, buff + sizeof(int), len - sizeof(int));
3262 wsc_ctx->surrounding_text[len - sizeof(int)] = '\0';
3263 return ECORE_CALLBACK_RENEW;
3265 LOGE ("malloc failed");
3269 int old_len = strlen (wsc_ctx->surrounding_text);
3270 void * _new = realloc (wsc_ctx->surrounding_text, len + old_len + 1);
3272 wsc_ctx->surrounding_text = (char*)_new;
3273 memcpy (wsc_ctx->surrounding_text + old_len, buff, len);
3274 wsc_ctx->surrounding_text[old_len + len] = '\0';
3275 return ECORE_CALLBACK_RENEW;
3277 LOGE ("realloc failed");
3282 if (wsc_ctx->surrounding_text_fd_read_handler) {
3284 ecore_main_fd_handler_del (wsc_ctx->surrounding_text_fd_read_handler);
3285 wsc_ctx->surrounding_text_fd_read_handler = NULL;
3288 if (wsc_ctx->surrounding_text) {
3289 free (wsc_ctx->surrounding_text);
3290 wsc_ctx->surrounding_text = NULL;
3293 return ECORE_CALLBACK_RENEW;
3297 socket_helper_get_surrounding_text (int id, uint32 context_id, uint32 maxlen_before, uint32 maxlen_after) {
3298 LOGD ("client id:%d", id);
3301 if (pipe2(filedes, O_CLOEXEC | O_NONBLOCK) == -1) {
3302 LOGW ("create pipe failed");
3305 LOGD("%d,%d", filedes[0], filedes[1]);
3306 WSCContextISF* ic = find_ic (context_id);
3310 wl_input_method_context_get_surrounding_text (ic->im_ctx, maxlen_before, maxlen_after, filedes[1]);
3312 Ecore_Wl2_Display *wl2_display = ecore_wl2_connected_display_get (NULL);
3314 ecore_wl2_display_flush (wl2_display);
3317 if (ic->surrounding_text_fd_read_handler) {
3318 int fd = ecore_main_fd_handler_fd_get (ic->surrounding_text_fd_read_handler);
3321 ecore_main_fd_handler_del (ic->surrounding_text_fd_read_handler);
3322 ic->surrounding_text_fd_read_handler = NULL;
3325 if (ic->surrounding_text) {
3326 free (ic->surrounding_text);
3327 ic->surrounding_text = NULL;
3330 ic->surrounding_text_fd_read_handler = ecore_main_fd_handler_add (filedes[0], ECORE_FD_READ, surrounding_text_fd_read_func, ic, NULL, NULL);
3334 socket_helper_delete_surrounding_text (int id, uint32 context_id, uint32 offset, uint32 len) {
3335 LOGD ("client id:%d", id);
3336 //panel_slot_delete_surrounding_text (context_id, offset, len);
3338 check_input_resource (_focused_ic, INPUT_RESOURCE_LOCAL);
3339 wsc_context_delete_surrounding (_focused_ic, offset, len);
3344 socket_helper_set_selection (int id, uint32 context_id, uint32 start, uint32 end) {
3345 LOGD ("client id:%d", id);
3347 wsc_context_set_selection (_focused_ic, start, end);
3351 send_private_command (int id, uint32 context_id, const String& command) {
3352 LOGD ("client id:%d", id);
3353 //panel_slot_send_private_command (context_id, command);
3354 if (_focused_ic && _focused_ic->im_ctx)
3355 wl_input_method_context_private_command (_focused_ic->im_ctx, _focused_ic->serial, command.c_str ());
3359 commit_content (int id, uint32 context_id, const String& content, const String& description, const String& mime_types) {
3360 LOGD ("client id:%d", id);
3361 if (_focused_ic && _focused_ic->im_ctx)
3362 wl_input_method_context_commit_content (_focused_ic->im_ctx, _focused_ic->serial, content.c_str (), description.c_str (), mime_types.c_str ());
3366 hide_helper_ise (int id, uint32 context_id)
3368 LOGD ("client id:%d", id);
3369 WSCContextISF* ic = find_ic (context_id);
3372 wl_input_method_context_hide_input_panel (ic->im_ctx, ic->serial);
3377 selection_text_fd_read_func (void* data, Ecore_Fd_Handler* fd_handler) {
3378 if (fd_handler == NULL || data == NULL)
3379 return ECORE_CALLBACK_RENEW;
3381 WSCContextISF* wsc_ctx = (WSCContextISF*)data;
3382 int fd = ecore_main_fd_handler_fd_get (fd_handler);
3384 return ECORE_CALLBACK_RENEW;
3387 int len = read (fd, buff, sizeof (buff) - 1);
3390 g_info_manager->socket_update_selection (wsc_ctx->selection_text ? wsc_ctx->selection_text : "");
3391 } else if (len < 0) {
3395 if (wsc_ctx->selection_text == NULL) {
3396 wsc_ctx->selection_text = (char*)malloc (len + 1);
3397 if (wsc_ctx->selection_text) {
3398 memcpy (wsc_ctx->selection_text, buff, len);
3399 wsc_ctx->selection_text[len] = '\0';
3400 return ECORE_CALLBACK_RENEW;
3402 LOGE ("malloc failed");
3405 int old_len = strlen (wsc_ctx->selection_text);
3406 void * _new = realloc (wsc_ctx->selection_text, len + old_len + 1);
3408 wsc_ctx->selection_text = (char*)_new;
3409 memcpy (wsc_ctx->selection_text + old_len, buff, len);
3410 wsc_ctx->selection_text[old_len + len] = '\0';
3411 return ECORE_CALLBACK_RENEW;
3413 LOGE ("realloc failed");
3418 if (wsc_ctx->selection_text_fd_read_handler) {
3420 ecore_main_fd_handler_del (wsc_ctx->selection_text_fd_read_handler);
3421 wsc_ctx->selection_text_fd_read_handler = NULL;
3424 if (wsc_ctx->selection_text) {
3425 free (wsc_ctx->selection_text);
3426 wsc_ctx->selection_text = NULL;
3429 return ECORE_CALLBACK_RENEW;
3433 socket_helper_get_selection (int id, uint32 context_id) {
3434 LOGD ("client id:%d", id);
3437 if (pipe2(filedes, O_CLOEXEC | O_NONBLOCK) ==-1 ) {
3438 LOGW ("create pipe failed");
3441 LOGD("%d,%d", filedes[0], filedes[1]);
3443 WSCContextISF* ic = find_ic (context_id);
3446 wl_input_method_context_get_selection_text (ic->im_ctx, filedes[1]);
3447 Ecore_Wl2_Display *wl2_display = ecore_wl2_connected_display_get (NULL);
3449 ecore_wl2_display_flush (wl2_display);
3452 if (ic->selection_text_fd_read_handler) {
3453 int fd = ecore_main_fd_handler_fd_get (ic->selection_text_fd_read_handler);
3457 ecore_main_fd_handler_del (ic->selection_text_fd_read_handler);
3458 ic->selection_text_fd_read_handler = NULL;
3461 if (ic->selection_text) {
3462 free (ic->selection_text);
3463 ic->selection_text = NULL;
3466 ic->selection_text_fd_read_handler = ecore_main_fd_handler_add (filedes[0], ECORE_FD_READ, selection_text_fd_read_func, ic, NULL, NULL);
3469 void process_key_event_done (int id, uint32 context_id, KeyEvent &key, uint32 ret, uint32 serial) {
3470 LOGD ("client id:%d", id);
3471 WSCContextISF* ic = find_ic (context_id);
3474 #if ENABLE_GRAB_KEYBOARD
3475 if (ret == EINA_FALSE) {
3476 send_wl_key_event (ic, key, false);
3479 wl_input_method_context_filter_key_event_done (ic->im_ctx, serial, ret);
3483 void request_ise_hide (int id, uint32 context_id) {
3484 LOGD ("client id:%d", id);
3485 WSCContextISF* ic = find_ic (context_id);
3488 wl_input_method_context_hide_input_panel (ic->im_ctx, ic->serial);
3492 update_ise_geometry (int id, uint32 context_id, uint32 x, uint32 y, uint32 width, uint32 height) {
3493 LOGD ("client id:%d", id);
3495 if (_focused_ic && _focused_ic->im_ctx) {
3496 wl_input_method_context_update_ise_geometry (_focused_ic->im_ctx, _focused_ic->serial, x, y, width, height);
3500 void helper_candidate_show(int id, uint32 context_id, const String& uuid)
3502 WSCContextISF* ic = find_ic(context_id);
3506 wl_input_method_context_update_candidate_state(ic->im_ctx, 1);
3510 void helper_candidate_hide(int id, uint32 context_id, const String& uuid)
3512 WSCContextISF* ic = find_ic(context_id);
3516 wl_input_method_context_update_candidate_state(ic->im_ctx, 0);
3520 void update_entry_metadata (int id, uint32 context_id) {
3521 LOGD ("client id:%d", id);
3522 WSCContextISF* ic = find_ic(context_id);
3523 if (!ic || !ic->im_ctx) return;
3525 Ecore_IMF_Input_Panel_Layout input_panel_layout = wsc_context_input_panel_layout_get (ic);
3527 if (ic->layout_initialized)
3528 isf_wsc_context_input_panel_layout_set (ic, input_panel_layout);
3530 if (ic->prediction_allow_initialized) {
3531 Eina_Bool prediction_allow = wsc_context_prediction_allow_get (ic);
3532 if (input_panel_layout == ECORE_IMF_INPUT_PANEL_LAYOUT_PASSWORD) {
3533 LOGI ("set prediction allow : FALSE in password layout");
3534 prediction_allow = EINA_FALSE;
3537 g_info_manager->set_prediction_allow (WAYLAND_MODULE_CLIENT_ID, prediction_allow);
3540 if (ic->autocapital_type_initialized)
3541 isf_wsc_context_autocapital_type_set (ic, wsc_context_autocapital_type_get (ic));
3543 if (ic->language_initialized)
3544 isf_wsc_context_input_panel_language_set (ic, wsc_context_input_panel_language_get (ic));
3546 g_info_manager->socket_update_cursor_position (ic->surrounding_cursor);
3547 isf_wsc_context_input_panel_return_key_type_set (ic, (Ecore_IMF_Input_Panel_Return_Key_Type)ic->return_key_type);
3548 isf_wsc_context_input_panel_return_key_disabled_set (ic, ic->return_key_disabled);
3551 isf_wsc_context_input_panel_imdata_set (ic, (void *)ic->impl->imdata, ic->impl->imdata_size);
3553 isf_wsc_context_bidi_direction_set (ic, (Ecore_IMF_BiDi_Direction)ic->bidi_direction);
3554 isf_wsc_context_input_panel_caps_mode_set (ic, ic->caps_mode);
3557 isf_wsc_context_input_panel_mime_type_accept_set (ic, ic->impl->mime_type.c_str ());
3560 isf_wsc_context_send_entry_metadata (ic, wsc_context_input_hint_get (ic), wsc_context_input_panel_layout_get (ic),
3561 wsc_context_input_panel_layout_variation_get (ic), wsc_context_autocapital_type_get (ic), ic->return_key_disabled,
3562 (Ecore_IMF_Input_Panel_Return_Key_Type)ic->return_key_type);
3566 void request_ise_reshow (int id, uint32 context_id) {
3567 LOGD ("client id:%d", id);
3568 WSCContextISF* ic = find_ic (context_id);
3571 wl_input_method_context_reshow_input_panel (ic->im_ctx);
3574 void set_transient_for (uint32 caller_pid, uint32 ime_pid)
3576 LOGI ("caller pid : %u, ime pid : %u", caller_pid, ime_pid);
3579 wl_input_method_manager_set_transient_for (_im_manager, caller_pid, ime_pid);
3581 LOGW ("Failed to get input method manager interface");
3584 void set_floating_mode (int id, uint32 context_id, uint32 floating_mode)
3586 LOGD ("client id:%d", id);
3587 WSCContextISF* ic = find_ic (context_id);
3591 wl_input_method_context_set_floating_panel (ic->im_ctx, floating_mode);
3594 void set_floating_drag_enabled (int id, uint32 context_id, uint32 enabled)
3596 WSCContextISF* ic = find_ic (context_id);
3600 wl_input_method_context_set_floating_drag_enabled (ic->im_ctx, enabled);
3606 EXAPI void scim_module_init (void)
3611 EXAPI void scim_module_exit (void)
3617 EXAPI void scim_panel_agent_module_init (const scim::ConfigPointer& config)
3623 EXAPI scim::PanelAgentPointer scim_panel_agent_module_get_instance ()
3625 scim::PanelAgentBase* _instance = NULL;
3626 if (instance.null ()) {
3628 _instance = new WaylandPanelAgent ();
3635 instance = _instance;
3642 vi:ts=4:nowrap:expandtab