2 * Copyright 2012 Samsung Electronics Co., Ltd
4 * Licensed under the Flora License, Version 1.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.tizenopensource.org/license
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 #define Uses_SCIM_UTILITY
19 #define Uses_SCIM_OBJECT
20 #define Uses_SCIM_POINTER
21 #define Uses_SCIM_EVENT
22 #define Uses_SCIM_HELPER
23 #define Uses_SCIM_CONFIG_BASE
28 #include <sys/types.h>
37 #include <Elementary.h>
42 #include "window_slide_animator.h"
47 #include <Ecore_IMF.h>
48 #include <Elementary.h>
52 #include <vconf-keys.h>
53 #include <ise_context.h>
55 #define SETTING_LANG "file/menu_widget/language"
57 extern ConfigPointer _scim_config;
58 extern SETTING_INFO _setup_info;
59 extern std::vector < int >v_lang_list;
60 extern mcfint privateId;
61 extern Evas_Object* ctxspopup;
62 /* Function declaration */
63 static void run(const String &display);
65 static int main_window_xpos = 0;
66 static int main_window_ypos = 0;
68 static int candidate_height = 79;
69 static int ise_height = 410;
71 /* Global variables */
72 extern Evas_Object *main_window;
73 extern HelperAgent helper_agent;
74 extern unsigned int gExplicitLanguageSetting;
75 extern bool gFHiddenState;
76 extern int gIseScreenDegree;
77 static int gLastIC = 0;
78 extern bool IseLangDataSelectState[MAX_LANG_NUM];
80 extern int init(const String &display);
83 static HelperInfo helper_info(String(ISEUUID), ISENAME, "", "",
85 SCIM_HELPER_STAND_ALONE |
86 SCIM_HELPER_NEED_SCREEN_INFO |
87 SCIM_HELPER_AUTO_RESTART);
89 SCIM_HELPER_STAND_ALONE |
90 SCIM_HELPER_NEED_SCREEN_INFO);
93 void save_config_ise(const ConfigPointer &config);
97 void scim_module_init(void)
99 DBG("%s\n", __func__);
100 helper_info.name = String(ISENAME);
101 helper_info.description =
102 String("An on-screen ise to input characters.");
104 void scim_module_exit(void)
106 DBG("%s\n", __func__);
109 unsigned int scim_helper_module_number_of_helpers(void)
111 DBG("%s\n", __func__);
115 bool scim_helper_module_get_helper_info(unsigned int idx,
118 DBG("%s\n", __func__);
126 String scim_helper_module_get_helper_language(unsigned int idx)
128 DBG("%s\n", __func__);
129 std::vector < String > langlist;
130 langlist.push_back(SUPPORTED_LANGUAGES);
131 return scim_combine_string_list(langlist);
134 void scim_helper_module_run_helper(const String &uuid,
135 const ConfigPointer &config,
136 const String &display)
138 DBG("%s\n", __func__);
140 if (!config.null()) {
141 _scim_config = config;
142 _setup_info.flag = config->read(CONFIG_SETTING_FLAG, 0);
143 config->read(CONFIG_LANGUAGE_LIST, &v_lang_list);
144 _setup_info.current_language = config->read(CONFIG_CURRENT_LANGUAGE, 0);
145 _setup_info.lang_count = config->read(CONFIG_LANGUAGE_COUNT, 1);
147 for (unsigned int loop = 0; loop < MAX_LANG_NUM; loop++) {
148 IseLangDataSelectState[loop] = false;
151 for (unsigned int i = 0; i < v_lang_list.size(); i++)
152 IseLangDataSelectState[v_lang_list[i]] = true;
154 DBG("ise:>>>> Done with assigning scim config \n\n");
156 if (uuid == ISEUUID) {
162 static void set_transient_for_app_window(Evas_Object *keypad_win)
164 /* Set a transient window for window stack */
165 /* Gets the current XID of the active window into the
166 * root window property */
168 unsigned long nitems_return;
169 unsigned long bytes_after_return;
172 Ecore_X_Window xAppWindow;
173 Ecore_X_Window xKeypadWin = elm_win_xwindow_get(keypad_win);
176 ret = XGetWindowProperty((Display *) ecore_x_display_get(),
177 ecore_x_window_root_get(xKeypadWin),
178 ecore_x_atom_get("_ISF_ACTIVE_WINDOW"), 0,
179 G_MAXLONG, False, ((Atom) 33), &type_return,
180 &format_return, &nitems_return,
181 &bytes_after_return, &data);
183 if (ret == Success) {
184 if ((type_return == ((Atom) 33)) && (format_return == 32) && (data)) {
185 xAppWindow = *(Window *) data;
186 ecore_x_icccm_transient_for_set(xKeypadWin, xAppWindow);
193 static void slot_exit(const HelperAgent *, int ic, const String &uuid)
195 DBG("%s\n", __func__);
203 slot_update_screen(const HelperAgent *, int ic,
204 const String &uuid, int screen)
206 DBG("%s\n", __func__);
211 slot_trigger_property(const HelperAgent *agent, int ic, const String &uuid,
212 const String &property)
214 DBG("%s\n", __func__);
217 static bool bind_ise_window_to_im()
219 DBG("%s\n", __func__);
220 if (main_window == NULL) {
221 scim_global_config_update();
222 int socId = scim_global_config_read("/IMWindowSocketID", socId);
227 static void slot_focus_out(const HelperAgent *, int ic, const String &uuid)
229 DBG("isemain.cpp slot_focus_out \n\n");
233 static void slot_focus_in(const HelperAgent *, int ic, const String &uuid)
235 DBG("\n================\n%s\n============\n", __func__);
241 static int get_root_window_degree()
244 unsigned long nitems_return;
245 unsigned long bytes_after_return;
251 XGetWindowProperty((Display *) ecore_x_display_get(),
252 ecore_x_window_root_get(elm_win_xwindow_get(main_window)),
253 ecore_x_atom_get("_E_ILLUME_ROTATE_ROOT_ANGLE"),
254 0, G_MAXLONG, False, ((Atom) 6), &type_return,
255 &format_return, &nitems_return,
256 &bytes_after_return, &data);
258 if (ret == Success) {
259 if ((type_return == ((Atom) 6)) && (format_return == 32)
261 retVal = *(unsigned int *)data;
270 static void slot_ise_show(const HelperAgent *, int ic, char *buf, size_t &len)
272 DBG("\n-------------------\n%s\n-------------------, %d\n",
277 evas_object_show(main_window);
278 /*elm_win_raise (main_window);*/
281 /* Set a transient window for window stack */
282 set_transient_for_app_window(main_window);
284 static const char *UUID = KEYBD_ISE_UUID;
285 helper_agent.set_keyboard_ise_by_uuid(UUID);
287 /* Check if effect is enabled */
288 static Ise_Context iseContext;
290 if (len >= sizeof(Ise_Context)) {
291 /* for EFL application*/
292 memcpy(&iseContext, buf, sizeof(iseContext));
294 ise_reset_context(); /* reset ISE*/
296 ise_set_screen_direction(get_root_window_degree());
298 ise_set_layout(iseContext.layout);
300 ise_set_return_key_type(iseContext.return_key_type);
302 ise_set_return_key_disable(iseContext.return_key_disabled);
304 ise_set_caps_mode(iseContext.caps_mode);
307 DBG("\n-=-=-=-=-=-=-= WARNING WARNING WARNING - slot_ise_show :\
308 buf %p len %d size %d =-=-=-=-=-=-=-=-=-=-\n",
309 buf, len, sizeof(iseContext));
316 static void slot_ise_hide(const HelperAgent *, int ic, const String &uuid)
318 DBG("%s\n", __func__);
319 CMCFWindows *windows = CMCFWindows::get_instance();
323 static void slot_get_size(const HelperAgent *, struct rectinfo &info)
325 DBG("%s\n", __func__);
327 int x, y, width, height;
328 ise_get_size(&x, &y, &width, &height);
333 info.height = height;
336 static void slot_set_caps_mode(const HelperAgent *, uint32 &mode)
338 ise_set_caps_mode(mode);
341 static void slot_set_language(const HelperAgent *, uint32 &language)
343 ise_explicitly_set_language(language);
346 static void slot_set_layout(const HelperAgent *, uint32 &layout)
348 ise_set_layout(layout);
351 static void slot_get_layout(const HelperAgent *, uint32 &layout)
353 layout = ise_get_layout();
356 static void slot_update_cursor_position(const HelperAgent *, int ic, const String &uuid, int position)
358 ise_update_cursor_position(position);
361 static void slot_get_language_locale(const HelperAgent *, int ic, char **locale)
363 ise_get_language_locale(locale);
365 static void slot_get_layout_list(const HelperAgent *,
366 std::vector < uint32 > &list)
369 #ifdef SUPPORTS_LAYOUT_STYLE_NORMAL
370 list.push_back(ISE_LAYOUT_STYLE_NORMAL);
372 #ifdef SUPPORTS_LAYOUT_STYLE_NUMBER
373 list.push_back(ISE_LAYOUT_STYLE_NUMBER);
375 #ifdef SUPPORTS_LAYOUT_STYLE_EMAIL
376 list.push_back(ISE_LAYOUT_STYLE_EMAIL);
378 #ifdef SUPPORTS_LAYOUT_STYLE_URL
379 list.push_back(ISE_LAYOUT_STYLE_URL);
381 #ifdef SUPPORTS_LAYOUT_STYLE_PHONENUMBER
382 list.push_back(ISE_LAYOUT_STYLE_PHONENUMBER);
384 #ifdef SUPPORTS_LAYOUT_STYLE_IP
385 list.push_back(ISE_LAYOUT_STYLE_IP);
387 #ifdef SUPPORTS_LAYOUT_STYLE_MONTH
388 list.push_back(ISE_LAYOUT_STYLE_MONTH);
390 #ifdef SUPPORTS_LAYOUT_STYLE_NUMBERONLY
391 list.push_back(ISE_LAYOUT_STYLE_NUMBERONLY);
395 static void slot_set_imdata(const HelperAgent *, char *buf, size_t &len)
400 static void slot_get_imdata(const HelperAgent *, char **buf, size_t &len)
406 * @brief Set return key type slot function for HelperAgent.
408 * @param type The type of return key.
412 static void slot_set_return_key_type (const HelperAgent *, uint32 &type)
414 ise_set_return_key_type(type);
418 * @brief Set return key disable slot function for HelperAgent.
420 * @param disabled The disable flag of return key.
424 static void slot_set_return_key_disable (const HelperAgent *, uint32 &disabled)
426 ise_set_return_key_disable(disabled);
429 static void slot_set_private_key_by_label(const HelperAgent *,
432 char *label, char *value)
434 std::cout << "<now> slot_set_private_key_by_label \n";
435 std::cout << "\tlayout_idx = " << layout_idx << "\n";
436 std::cout << "\tkey_idx = " << key_idx << "\n";
437 std::cout << "\tlabel = " << label << "\n";
438 std::cout << "\tvalue = " << value << "\n";
439 ise_set_private_key(key_idx, label, NULL, -1, value);
442 static void slot_set_private_key_by_image(const HelperAgent *,
445 char *img_path, char *value)
447 std::cout << "<now> slot_set_private_key_by_imagel \n";
448 std::cout << "\tlayout_idx = " << layout_idx << "\n";
449 std::cout << "\tkey_idx = " << key_idx << "\n";
450 std::cout << "\tlabel = " << img_path << "\n";
451 std::cout << "\tvalue = " << value << "\n";
452 ise_set_private_key(key_idx, NULL, img_path, -1, value);
455 static void slot_set_disable_key(const HelperAgent *,
457 uint32 &key_idx, uint32 &disabled)
459 std::cout << "<now> slot_set_disable_key \n";
460 std::cout << "\tlayout_idx = " << layout_idx << "\n";
461 std::cout << "\tkey_idx = " << key_idx << "\n";
462 std::cout << "\tdisabled = " << disabled << "\n";
464 ise_set_disable_key(key_idx, disabled);
467 static void slot_reset_ise_context(const HelperAgent *, int ic,
470 DBG("%s\n", __func__);
474 static void slot_reset_ise_input_context(const HelperAgent *, int ic,
477 std::cout << "<now> slot_reset_ise_input_context\n";
478 ise_reset_input_context();
481 static void slot_set_screen_direction(const HelperAgent *, uint32 &mode)
483 std::cout << "<now> slot_set_screen_direction" << mode << " \n";
484 ise_set_screen_direction(mode);
488 static void slot_update_keyboard_ise(const HelperAgent *, int ic,
490 const String &ise_name,
491 const String &ise_uuid)
493 static int failnum = 0;
494 static const char *UUID = KEYBD_ISE_UUID;
499 DBG("***Warning : KEYBOARDISE is not ISE!!! Retrying ... %d\n", failnum);
500 helper_agent.set_keyboard_ise_by_uuid(UUID);
502 DBG("***Warning : KEYBOARDISE is not ISE!!! Giving up\n");
509 static void slot_update_keyboard_ise_list(const HelperAgent *, int ic,
511 const std::vector < String >
517 static void slot_update_candidate_rect(const HelperAgent *, int ic,
519 const rectinfo &info)
522 std::cout << " x=" << info.pos_x << " y=" << info.
523 pos_y << " width=" << info.width << " height=" << info.
525 candidate_height = info.height;
528 static void slot_update_spot_location(const HelperAgent *agent, int ic,
529 const String &ic_uuid, int x, int y)
531 DBG("%s\n", __func__);
534 static Eina_Bool helper_agent_input_handler(void *data,
535 Ecore_Fd_Handler *fd_handler)
537 DBG("%s\n", __func__);
539 if (helper_agent.has_pending_event()) {
540 if (!helper_agent.filter_event()) {
541 std::cerr <<"helper_agent.filter_event () is failed!!!\n";
545 std::cerr << "helper_agent.has_pending_event () is failed!!!\n";
549 return ECORE_CALLBACK_RENEW;
552 static void slot_reload_config_callback(const HelperAgent *, int ic,
555 CMCFCore *gCore = NULL;
557 if (!_scim_config.null()) {
558 _setup_info.flag = _scim_config->read(CONFIG_SETTING_FLAG, _setup_info.flag);
559 _scim_config->read(CONFIG_LANGUAGE_LIST, &v_lang_list);
560 _setup_info.current_language = _scim_config->read(CONFIG_CURRENT_LANGUAGE,
561 _setup_info.current_language);
562 _setup_info.lang_count = _scim_config->read(CONFIG_LANGUAGE_COUNT, _setup_info.lang_count);
564 for (unsigned int loop = 0; loop < MAX_LANG_NUM; loop++) {
565 IseLangDataSelectState[loop] = false;
568 for (unsigned int i = 0; i < v_lang_list.size(); i++)
569 IseLangDataSelectState[v_lang_list[i]] = true;
571 ise_set_language(_setup_info.current_language);
572 /* for updating _setup_info before launching
573 * keyboard from any application
574 if the values are changed through keyboard further
575 , it will be written through setting_window_cb */
576 _setup_info = ise_setting_update_on_reload_config(_setup_info);
580 extern int init_i18n(const char *domain, const char *dir);
582 void isf_setting_language_changed_cb(keynode_t *key, void *data)
584 DBG("###################### ISE listen that language\
585 changed ###########################\n");
586 char clang[256] = { 0 };
587 snprintf(clang, sizeof(clang), "%s", vconf_get_str(VCONFKEY_LANGSET));
588 DBG("###################### current language is %s \
589 ##############################\n",clang);
592 setenv("LANG", clang, 1);
593 setlocale(LC_MESSAGES, clang);
594 init_i18n(PACKAGE, LOCALEDIR);
596 setenv("LANG", "en_US.utf8", 1);
597 setlocale(LC_MESSAGES, "en_US.utf8");
598 init_i18n(PACKAGE, LOCALEDIR);
602 void signalhandler(int sig)
604 std::cerr << " Signal=" << sig << "\n";
608 static Eina_Bool _client_message_cb(void *data, int type, void *event)
610 Ecore_X_Event_Client_Message *ev = (Ecore_X_Event_Client_Message *) event;
614 if (ev->message_type == ECORE_X_ATOM_E_ILLUME_ROTATE_ROOT_ANGLE) {
615 if (!gFHiddenState) {
616 CMCFWindows *windows = CMCFWindows::get_instance();
617 Evas_Object* win = windows->get_context_popup();
619 evas_object_del(win);
620 evas_object_del(ctxspopup);
622 angle = ev->data.l[0];
623 Ecore_X_Window activeWin = ev->data.l[1];
625 ecore_x_icccm_transient_for_get(elm_win_xwindow_get(main_window))) {
626 ise_set_screen_direction(angle);
632 return ECORE_CALLBACK_RENEW;
635 void hibernation_enter_callback(void *data)
637 vconf_ignore_key_changed(VCONFKEY_LANGSET,
638 isf_setting_language_changed_cb);
641 void hibernation_leave_callback(void *data)
643 vconf_notify_key_changed(VCONFKEY_LANGSET,
644 isf_setting_language_changed_cb, NULL);
647 void run(const String &display)
650 DBG("[%s] current time : %10.3f\n", __func__, cur_time_get());
653 DBG("DBG : %s\n", __func__);
654 PERF_TEST_START("run()");
655 char clang[256] = { 0 };
658 int id = helper_agent.open_connection(helper_info, display);
661 DBG("\n ERROR: helper_agent open_connection id invalid \n");
666 PERF_TEST_MID("\tinit()");
668 isf_setting_language_changed_cb(NULL, NULL);
670 slp_fd = heynoti_init();
671 heynoti_subscribe(slp_fd, "HIBERNATION_ENTER",
672 hibernation_enter_callback, NULL);
673 heynoti_subscribe(slp_fd, "HIBERNATION_LEAVE",
674 hibernation_leave_callback, NULL);
676 vconf_notify_key_changed(VCONFKEY_LANGSET,
677 isf_setting_language_changed_cb, NULL);
679 snprintf(clang, sizeof(clang), "%s", vconf_get_str(VCONFKEY_LANGSET));
681 for (int loop = 0; loop < MAX_LANG_NUM; loop++) {
682 if (!strcmp(clang, scim::scim_get_language_name_english(IseLangData[1][loop].
684 gExplicitLanguageSetting = loop;
689 ret1 = heynoti_attach_handler(slp_fd);
691 helper_agent.signal_connect_exit(slot(slot_exit));
692 helper_agent.signal_connect_update_screen(slot(slot_update_screen));
693 helper_agent.signal_connect_trigger_property(slot(slot_trigger_property));
694 helper_agent.signal_connect_focus_out(slot(slot_focus_out));
695 helper_agent.signal_connect_focus_in(slot(slot_focus_in));
696 helper_agent.signal_connect_ise_show(slot(slot_ise_show));
697 helper_agent.signal_connect_ise_hide(slot(slot_ise_hide));
698 helper_agent.signal_connect_get_geometry(slot(slot_get_size));
699 helper_agent.signal_connect_set_language(slot(slot_set_language));
700 helper_agent.signal_connect_set_imdata(slot(slot_set_imdata));
701 helper_agent.signal_connect_get_imdata(slot(slot_get_imdata));
702 helper_agent.signal_connect_set_layout(slot(slot_set_layout));
703 helper_agent.signal_connect_get_layout(slot(slot_get_layout));
704 helper_agent.signal_connect_reset_input_context(slot(slot_reset_ise_input_context));
705 helper_agent.signal_connect_update_keyboard_ise(slot(slot_update_keyboard_ise));
706 helper_agent.signal_connect_update_keyboard_ise_list(slot(slot_update_keyboard_ise_list));
707 helper_agent.signal_connect_update_candidate_geometry(slot(slot_update_candidate_rect));
708 helper_agent.signal_connect_update_spot_location(slot(slot_update_spot_location));
709 helper_agent.signal_connect_set_caps_mode(slot(slot_set_caps_mode));
710 helper_agent.signal_connect_update_cursor_position( slot (slot_update_cursor_position));
711 helper_agent.signal_connect_get_language_locale( slot (slot_get_language_locale));
712 helper_agent.signal_connect_reload_config(slot(slot_reload_config_callback));
713 helper_agent.signal_connect_set_return_key_type (slot (slot_set_return_key_type));
714 helper_agent.signal_connect_set_return_key_disable (slot (slot_set_return_key_disable));
716 helper_agent.signal_connect_get_geometry(slot(slot_get_size));
719 helper_agent.set_candidate_position(-1, -1);
721 int fd = helper_agent.get_connection_number();
723 Property prop("/EuropeanISE", "EuropeanISE", "",
724 "Show/Hide EuropeanISE.");
726 props.push_back(prop);
727 helper_agent.register_properties(props);
728 ecore_main_fd_handler_add(fd, ECORE_FD_READ,
729 helper_agent_input_handler, NULL,
733 Ecore_Event_Handler *XClientMsgHandler =
734 ecore_event_handler_add(ECORE_X_EVENT_CLIENT_MESSAGE,
735 _client_message_cb, NULL);
737 PERF_TEST_MID("\tbegin elm_run()");
739 PERF_TEST_END("run()");
741 signal(SIGQUIT, signalhandler);
742 signal(SIGTERM, signalhandler);
743 signal(SIGINT, signalhandler);
744 signal(SIGHUP, signalhandler);
747 vconf_ignore_key_changed(VCONFKEY_LANGSET,
748 isf_setting_language_changed_cb);
749 ecore_event_handler_del(XClientMsgHandler);
750 heynoti_close(slp_fd);