1 /** @file scim_socket_frontend.cpp
2 * implementation of class SocketFrontEnd.
3 */
4
5 /*
6 * Smart Common Input Method
7 *
8 * Copyright (c) 2002-2005 James Su <suzhe@tsinghua.org.cn>
9 *
10 *
11 * This library is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2 of the License, or (at your option) any later version.
15 *
16 * This library is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License for more details.
20 *
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with this program; if not, write to the
23 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
24 * Boston, MA 02111-1307 USA
25 *
26 * $Id: scim_socket_frontend.cpp,v 1.37 2005/07/03 08:36:42 suzhe Exp $
27 *
28 */
29
30 #define Uses_SCIM_CONFIG_PATH
31 #define Uses_SCIM_FRONTEND
32 #define Uses_SCIM_SOCKET
33 #define Uses_SCIM_TRANSACTION
34 #define Uses_STL_UTILITY
35 #define Uses_C_STDIO
36 #define Uses_C_STDLIB
37
38 #include <limits.h>
39 #include "scim_private.h"
40 #include "scim.h"
41 #include "scim_socket_frontend.h"
42 #include <sys/time.h>
43
44 #define scim_module_init socket_LTX_scim_module_init
45 #define scim_module_exit socket_LTX_scim_module_exit
46 #define scim_frontend_module_init socket_LTX_scim_frontend_module_init
47 #define scim_frontend_module_run socket_LTX_scim_frontend_module_run
48
49 #define SCIM_CONFIG_FRONTEND_SOCKET_CONFIG_READONLY "/FrontEnd/Socket/ConfigReadOnly"
50 #define SCIM_CONFIG_FRONTEND_SOCKET_MAXCLIENTS "/FrontEnd/Socket/MaxClients"
51
52 using namespace scim;
53
54 static Pointer <SocketFrontEnd> _scim_frontend (0);
55
56 static int _argc;
57 static char **_argv;
58
59 //Module Interface
60 extern "C" {
scim_module_init(void)61 void scim_module_init (void)
62 {
63 SCIM_DEBUG_FRONTEND(1) << "Initializing Socket FrontEnd module...\n";
64 }
65
scim_module_exit(void)66 void scim_module_exit (void)
67 {
68 SCIM_DEBUG_FRONTEND(1) << "Exiting Socket FrontEnd module...\n";
69 _scim_frontend.reset ();
70 }
71
scim_frontend_module_init(const BackEndPointer & backend,const ConfigPointer & config,int argc,char ** argv)72 void scim_frontend_module_init (const BackEndPointer &backend,
73 const ConfigPointer &config,
74 int argc,
75 char **argv)
76 {
77 if (_scim_frontend.null ()) {
78 SCIM_DEBUG_FRONTEND(1) << "Initializing Socket FrontEnd module (more)...\n";
79 _scim_frontend = new SocketFrontEnd (backend, config);
80 _argc = argc;
81 _argv = argv;
82 }
83 }
84
scim_frontend_module_run(void)85 void scim_frontend_module_run (void)
86 {
87 if (!_scim_frontend.null ()) {
88 SCIM_DEBUG_FRONTEND(1) << "Starting Socket FrontEnd module...\n";
89 _scim_frontend->init (_argc, _argv);
90 _scim_frontend->run ();
91 }
92 }
93 }
94
SocketFrontEnd(const BackEndPointer & backend,const ConfigPointer & config)95 SocketFrontEnd::SocketFrontEnd (const BackEndPointer &backend,
96 const ConfigPointer &config)
97 : FrontEndBase (backend),
98 m_config (config),
99 m_stay (true),
100 m_config_readonly (false),
101 m_socket_timeout (scim_get_default_socket_timeout ()),
102 m_current_instance (-1),
103 m_current_socket_client (-1),
104 m_current_socket_client_key (0)
105 {
106 SCIM_DEBUG_FRONTEND (2) << " Constructing SocketFrontEnd object...\n";
107 }
108
~SocketFrontEnd()109 SocketFrontEnd::~SocketFrontEnd ()
110 {
111 SCIM_DEBUG_FRONTEND (2) << " Destructing SocketFrontEnd object...\n";
112 if (m_socket_server.is_running ())
113 m_socket_server.shutdown ();
114 }
115
116 void
show_preedit_string(int id)117 SocketFrontEnd::show_preedit_string (int id)
118 {
119 if (m_current_instance == id)
120 m_send_trans.put_command (SCIM_TRANS_CMD_SHOW_PREEDIT_STRING);
121 }
122
123 void
show_aux_string(int id)124 SocketFrontEnd::show_aux_string (int id)
125 {
126 if (m_current_instance == id)
127 m_send_trans.put_command (SCIM_TRANS_CMD_SHOW_AUX_STRING);
128 }
129
130 void
show_lookup_table(int id)131 SocketFrontEnd::show_lookup_table (int id)
132 {
133 if (m_current_instance == id)
134 m_send_trans.put_command (SCIM_TRANS_CMD_SHOW_LOOKUP_TABLE);
135 }
136
137 void
hide_preedit_string(int id)138 SocketFrontEnd::hide_preedit_string (int id)
139 {
140 if (m_current_instance == id)
141 m_send_trans.put_command (SCIM_TRANS_CMD_HIDE_PREEDIT_STRING);
142 }
143
144 void
hide_aux_string(int id)145 SocketFrontEnd::hide_aux_string (int id)
146 {
147 if (m_current_instance == id)
148 m_send_trans.put_command (SCIM_TRANS_CMD_HIDE_AUX_STRING);
149 }
150
151 void
hide_lookup_table(int id)152 SocketFrontEnd::hide_lookup_table (int id)
153 {
154 if (m_current_instance == id)
155 m_send_trans.put_command (SCIM_TRANS_CMD_HIDE_LOOKUP_TABLE);
156 }
157
158 void
update_preedit_caret(int id,int caret)159 SocketFrontEnd::update_preedit_caret (int id, int caret)
160 {
161 if (m_current_instance == id) {
162 m_send_trans.put_command (SCIM_TRANS_CMD_UPDATE_PREEDIT_CARET);
163 m_send_trans.put_data ((uint32) caret);
164 }
165 }
166
167 void
update_preedit_string(int id,const WideString & str,const AttributeList & attrs)168 SocketFrontEnd::update_preedit_string (int id,
169 const WideString & str,
170 const AttributeList & attrs)
171 {
172 if (m_current_instance == id) {
173 m_send_trans.put_command (SCIM_TRANS_CMD_UPDATE_PREEDIT_STRING);
174 m_send_trans.put_data (str);
175 m_send_trans.put_data (attrs);
176 }
177 }
178
179 void
update_aux_string(int id,const WideString & str,const AttributeList & attrs)180 SocketFrontEnd::update_aux_string (int id,
181 const WideString & str,
182 const AttributeList & attrs)
183 {
184 if (m_current_instance == id) {
185 m_send_trans.put_command (SCIM_TRANS_CMD_UPDATE_AUX_STRING);
186 m_send_trans.put_data (str);
187 m_send_trans.put_data (attrs);
188 }
189 }
190
191 void
commit_string(int id,const WideString & str)192 SocketFrontEnd::commit_string (int id, const WideString & str)
193 {
194 if (m_current_instance == id) {
195 m_send_trans.put_command (SCIM_TRANS_CMD_COMMIT_STRING);
196 m_send_trans.put_data (str);
197 }
198 }
199
200 void
forward_key_event(int id,const KeyEvent & key)201 SocketFrontEnd::forward_key_event (int id, const KeyEvent & key)
202 {
203 if (m_current_instance == id) {
204 m_send_trans.put_command (SCIM_TRANS_CMD_FORWARD_KEY_EVENT);
205 m_send_trans.put_data (key);
206 }
207 }
208
209 void
update_lookup_table(int id,const LookupTable & table)210 SocketFrontEnd::update_lookup_table (int id, const LookupTable & table)
211 {
212 if (m_current_instance == id) {
213 m_send_trans.put_command (SCIM_TRANS_CMD_UPDATE_LOOKUP_TABLE);
214 m_send_trans.put_data (table);
215 }
216 }
217
218 void
register_properties(int id,const PropertyList & properties)219 SocketFrontEnd::register_properties (int id, const PropertyList &properties)
220 {
221 if (m_current_instance == id) {
222 m_send_trans.put_command (SCIM_TRANS_CMD_REGISTER_PROPERTIES);
223 m_send_trans.put_data (properties);
224 }
225 }
226
227 void
update_property(int id,const Property & property)228 SocketFrontEnd::update_property (int id, const Property &property)
229 {
230 if (m_current_instance == id) {
231 m_send_trans.put_command (SCIM_TRANS_CMD_UPDATE_PROPERTY);
232 m_send_trans.put_data (property);
233 }
234 }
235
236 void
beep(int id)237 SocketFrontEnd::beep (int id)
238 {
239 if (m_current_instance == id) {
240 m_send_trans.put_command (SCIM_TRANS_CMD_BEEP);
241 }
242 }
243
244 void
start_helper(int id,const String & helper_uuid)245 SocketFrontEnd::start_helper (int id, const String &helper_uuid)
246 {
247 SCIM_DEBUG_FRONTEND (2) << "start_helper (" << helper_uuid << ")\n";
248 if (m_current_instance == id) {
249 m_send_trans.put_command (SCIM_TRANS_CMD_START_HELPER);
250 m_send_trans.put_data (helper_uuid);
251 }
252 }
253
254 void
stop_helper(int id,const String & helper_uuid)255 SocketFrontEnd::stop_helper (int id, const String &helper_uuid)
256 {
257 SCIM_DEBUG_FRONTEND (2) << "stop_helper (" << helper_uuid << ")\n";
258
259 if (m_current_instance == id) {
260 m_send_trans.put_command (SCIM_TRANS_CMD_STOP_HELPER);
261 m_send_trans.put_data (helper_uuid);
262 }
263 }
264
265 void
send_helper_event(int id,const String & helper_uuid,const Transaction & trans)266 SocketFrontEnd::send_helper_event (int id, const String &helper_uuid, const Transaction &trans)
267 {
268 if (m_current_instance == id) {
269 m_send_trans.put_command (SCIM_TRANS_CMD_SEND_HELPER_EVENT);
270 m_send_trans.put_data (helper_uuid);
271 m_send_trans.put_data (trans);
272 }
273 }
274
275 bool
get_surrounding_text(int id,WideString & text,int & cursor,int maxlen_before,int maxlen_after)276 SocketFrontEnd::get_surrounding_text (int id, WideString &text, int &cursor, int maxlen_before, int maxlen_after)
277 {
278 text.clear ();
279 cursor = 0;
280
281 if (m_current_instance == id && m_current_socket_client >= 0 && (maxlen_before != 0 || maxlen_after != 0)) {
282 if (maxlen_before < 0) maxlen_before = -1;
283 if (maxlen_after < 0) maxlen_after = -1;
284
285 m_temp_trans.clear ();
286 m_temp_trans.put_command (SCIM_TRANS_CMD_REPLY);
287 m_temp_trans.put_command (SCIM_TRANS_CMD_GET_SURROUNDING_TEXT);
288 m_temp_trans.put_data ((uint32) maxlen_before);
289 m_temp_trans.put_data ((uint32) maxlen_after);
290
291 Socket socket_client (m_current_socket_client);
292
293 if (m_temp_trans.write_to_socket (socket_client) &&
294 m_temp_trans.read_from_socket (socket_client, m_socket_timeout)) {
295
296 int cmd;
297 uint32 key;
298 uint32 cur;
299
300 if (m_temp_trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_REQUEST &&
301 m_temp_trans.get_data (key) && key == m_current_socket_client_key &&
302 m_temp_trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_GET_SURROUNDING_TEXT &&
303 m_temp_trans.get_data (text) && m_temp_trans.get_data (cur)) {
304 cursor = (int) cur;
305 return true;
306 }
307 }
308 }
309 return false;
310 }
311
312 bool
delete_surrounding_text(int id,int offset,int len)313 SocketFrontEnd::delete_surrounding_text (int id, int offset, int len)
314 {
315 if (m_current_instance == id && m_current_socket_client >= 0 && len > 0) {
316 m_temp_trans.clear ();
317 m_temp_trans.put_command (SCIM_TRANS_CMD_REPLY);
318 m_temp_trans.put_command (SCIM_TRANS_CMD_DELETE_SURROUNDING_TEXT);
319 m_temp_trans.put_data ((uint32) offset);
320 m_temp_trans.put_data ((uint32) len);
321
322 Socket socket_client (m_current_socket_client);
323
324 if (m_temp_trans.write_to_socket (socket_client) &&
325 m_temp_trans.read_from_socket (socket_client, m_socket_timeout)) {
326
327 int cmd;
328 uint32 key;
329
330 if (m_temp_trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_REQUEST &&
331 m_temp_trans.get_data (key) && key == m_current_socket_client_key &&
332 m_temp_trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_DELETE_SURROUNDING_TEXT &&
333 m_temp_trans.get_command (cmd) && cmd == SCIM_TRANS_CMD_OK)
334 return true;
335 }
336 }
337 return false;
338 }
339
340 void
init(int argc,char ** argv)341 SocketFrontEnd::init (int argc, char **argv)
342 {
343 int max_clients = -1;
344
345 if (!m_config.null ()) {
346 String str;
347
348 m_config_readonly = m_config->read (String (SCIM_CONFIG_FRONTEND_SOCKET_CONFIG_READONLY), false);
349
350 max_clients = m_config->read (String (SCIM_CONFIG_FRONTEND_SOCKET_MAXCLIENTS), -1);
351
352 m_config->signal_connect_reload (slot (this, &SocketFrontEnd::reload_config_callback));
353 } else {
354 m_config_readonly = false;
355 max_clients = -1;
356 }
357
358 if (!m_socket_server.create (scim_get_default_socket_frontend_address ()))
359 throw FrontEndError ("SocketFrontEnd -- Cannot create SocketServer.");
360
361 m_socket_server.set_max_clients (max_clients);
362
363 m_socket_server.signal_connect_accept (
364 slot (this, &SocketFrontEnd::socket_accept_callback));
365
366 m_socket_server.signal_connect_receive (
367 slot (this, &SocketFrontEnd::socket_receive_callback));
368
369 m_socket_server.signal_connect_exception(
370 slot (this, &SocketFrontEnd::socket_exception_callback));
371
372 if (argv && argc > 1) {
373 for (int i = 1; i < argc && argv [i]; ++i) {
374 if (String ("--no-stay") == argv [i])
375 m_stay = false;
376 }
377 }
378
379 /**
380 * initialize the random number generator.
381 */
382 srand (time (0));
383 }
384
385 void
run()386 SocketFrontEnd::run ()
387 {
388 if (m_socket_server.valid ())
389 m_socket_server.run ();
390 }
391
392 uint32
generate_key() const393 SocketFrontEnd::generate_key () const
394 {
395 return rand ();
396 }
397
398 bool
check_client_connection(const Socket & client) const399 SocketFrontEnd::check_client_connection (const Socket &client) const
400 {
401 SCIM_DEBUG_FRONTEND (1) << "check_client_connection (" << client.get_id () << ").\n";
402
403 unsigned char buf [sizeof(uint32)];
404
405 int nbytes = client.read_with_timeout (buf, sizeof(uint32), m_socket_timeout);
406
407 if (nbytes == sizeof (uint32))
408 return true;
409
410 if (nbytes < 0) {
411 SCIM_DEBUG_FRONTEND (2) << " Error occurred when reading socket (" << client.get_id ()
412 << "):" << client.get_error_message () << "\n";
413 } else {
414 SCIM_DEBUG_FRONTEND (2) << " Timeout when reading socket (" << client.get_id ()
415 << ").\n";
416 }
417
418 return false;
419 }
420
421 void
socket_accept_callback(SocketServer * server,const Socket & client)422 SocketFrontEnd::socket_accept_callback (SocketServer *server, const Socket &client)
423 {
424 SCIM_DEBUG_FRONTEND (1) << "socket_accept_callback (" << client.get_id () << ").\n";
425 }
426
427 void
socket_receive_callback(SocketServer * server,const Socket & client)428 SocketFrontEnd::socket_receive_callback (SocketServer *server, const Socket &client)
429 {
430 int id = client.get_id ();
431 int cmd;
432 uint32 key;
433
434 ClientInfo client_info;
435
436 SCIM_DEBUG_FRONTEND (1) << "socket_receive_callback (" << id << ").\n";
437
438 // Check if the client is closed.
439 if (!check_client_connection (client)) {
440 SCIM_DEBUG_FRONTEND (2) << " closing client connection.\n";
441 socket_close_connection (server, client);
442 return;
443 }
444
445 client_info = socket_get_client_info (client);
446
447 // If it's a new client, then request to open the connection first.
448 if (client_info.type == UNKNOWN_CLIENT) {
449 socket_open_connection (server, client);
450 return;
451 }
452
453 // If can not read the transaction,
454 // or the transaction is not started with SCIM_TRANS_CMD_REQUEST,
455 // or the key is mismatch,
456 // just return.
457 if (!m_receive_trans.read_from_socket (client, m_socket_timeout) ||
458 !m_receive_trans.get_command (cmd) || cmd != SCIM_TRANS_CMD_REQUEST ||
459 !m_receive_trans.get_data (key) || key != (uint32) client_info.key)
460 return;
461
462 m_current_socket_client = id;
463 m_current_socket_client_key = key;
464
465 m_send_trans.clear ();
466 m_send_trans.put_command (SCIM_TRANS_CMD_REPLY);
467
468 // Move the read ptr to the end.
469 m_send_trans.get_command (cmd);
470
471 while (m_receive_trans.get_command (cmd)) {
472 if (cmd == SCIM_TRANS_CMD_PROCESS_KEY_EVENT)
473 socket_process_key_event (id);
474 else if (cmd == SCIM_TRANS_CMD_MOVE_PREEDIT_CARET)
475 socket_move_preedit_caret (id);
476 else if (cmd == SCIM_TRANS_CMD_SELECT_CANDIDATE)
477 socket_select_candidate (id);
478 else if (cmd == SCIM_TRANS_CMD_UPDATE_LOOKUP_TABLE_PAGE_SIZE)
479 socket_update_lookup_table_page_size (id);
480 else if (cmd == SCIM_TRANS_CMD_LOOKUP_TABLE_PAGE_UP)
481 socket_lookup_table_page_up (id);
482 else if (cmd == SCIM_TRANS_CMD_LOOKUP_TABLE_PAGE_DOWN)
483 socket_lookup_table_page_down (id);
484 else if (cmd == SCIM_TRANS_CMD_RESET)
485 socket_reset (id);
486 else if (cmd == SCIM_TRANS_CMD_FOCUS_IN)
487 socket_focus_in (id);
488 else if (cmd == SCIM_TRANS_CMD_FOCUS_OUT)
489 socket_focus_out (id);
490 else if (cmd == SCIM_TRANS_CMD_TRIGGER_PROPERTY)
491 socket_trigger_property (id);
492 else if (cmd == SCIM_TRANS_CMD_PROCESS_HELPER_EVENT)
493 socket_process_helper_event (id);
494 else if (cmd == SCIM_TRANS_CMD_UPDATE_CLIENT_CAPABILITIES)
495 socket_update_client_capabilities (id);
496 else if (cmd == SCIM_TRANS_CMD_GET_FACTORY_LIST)
497 socket_get_factory_list (id);
498 else if (cmd == SCIM_TRANS_CMD_GET_FACTORY_NAME)
499 socket_get_factory_name (id);
500 else if (cmd == SCIM_TRANS_CMD_GET_FACTORY_AUTHORS)
501 socket_get_factory_authors (id);
502 else if (cmd == SCIM_TRANS_CMD_GET_FACTORY_CREDITS)
503 socket_get_factory_credits (id);
504 else if (cmd == SCIM_TRANS_CMD_GET_FACTORY_HELP)
505 socket_get_factory_help (id);
506 else if (cmd == SCIM_TRANS_CMD_GET_FACTORY_LOCALES)
507 socket_get_factory_locales (id);
508 else if (cmd == SCIM_TRANS_CMD_GET_FACTORY_ICON_FILE)
509 socket_get_factory_icon_file (id);
510 else if (cmd == SCIM_TRANS_CMD_GET_FACTORY_LANGUAGE)
511 socket_get_factory_language (id);
512 else if (cmd == SCIM_TRANS_CMD_NEW_INSTANCE)
513 socket_new_instance (id);
514 else if (cmd == SCIM_TRANS_CMD_DELETE_INSTANCE)
515 socket_delete_instance (id);
516 else if (cmd == SCIM_TRANS_CMD_DELETE_ALL_INSTANCES)
517 socket_delete_all_instances (id);
518 else if (cmd == SCIM_TRANS_CMD_FLUSH_CONFIG)
519 socket_flush_config (id);
520 else if (cmd == SCIM_TRANS_CMD_ERASE_CONFIG)
521 socket_erase_config (id);
522 else if (cmd == SCIM_TRANS_CMD_RELOAD_CONFIG)
523 socket_reload_config (id);
524 else if (cmd == SCIM_TRANS_CMD_GET_CONFIG_STRING)
525 socket_get_config_string (id);
526 else if (cmd == SCIM_TRANS_CMD_SET_CONFIG_STRING)
527 socket_set_config_string (id);
528 else if (cmd == SCIM_TRANS_CMD_GET_CONFIG_INT)
529 socket_get_config_int (id);
530 else if (cmd == SCIM_TRANS_CMD_SET_CONFIG_INT)
531 socket_set_config_int (id);
532 else if (cmd == SCIM_TRANS_CMD_GET_CONFIG_BOOL)
533 socket_get_config_bool (id);
534 else if (cmd == SCIM_TRANS_CMD_SET_CONFIG_BOOL)
535 socket_set_config_bool (id);
536 else if (cmd == SCIM_TRANS_CMD_GET_CONFIG_DOUBLE)
537 socket_get_config_double (id);
538 else if (cmd == SCIM_TRANS_CMD_SET_CONFIG_DOUBLE)
539 socket_set_config_double (id);
540 else if (cmd == SCIM_TRANS_CMD_GET_CONFIG_VECTOR_STRING)
541 socket_get_config_vector_string (id);
542 else if (cmd == SCIM_TRANS_CMD_SET_CONFIG_VECTOR_STRING)
543 socket_set_config_vector_string (id);
544 else if (cmd == SCIM_TRANS_CMD_GET_CONFIG_VECTOR_INT)
545 socket_get_config_vector_int (id);
546 else if (cmd == SCIM_TRANS_CMD_SET_CONFIG_VECTOR_INT)
547 socket_set_config_vector_int (id);
548 else if (cmd == SCIM_TRANS_CMD_LOAD_FILE)
549 socket_load_file (id);
550 else if (cmd == SCIM_TRANS_CMD_CLOSE_CONNECTION) {
551 socket_close_connection (server, client);
552 m_current_socket_client = -1;
553 m_current_socket_client_key = 0;
554 return;
555 }
556 }
557
558 // Send reply to client
559 if (m_send_trans.get_data_type () == SCIM_TRANS_DATA_UNKNOWN)
560 m_send_trans.put_command (SCIM_TRANS_CMD_FAIL);
561
562 m_send_trans.write_to_socket (client);
563
564 m_current_socket_client = -1;
565 m_current_socket_client_key = 0;
566
567 SCIM_DEBUG_FRONTEND (1) << "End of socket_receive_callback (" << id << ").\n";
568 }
569
570 bool
socket_open_connection(SocketServer * server,const Socket & client)571 SocketFrontEnd::socket_open_connection (SocketServer *server, const Socket &client)
572 {
573 SCIM_DEBUG_FRONTEND (2) << " Open socket connection for client " << client.get_id () << " number of clients=" << m_socket_client_repository.size () << ".\n";
574
575 uint32 key;
576 String type = scim_socket_accept_connection (key,
577 String ("SocketFrontEnd"),
578 String ("SocketIMEngine,SocketConfig"),
579 client,
580 m_socket_timeout);
581
582 if (type.length ()) {
583 ClientInfo info;
584 info.key = key;
585 info.type = ((type == "SocketIMEngine") ? IMENGINE_CLIENT : CONFIG_CLIENT);
586
587 SCIM_DEBUG_MAIN (2) << " Add client to repository. Type=" << type << " key=" << key << "\n";
588 m_socket_client_repository [client.get_id ()] = info;
589 return true;
590 }
591
592 // Client did not pass the registration process, close it.
593 SCIM_DEBUG_FRONTEND (2) << " Failed to create new connection.\n";
594 server->close_connection (client);
595 return false;
596 }
597
598 void
socket_close_connection(SocketServer * server,const Socket & client)599 SocketFrontEnd::socket_close_connection (SocketServer *server, const Socket &client)
600 {
601 SCIM_DEBUG_FRONTEND (2) << " Close client connection " << client.get_id () << " number of clients=" << m_socket_client_repository.size () << ".\n";
602
603 ClientInfo client_info = socket_get_client_info (client);
604
605 server->close_connection (client);
606
607 if (client_info.type != UNKNOWN_CLIENT) {
608 m_socket_client_repository.erase (client.get_id ());
609
610 if (client_info.type == IMENGINE_CLIENT)
611 socket_delete_all_instances (client.get_id ());
612
613 if (!m_socket_client_repository.size () && !m_stay)
614 server->shutdown ();
615 }
616 }
617
618 SocketFrontEnd::ClientInfo
socket_get_client_info(const Socket & client)619 SocketFrontEnd::socket_get_client_info (const Socket &client)
620 {
621 static ClientInfo null_client = { 0, UNKNOWN_CLIENT };
622 SocketClientRepository::iterator it = m_socket_client_repository.find (client.get_id ());
623
624 if (it != m_socket_client_repository.end ())
625 return it->second;
626
627 return null_client;
628 }
629
630 void
socket_exception_callback(SocketServer * server,const Socket & client)631 SocketFrontEnd::socket_exception_callback (SocketServer *server, const Socket &client)
632 {
633 SCIM_DEBUG_FRONTEND (1) << "socket_exception_callback (" << client.get_id () << ").\n";
634
635 socket_close_connection (server, client);
636 }
637
638 //client_id is client's socket id
639 void
socket_get_factory_list(int)640 SocketFrontEnd::socket_get_factory_list (int /*client_id*/)
641 {
642 String encoding;
643
644 SCIM_DEBUG_FRONTEND (2) << " socket_get_factory_list.\n";
645
646 if (m_receive_trans.get_data (encoding)) {
647 std::vector<String> uuids;
648
649 get_factory_list_for_encoding (uuids, encoding);
650
651 SCIM_DEBUG_FRONTEND (3) << " Encoding (" << encoding
652 << ") Num(" << uuids.size () << ").\n";
653
654 m_send_trans.put_data (uuids);
655 m_send_trans.put_command (SCIM_TRANS_CMD_OK);
656 }
657 }
658
659 void
socket_get_factory_name(int)660 SocketFrontEnd::socket_get_factory_name (int /*client_id*/)
661 {
662 String sfid;
663
664 SCIM_DEBUG_FRONTEND (2) << " socket_get_factory_name.\n";
665
666 if (m_receive_trans.get_data (sfid)) {
667 WideString name = get_factory_name (sfid);
668
669 m_send_trans.put_data (name);
670 m_send_trans.put_command (SCIM_TRANS_CMD_OK);
671 }
672 }
673
674 void
socket_get_factory_authors(int)675 SocketFrontEnd::socket_get_factory_authors (int /*client_id*/)
676 {
677 String sfid;
678
679 SCIM_DEBUG_FRONTEND (2) << " socket_get_factory_authors.\n";
680
681 if (m_receive_trans.get_data (sfid)) {
682 WideString authors = get_factory_authors (sfid);
683
684 m_send_trans.put_data (authors);
685 m_send_trans.put_command (SCIM_TRANS_CMD_OK);
686 }
687 }
688
689 void
socket_get_factory_credits(int)690 SocketFrontEnd::socket_get_factory_credits (int /*client_id*/)
691 {
692 String sfid;
693
694 SCIM_DEBUG_FRONTEND (2) << " socket_get_factory_credits.\n";
695
696 if (m_receive_trans.get_data (sfid)) {
697 WideString credits = get_factory_credits (sfid);
698
699 m_send_trans.put_data (credits);
700 m_send_trans.put_command (SCIM_TRANS_CMD_OK);
701 }
702 }
703
704 void
socket_get_factory_help(int)705 SocketFrontEnd::socket_get_factory_help (int /*client_id*/)
706 {
707 String sfid;
708
709 SCIM_DEBUG_FRONTEND (2) << " socket_get_factory_help.\n";
710
711 if (m_receive_trans.get_data (sfid)) {
712 WideString help = get_factory_help (sfid);
713
714 m_send_trans.put_data (help);
715 m_send_trans.put_command (SCIM_TRANS_CMD_OK);
716 }
717 }
718
719 void
socket_get_factory_locales(int)720 SocketFrontEnd::socket_get_factory_locales (int /*client_id*/)
721 {
722 String sfid;
723
724 SCIM_DEBUG_FRONTEND (2) << " socket_get_factory_locales.\n";
725
726 if (m_receive_trans.get_data (sfid)) {
727 String locales = get_factory_locales (sfid);
728
729 SCIM_DEBUG_FRONTEND (3) << " Locales (" << locales << ").\n";
730
731 m_send_trans.put_data (locales);
732 m_send_trans.put_command (SCIM_TRANS_CMD_OK);
733 }
734 }
735
736 void
socket_get_factory_icon_file(int)737 SocketFrontEnd::socket_get_factory_icon_file (int /*client_id*/)
738 {
739 String sfid;
740
741 SCIM_DEBUG_FRONTEND (2) << " socket_get_factory_icon_file.\n";
742
743 if (m_receive_trans.get_data (sfid)) {
744 String iconfile = get_factory_icon_file (sfid);
745
746 SCIM_DEBUG_FRONTEND (3) << " ICON File (" << iconfile << ").\n";
747
748 m_send_trans.put_data (iconfile);
749 m_send_trans.put_command (SCIM_TRANS_CMD_OK);
750 }
751 }
752
753 void
socket_get_factory_language(int)754 SocketFrontEnd::socket_get_factory_language (int /*client_id*/)
755 {
756 String sfid;
757
758 SCIM_DEBUG_FRONTEND (2) << " socket_get_factory_language.\n";
759
760 if (m_receive_trans.get_data (sfid)) {
761 String language = get_factory_language (sfid);
762
763 SCIM_DEBUG_FRONTEND (3) << " Language (" << language << ").\n";
764
765 m_send_trans.put_data (language);
766 m_send_trans.put_command (SCIM_TRANS_CMD_OK);
767 }
768 }
769
770 void
socket_new_instance(int client_id)771 SocketFrontEnd::socket_new_instance (int client_id)
772 {
773 String sfid;
774 String encoding;
775
776 SCIM_DEBUG_FRONTEND (2) << " socket_new_instance.\n";
777
778 if (m_receive_trans.get_data (sfid) &&
779 m_receive_trans.get_data (encoding)) {
780 int siid = new_instance (sfid, encoding);
781
782 // Instance created OK.
783 if (siid >= 0) {
784 SocketInstanceRepository::iterator it =
785 std::lower_bound (m_socket_instance_repository.begin (),
786 m_socket_instance_repository.end (),
787 std::pair <int, int> (client_id, siid));
788
789 if (it == m_socket_instance_repository.end ())
790 m_socket_instance_repository.push_back (std::pair <int, int> (client_id, siid));
791 else
792 m_socket_instance_repository.insert (it, std::pair <int, int> (client_id, siid));
793
794 SCIM_DEBUG_FRONTEND (3) << " InstanceID (" << siid << ").\n";
795
796 m_send_trans.put_data ((uint32)siid);
797 m_send_trans.put_command (SCIM_TRANS_CMD_OK);
798 }
799 }
800 }
801
802 void
socket_delete_instance(int client_id)803 SocketFrontEnd::socket_delete_instance (int client_id)
804 {
805 uint32 siid;
806
807 SCIM_DEBUG_FRONTEND (2) << " socket_delete_instance.\n";
808
809 if (m_receive_trans.get_data (siid)) {
810
811 SCIM_DEBUG_FRONTEND (3) << " InstanceID (" << siid << ").\n";
812
813 m_current_instance = (int) siid;
814
815 delete_instance ((int) siid);
816
817 m_current_instance = -1;
818
819 SocketInstanceRepository::iterator it =
820 std::lower_bound (m_socket_instance_repository.begin (),
821 m_socket_instance_repository.end (),
822 std::pair <int, int> (client_id, siid));
823
824 if (it != m_socket_instance_repository.end () &&
825 *it == std::pair <int, int> (client_id, siid))
826 m_socket_instance_repository.erase (it);
827
828 m_send_trans.put_command (SCIM_TRANS_CMD_OK);
829 }
830 }
831
832 void
socket_delete_all_instances(int client_id)833 SocketFrontEnd::socket_delete_all_instances (int client_id)
834 {
835 SCIM_DEBUG_FRONTEND (2) << " socket_delete_all_instances.\n";
836
837 SocketInstanceRepository::iterator it;
838
839 SocketInstanceRepository::iterator lit =
840 std::lower_bound (m_socket_instance_repository.begin (),
841 m_socket_instance_repository.end (),
842 std::pair <int, int> (client_id, 0));
843
844 SocketInstanceRepository::iterator uit =
845 std::upper_bound (m_socket_instance_repository.begin (),
846 m_socket_instance_repository.end (),
847 std::pair <int, int> (client_id, INT_MAX));
848
849 if (lit != uit) {
850 for (it = lit; it != uit; ++it) {
851 m_current_instance = it->second;
852 delete_instance (it->second);
853 }
854 m_current_instance = -1;
855 m_socket_instance_repository.erase (lit, uit);
856 m_send_trans.put_command (SCIM_TRANS_CMD_OK);
857 }
858 }
859
860 void
socket_process_key_event(int)861 SocketFrontEnd::socket_process_key_event (int /*client_id*/)
862 {
863 uint32 siid;
864 KeyEvent event;
865
866 SCIM_DEBUG_FRONTEND (2) << " socket_process_key_event.\n";
867
868 if (m_receive_trans.get_data (siid) &&
869 m_receive_trans.get_data (event)) {
870
871 SCIM_DEBUG_FRONTEND (3) << " SI (" << siid << ") KeyEvent ("
872 << event.code << "," << event.mask << ").\n";
873
874 m_current_instance = (int) siid;
875
876 if (process_key_event ((int) siid, event))
877 m_send_trans.put_command (SCIM_TRANS_CMD_OK);
878 else
879 m_send_trans.put_command (SCIM_TRANS_CMD_FAIL);
880
881 m_current_instance = -1;
882 }
883 }
884
885 void
socket_move_preedit_caret(int)886 SocketFrontEnd::socket_move_preedit_caret (int /*client_id*/)
887 {
888 uint32 siid;
889 uint32 caret;
890
891 SCIM_DEBUG_FRONTEND (2) << " socket_move_preedit_caret.\n";
892
893 if (m_receive_trans.get_data (siid) &&
894 m_receive_trans.get_data (caret)) {
895
896 SCIM_DEBUG_FRONTEND (3) << " SI (" << siid
897 << ") Caret (" << caret << ").\n";
898
899 m_current_instance = (int) siid;
900
901 move_preedit_caret ((int) siid, caret);
902 m_send_trans.put_command (SCIM_TRANS_CMD_OK);
903
904 m_current_instance = -1;
905 }
906 }
907
908 void
socket_select_candidate(int)909 SocketFrontEnd::socket_select_candidate (int /*client_id*/)
910 {
911 uint32 siid;
912 uint32 item;
913
914 SCIM_DEBUG_FRONTEND (2) << " socket_select_candidate.\n";
915
916 if (m_receive_trans.get_data (siid) &&
917 m_receive_trans.get_data (item)) {
918
919 SCIM_DEBUG_FRONTEND (3) << " SI (" << siid << ") Item (" << item << ").\n";
920
921 m_current_instance = (int) siid;
922
923 select_candidate ((int) siid, item);
924 m_send_trans.put_command (SCIM_TRANS_CMD_OK);
925
926 m_current_instance = -1;
927 }
928 }
929
930 void
socket_update_lookup_table_page_size(int)931 SocketFrontEnd::socket_update_lookup_table_page_size (int /*client_id*/)
932 {
933 uint32 siid;
934 uint32 size;
935
936 SCIM_DEBUG_FRONTEND (2) << " socket_update_lookup_table_page_size.\n";
937
938 if (m_receive_trans.get_data (siid) &&
939 m_receive_trans.get_data (size)) {
940
941 SCIM_DEBUG_FRONTEND (3) << " SI (" << siid << ") PageSize (" << size << ").\n";
942
943 m_current_instance = (int) siid;
944
945 update_lookup_table_page_size ((int) siid, size);
946 m_send_trans.put_command (SCIM_TRANS_CMD_OK);
947
948 m_current_instance = -1;
949 }
950 }
951
952 void
socket_lookup_table_page_up(int)953 SocketFrontEnd::socket_lookup_table_page_up (int /*client_id*/)
954 {
955 uint32 siid;
956
957 SCIM_DEBUG_FRONTEND (2) << " socket_lookup_table_page_up.\n";
958
959 if (m_receive_trans.get_data (siid)) {
960
961 SCIM_DEBUG_FRONTEND (3) << " SI (" << siid << ").\n";
962
963 m_current_instance = (int) siid;
964
965 lookup_table_page_up ((int) siid);
966 m_send_trans.put_command (SCIM_TRANS_CMD_OK);
967
968 m_current_instance = -1;
969 }
970 }
971
972 void
socket_lookup_table_page_down(int)973 SocketFrontEnd::socket_lookup_table_page_down (int /*client_id*/)
974 {
975 uint32 siid;
976
977 SCIM_DEBUG_FRONTEND (2) << " socket_lookup_table_page_down.\n";
978
979 if (m_receive_trans.get_data (siid)) {
980
981 SCIM_DEBUG_FRONTEND (3) << " SI (" << siid << ").\n";
982
983 m_current_instance = (int) siid;
984
985 lookup_table_page_down ((int) siid);
986 m_send_trans.put_command (SCIM_TRANS_CMD_OK);
987
988 m_current_instance = -1;
989 }
990 }
991
992 void
socket_reset(int)993 SocketFrontEnd::socket_reset (int /*client_id*/)
994 {
995 uint32 siid;
996
997 SCIM_DEBUG_FRONTEND (2) << " socket_reset.\n";
998
999 if (m_receive_trans.get_data (siid)) {
1000
1001 SCIM_DEBUG_FRONTEND (3) << " SI (" << siid << ").\n";
1002
1003 m_current_instance = (int) siid;
1004
1005 reset ((int) siid);
1006 m_send_trans.put_command (SCIM_TRANS_CMD_OK);
1007
1008 m_current_instance = -1;
1009 }
1010 }
1011
1012 void
socket_focus_in(int)1013 SocketFrontEnd::socket_focus_in (int /*client_id*/)
1014 {
1015 uint32 siid;
1016
1017 SCIM_DEBUG_FRONTEND (2) << " socket_focus_in.\n";
1018
1019 if (m_receive_trans.get_data (siid)) {
1020
1021 SCIM_DEBUG_FRONTEND (3) << " SI (" << siid << ").\n";
1022
1023 m_current_instance = (int) siid;
1024
1025 focus_in ((int) siid);
1026 m_send_trans.put_command (SCIM_TRANS_CMD_OK);
1027
1028 m_current_instance = -1;
1029 }
1030 }
1031
1032 void
socket_focus_out(int)1033 SocketFrontEnd::socket_focus_out (int /*client_id*/)
1034 {
1035 uint32 siid;
1036
1037 SCIM_DEBUG_FRONTEND (2) << " socket_focus_out.\n";
1038
1039 if (m_receive_trans.get_data (siid)) {
1040
1041 SCIM_DEBUG_FRONTEND (3) << " SI (" << siid << ").\n";
1042
1043 m_current_instance = (int) siid;
1044
1045 focus_out ((int) siid);
1046 m_send_trans.put_command (SCIM_TRANS_CMD_OK);
1047
1048 m_current_instance = -1;
1049 }
1050 }
1051
1052 void
socket_trigger_property(int)1053 SocketFrontEnd::socket_trigger_property (int /*client_id*/)
1054 {
1055 uint32 siid;
1056 String property;
1057
1058 SCIM_DEBUG_FRONTEND (2) << " socket_trigger_property.\n";
1059
1060 if (m_receive_trans.get_data (siid) &&
1061 m_receive_trans.get_data (property)) {
1062
1063 SCIM_DEBUG_FRONTEND (3) << " SI (" << siid << ").\n";
1064
1065 m_current_instance = (int) siid;
1066
1067 trigger_property ((int) siid, property);
1068 m_send_trans.put_command (SCIM_TRANS_CMD_OK);
1069
1070 m_current_instance = -1;
1071 }
1072 }
1073
1074 void
socket_process_helper_event(int)1075 SocketFrontEnd::socket_process_helper_event (int /*client_id*/)
1076 {
1077 uint32 siid;
1078 String helper_uuid;
1079 Transaction trans;
1080
1081 SCIM_DEBUG_FRONTEND (2) << " socket_process_helper_event.\n";
1082
1083 if (m_receive_trans.get_data (siid) &&
1084 m_receive_trans.get_data (helper_uuid) &&
1085 m_receive_trans.get_data (trans)) {
1086
1087 SCIM_DEBUG_FRONTEND (3) << " SI (" << siid << ").\n";
1088
1089 m_current_instance = (int) siid;
1090
1091 process_helper_event ((int) siid, helper_uuid, trans);
1092 m_send_trans.put_command (SCIM_TRANS_CMD_OK);
1093
1094 m_current_instance = -1;
1095 }
1096 }
1097
1098 void
socket_update_client_capabilities(int)1099 SocketFrontEnd::socket_update_client_capabilities (int /*client_id*/)
1100 {
1101 uint32 siid;
1102 uint32 cap;
1103
1104 SCIM_DEBUG_FRONTEND (2) << " socket_update_client_capabilities.\n";
1105
1106 if (m_receive_trans.get_data (siid) && m_receive_trans.get_data (cap)) {
1107
1108 SCIM_DEBUG_FRONTEND (3) << " SI (" << siid << ").\n";
1109
1110 m_current_instance = (int) siid;
1111
1112 update_client_capabilities ((int) siid, cap);
1113
1114 m_send_trans.put_command (SCIM_TRANS_CMD_OK);
1115
1116 m_current_instance = -1;
1117 }
1118 }
1119
1120
1121 void
socket_flush_config(int)1122 SocketFrontEnd::socket_flush_config (int /*client_id*/)
1123 {
1124 if (m_config_readonly || m_config.null ())
1125 return;
1126
1127 SCIM_DEBUG_FRONTEND (2) << " socket_flush_config.\n";
1128
1129 if (m_config->flush ())
1130 m_send_trans.put_command (SCIM_TRANS_CMD_OK);
1131 }
1132
1133 void
socket_erase_config(int)1134 SocketFrontEnd::socket_erase_config (int /*client_id*/)
1135 {
1136 if (m_config_readonly || m_config.null ())
1137 return;
1138
1139 String key;
1140
1141 SCIM_DEBUG_FRONTEND (2) << " socket_erase_config.\n";
1142
1143 if (m_receive_trans.get_data (key)) {
1144
1145 SCIM_DEBUG_FRONTEND (3) << " Key (" << key << ").\n";
1146
1147 if (m_config->erase (key))
1148 m_send_trans.put_command (SCIM_TRANS_CMD_OK);
1149 }
1150 }
1151
1152 void
socket_reload_config(int)1153 SocketFrontEnd::socket_reload_config (int /*client_id*/)
1154 {
1155 static timeval last_timestamp = {0, 0};
1156
1157 if (m_config.null ())
1158 return;
1159
1160 SCIM_DEBUG_FRONTEND (2) << " socket_reload_config.\n";
1161
1162 timeval timestamp;
1163
1164 gettimeofday (×tamp, 0);
1165
1166 if (timestamp.tv_sec > last_timestamp.tv_sec + 1)
1167 m_config->reload ();
1168
1169 gettimeofday (&last_timestamp, 0);
1170
1171 m_send_trans.put_command (SCIM_TRANS_CMD_OK);
1172 }
1173
1174 void
socket_get_config_string(int)1175 SocketFrontEnd::socket_get_config_string (int /*client_id*/)
1176 {
1177 if (m_config.null ()) return;
1178
1179 String key;
1180
1181 SCIM_DEBUG_FRONTEND (2) << " socket_get_config_string.\n";
1182
1183 if (m_receive_trans.get_data (key)) {
1184 String value;
1185
1186 SCIM_DEBUG_FRONTEND (3) << " Key (" << key << ").\n";
1187
1188 if (m_config->read (key, &value)) {
1189 m_send_trans.put_data (value);
1190 m_send_trans.put_command (SCIM_TRANS_CMD_OK);
1191 }
1192 }
1193 }
1194
1195 void
socket_set_config_string(int)1196 SocketFrontEnd::socket_set_config_string (int /*client_id*/)
1197 {
1198 if (m_config_readonly || m_config.null ())
1199 return;
1200
1201 String key;
1202 String value;
1203
1204 SCIM_DEBUG_FRONTEND (2) << " socket_set_config_string.\n";
1205
1206 if (m_receive_trans.get_data (key) &&
1207 m_receive_trans.get_data (value)) {
1208
1209 SCIM_DEBUG_FRONTEND (3) << " Key (" << key << ").\n";
1210 SCIM_DEBUG_FRONTEND (3) << " Value (" << value << ").\n";
1211
1212 if (m_config->write (key, value))
1213 m_send_trans.put_command (SCIM_TRANS_CMD_OK);
1214 }
1215 }
1216
1217 void
socket_get_config_int(int)1218 SocketFrontEnd::socket_get_config_int (int /*client_id*/)
1219 {
1220 if (m_config.null ()) return;
1221
1222 String key;
1223
1224 SCIM_DEBUG_FRONTEND (2) << " socket_get_config_int.\n";
1225
1226 if (m_receive_trans.get_data (key)) {
1227
1228 SCIM_DEBUG_FRONTEND (3) << " Key (" << key << ").\n";
1229
1230 int value;
1231 if (m_config->read (key, &value)) {
1232 m_send_trans.put_data ((uint32) value);
1233 m_send_trans.put_command (SCIM_TRANS_CMD_OK);
1234 }
1235 }
1236 }
1237
1238 void
socket_set_config_int(int)1239 SocketFrontEnd::socket_set_config_int (int /*client_id*/)
1240 {
1241 if (m_config_readonly || m_config.null ())
1242 return;
1243
1244 String key;
1245 uint32 value;
1246
1247 SCIM_DEBUG_FRONTEND (2) << " socket_set_config_int.\n";
1248
1249 if (m_receive_trans.get_data (key) &&
1250 m_receive_trans.get_data (value)) {
1251
1252 SCIM_DEBUG_FRONTEND (3) << " Key (" << key << ").\n";
1253 SCIM_DEBUG_FRONTEND (3) << " Value (" << value << ").\n";
1254
1255 if (m_config->write (key, (int) value))
1256 m_send_trans.put_command (SCIM_TRANS_CMD_OK);
1257 }
1258 }
1259
1260 void
socket_get_config_bool(int)1261 SocketFrontEnd::socket_get_config_bool (int /*client_id*/)
1262 {
1263 if (m_config.null ()) return;
1264
1265 String key;
1266
1267 SCIM_DEBUG_FRONTEND (2) << " socket_get_config_bool.\n";
1268
1269 if (m_receive_trans.get_data (key)) {
1270 bool value;
1271
1272 SCIM_DEBUG_FRONTEND (3) << " Key (" << key << ").\n";
1273
1274 if (m_config->read (key, &value)) {
1275 m_send_trans.put_data ((uint32) value);
1276 m_send_trans.put_command (SCIM_TRANS_CMD_OK);
1277 }
1278 }
1279 }
1280
1281 void
socket_set_config_bool(int)1282 SocketFrontEnd::socket_set_config_bool (int /*client_id*/)
1283 {
1284 if (m_config_readonly || m_config.null ())
1285 return;
1286
1287 String key;
1288 uint32 value;
1289
1290 SCIM_DEBUG_FRONTEND (2) << " socket_set_config_bool.\n";
1291
1292 if (m_receive_trans.get_data (key) &&
1293 m_receive_trans.get_data (value)) {
1294
1295 SCIM_DEBUG_FRONTEND (3) << " Key (" << key << ").\n";
1296 SCIM_DEBUG_FRONTEND (3) << " Value (" << value << ").\n";
1297
1298 if (m_config->write (key, (bool) value))
1299 m_send_trans.put_command (SCIM_TRANS_CMD_OK);
1300 }
1301 }
1302
1303 void
socket_get_config_double(int)1304 SocketFrontEnd::socket_get_config_double (int /*client_id*/)
1305 {
1306 if (m_config.null ()) return;
1307
1308 String key;
1309
1310 SCIM_DEBUG_FRONTEND (2) << " socket_get_config_double.\n";
1311
1312 if (m_receive_trans.get_data (key)) {
1313 double value;
1314
1315 SCIM_DEBUG_FRONTEND (3) << " Key (" << key << ").\n";
1316
1317 if (m_config->read (key, &value)) {
1318 char buf [80];
1319 snprintf (buf, 79, "%lE", value);
1320 m_send_trans.put_data (String (buf));
1321 m_send_trans.put_command (SCIM_TRANS_CMD_OK);
1322 }
1323 }
1324 }
1325
1326 void
socket_set_config_double(int)1327 SocketFrontEnd::socket_set_config_double (int /*client_id*/)
1328 {
1329 if (m_config_readonly || m_config.null ())
1330 return;
1331
1332 String key;
1333 String str;
1334
1335 SCIM_DEBUG_FRONTEND (2) << " socket_set_config_double.\n";
1336
1337 if (m_receive_trans.get_data (key) &&
1338 m_receive_trans.get_data (str)) {
1339 double value;
1340 sscanf (str.c_str (), "%lE", &value);
1341
1342 SCIM_DEBUG_FRONTEND (3) << " Key (" << key << ").\n";
1343 SCIM_DEBUG_FRONTEND (3) << " Value (" << value << ").\n";
1344
1345 if (m_config->write (key, value))
1346 m_send_trans.put_command (SCIM_TRANS_CMD_OK);
1347 }
1348 }
1349
1350 void
socket_get_config_vector_string(int)1351 SocketFrontEnd::socket_get_config_vector_string (int /*client_id*/)
1352 {
1353 if (m_config.null ()) return;
1354
1355 String key;
1356
1357 SCIM_DEBUG_FRONTEND (2) << " socket_get_config_vector_string.\n";
1358
1359 if (m_receive_trans.get_data (key)) {
1360 std::vector <String> vec;
1361
1362 SCIM_DEBUG_FRONTEND (3) << " Key (" << key << ").\n";
1363
1364 if (m_config->read (key, &vec)) {
1365 m_send_trans.put_data (vec);
1366 m_send_trans.put_command (SCIM_TRANS_CMD_OK);
1367 }
1368 }
1369 }
1370
1371 void
socket_set_config_vector_string(int)1372 SocketFrontEnd::socket_set_config_vector_string (int /*client_id*/)
1373 {
1374 if (m_config_readonly || m_config.null ())
1375 return;
1376
1377 String key;
1378 std::vector<String> vec;
1379
1380 SCIM_DEBUG_FRONTEND (2) << " socket_set_config_vector_string.\n";
1381
1382 if (m_receive_trans.get_data (key) &&
1383 m_receive_trans.get_data (vec)) {
1384
1385 SCIM_DEBUG_FRONTEND (3) << " Key (" << key << ").\n";
1386
1387 if (m_config->write (key, vec))
1388 m_send_trans.put_command (SCIM_TRANS_CMD_OK);
1389 }
1390 }
1391
1392 void
socket_get_config_vector_int(int)1393 SocketFrontEnd::socket_get_config_vector_int (int /*client_id*/)
1394 {
1395 if (m_config.null ()) return;
1396
1397 String key;
1398
1399 SCIM_DEBUG_FRONTEND (2) << " socket_get_config_vector_int.\n";
1400
1401 if (m_receive_trans.get_data (key)) {
1402 std::vector <int> vec;
1403
1404 SCIM_DEBUG_FRONTEND (3) << " Key (" << key << ").\n";
1405
1406 if (m_config->read (key, &vec)) {
1407 std::vector <uint32> reply;
1408
1409 for (uint32 i=0; i<vec.size (); ++i)
1410 reply.push_back ((uint32) vec[i]);
1411
1412 m_send_trans.put_data (reply);
1413 m_send_trans.put_command (SCIM_TRANS_CMD_OK);
1414 }
1415 }
1416 }
1417
1418 void
socket_set_config_vector_int(int)1419 SocketFrontEnd::socket_set_config_vector_int (int /*client_id*/)
1420 {
1421 if (m_config_readonly || m_config.null ())
1422 return;
1423
1424 String key;
1425 std::vector<uint32> vec;
1426
1427 SCIM_DEBUG_FRONTEND (2) << " socket_set_config_vector_int.\n";
1428
1429 if (m_receive_trans.get_data (key) &&
1430 m_receive_trans.get_data (vec)) {
1431 std::vector<int> req;
1432
1433 SCIM_DEBUG_FRONTEND (3) << " Key (" << key << ").\n";
1434
1435 for (uint32 i=0; i<vec.size (); ++i)
1436 req.push_back ((int) vec[i]);
1437
1438 if (m_config->write (key, req))
1439 m_send_trans.put_command (SCIM_TRANS_CMD_OK);
1440 }
1441 }
1442
1443 void
socket_load_file(int)1444 SocketFrontEnd::socket_load_file (int /*client_id*/)
1445 {
1446 String filename;
1447 char *bufptr = 0;
1448 size_t filesize = 0;
1449
1450 SCIM_DEBUG_FRONTEND (2) << " socket_load_file.\n";
1451
1452 if (m_receive_trans.get_data (filename)) {
1453 SCIM_DEBUG_FRONTEND (3) << " File (" << filename << ").\n";
1454
1455 if ((filesize = scim_load_file (filename, &bufptr)) > 0) {
1456 m_send_trans.put_data (bufptr, filesize);
1457 m_send_trans.put_command (SCIM_TRANS_CMD_OK);
1458 }
1459
1460 delete [] bufptr;
1461 }
1462 }
1463
1464 void
reload_config_callback(const ConfigPointer & config)1465 SocketFrontEnd::reload_config_callback (const ConfigPointer &config)
1466 {
1467 SCIM_DEBUG_FRONTEND (1) << "Reload configuration.\n";
1468
1469 int max_clients = -1;
1470
1471 m_config_readonly = config->read (String (SCIM_CONFIG_FRONTEND_SOCKET_CONFIG_READONLY), false);
1472 max_clients = config->read (String (SCIM_CONFIG_FRONTEND_SOCKET_MAXCLIENTS), -1);
1473
1474 m_socket_server.set_max_clients (max_clients);
1475 }
1476
1477 /*
1478 vi:ts=4:nowrap:expandtab
1479 */
1480