2 * ISF(Input Service Framework)
4 * ISF is based on SCIM 1.4.7 and extended for supporting more mobile fitable.
5 * Copyright (c) 2012-2015 Samsung Electronics Co., Ltd.
7 * Contact: Haifeng Deng <haifeng.deng@samsung.com>, Hengliang Luo <hl.luo@samsung.com>
9 * This library is free software; you can redistribute it and/or modify it under
10 * the terms of the GNU Lesser General Public License as published by the
11 * Free Software Foundation; either version 2.1 of the License, or (at your option)
14 * This library is distributed in the hope that it will be useful, but WITHOUT ANY
15 * WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
17 * License for more details.
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with this library; if not, write to the Free Software Foundation, Inc., 51
21 * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
25 #define Uses_SCIM_TRANSACTION
26 #define Uses_ISF_IMCONTROL_CLIENT
27 #define Uses_SCIM_PANEL_AGENT
28 #define Uses_SCIM_IMENGINE_MODULE
29 #define Uses_SCIM_HELPER_MODULE
38 typedef Signal1<void, int> IMControlClientSignalVoid;
40 #if ENABLE_LAZY_LAUNCH
41 static bool check_panel (const String &display)
43 SocketAddress address;
48 address.set_address (scim_get_default_panel_socket_address (display));
50 if (!client.connect (address))
53 if (!scim_socket_open_connection (magic,
54 String ("ConnectionTester"),
65 check_socket_frontend (void)
67 SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
69 SocketAddress address;
74 address.set_address (scim_get_default_socket_frontend_address ());
76 if (!client.connect (address)) {
77 std::cerr << "check_socket_frontend's connect () failed.\n";
81 if (!scim_socket_open_connection (magic,
82 String ("ConnectionTester"),
83 String ("SocketFrontEnd"),
86 std::cerr << "check_socket_frontend's scim_socket_open_connection () failed.\n";
94 launch_socket_frontend ()
96 SCIM_DEBUG_FRONTEND(1) << __FUNCTION__ << "...\n";
98 std::vector<String> engine_list;
99 std::vector<String> helper_list;
100 std::vector<String> load_engine_list;
102 std::vector<String>::iterator it;
104 std::cerr << "Launching a ISF daemon with Socket FrontEnd...\n";
106 scim_get_imengine_module_list (engine_list);
107 scim_get_helper_module_list (helper_list);
109 for (it = engine_list.begin (); it != engine_list.end (); it++) {
111 load_engine_list.push_back (*it);
113 for (it = helper_list.begin (); it != helper_list.end (); it++)
114 load_engine_list.push_back (*it);
116 return scim_launch (true,
118 (load_engine_list.size () > 0 ? scim_combine_string_list (load_engine_list, ',') : "none"),
124 class IMControlClient::IMControlClientImpl
126 SocketClient m_socket_imclient2panel;
127 SocketClient m_socket_panel2imclient;
128 int m_socket_timeout;
129 uint32 m_socket_i2p_magic_key;
130 uint32 m_socket_p2i_magic_key;
133 IMControlClientSignalVoid m_signal_show_ise;
134 IMControlClientSignalVoid m_signal_hide_ise;
137 IMControlClientImpl ()
138 : m_socket_timeout (scim_get_default_socket_timeout ()),
139 m_socket_i2p_magic_key (0),
140 m_socket_p2i_magic_key (0) {
143 int open_connection (void) {
144 const char *p = getenv ("DISPLAY");
146 if (p) display = String (p);
148 SocketAddress addr (scim_get_default_panel_socket_address (display));
150 if (m_socket_imclient2panel.is_connected ()) close_connection ();
152 bool ret = false, ret2 = false;
155 /* Try three times. */
157 ret = m_socket_imclient2panel.connect (addr);
158 ret2 = m_socket_panel2imclient.connect (addr);
160 scim_usleep (100000);
161 #if ENABLE_LAZY_LAUNCH
162 if (!check_socket_frontend ())
163 launch_socket_frontend ();
164 if (!check_panel (display))
165 scim_launch_panel (true, "socket", display, NULL);
167 for (int i = 0; i < 200; ++i) {
168 if (m_socket_imclient2panel.connect (addr)) {
172 scim_usleep (100000);
176 if (ret && scim_socket_open_connection (m_socket_i2p_magic_key, String ("IMControl_Active"), String ("Panel"), m_socket_imclient2panel, m_socket_timeout)) {
177 if (ret2 && scim_socket_open_connection (m_socket_p2i_magic_key, String ("IMControl_Passive"), String ("Panel"), m_socket_panel2imclient, m_socket_timeout))
180 m_socket_imclient2panel.close ();
181 m_socket_panel2imclient.close ();
183 if (count++ >= 3) break;
185 scim_usleep (100000);
188 return m_socket_imclient2panel.get_id ();
191 void close_connection (void) {
192 m_socket_imclient2panel.close ();
193 m_socket_panel2imclient.close ();
194 m_socket_i2p_magic_key = 0;
195 m_socket_p2i_magic_key = 0;
198 bool is_connected (void) const {
199 return (m_socket_imclient2panel.is_connected () && m_socket_panel2imclient.is_connected ());
202 int get_panel2imclient_connection_number (void) const {
203 return m_socket_panel2imclient.get_id ();
206 bool prepare (void) {
207 if (!m_socket_imclient2panel.is_connected ()) return false;
210 m_trans.put_command (SCIM_TRANS_CMD_REQUEST);
211 m_trans.put_data (m_socket_i2p_magic_key);
217 if (!m_socket_imclient2panel.is_connected ()) return false;
218 if (m_trans.get_data_type () != SCIM_TRANS_DATA_UNKNOWN)
219 return m_trans.write_to_socket (m_socket_imclient2panel, 0x4d494353);
223 bool set_active_ise_by_uuid (const char* uuid) {
225 m_trans.put_command (ISM_TRANS_CMD_SET_ACTIVE_ISE_BY_UUID);
226 m_trans.put_data (uuid, strlen (uuid)+1);
227 m_trans.write_to_socket (m_socket_imclient2panel);
228 if (!m_trans.read_from_socket (m_socket_imclient2panel, m_socket_timeout)) {
229 std::cerr << __func__ << " read_from_socket() may be timeout \n";
233 if (m_trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_REPLY &&
234 m_trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_OK) {
236 std::cerr << __func__ << " get_command() or get_data() may fail!!!\n";
243 bool set_initial_ise_by_uuid (const char* uuid) {
245 m_trans.put_command (ISM_TRANS_CMD_SET_INITIAL_ISE_BY_UUID);
246 m_trans.put_data (uuid, strlen (uuid)+1);
247 m_trans.write_to_socket (m_socket_imclient2panel);
248 if (!m_trans.read_from_socket (m_socket_imclient2panel, m_socket_timeout)) {
249 std::cerr << __func__ << " read_from_socket() may be timeout \n";
253 if (m_trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_REPLY &&
254 m_trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_OK) {
256 std::cerr << __func__ << " get_command() or get_data() may fail!!!\n";
263 bool get_active_ise (String &uuid) {
267 m_trans.put_command (ISM_TRANS_CMD_GET_ACTIVE_ISE);
268 m_trans.write_to_socket (m_socket_imclient2panel);
269 if (!m_trans.read_from_socket (m_socket_imclient2panel, m_socket_timeout)) {
270 std::cerr << __func__ << " read_from_socket() may be timeout \n";
274 if (m_trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_REPLY &&
275 m_trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_OK &&
276 m_trans.get_data (strTemp)) {
279 std::cerr << __func__ << " get_command() or get_data() may fail!!!\n";
286 bool get_ise_list (int* count, char*** iselist) {
288 uint32 count_temp = 0;
291 char *buf_temp = NULL;
293 m_trans.put_command (ISM_TRANS_CMD_GET_ISE_LIST);
294 m_trans.write_to_socket (m_socket_imclient2panel);
295 if (!m_trans.read_from_socket (m_socket_imclient2panel, m_socket_timeout)) {
296 std::cerr << __func__ << " read_from_socket() may be timeout \n";
300 if (m_trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_REPLY &&
301 m_trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_OK &&
302 m_trans.get_data (count_temp) ) {
308 std::cerr << __func__ << " get_command() or get_data() may fail!!!\n";
313 if (count_temp > 0) {
314 buf = (char**)calloc (1, count_temp * sizeof (char*));
316 for (uint32 i = 0; i < count_temp; i++) {
317 if (m_trans.get_data (&buf_temp, len)) {
319 buf[i] = strdup (buf_temp);
333 bool get_ise_info (const char* uuid, String &name, String &language, int &type, int &option, String &module_name)
336 uint32 tmp_type, tmp_option;
337 String tmp_name, tmp_language, tmp_module_name;
339 m_trans.put_command (ISM_TRANS_CMD_GET_ISE_INFORMATION);
340 m_trans.put_data (String (uuid));
341 m_trans.write_to_socket (m_socket_imclient2panel);
342 if (!m_trans.read_from_socket (m_socket_imclient2panel, m_socket_timeout)) {
343 std::cerr << __func__ << " read_from_socket() may be timeout \n";
347 if (m_trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_REPLY &&
348 m_trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_OK &&
349 m_trans.get_data (tmp_name) && m_trans.get_data (tmp_language) &&
350 m_trans.get_data (tmp_type) && m_trans.get_data (tmp_option) && m_trans.get_data (tmp_module_name)) {
352 language = tmp_language;
355 module_name = tmp_module_name;
359 std::cerr << __func__ << " get_command() or get_data() may fail!!!\n";
364 bool reset_ise_option (void) {
367 m_trans.put_command (ISM_TRANS_CMD_RESET_ISE_OPTION);
368 m_trans.write_to_socket (m_socket_imclient2panel);
369 if (!m_trans.read_from_socket (m_socket_imclient2panel, m_socket_timeout)) {
370 std::cerr << __func__ << " read_from_socket() may be timeout \n";
374 if (m_trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_REPLY &&
375 m_trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_OK) {
378 std::cerr << __func__ << " get_command() is failed!!!\n";
383 void set_active_ise_to_default (void) {
384 m_trans.put_command (ISM_TRANS_CMD_RESET_DEFAULT_ISE);
387 void show_ise_selector (void) {
388 m_trans.put_command (ISM_TRANS_CMD_SHOW_ISF_CONTROL);
391 void show_ise_option_window (void) {
392 m_trans.put_command (ISM_TRANS_CMD_SHOW_ISE_OPTION_WINDOW);
395 void resume_ise_option_window (void) {
396 m_trans.put_command (ISM_TRANS_CMD_RESUME_ISE_OPTION_WINDOW);
399 bool get_all_helper_ise_info (HELPER_ISE_INFO &info) {
401 std::vector<String> appid;
402 std::vector<String> label;
403 std::vector<uint32> is_enabled;
404 std::vector<uint32> is_preinstalled;
405 std::vector<uint32> has_option;
409 info.is_enabled.clear ();
410 info.is_preinstalled.clear ();
411 info.has_option.clear ();
413 m_trans.put_command (ISM_TRANS_CMD_GET_ALL_HELPER_ISE_INFO);
414 m_trans.write_to_socket (m_socket_imclient2panel);
415 if (!m_trans.read_from_socket (m_socket_imclient2panel, m_socket_timeout)) {
416 std::cerr << __func__ << " read_from_socket() may be timeout \n";
420 if (m_trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_REPLY &&
421 m_trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_OK &&
422 m_trans.get_data (appid) ) {
424 std::cerr << __func__ << " get_command() or get_data() may fail!!!\n";
428 if (appid.size () > 0) {
429 m_trans.get_data (label);
430 m_trans.get_data (is_enabled);
431 m_trans.get_data (is_preinstalled);
432 m_trans.get_data (has_option);
433 if (appid.size () == label.size () && appid.size () == is_enabled.size () && appid.size () == is_preinstalled.size () && appid.size () == has_option.size ()) {
436 info.is_enabled = is_enabled;
437 info.is_preinstalled = is_preinstalled;
438 info.has_option = has_option;
446 bool set_enable_helper_ise_info (const char *appid, bool is_enabled) {
452 m_trans.put_command (ISM_TRANS_CMD_SET_ENABLE_HELPER_ISE_INFO);
453 m_trans.put_data (String (appid));
454 m_trans.put_data (static_cast<uint32>(is_enabled));
455 m_trans.write_to_socket (m_socket_imclient2panel);
456 if (!m_trans.read_from_socket (m_socket_imclient2panel, m_socket_timeout)) {
457 std::cerr << __func__ << " read_from_socket() may be timeout \n";
461 if (m_trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_REPLY &&
462 m_trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_OK) {
465 std::cerr << __func__ << " get_command() or get_data() may fail!!!\n";
470 bool show_helper_ise_list (void) {
472 m_trans.put_command (ISM_TRANS_CMD_SHOW_HELPER_ISE_LIST);
473 m_trans.write_to_socket (m_socket_imclient2panel);
474 if (!m_trans.read_from_socket (m_socket_imclient2panel, m_socket_timeout)) {
475 std::cerr << __func__ << " read_from_socket() may be timeout \n";
479 if (m_trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_REPLY &&
480 m_trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_OK) {
483 std::cerr << __func__ << " get_command() or get_data() may fail!!!\n";
488 bool show_helper_ise_selector (void) {
490 m_trans.put_command (ISM_TRANS_CMD_SHOW_HELPER_ISE_SELECTOR);
491 m_trans.write_to_socket (m_socket_imclient2panel);
492 if (!m_trans.read_from_socket (m_socket_imclient2panel, m_socket_timeout)) {
493 std::cerr << __func__ << " read_from_socket() may be timeout \n";
497 if (m_trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_REPLY &&
498 m_trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_OK) {
501 std::cerr << __func__ << " get_command() or get_data() may fail!!!\n";
506 bool is_helper_ise_enabled (const char* appid, int &enabled)
511 m_trans.put_command (ISM_TRANS_CMD_IS_HELPER_ISE_ENABLED);
512 m_trans.put_data (String (appid));
513 m_trans.write_to_socket (m_socket_imclient2panel);
514 if (!m_trans.read_from_socket (m_socket_imclient2panel, m_socket_timeout)) {
515 std::cerr << __func__ << " read_from_socket() may be timeout \n";
519 if (m_trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_REPLY &&
520 m_trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_OK &&
521 m_trans.get_data (tmp_enabled)) {
522 enabled = static_cast<int>(tmp_enabled);
525 std::cerr << __func__ << " get_command() or get_data() may fail!!!\n";
530 bool get_recent_ime_geometry (int *x, int *y, int *w, int *h, int angle)
533 uint32 tmp_x, tmp_y, tmp_w, tmp_h;
535 m_trans.put_command (ISM_TRANS_CMD_GET_RECENT_ISE_GEOMETRY);
536 m_trans.put_data (angle);
537 m_trans.write_to_socket (m_socket_imclient2panel);
538 if (!m_trans.read_from_socket (m_socket_imclient2panel, m_socket_timeout)) {
539 std::cerr << __func__ << " read_from_socket() may be timeout \n";
543 if (m_trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_REPLY &&
544 m_trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_OK &&
545 m_trans.get_data (tmp_x) && m_trans.get_data (tmp_y) &&
546 m_trans.get_data (tmp_w) && m_trans.get_data (tmp_h)) {
559 if ((int)tmp_w == -1 && (int)tmp_h == -1)
564 std::cerr << __func__ << " get_command() or get_data() may fail!!!\n";
569 bool hide_helper_ise (void) {
571 m_trans.put_command (ISM_TRANS_CMD_HIDE_ISE_PANEL);
572 m_trans.write_to_socket (m_socket_imclient2panel);
573 if (!m_trans.read_from_socket (m_socket_imclient2panel, m_socket_timeout)) {
574 std::cerr << __func__ << " read_from_socket() may be timeout \n";
578 if (m_trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_REPLY &&
579 m_trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_OK) {
582 std::cerr << __func__ << " get_command() or get_data() may fail!!!\n";
588 IMControlClient::IMControlClient ()
589 : m_impl (new IMControlClientImpl ())
593 IMControlClient::~IMControlClient ()
599 IMControlClient::open_connection (void)
601 return m_impl->open_connection ();
605 IMControlClient::close_connection (void)
607 m_impl->close_connection ();
610 bool IMControlClient::is_connected (void) const
612 return m_impl->is_connected ();
615 int IMControlClient::get_panel2imclient_connection_number (void) const
617 return m_impl->get_panel2imclient_connection_number ();
621 IMControlClient::prepare (void)
623 return m_impl->prepare ();
627 IMControlClient::send (void)
629 return m_impl->send ();
632 bool IMControlClient::set_active_ise_by_uuid (const char* uuid)
634 return m_impl->set_active_ise_by_uuid (uuid);
637 bool IMControlClient::set_initial_ise_by_uuid (const char* uuid)
639 return m_impl->set_initial_ise_by_uuid (uuid);
642 bool IMControlClient::get_active_ise (String &uuid)
644 return m_impl->get_active_ise (uuid);
647 bool IMControlClient::get_ise_list (int* count, char*** iselist)
649 return m_impl->get_ise_list (count, iselist);
652 bool IMControlClient::get_ise_info (const char* uuid, String &name, String &language, int &type, int &option, String &module_name)
654 return m_impl->get_ise_info (uuid, name, language, type, option, module_name);
657 bool IMControlClient::reset_ise_option (void)
659 return m_impl->reset_ise_option ();
662 void IMControlClient::set_active_ise_to_default (void)
664 m_impl->set_active_ise_to_default ();
667 void IMControlClient::show_ise_selector (void)
669 m_impl->show_ise_selector ();
672 void IMControlClient::show_ise_option_window (void)
674 m_impl->show_ise_option_window ();
677 void IMControlClient::resume_ise_option_window (void)
679 m_impl->resume_ise_option_window ();
682 bool IMControlClient::get_all_helper_ise_info (HELPER_ISE_INFO &info)
684 return m_impl->get_all_helper_ise_info (info);
687 bool IMControlClient::set_enable_helper_ise_info (const char *appid, bool is_enabled)
689 return m_impl->set_enable_helper_ise_info (appid, is_enabled);
692 bool IMControlClient::show_helper_ise_list (void)
694 return m_impl->show_helper_ise_list ();
697 bool IMControlClient::show_helper_ise_selector (void)
699 return m_impl->show_helper_ise_selector ();
702 bool IMControlClient::is_helper_ise_enabled (const char* appid, int &enabled)
704 return m_impl->is_helper_ise_enabled (appid, enabled);
707 bool IMControlClient::get_recent_ime_geometry (int *x, int *y, int *w, int *h, int angle)
709 return m_impl->get_recent_ime_geometry (x, y, w, h, angle);
712 bool IMControlClient::hide_helper_ise (void)
714 return m_impl->hide_helper_ise ();
719 vi:ts=4:nowrap:ai:expandtab