1 /* vim:set et sts=4: */
2 /* ibus - The Input Bus
3 * Copyright (C) 2008-2010 Peng Huang <shawn.p.huang@gmail.com>
4 * Copyright (C) 2008-2010 Red Hat, Inc.
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
23 #include <sys/types.h>
30 #include <dbus/dbus.h>
34 #include "connection.h"
36 #include "factoryproxy.h"
37 #include "panelproxy.h"
38 #include "inputcontext.h"
49 // static guint _signals[LAST_SIGNAL] = { 0 };
51 /* functions prototype */
52 static void bus_ibus_impl_destroy (BusIBusImpl *ibus);
53 static gboolean bus_ibus_impl_ibus_message (BusIBusImpl *ibus,
54 BusConnection *connection,
55 IBusMessage *message);
56 static void bus_ibus_impl_add_factory (BusIBusImpl *ibus,
57 BusFactoryProxy *factory);
58 static void bus_ibus_impl_set_trigger (BusIBusImpl *ibus,
60 static void bus_ibus_impl_set_next_engine_in_menu
63 static void bus_ibus_impl_set_previous_engine
67 static void bus_ibus_impl_set_preload_engines
70 static void bus_ibus_impl_set_use_sys_layout
73 static void bus_ibus_impl_set_embed_preedit_text
76 static void bus_ibus_impl_set_enable_by_default
80 static void bus_ibus_impl_set_use_global_engine
83 static void bus_ibus_impl_set_global_engine (BusIBusImpl *ibus,
84 BusEngineProxy *engine);
86 static void bus_ibus_impl_registry_changed (BusIBusImpl *ibus);
87 static void bus_ibus_impl_global_engine_changed
90 static void _factory_destroy_cb (BusFactoryProxy *factory,
93 static void bus_ibus_impl_set_context_engine(BusIBusImpl *ibus,
94 BusInputContext *context,
95 BusEngineProxy *engine);
97 static gchar *bus_ibus_impl_load_global_engine_name_from_config
99 static void bus_ibus_impl_save_global_engine_name_to_config
102 static gchar *bus_ibus_impl_load_global_previous_engine_name_from_config
104 static void bus_ibus_impl_save_global_previous_engine_name_to_config
107 G_DEFINE_TYPE(BusIBusImpl, bus_ibus_impl, IBUS_TYPE_SERVICE)
110 bus_ibus_impl_get_default (void)
112 static BusIBusImpl *ibus = NULL;
115 ibus = (BusIBusImpl *) g_object_new (BUS_TYPE_IBUS_IMPL,
116 "path", IBUS_PATH_IBUS,
118 bus_dbus_impl_register_object (BUS_DEFAULT_DBUS,
119 (IBusService *)ibus);
125 bus_ibus_impl_class_init (BusIBusImplClass *klass)
127 IBusObjectClass *ibus_object_class = IBUS_OBJECT_CLASS (klass);
129 ibus_object_class->destroy = (IBusObjectDestroyFunc) bus_ibus_impl_destroy;
131 IBUS_SERVICE_CLASS (klass)->ibus_message = (ServiceIBusMessageFunc) bus_ibus_impl_ibus_message;
136 _panel_destroy_cb (BusPanelProxy *panel,
139 g_assert (BUS_IS_PANEL_PROXY (panel));
140 g_assert (BUS_IS_IBUS_IMPL (ibus));
142 g_return_if_fail (ibus->panel == panel);
145 g_object_unref (panel);
149 bus_ibus_impl_set_hotkey (BusIBusImpl *ibus,
153 g_assert (BUS_IS_IBUS_IMPL (ibus));
158 ibus_hotkey_profile_remove_hotkey_by_event (ibus->hotkey_profile, hotkey);
164 g_return_if_fail (G_VALUE_TYPE (value) == G_TYPE_VALUE_ARRAY);
165 array = g_value_get_boxed (value);
167 for (i = 0; i < array->n_values; i++) {
170 str = g_value_array_get_nth (array, i);
171 g_return_if_fail (G_VALUE_TYPE (str) == G_TYPE_STRING);
173 ibus_hotkey_profile_add_hotkey_from_string (ibus->hotkey_profile,
174 g_value_get_string (str),
181 bus_ibus_impl_set_trigger (BusIBusImpl *ibus,
184 GQuark hotkey = g_quark_from_static_string ("trigger");
185 bus_ibus_impl_set_hotkey (ibus, hotkey, value);
187 ibus_hotkey_profile_add_hotkey (ibus->hotkey_profile,
195 bus_ibus_impl_set_next_engine_in_menu (BusIBusImpl *ibus,
198 GQuark hotkey = g_quark_from_static_string ("next-engine-in-menu");
199 bus_ibus_impl_set_hotkey (ibus, hotkey, value);
203 bus_ibus_impl_set_previous_engine (BusIBusImpl *ibus,
206 GQuark hotkey = g_quark_from_static_string ("previous-engine");
207 bus_ibus_impl_set_hotkey (ibus, hotkey, value);
211 bus_ibus_impl_set_preload_engines (BusIBusImpl *ibus,
214 GList *engine_list = NULL;
216 g_list_foreach (ibus->engine_list, (GFunc) g_object_unref, NULL);
217 g_list_free (ibus->engine_list);
219 if (value != NULL && G_VALUE_TYPE (value) == G_TYPE_VALUE_ARRAY) {
223 array = (GValueArray *) g_value_get_boxed (value);
224 for (i = 0; array && i < array->n_values; i++) {
225 const gchar *engine_name;
226 IBusEngineDesc *engine;
228 if (G_VALUE_TYPE (&array->values[i]) != G_TYPE_STRING)
231 engine_name = g_value_get_string (&array->values[i]);
233 engine = bus_registry_find_engine_by_name (ibus->registry, engine_name);
235 if (engine == NULL || g_list_find (engine_list, engine) != NULL)
238 engine_list = g_list_append (engine_list, engine);
242 g_list_foreach (engine_list, (GFunc) g_object_ref, NULL);
243 ibus->engine_list = engine_list;
245 if (ibus->engine_list) {
246 IBusComponent *component;
248 component = ibus_component_get_from_engine ((IBusEngineDesc *) ibus->engine_list->data);
249 if (component && !ibus_component_is_running (component)) {
250 ibus_component_start (component, g_verbose);
256 bus_ibus_impl_set_use_sys_layout (BusIBusImpl *ibus,
259 if (value != NULL && G_VALUE_TYPE (value) == G_TYPE_BOOLEAN) {
260 ibus->use_sys_layout = g_value_get_boolean (value);
265 bus_ibus_impl_set_embed_preedit_text (BusIBusImpl *ibus,
268 if (value != NULL && G_VALUE_TYPE (value) == G_TYPE_BOOLEAN) {
269 ibus->embed_preedit_text = g_value_get_boolean (value);
274 bus_ibus_impl_set_enable_by_default (BusIBusImpl *ibus,
277 if (value != NULL && G_VALUE_TYPE (value) == G_TYPE_BOOLEAN) {
278 ibus->enable_by_default = g_value_get_boolean (value);
283 bus_ibus_impl_set_use_global_engine (BusIBusImpl *ibus,
288 if (value == NULL || G_VALUE_TYPE (value) != G_TYPE_BOOLEAN) {
292 new_value = g_value_get_boolean (value);
293 if (ibus->use_global_engine == new_value) {
297 if (new_value == TRUE) {
298 BusEngineProxy *engine;
299 /* turn on use_global_engine option */
300 ibus->use_global_engine = TRUE;
301 engine = ibus->focused_context != NULL ?
302 bus_input_context_get_engine (ibus->focused_context) : NULL;
304 bus_ibus_impl_set_global_engine (ibus, engine);
308 /* turn off use_global_engine option */
309 bus_ibus_impl_set_global_engine (ibus, NULL);
310 ibus->use_global_engine = FALSE;
312 g_free (ibus->global_previous_engine_name);
317 _engine_desc_cmp (IBusEngineDesc *desc1,
318 IBusEngineDesc *desc2)
320 return - ((gint) desc1->rank) + ((gint) desc2->rank);
324 bus_ibus_impl_set_default_preload_engines (BusIBusImpl *ibus)
326 g_assert (BUS_IS_IBUS_IMPL (ibus));
328 static gboolean done = FALSE;
329 GValue value = { 0 };
330 GList *engines, *list;
334 if (done || ibus->config == NULL) {
338 if (ibus_config_get_value (ibus->config, "general", "preload_engines", &value)) {
340 g_value_unset (&value);
345 lang = g_strdup (setlocale (LC_ALL, NULL));
346 p = index (lang, '.');
351 engines = bus_registry_get_engines_by_language (ibus->registry, lang);
352 if (engines == NULL) {
353 p = index (lang, '_');
356 engines = bus_registry_get_engines_by_language (ibus->registry, lang);
361 /* sort engines by rank */
362 engines = g_list_sort (engines, (GCompareFunc) _engine_desc_cmp);
364 g_value_init (&value, G_TYPE_VALUE_ARRAY);
365 array = g_value_array_new (5);
366 for (list = engines; list != NULL; list = list->next) {
367 IBusEngineDesc *desc;
369 desc = (IBusEngineDesc *)list->data;
371 /* ignore engines with rank <== 0 */
374 g_value_init (&name, G_TYPE_STRING);
375 g_value_set_string (&name, desc->name);
376 g_value_array_append (array, &name);
378 g_value_take_boxed (&value, array);
379 ibus_config_set_value (ibus->config, "general", "preload_engines", &value);
380 g_value_unset (&value);
381 g_list_free (engines);
385 bus_ibus_impl_reload_config (BusIBusImpl *ibus)
387 g_assert (BUS_IS_IBUS_IMPL (ibus));
390 GValue value = { 0 };
392 const static struct {
395 void ( *func) (BusIBusImpl *, GValue *);
397 { "general/hotkey", "trigger", bus_ibus_impl_set_trigger },
398 /* Only for backward compatibility, shall be removed later. */
399 { "general/hotkey", "next_engine", bus_ibus_impl_set_next_engine_in_menu },
400 { "general/hotkey", "next_engine_in_menu", bus_ibus_impl_set_next_engine_in_menu },
401 /* Only for backward compatibility, shall be removed later. */
402 { "general/hotkey", "prev_engine", bus_ibus_impl_set_previous_engine },
403 { "general/hotkey", "previous_engine", bus_ibus_impl_set_previous_engine },
404 { "general", "preload_engines", bus_ibus_impl_set_preload_engines },
405 { "general", "use_system_keyboard_layout", bus_ibus_impl_set_use_sys_layout },
406 { "general", "use_global_engine", bus_ibus_impl_set_use_global_engine },
407 { "general", "embed_preedit_text", bus_ibus_impl_set_embed_preedit_text },
408 { "general", "enable_by_default", bus_ibus_impl_set_enable_by_default },
411 for (i = 0; i < G_N_ELEMENTS (entries); i++) {
412 if (ibus->config != NULL &&
413 ibus_config_get_value (ibus->config,
417 entries[i].func (ibus, &value);
418 g_value_unset (&value);
421 entries[i].func (ibus, NULL);
427 _config_value_changed_cb (IBusConfig *config,
433 g_assert (IBUS_IS_CONFIG (config));
437 g_assert (BUS_IS_IBUS_IMPL (ibus));
441 const static struct {
444 void ( *func) (BusIBusImpl *, GValue *);
446 { "general/hotkey", "trigger", bus_ibus_impl_set_trigger },
447 /* Only for backward compatibility, shall be removed later. */
448 { "general/hotkey", "next_engine", bus_ibus_impl_set_next_engine_in_menu },
449 { "general/hotkey", "next_engine_in_menu", bus_ibus_impl_set_next_engine_in_menu },
450 /* Only for backward compatibility, shall be removed later. */
451 { "general/hotkey", "prev_engine", bus_ibus_impl_set_previous_engine },
452 { "general/hotkey", "previous_engine", bus_ibus_impl_set_previous_engine },
453 { "general", "preload_engines", bus_ibus_impl_set_preload_engines },
454 { "general", "use_system_keyboard_layout", bus_ibus_impl_set_use_sys_layout },
455 { "general", "use_global_engine", bus_ibus_impl_set_use_global_engine },
456 { "general", "embed_preedit_text", bus_ibus_impl_set_embed_preedit_text },
457 { "general", "enable_by_default", bus_ibus_impl_set_enable_by_default },
460 for (i = 0; i < G_N_ELEMENTS (entries); i++) {
461 if (g_strcmp0 (entries[i].section, section) == 0 &&
462 g_strcmp0 (entries[i].key, key) == 0) {
463 entries[i].func (ibus, value);
470 _config_destroy_cb (IBusConfig *config,
473 g_assert (IBUS_IS_CONFIG (config));
474 g_assert (BUS_IS_IBUS_IMPL (ibus));
476 g_assert (ibus->config == config);
478 g_object_unref (ibus->config);
483 _registry_changed_cb (BusRegistry *registry,
486 bus_ibus_impl_registry_changed (ibus);
490 _dbus_name_owner_changed_cb (BusDBusImpl *dbus,
492 const gchar *old_name,
493 const gchar *new_name,
496 g_assert (BUS_IS_DBUS_IMPL (dbus));
497 g_assert (name != NULL);
498 g_assert (old_name != NULL);
499 g_assert (new_name != NULL);
500 g_assert (BUS_IS_IBUS_IMPL (ibus));
502 BusFactoryProxy *factory;
504 if (g_strcmp0 (name, IBUS_SERVICE_PANEL) == 0) {
505 if (g_strcmp0 (new_name, "") != 0) {
506 BusConnection *connection;
508 if (ibus->panel != NULL) {
509 ibus_object_destroy (IBUS_OBJECT (ibus->panel));
510 /* panel should be NULL after destroy */
511 g_assert (ibus->panel == NULL);
514 connection = bus_dbus_impl_get_connection_by_name (BUS_DEFAULT_DBUS, new_name);
515 g_return_if_fail (connection != NULL);
517 ibus->panel = bus_panel_proxy_new (connection);
518 g_object_ref_sink (ibus->panel);
520 g_signal_connect (ibus->panel,
522 G_CALLBACK (_panel_destroy_cb),
525 if (ibus->focused_context != NULL) {
526 bus_panel_proxy_focus_in (ibus->panel, ibus->focused_context);
530 else if (g_strcmp0 (name, IBUS_SERVICE_CONFIG) == 0) {
531 if (g_strcmp0 (new_name, "") != 0) {
532 BusConnection *connection;
534 if (ibus->config != NULL) {
535 ibus_object_destroy (IBUS_OBJECT (ibus->config));
536 /* config should be NULL */
537 g_assert (ibus->config == NULL);
540 connection = bus_dbus_impl_get_connection_by_name (BUS_DEFAULT_DBUS, new_name);
541 g_return_if_fail (connection != NULL);
543 ibus->config = g_object_new (IBUS_TYPE_CONFIG,
545 "path", IBUS_PATH_CONFIG,
546 "connection", connection,
548 g_object_ref_sink (ibus->config);
550 g_signal_connect (ibus->config,
552 G_CALLBACK (_config_value_changed_cb),
555 g_signal_connect (ibus->config,
557 G_CALLBACK (_config_destroy_cb),
560 bus_ibus_impl_set_default_preload_engines (ibus);
561 bus_ibus_impl_reload_config (ibus);
565 factory = bus_registry_name_owner_changed (ibus->registry, name, old_name, new_name);
568 bus_ibus_impl_add_factory (ibus, factory);
573 bus_ibus_impl_init (BusIBusImpl *ibus)
575 ibus->factory_dict = g_hash_table_new_full (
579 (GDestroyNotify) g_object_unref);
581 ibus->engine_list = NULL;
582 ibus->register_engine_list = NULL;
583 ibus->contexts = NULL;
584 ibus->focused_context = NULL;
588 ibus->registry = bus_registry_new ();
590 g_signal_connect (ibus->registry,
592 G_CALLBACK (_registry_changed_cb),
594 #ifdef G_THREADS_ENABLED
595 extern gint g_monitor_timeout;
596 if (g_monitor_timeout != 0) {
597 bus_registry_start_monitor_changes (ibus->registry);
601 ibus->hotkey_profile = ibus_hotkey_profile_new ();
602 ibus->keymap = ibus_keymap_get ("us");
604 ibus->use_sys_layout = FALSE;
605 ibus->embed_preedit_text = TRUE;
606 ibus->enable_by_default = FALSE;
607 ibus->use_global_engine = FALSE;
608 ibus->global_engine = NULL;
609 ibus->global_previous_engine_name = NULL;
611 bus_ibus_impl_reload_config (ibus);
613 g_signal_connect (BUS_DEFAULT_DBUS,
614 "name-owner-changed",
615 G_CALLBACK (_dbus_name_owner_changed_cb),
620 bus_ibus_impl_destroy (BusIBusImpl *ibus)
627 bus_registry_stop_all_components (ibus->registry);
633 while ((pid = waitpid (0, &status, WNOHANG)) > 0);
635 if (pid == -1) { /* all children finished */
638 if (pid == 0) { /* no child status changed */
641 if (timeout >= G_USEC_PER_SEC) {
644 old = signal (SIGTERM, SIG_IGN);
645 kill (-getpid (), SIGTERM);
646 signal (SIGTERM, old);
650 g_warning ("Not every child processes exited!");
657 g_list_foreach (ibus->engine_list, (GFunc) g_object_unref, NULL);
658 g_list_free (ibus->engine_list);
659 ibus->engine_list = NULL;
661 g_list_foreach (ibus->register_engine_list, (GFunc) g_object_unref, NULL);
662 g_list_free (ibus->register_engine_list);
663 ibus->register_engine_list = NULL;
665 if (ibus->factory_dict != NULL) {
666 g_hash_table_destroy (ibus->factory_dict);
667 ibus->factory_dict = NULL;
670 if (ibus->hotkey_profile != NULL) {
671 g_object_unref (ibus->hotkey_profile);
672 ibus->hotkey_profile = NULL;
675 if (ibus->keymap != NULL) {
676 g_object_unref (ibus->keymap);
680 if (ibus->global_engine) {
681 g_object_unref (ibus->global_engine);
682 ibus->global_engine = NULL;
685 g_free (ibus->global_previous_engine_name);
687 bus_server_quit (BUS_DEFAULT_SERVER);
688 ibus_object_destroy ((IBusObject *) BUS_DEFAULT_SERVER);
689 IBUS_OBJECT_CLASS(bus_ibus_impl_parent_class)->destroy (IBUS_OBJECT (ibus));
692 /* introspectable interface */
694 _ibus_introspect (BusIBusImpl *ibus,
695 IBusMessage *message,
696 BusConnection *connection)
698 static const gchar *introspect =
699 DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE
701 " <interface name=\"org.freedesktop.DBus.Introspectable\">\n"
702 " <method name=\"Introspect\">\n"
703 " <arg name=\"data\" direction=\"out\" type=\"s\"/>\n"
706 " <interface name=\"org.freedesktop.IBus\">\n"
707 " <method name=\"GetAddress\">\n"
708 " <arg name=\"address\" direction=\"out\" type=\"s\"/>\n"
710 " <method name=\"CreateInputContext\">\n"
711 " <arg name=\"name\" direction=\"in\" type=\"s\"/>\n"
712 " <arg name=\"context\" direction=\"out\" type=\"o\"/>\n"
714 " <method name=\"CurrentInputContext\">\n"
715 " <arg name=\"name\" direction=\"out\" type=\"s\"/>\n"
717 " <method name=\"RegisterComponent\">\n"
718 " <arg name=\"components\" direction=\"in\" type=\"v\"/>\n"
720 " <method name=\"ListEngines\">\n"
721 " <arg name=\"engines\" direction=\"out\" type=\"av\"/>\n"
723 " <method name=\"ListActiveEngines\">\n"
724 " <arg name=\"engines\" direction=\"out\" type=\"av\"/>\n"
726 " <method name=\"Exit\">\n"
727 " <arg name=\"restart\" direction=\"in\" type=\"b\"/>\n"
729 " <method name=\"Ping\">\n"
730 " <arg name=\"data\" direction=\"in\" type=\"v\"/>\n"
731 " <arg name=\"data\" direction=\"out\" type=\"v\"/>\n"
733 " <method name=\"GetUseSysLayout\">\n"
734 " <arg name=\"enable\" direction=\"out\" type=\"b\"/>\n"
736 " <method name=\"GetUseGlobalEngine\">\n"
737 " <arg name=\"enable\" direction=\"out\" type=\"b\"/>\n"
739 " <method name=\"GetGlobalEngine\">\n"
740 " <arg name=\"desc\" direction=\"out\" type=\"v\"/>\n"
742 " <method name=\"SetGlobalEngine\">\n"
743 " <arg name=\"name\" direction=\"in\" type=\"s\"/>\n"
745 " <method name=\"IsGlobalEngineEnabled\">\n"
746 " <arg name=\"enable\" direction=\"out\" type=\"b\"/>\n"
748 " <signal name=\"RegistryChanged\">\n"
750 " <signal name=\"GlobalEngineChanged\">\n"
755 IBusMessage *reply_message;
756 reply_message = ibus_message_new_method_return (message);
757 ibus_message_append_args (reply_message,
758 G_TYPE_STRING, &introspect,
761 return reply_message;
767 _ibus_get_address (BusIBusImpl *ibus,
768 IBusMessage *message,
769 BusConnection *connection)
771 const gchar *address;
774 address = ibus_server_get_address (IBUS_SERVER (BUS_DEFAULT_SERVER));
776 reply = ibus_message_new_method_return (message);
777 ibus_message_append_args (reply,
778 G_TYPE_STRING, &address,
784 static BusEngineProxy *
785 bus_ibus_impl_create_engine (IBusEngineDesc *engine_desc)
788 BusFactoryProxy *factory;
789 BusEngineProxy *engine;
792 factory = bus_factory_proxy_get_from_engine (engine_desc);
794 if (factory == NULL) {
795 /* try to execute the engine */
796 comp = ibus_component_get_from_engine (engine_desc);
799 if (!ibus_component_is_running (comp)) {
800 ibus_component_start (comp, g_verbose);
801 g_get_current_time (&t1);
803 if (g_main_context_pending (NULL)) {
804 g_main_context_iteration (NULL, FALSE);
805 factory = bus_factory_proxy_get_from_engine (engine_desc);
806 if (factory != NULL) {
810 g_get_current_time (&t2);
811 if (t2.tv_sec - t1.tv_sec >= 5)
816 factory = bus_factory_proxy_get_from_engine (engine_desc);
820 if (factory == NULL) {
824 g_object_ref (factory);
825 engine = bus_factory_proxy_create_engine (factory, engine_desc);
826 g_object_unref (factory);
831 static IBusEngineDesc *
832 _find_engine_desc_by_name(BusIBusImpl *ibus,
835 IBusEngineDesc *engine_desc = NULL;
838 /* find engine in registered engine list */
839 for (p = ibus->register_engine_list; p != NULL; p = p->next) {
840 engine_desc = (IBusEngineDesc *)p->data;
841 if (g_strcmp0 (engine_desc->name, engine_name) == 0)
845 /* find engine in preload engine list */
846 for (p = ibus->engine_list; p != NULL; p = p->next) {
847 engine_desc = (IBusEngineDesc *)p->data;
848 if (g_strcmp0 (engine_desc->name, engine_name) == 0)
856 _context_request_engine_cb (BusInputContext *context,
860 IBusEngineDesc *engine_desc = NULL;
861 BusEngineProxy *engine;
863 /* context should has focus before request an engine */
864 g_return_if_fail (bus_input_context_has_focus (context));
866 if (engine_name == NULL || engine_name[0] == '\0') {
867 /* Use global engine if possible. */
868 if (ibus->use_global_engine) {
869 if (ibus->global_engine) {
870 bus_ibus_impl_set_context_engine (ibus, context, ibus->global_engine);
874 engine_name = bus_ibus_impl_load_global_engine_name_from_config (ibus);
876 engine_desc = _find_engine_desc_by_name (ibus, engine_name);
877 g_free (engine_name);
881 /* request default engine */
883 if (ibus->register_engine_list) {
884 engine_desc = (IBusEngineDesc *)ibus->register_engine_list->data;
886 else if (ibus->engine_list) {
887 engine_desc = (IBusEngineDesc *)ibus->engine_list->data;
892 /* request engine by name */
893 engine_desc = _find_engine_desc_by_name (ibus, engine_name);
896 if (engine_desc != NULL) {
897 engine = bus_ibus_impl_create_engine (engine_desc);
898 if (engine != NULL) {
899 bus_ibus_impl_set_context_engine (ibus, context, engine);
905 bus_ibus_impl_context_request_next_engine_in_menu (BusIBusImpl *ibus,
906 BusInputContext *context)
908 BusEngineProxy *engine;
909 IBusEngineDesc *desc;
910 IBusEngineDesc *next_desc = NULL;
913 engine = bus_input_context_get_engine (context);
914 if (engine == NULL) {
915 _context_request_engine_cb (context, NULL, ibus);
919 desc = bus_engine_proxy_get_desc (engine);
921 p = g_list_find (ibus->register_engine_list, desc);
926 p = g_list_find (ibus->engine_list, desc);
933 next_desc = (IBusEngineDesc*) p->data;
936 if (ibus->register_engine_list) {
937 next_desc = (IBusEngineDesc *)ibus->register_engine_list->data;
939 else if (ibus->engine_list) {
940 next_desc = (IBusEngineDesc *)ibus->engine_list->data;
944 if (next_desc != NULL) {
945 engine = bus_ibus_impl_create_engine (next_desc);
946 if (engine != NULL) {
947 bus_ibus_impl_set_context_engine (ibus, context, engine);
953 bus_ibus_impl_context_request_previous_engine (BusIBusImpl *ibus,
954 BusInputContext *context)
956 gchar *engine_name = NULL;
957 if (!ibus->use_global_engine) {
958 engine_name = (gchar *) g_object_get_data (G_OBJECT (context), "previous-engine-name");
961 if (!ibus->global_previous_engine_name) {
962 ibus->global_previous_engine_name = bus_ibus_impl_load_global_previous_engine_name_from_config (ibus);
964 engine_name = ibus->global_previous_engine_name;
967 _context_request_engine_cb (context, engine_name, ibus);
971 _global_engine_destroy_cb (BusEngineProxy *engine,
974 if (ibus->global_engine != engine) {
978 g_signal_handlers_disconnect_by_func (ibus->global_engine,
979 G_CALLBACK (_global_engine_destroy_cb), ibus);
980 g_object_unref (ibus->global_engine);
981 ibus->global_engine = NULL;
985 bus_ibus_impl_set_global_engine (BusIBusImpl *ibus,
986 BusEngineProxy *engine)
988 g_assert (ibus->use_global_engine == TRUE);
990 if (ibus->global_engine == engine) {
994 g_free (ibus->global_previous_engine_name);
995 ibus->global_previous_engine_name = NULL;
996 if (ibus->global_engine) {
997 /* Save the current global engine's name as previous engine. */
998 ibus->global_previous_engine_name = g_strdup (bus_engine_proxy_get_desc (ibus->global_engine)->name);
1000 ibus_object_destroy ((IBusObject *)ibus->global_engine);
1001 /* global_engine should be NULL */
1002 g_assert (ibus->global_engine == NULL);
1005 if (engine != NULL && !IBUS_OBJECT_DESTROYED (engine)) {
1006 g_object_ref (engine);
1007 ibus->global_engine = engine;
1008 g_signal_connect (ibus->global_engine, "destroy",
1009 G_CALLBACK (_global_engine_destroy_cb), ibus);
1012 bus_ibus_impl_save_global_engine_name_to_config (ibus);
1013 bus_ibus_impl_save_global_previous_engine_name_to_config (ibus);
1014 bus_ibus_impl_global_engine_changed (ibus);
1018 bus_ibus_impl_set_context_engine (BusIBusImpl *ibus,
1019 BusInputContext *context,
1020 BusEngineProxy *engine) {
1021 g_object_set_data (G_OBJECT (context), "previous-engine-name", NULL);
1023 /* If use_global_engine is disabled, then we need to save the previous engine
1024 * of each input context. */
1025 if (!ibus->use_global_engine) {
1026 BusEngineProxy *previous_engine = bus_input_context_get_engine (context);
1027 if (previous_engine) {
1028 g_object_set_data_full (G_OBJECT (context), "previous-engine-name",
1029 g_strdup (bus_engine_proxy_get_desc (previous_engine)->name),
1034 bus_input_context_set_engine (context, engine);
1038 _context_engine_changed_cb (BusInputContext *context,
1041 BusEngineProxy *engine;
1043 if (context != ibus->focused_context || !ibus->use_global_engine) {
1047 engine = bus_input_context_get_engine (context);
1048 if (engine != NULL) {
1049 /* only set global engine if engine is not NULL */
1050 bus_ibus_impl_set_global_engine (ibus, engine);
1055 _context_focus_out_cb (BusInputContext *context,
1058 g_assert (BUS_IS_IBUS_IMPL (ibus));
1059 g_assert (BUS_IS_INPUT_CONTEXT (context));
1061 /* Do noting if context does not support focus.
1062 * Actually, the context should emit focus signals, if it does not support focus */
1063 if ((bus_input_context_get_capabilities (context) & IBUS_CAP_FOCUS) == 0) {
1067 /* Do noting if it is not focused context. */
1068 if (ibus->focused_context != context) {
1072 ibus->focused_context = NULL;
1074 if (ibus->panel != NULL) {
1075 bus_panel_proxy_focus_out (ibus->panel, context);
1078 /* If the use_global_engine option is enabled,
1079 * the global engine shoule be detached from the focused context. */
1080 if (ibus->use_global_engine) {
1081 bus_ibus_impl_set_context_engine (ibus, context, NULL);
1084 g_object_unref (context);
1088 _context_focus_in_cb (BusInputContext *context,
1091 g_assert (BUS_IS_IBUS_IMPL (ibus));
1092 g_assert (BUS_IS_INPUT_CONTEXT (context));
1094 /* Do nothing if context does not support focus.
1095 * The global engine shoule be detached from the focused context. */
1096 if ((bus_input_context_get_capabilities (context) & IBUS_CAP_FOCUS) == 0) {
1100 /* Do nothing if it is focused context already. */
1101 if (ibus->focused_context == context) {
1105 if (ibus->focused_context) {
1106 /* focus out context */
1107 bus_input_context_focus_out (ibus->focused_context);
1108 g_assert (ibus->focused_context == NULL);
1111 /* If the use_global_engine option is enabled, then we need:
1112 * - Switch the context to use the global engine or save the context's
1113 * existing engine as global engine.
1114 * - Set the context's enabled state according to the saved state.
1115 * Note: we get this signal only if the context supports IBUS_CAP_FOCUS. */
1116 if (ibus->use_global_engine) {
1117 if (!ibus->global_engine) {
1118 bus_ibus_impl_set_global_engine (ibus, bus_input_context_get_engine (context));
1121 bus_ibus_impl_set_context_engine (ibus, context, ibus->global_engine);
1122 if (ibus->global_engine && bus_engine_proxy_is_enabled (ibus->global_engine)) {
1123 bus_input_context_enable (context);
1128 if (ibus->panel != NULL) {
1129 bus_panel_proxy_focus_in (ibus->panel, context);
1132 g_object_ref (context);
1133 ibus->focused_context = context;
1137 _context_destroy_cb (BusInputContext *context,
1140 g_assert (BUS_IS_IBUS_IMPL (ibus));
1141 g_assert (BUS_IS_INPUT_CONTEXT (context));
1143 if (context == ibus->focused_context) {
1144 /* focus out context */
1145 bus_input_context_focus_out (ibus->focused_context);
1146 g_assert (ibus->focused_context == NULL);
1149 ibus->contexts = g_list_remove (ibus->contexts, context);
1150 g_object_unref (context);
1155 _context_enabled_cb (BusInputContext *context,
1161 _context_disabled_cb (BusInputContext *context,
1167 static IBusMessage *
1168 _ibus_create_input_context (BusIBusImpl *ibus,
1169 IBusMessage *message,
1170 BusConnection *connection)
1172 g_assert (BUS_IS_IBUS_IMPL (ibus));
1173 g_assert (message != NULL);
1174 g_assert (BUS_IS_CONNECTION (connection));
1180 BusInputContext *context;
1183 if (!ibus_message_get_args (message,
1185 G_TYPE_STRING, &client,
1187 reply = ibus_message_new_error (message,
1188 DBUS_ERROR_INVALID_ARGS,
1189 "Argument 1 of CreateInputContext should be an string");
1190 ibus_error_free (error);
1194 context = bus_input_context_new (connection, client);
1195 g_object_ref_sink (context);
1196 ibus->contexts = g_list_append (ibus->contexts, context);
1198 static const struct {
1202 { "request-engine", G_CALLBACK (_context_request_engine_cb) },
1203 { "engine-changed", G_CALLBACK (_context_engine_changed_cb) },
1204 { "focus-in", G_CALLBACK (_context_focus_in_cb) },
1205 { "focus-out", G_CALLBACK (_context_focus_out_cb) },
1206 { "destroy", G_CALLBACK (_context_destroy_cb) },
1208 { "enabled", G_CALLBACK (_context_enabled_cb) },
1209 { "disabled", G_CALLBACK (_context_disabled_cb) },
1213 for (i = 0; i < G_N_ELEMENTS (signals); i++) {
1214 g_signal_connect (context,
1216 signals[i].callback,
1220 if (ibus->enable_by_default) {
1221 bus_input_context_enable (context);
1224 path = ibus_service_get_path ((IBusService *) context);
1225 reply = ibus_message_new_method_return (message);
1226 ibus_message_append_args (reply,
1227 IBUS_TYPE_OBJECT_PATH, &path,
1230 bus_dbus_impl_register_object (BUS_DEFAULT_DBUS,
1231 (IBusService *)context);
1235 static IBusMessage *
1236 _ibus_current_input_context (BusIBusImpl *ibus,
1237 IBusMessage *message,
1238 BusConnection *connection)
1240 g_assert (BUS_IS_IBUS_IMPL (ibus));
1241 g_assert (message != NULL);
1242 g_assert (BUS_IS_CONNECTION (connection));
1247 if (!ibus->focused_context)
1249 reply = ibus_message_new_error (message,
1251 "No input context focused");
1255 reply = ibus_message_new_method_return (message);
1256 path = ibus_service_get_path((IBusService *)ibus->focused_context);
1257 ibus_message_append_args (reply,
1258 G_TYPE_STRING, &path,
1265 _factory_destroy_cb (BusFactoryProxy *factory,
1268 g_assert (BUS_IS_IBUS_IMPL (ibus));
1269 g_assert (BUS_IS_FACTORY_PROXY (factory));
1271 IBusComponent *component;
1274 ibus->factory_list = g_list_remove (ibus->factory_list, factory);
1276 component = bus_factory_proxy_get_component (factory);
1278 if (component != NULL) {
1279 p = engines = ibus_component_get_engines (component);
1280 for (; p != NULL; p = p->next) {
1281 if (g_list_find (ibus->register_engine_list, p->data)) {
1282 ibus->register_engine_list = g_list_remove (ibus->register_engine_list, p->data);
1283 g_object_unref (p->data);
1286 g_list_free (engines);
1289 g_object_unref (factory);
1293 bus_ibus_impl_add_factory (BusIBusImpl *ibus,
1294 BusFactoryProxy *factory)
1296 g_assert (BUS_IS_IBUS_IMPL (ibus));
1297 g_assert (BUS_IS_FACTORY_PROXY (factory));
1299 g_object_ref_sink (factory);
1300 ibus->factory_list = g_list_append (ibus->factory_list, factory);
1302 g_signal_connect (factory, "destroy", G_CALLBACK (_factory_destroy_cb), ibus);
1306 static IBusMessage *
1307 _ibus_register_component (BusIBusImpl *ibus,
1308 IBusMessage *message,
1309 BusConnection *connection)
1315 IBusComponent *component;
1316 BusFactoryProxy *factory;
1318 retval = ibus_message_get_args (message, &error,
1319 IBUS_TYPE_COMPONENT, &component,
1323 reply = ibus_message_new_error_printf (message,
1324 DBUS_ERROR_INVALID_ARGS,
1325 "1st Argument must be IBusComponent: %s",
1327 ibus_error_free (error);
1331 g_object_ref_sink (component);
1332 factory = bus_factory_proxy_new (component, connection);
1334 if (factory == NULL) {
1335 reply = ibus_message_new_error (message,
1337 "Can not create factory");
1341 bus_ibus_impl_add_factory (ibus, factory);
1343 engines = ibus_component_get_engines (component);
1345 g_list_foreach (engines, (GFunc) g_object_ref, NULL);
1346 ibus->register_engine_list = g_list_concat (ibus->register_engine_list, engines);
1347 g_object_unref (component);
1349 reply = ibus_message_new_method_return (message);
1353 static IBusMessage *
1354 _ibus_list_engines (BusIBusImpl *ibus,
1355 IBusMessage *message,
1356 BusConnection *connection)
1359 IBusMessageIter iter, sub_iter;
1362 reply = ibus_message_new_method_return (message);
1364 ibus_message_iter_init_append (reply, &iter);
1365 ibus_message_iter_open_container (&iter, IBUS_TYPE_ARRAY, "v", &sub_iter);
1367 engines = bus_registry_get_engines (ibus->registry);
1368 for (p = engines; p != NULL; p = p->next) {
1369 ibus_message_iter_append (&sub_iter, IBUS_TYPE_ENGINE_DESC, &(p->data));
1371 g_list_free (engines);
1372 ibus_message_iter_close_container (&iter, &sub_iter);
1377 static IBusMessage *
1378 _ibus_list_active_engines (BusIBusImpl *ibus,
1379 IBusMessage *message,
1380 BusConnection *connection)
1383 IBusMessageIter iter, sub_iter;
1386 reply = ibus_message_new_method_return (message);
1388 ibus_message_iter_init_append (reply, &iter);
1389 ibus_message_iter_open_container (&iter, IBUS_TYPE_ARRAY, "v", &sub_iter);
1391 for (p = ibus->engine_list; p != NULL; p = p->next) {
1392 ibus_message_iter_append (&sub_iter, IBUS_TYPE_ENGINE_DESC, &(p->data));
1395 for (p = ibus->register_engine_list; p != NULL; p = p->next) {
1396 ibus_message_iter_append (&sub_iter, IBUS_TYPE_ENGINE_DESC, &(p->data));
1398 ibus_message_iter_close_container (&iter, &sub_iter);
1404 static IBusMessage *
1405 _ibus_exit (BusIBusImpl *ibus,
1406 IBusMessage *message,
1407 BusConnection *connection)
1413 if (!ibus_message_get_args (message,
1415 G_TYPE_BOOLEAN, &restart,
1417 reply = ibus_message_new_error (message,
1418 DBUS_ERROR_INVALID_ARGS,
1419 "Argument 1 of Exit should be an boolean");
1420 ibus_error_free (error);
1424 reply = ibus_message_new_method_return (message);
1425 ibus_connection_send ((IBusConnection *) connection, reply);
1426 ibus_connection_flush ((IBusConnection *) connection);
1427 ibus_message_unref (reply);
1429 ibus_object_destroy ((IBusObject *) BUS_DEFAULT_SERVER);
1435 extern gchar **g_argv;
1439 exe = g_strdup_printf ("/proc/%d/exe", getpid ());
1440 exe = g_file_read_link (exe, NULL);
1443 exe = BINDIR"/ibus-daemon";
1445 /* close all fds except stdin, stdout, stderr */
1446 for (fd = 3; fd <= sysconf (_SC_OPEN_MAX); fd ++) {
1450 execv (exe, g_argv);
1452 /* If the server binary is replaced while the server is running,
1453 * "readlink /proc/[pid]/exe" might return a path with " (deleted)"
1455 const gchar suffix[] = " (deleted)";
1456 if (g_str_has_suffix (exe, suffix)) {
1457 exe [strlen (exe) - sizeof (suffix) + 1] = '\0';
1458 execv (exe, g_argv);
1460 g_warning ("execv %s failed!", g_argv[0]);
1464 /* should not reach here */
1465 g_assert_not_reached ();
1470 static IBusMessage *
1471 _ibus_ping (BusIBusImpl *ibus,
1472 IBusMessage *message,
1473 BusConnection *connection)
1476 IBusMessageIter src, dst;
1478 reply = ibus_message_new_method_return (message);
1480 ibus_message_iter_init (message, &src);
1481 ibus_message_iter_init_append (reply, &dst);
1483 ibus_message_iter_copy_data (&dst, &src);
1488 static IBusMessage *
1489 _ibus_get_use_sys_layout (BusIBusImpl *ibus,
1490 IBusMessage *message,
1491 BusConnection *connection)
1495 reply = ibus_message_new_method_return (message);
1496 ibus_message_append_args (reply,
1497 G_TYPE_BOOLEAN, &ibus->use_sys_layout,
1503 static IBusMessage *
1504 _ibus_get_use_global_engine (BusIBusImpl *ibus,
1505 IBusMessage *message,
1506 BusConnection *connection)
1510 reply = ibus_message_new_method_return (message);
1511 ibus_message_append_args (reply,
1512 G_TYPE_BOOLEAN, &ibus->use_global_engine,
1518 static IBusMessage *
1519 _ibus_get_global_engine (BusIBusImpl *ibus,
1520 IBusMessage *message,
1521 BusConnection *connection)
1525 if (ibus->use_global_engine && ibus->global_engine) {
1526 IBusEngineDesc *desc = bus_engine_proxy_get_desc (ibus->global_engine);
1528 reply = ibus_message_new_method_return (message);
1529 ibus_message_append_args (reply,
1530 IBUS_TYPE_ENGINE_DESC, &desc,
1536 reply = ibus_message_new_error (message, DBUS_ERROR_FAILED,
1537 "No global engine.");
1541 static IBusMessage *
1542 _ibus_set_global_engine (BusIBusImpl *ibus,
1543 IBusMessage *message,
1544 BusConnection *connection)
1549 gchar *new_engine_name;
1550 gchar *old_engine_name;
1552 if (!ibus->use_global_engine) {
1553 reply = ibus_message_new_error (message, DBUS_ERROR_FAILED,
1554 "Global engine feature is disable.");
1558 retval = ibus_message_get_args (message,
1560 G_TYPE_STRING, &new_engine_name,
1563 reply = ibus_message_new_error (message,
1566 ibus_error_free (error);
1570 reply = ibus_message_new_method_return (message);
1571 old_engine_name = NULL;
1573 if (ibus->global_engine) {
1574 old_engine_name = bus_engine_proxy_get_desc (ibus->global_engine)->name;
1577 if (g_strcmp0 (new_engine_name, old_engine_name) == 0) {
1578 /* If the user requested the same global engine, then we just enable the
1580 if (ibus->focused_context) {
1581 bus_input_context_enable (ibus->focused_context);
1583 else if (ibus->global_engine) {
1584 bus_engine_proxy_enable (ibus->global_engine);
1589 /* If there is a focused input context, then we just change the engine of
1590 * the focused context, which will then change the global engine
1591 * automatically. Otherwise, we need to change the global engine directly.
1593 if (ibus->focused_context) {
1594 _context_request_engine_cb (ibus->focused_context, new_engine_name, ibus);
1597 IBusEngineDesc *engine_desc = _find_engine_desc_by_name (ibus, new_engine_name);
1598 if (engine_desc != NULL) {
1599 BusEngineProxy *new_engine = bus_ibus_impl_create_engine (engine_desc);
1600 if (new_engine != NULL) {
1601 /* Enable the global engine by default, because the user
1602 * selected it explicitly. */
1603 bus_engine_proxy_enable (new_engine);
1605 /* Assume the ownership of the new global engine. Normally it's
1606 * done by the input context. But as we need to change the global
1607 * engine directly, so we need to do it here. */
1608 g_object_ref_sink (new_engine);
1609 bus_ibus_impl_set_global_engine (ibus, new_engine);
1611 /* The global engine should already be referenced. */
1612 g_object_unref (new_engine);
1620 static IBusMessage *
1621 _ibus_is_global_engine_enabled (BusIBusImpl *ibus,
1622 IBusMessage *message,
1623 BusConnection *connection)
1626 gboolean enabled = (ibus->use_global_engine && ibus->global_engine &&
1627 bus_engine_proxy_is_enabled (ibus->global_engine));
1629 reply = ibus_message_new_method_return (message);
1630 ibus_message_append_args (reply,
1631 G_TYPE_BOOLEAN, &enabled,
1638 bus_ibus_impl_ibus_message (BusIBusImpl *ibus,
1639 BusConnection *connection,
1640 IBusMessage *message)
1642 g_assert (BUS_IS_IBUS_IMPL (ibus));
1643 g_assert (BUS_IS_CONNECTION (connection));
1644 g_assert (message != NULL);
1647 IBusMessage *reply_message = NULL;
1649 static const struct {
1650 const gchar *interface;
1652 IBusMessage *(* handler) (BusIBusImpl *, IBusMessage *, BusConnection *);
1654 /* Introspectable interface */
1655 { DBUS_INTERFACE_INTROSPECTABLE,
1656 "Introspect", _ibus_introspect },
1657 /* IBus interface */
1658 { IBUS_INTERFACE_IBUS, "GetAddress", _ibus_get_address },
1659 { IBUS_INTERFACE_IBUS, "CreateInputContext", _ibus_create_input_context },
1660 { IBUS_INTERFACE_IBUS, "CurrentInputContext", _ibus_current_input_context },
1661 { IBUS_INTERFACE_IBUS, "RegisterComponent", _ibus_register_component },
1662 { IBUS_INTERFACE_IBUS, "ListEngines", _ibus_list_engines },
1663 { IBUS_INTERFACE_IBUS, "ListActiveEngines", _ibus_list_active_engines },
1664 { IBUS_INTERFACE_IBUS, "Exit", _ibus_exit },
1665 { IBUS_INTERFACE_IBUS, "Ping", _ibus_ping },
1666 { IBUS_INTERFACE_IBUS, "GetUseSysLayout", _ibus_get_use_sys_layout },
1667 { IBUS_INTERFACE_IBUS, "GetUseGlobalEngine", _ibus_get_use_global_engine },
1668 { IBUS_INTERFACE_IBUS, "GetGlobalEngine", _ibus_get_global_engine },
1669 { IBUS_INTERFACE_IBUS, "SetGlobalEngine", _ibus_set_global_engine },
1670 { IBUS_INTERFACE_IBUS, "IsGlobalEngineEnabled", _ibus_is_global_engine_enabled },
1673 ibus_message_set_sender (message, bus_connection_get_unique_name (connection));
1674 ibus_message_set_destination (message, DBUS_SERVICE_DBUS);
1676 if (ibus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_CALL) {
1677 for (i = 0; i < G_N_ELEMENTS (handlers); i++) {
1678 if (ibus_message_is_method_call (message,
1679 handlers[i].interface,
1680 handlers[i].name)) {
1682 reply_message = handlers[i].handler (ibus, message, connection);
1683 if (reply_message) {
1685 ibus_message_set_sender (reply_message, DBUS_SERVICE_DBUS);
1686 ibus_message_set_destination (reply_message, bus_connection_get_unique_name (connection));
1687 ibus_message_set_no_reply (reply_message, TRUE);
1689 ibus_connection_send ((IBusConnection *) connection, reply_message);
1690 ibus_message_unref (reply_message);
1693 g_signal_stop_emission_by_name (ibus, "ibus-message");
1699 return IBUS_SERVICE_CLASS(bus_ibus_impl_parent_class)->ibus_message (
1700 (IBusService *) ibus,
1701 (IBusConnection *) connection,
1706 bus_ibus_impl_lookup_factory (BusIBusImpl *ibus,
1709 g_assert (BUS_IS_IBUS_IMPL (ibus));
1711 BusFactoryProxy *factory;
1713 factory = (BusFactoryProxy *) g_hash_table_lookup (ibus->factory_dict, path);
1719 bus_ibus_impl_get_hotkey_profile (BusIBusImpl *ibus)
1721 g_assert (BUS_IS_IBUS_IMPL (ibus));
1723 return ibus->hotkey_profile;
1727 bus_ibus_impl_get_keymap (BusIBusImpl *ibus)
1730 g_assert (BUS_IS_IBUS_IMPL (ibus));
1732 return ibus->keymap;
1736 bus_ibus_impl_get_registry (BusIBusImpl *ibus)
1739 g_assert (BUS_IS_IBUS_IMPL (ibus));
1741 return ibus->registry;
1745 bus_ibus_impl_registry_changed (BusIBusImpl *ibus)
1747 g_assert (BUS_IS_IBUS_IMPL (ibus));
1749 IBusMessage *message;
1751 message = ibus_message_new_signal (IBUS_PATH_IBUS,
1752 IBUS_INTERFACE_IBUS,
1754 ibus_message_append_args (message,
1756 ibus_message_set_sender (message, IBUS_SERVICE_IBUS);
1758 bus_dbus_impl_dispatch_message_by_rule (BUS_DEFAULT_DBUS, message, NULL);
1760 ibus_message_unref (message);
1765 bus_ibus_impl_global_engine_changed (BusIBusImpl *ibus)
1767 g_assert (BUS_IS_IBUS_IMPL (ibus));
1769 IBusMessage *message;
1771 message = ibus_message_new_signal (IBUS_PATH_IBUS,
1772 IBUS_INTERFACE_IBUS,
1773 "GlobalEngineChanged");
1774 ibus_message_append_args (message,
1776 ibus_message_set_sender (message, IBUS_SERVICE_IBUS);
1778 bus_dbus_impl_dispatch_message_by_rule (BUS_DEFAULT_DBUS, message, NULL);
1780 ibus_message_unref (message);
1784 bus_ibus_impl_filter_keyboard_shortcuts (BusIBusImpl *ibus,
1785 BusInputContext *context,
1789 guint prev_modifiers)
1791 static GQuark trigger = 0;
1792 static GQuark next = 0;
1793 static GQuark previous = 0;
1796 trigger = g_quark_from_static_string ("trigger");
1797 next = g_quark_from_static_string ("next-engine-in-menu");
1798 previous = g_quark_from_static_string ("previous-engine");
1801 GQuark event = ibus_hotkey_profile_filter_key_event (ibus->hotkey_profile,
1808 if (event == trigger) {
1809 gboolean enabled = bus_input_context_is_enabled (context);
1811 bus_input_context_disable (context);
1814 bus_input_context_enable (context);
1816 return (enabled != bus_input_context_is_enabled (context));
1818 if (event == next) {
1819 if (bus_input_context_is_enabled(context)) {
1820 bus_ibus_impl_context_request_next_engine_in_menu (ibus, context);
1823 bus_input_context_enable (context);
1827 if (event == previous) {
1828 if (bus_input_context_is_enabled(context)) {
1829 bus_ibus_impl_context_request_previous_engine (ibus, context);
1832 bus_input_context_enable (context);
1840 bus_ibus_impl_load_global_engine_name_from_config (BusIBusImpl *ibus)
1842 GValue value = { 0 };
1843 gchar *global_engine_name = NULL;
1845 g_assert (IBUS_IS_CONFIG (ibus->config));
1847 if (ibus_config_get_value (ibus->config, "general", "global_engine", &value) &&
1848 G_VALUE_TYPE (&value) == G_TYPE_STRING) {
1849 global_engine_name = g_value_dup_string (&value);
1850 g_value_unset (&value);
1853 return global_engine_name;
1857 bus_ibus_impl_save_global_engine_name_to_config (BusIBusImpl *ibus)
1859 g_assert (IBUS_IS_CONFIG (ibus->config));
1861 if (ibus->use_global_engine && ibus->global_engine) {
1862 GValue value = { 0 };
1863 g_value_init (&value, G_TYPE_STRING);
1864 g_value_set_static_string (&value, bus_engine_proxy_get_desc (ibus->global_engine)->name);
1866 ibus_config_set_value (ibus->config, "general", "global_engine", &value);
1867 g_value_unset (&value);
1872 bus_ibus_impl_load_global_previous_engine_name_from_config (BusIBusImpl *ibus)
1874 GValue value = { 0 };
1875 gchar *global_previous_engine_name = NULL;
1877 g_assert (IBUS_IS_CONFIG (ibus->config));
1879 if (ibus_config_get_value (ibus->config, "general", "global_previous_engine", &value) &&
1880 G_VALUE_TYPE (&value) == G_TYPE_STRING) {
1881 global_previous_engine_name = g_value_dup_string (&value);
1882 g_value_unset (&value);
1885 return global_previous_engine_name;
1889 bus_ibus_impl_save_global_previous_engine_name_to_config (BusIBusImpl *ibus)
1891 g_assert (IBUS_IS_CONFIG (ibus->config));
1893 if (ibus->use_global_engine && ibus->global_previous_engine_name) {
1894 GValue value = { 0 };
1895 g_value_init (&value, G_TYPE_STRING);
1896 g_value_set_static_string (&value, ibus->global_previous_engine_name);
1898 ibus_config_set_value (ibus->config, "general", "global_previous_engine", &value);
1899 g_value_unset (&value);