1 /* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
2 /* vim:set et sts=4: */
3 /* ibus - The Input Bus
4 * Copyright (C) 2008-2010 Peng Huang <shawn.p.huang@gmail.com>
5 * Copyright (C) 2008-2010 Red Hat, Inc.
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the
19 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
22 #include "ibusinternal.h"
23 #include "ibusmarshalers.h"
24 #include "ibusshare.h"
25 #include "ibusconfig.h"
27 #include "ibuserror.h"
29 #define IBUS_CONFIG_GET_PRIVATE(o) \
30 (G_TYPE_INSTANCE_GET_PRIVATE ((o), IBUS_TYPE_CONFIG, IBusConfigPrivate))
39 struct _IBusConfigPrivate {
41 guint watch_config_signal_id;
44 static guint config_signals[LAST_SIGNAL] = { 0 };
46 static void ibus_config_class_init (IBusConfigClass *class);
47 static void ibus_config_init (IBusConfig *config);
48 static void ibus_config_real_destroy (IBusProxy *proxy);
50 static void ibus_config_g_signal (GDBusProxy *proxy,
51 const gchar *sender_name,
52 const gchar *signal_name,
53 GVariant *parameters);
55 static void initable_iface_init (GInitableIface *initable_iface);
56 static void async_initable_iface_init (GAsyncInitableIface
57 *async_initable_iface);
59 static gchar *_make_match_rule (const gchar *section,
61 static guint _signal_subscribe (GDBusProxy *proxy);
62 static void _signal_unsubscribe (GDBusProxy *proxy,
65 static void _remove_all_match_rules (IBusConfig *config);
67 G_DEFINE_TYPE_WITH_CODE (IBusConfig, ibus_config, IBUS_TYPE_PROXY,
68 G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, initable_iface_init)
69 G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE, async_initable_iface_init)
73 ibus_config_class_init (IBusConfigClass *class)
75 GDBusProxyClass *dbus_proxy_class = G_DBUS_PROXY_CLASS (class);
76 IBusProxyClass *proxy_class = IBUS_PROXY_CLASS (class);
78 g_type_class_add_private (class, sizeof (IBusConfigPrivate));
80 dbus_proxy_class->g_signal = ibus_config_g_signal;
81 proxy_class->destroy = ibus_config_real_destroy;
86 * IBusConfig::value-changed:
87 * @config: An IBusConfig.
88 * @section: Section name.
89 * @name: Name of the property.
92 * Emitted when configuration value is changed.
93 * <note><para>Argument @user_data is ignored in this function.</para></note>
95 config_signals[VALUE_CHANGED] =
96 g_signal_new (I_("value-changed"),
97 G_TYPE_FROM_CLASS (class),
101 _ibus_marshal_VOID__STRING_STRING_VARIANT,
106 G_TYPE_VARIANT | G_SIGNAL_TYPE_STATIC_SCOPE);
110 ibus_config_init (IBusConfig *config)
112 config->priv = IBUS_CONFIG_GET_PRIVATE (config);
113 config->priv->watch_rules = g_array_new (FALSE, FALSE, sizeof (gchar *));
117 ibus_config_real_destroy (IBusProxy *proxy)
119 IBusConfigPrivate *priv = IBUS_CONFIG_GET_PRIVATE (proxy);
121 _signal_unsubscribe (G_DBUS_PROXY (proxy), priv->watch_config_signal_id);
122 _remove_all_match_rules (IBUS_CONFIG (proxy));
123 g_array_free (priv->watch_rules, FALSE);
125 IBUS_PROXY_CLASS(ibus_config_parent_class)->destroy (proxy);
130 ibus_config_g_signal (GDBusProxy *proxy,
131 const gchar *sender_name,
132 const gchar *signal_name,
133 GVariant *parameters)
135 if (g_strcmp0 (signal_name, "ValueChanged") == 0) {
136 const gchar *section = NULL;
137 const gchar *name = NULL;
138 GVariant *value = NULL;
140 g_variant_get (parameters, "(&s&sv)", §ion, &name, &value);
142 g_signal_emit (proxy,
143 config_signals[VALUE_CHANGED],
148 g_variant_unref (value);
152 g_return_if_reached ();
156 _connection_signal_cb (GDBusConnection *connection,
157 const gchar *sender_name,
158 const gchar *object_path,
159 const gchar *interface_name,
160 const gchar *signal_name,
161 GVariant *parameters,
164 g_return_if_fail (IBUS_IS_CONFIG (config));
166 ibus_config_g_signal (G_DBUS_PROXY (config),
173 _make_match_rule (const gchar *section,
176 GString *str = g_string_new ("type='signal',"
177 "interface='" IBUS_INTERFACE_CONFIG "',"
178 "path='" IBUS_PATH_CONFIG "',"
179 "member='ValueChanged'");
180 if (section != NULL) {
181 g_string_append_printf (str, ",arg0='%s'", section);
183 g_string_append_printf (str, ",arg1='%s'", name);
185 return g_string_free (str, FALSE);
189 _remove_all_match_rules (IBusConfig *config)
193 for (i = 0; i < config->priv->watch_rules->len; i++) {
194 IBusBus *bus = ibus_bus_new ();
195 gchar *rule = g_array_index (config->priv->watch_rules, gchar *, i);
196 ibus_bus_remove_match (bus, rule);
197 g_object_unref (bus);
200 g_array_set_size (config->priv->watch_rules, 0);
204 ibus_config_watch (IBusConfig *config,
205 const gchar *section,
208 g_return_val_if_fail (IBUS_IS_CONFIG (config), FALSE);
209 g_assert ((section != NULL) || (section == NULL && name == NULL));
211 IBusBus *bus = ibus_bus_new ();
215 if (section == NULL && name == NULL) {
216 _remove_all_match_rules (config);
218 rule = _make_match_rule (NULL, NULL);
219 retval = ibus_bus_add_match (bus, rule);
220 g_object_unref (bus);
226 if (config->priv->watch_rules->len == 0) {
227 rule = _make_match_rule (NULL, NULL);
228 retval = ibus_bus_remove_match (bus, rule);
231 g_object_unref (bus);
236 rule = _make_match_rule (section, name);
237 retval = ibus_bus_add_match (bus, rule);
238 g_object_unref (bus);
244 g_array_append_val (config->priv->watch_rules, rule);
249 ibus_config_unwatch (IBusConfig *config,
250 const gchar *section,
253 g_return_val_if_fail (IBUS_IS_CONFIG (config), FALSE);
254 g_assert ((section != NULL) || (section == NULL && name == NULL));
256 IBusBus *bus = ibus_bus_new ();
257 gchar *rule = _make_match_rule (section, name);
260 retval = ibus_bus_remove_match (bus, rule);
261 g_object_unref (bus);
262 if (retval && (section != NULL || name != NULL)) {
263 /* Remove the previously registered match rule from
264 config->priv->watch_rules. */
266 for (i = 0; i < config->priv->watch_rules->len; i++) {
267 gchar *_rule = g_array_index (config->priv->watch_rules, gchar *,
269 if (g_strcmp0 (_rule, rule) == 0) {
270 config->priv->watch_rules =
271 g_array_remove_index_fast (config->priv->watch_rules, i);
283 ibus_config_new (GDBusConnection *connection,
284 GCancellable *cancellable,
287 g_assert (G_IS_DBUS_CONNECTION (connection));
291 GDBusProxyFlags flags = G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START |
292 G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES |
293 G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS;
295 initable = g_initable_new (IBUS_TYPE_CONFIG,
298 "g-connection", connection,
300 "g-name", IBUS_SERVICE_CONFIG,
301 "g-interface-name", IBUS_INTERFACE_CONFIG,
302 "g-object-path", IBUS_PATH_CONFIG,
303 "g-default-timeout", ibus_get_timeout (),
305 if (initable == NULL)
308 if (g_dbus_proxy_get_name_owner (G_DBUS_PROXY (initable)) == NULL) {
309 /* The configuration daemon, which is usually ibus-gconf, is not started yet. */
312 IBUS_ERROR_NO_CONFIG,
313 "Configuration daemon is not running.");
314 g_object_unref (initable);
318 /* clients should not destroy the config service. */
319 IBUS_PROXY (initable)->own = FALSE;
321 return IBUS_CONFIG (initable);
325 ibus_config_new_async (GDBusConnection *connection,
326 GCancellable *cancellable,
327 GAsyncReadyCallback callback,
330 g_assert (G_IS_DBUS_CONNECTION (connection));
331 g_assert (callback != NULL);
333 GDBusProxyFlags flags = G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START |
334 G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES |
335 G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS;
337 g_async_initable_new_async (IBUS_TYPE_CONFIG,
342 "g-connection", connection,
344 "g-name", IBUS_SERVICE_CONFIG,
345 "g-interface-name", IBUS_INTERFACE_CONFIG,
346 "g-object-path", IBUS_PATH_CONFIG,
347 "g-default-timeout", ibus_get_timeout (),
352 ibus_config_new_async_finish (GAsyncResult *res,
355 g_assert (G_IS_ASYNC_RESULT (res));
356 g_assert (error == NULL || *error == NULL);
358 GObject *object = NULL;
359 GObject *source_object = NULL;
361 source_object = g_async_result_get_source_object (res);
362 g_assert (source_object != NULL);
364 object = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object),
367 g_object_unref (source_object);
369 if (object != NULL) {
370 if (g_dbus_proxy_get_name_owner (G_DBUS_PROXY (object)) == NULL) {
371 /* The configuration daemon, which is usually ibus-gconf,
372 * is not started yet. */
375 IBUS_ERROR_NO_CONFIG,
376 "Configuration daemon is not running.");
377 g_object_unref (object);
380 /* clients should not destroy the config service. */
381 IBUS_PROXY (object)->own = FALSE;
382 return IBUS_CONFIG (object);
390 ibus_config_get_value (IBusConfig *config,
391 const gchar *section,
394 g_assert (IBUS_IS_CONFIG (config));
395 g_assert (section != NULL);
396 g_assert (name != NULL);
398 GError *error = NULL;
400 result = g_dbus_proxy_call_sync ((GDBusProxy *) config,
401 "GetValue", /* method_name */
402 g_variant_new ("(ss)",
403 section, name), /* parameters */
404 G_DBUS_CALL_FLAGS_NONE, /* flags */
406 NULL, /* cancellable */
409 if (result == NULL) {
410 g_warning ("%s.GetValue: %s", IBUS_INTERFACE_CONFIG, error->message);
411 g_error_free (error);
415 GVariant *value = NULL;
416 g_variant_get (result, "(v)", &value);
417 g_variant_unref (result);
423 ibus_config_get_value_async (IBusConfig *config,
424 const gchar *section,
427 GCancellable *cancellable,
428 GAsyncReadyCallback callback,
431 g_assert (IBUS_IS_CONFIG (config));
432 g_assert (section != NULL);
433 g_assert (name != NULL);
435 g_dbus_proxy_call ((GDBusProxy *)config,
437 g_variant_new ("(ss)", section, name),
438 G_DBUS_CALL_FLAGS_NONE,
446 ibus_config_get_value_async_finish (IBusConfig *config,
447 GAsyncResult *result,
450 g_assert (IBUS_IS_CONFIG (config));
451 g_assert (G_IS_ASYNC_RESULT (result));
452 g_assert (error == NULL || *error == NULL);
454 GVariant *value = NULL;
455 GVariant *retval = g_dbus_proxy_call_finish ((GDBusProxy *)config,
458 if (retval != NULL) {
459 g_variant_get (retval, "(v)", &value);
460 g_variant_unref (retval);
467 ibus_config_get_values (IBusConfig *config,
468 const gchar *section)
470 g_assert (IBUS_IS_CONFIG (config));
471 g_assert (section != NULL);
473 GError *error = NULL;
475 result = g_dbus_proxy_call_sync ((GDBusProxy *) config,
477 g_variant_new ("(s)", section),
478 G_DBUS_CALL_FLAGS_NONE,
482 if (result == NULL) {
483 g_warning ("%s.GetValues: %s", IBUS_INTERFACE_CONFIG, error->message);
484 g_error_free (error);
488 GVariant *value = NULL;
489 g_variant_get (result, "(@a{sv})", &value);
490 g_variant_unref (result);
496 ibus_config_get_values_async (IBusConfig *config,
497 const gchar *section,
499 GCancellable *cancellable,
500 GAsyncReadyCallback callback,
503 g_assert (IBUS_IS_CONFIG (config));
504 g_assert (section != NULL);
506 g_dbus_proxy_call ((GDBusProxy *)config,
508 g_variant_new ("(s)", section),
509 G_DBUS_CALL_FLAGS_NONE,
517 ibus_config_get_values_async_finish (IBusConfig *config,
518 GAsyncResult *result,
521 g_assert (IBUS_IS_CONFIG (config));
522 g_assert (G_IS_ASYNC_RESULT (result));
523 g_assert (error == NULL || *error == NULL);
525 GVariant *value = NULL;
526 GVariant *retval = g_dbus_proxy_call_finish ((GDBusProxy *)config,
529 if (retval != NULL) {
530 g_variant_get (retval, "(@a{sv})", &value);
531 g_variant_unref (retval);
538 ibus_config_set_value (IBusConfig *config,
539 const gchar *section,
543 g_assert (IBUS_IS_CONFIG (config));
544 g_assert (section != NULL);
545 g_assert (name != NULL);
546 g_assert (value != NULL);
548 GError *error = NULL;
550 result = g_dbus_proxy_call_sync ((GDBusProxy *) config,
551 "SetValue", /* method_name */
552 g_variant_new ("(ssv)",
553 section, name, value), /* parameters */
554 G_DBUS_CALL_FLAGS_NONE, /* flags */
556 NULL, /* cancellable */
559 if (result == NULL) {
560 g_warning ("%s.SetValue: %s", IBUS_INTERFACE_CONFIG, error->message);
561 g_error_free (error);
564 g_variant_unref (result);
569 ibus_config_set_value_async (IBusConfig *config,
570 const gchar *section,
574 GCancellable *cancellable,
575 GAsyncReadyCallback callback,
578 g_assert (IBUS_IS_CONFIG (config));
579 g_assert (section != NULL);
580 g_assert (name != NULL);
581 g_assert (value != NULL);
583 g_dbus_proxy_call ((GDBusProxy *) config,
584 "SetValue", /* method_name */
585 g_variant_new ("(ssv)",
586 section, name, value), /* parameters */
587 G_DBUS_CALL_FLAGS_NONE, /* flags */
595 ibus_config_set_value_async_finish (IBusConfig *config,
596 GAsyncResult *result,
599 g_assert (IBUS_IS_CONFIG (config));
600 g_assert (G_IS_ASYNC_RESULT (result));
601 g_assert (error == NULL || *error == NULL);
603 GVariant *retval = g_dbus_proxy_call_finish ((GDBusProxy *)config,
606 if (retval != NULL) {
607 g_variant_unref (retval);
615 ibus_config_unset (IBusConfig *config,
616 const gchar *section,
619 g_assert (IBUS_IS_CONFIG (config));
620 g_assert (section != NULL);
621 g_assert (name != NULL);
623 GError *error = NULL;
625 result = g_dbus_proxy_call_sync ((GDBusProxy *) config,
626 "UnsetValue", /* method_name */
627 g_variant_new ("(ss)",
628 section, name), /* parameters */
629 G_DBUS_CALL_FLAGS_NONE, /* flags */
631 NULL, /* cancellable */
634 if (result == NULL) {
635 g_warning ("%s.UnsetValue: %s", IBUS_INTERFACE_CONFIG, error->message);
636 g_error_free (error);
639 g_variant_unref (result);
644 _signal_subscribe (GDBusProxy *proxy)
646 GDBusConnection *connection = g_dbus_proxy_get_connection (proxy);
647 return g_dbus_connection_signal_subscribe (connection,
649 IBUS_INTERFACE_CONFIG,
653 G_DBUS_SIGNAL_FLAGS_NO_MATCH_RULE,
654 (GDBusSignalCallback) _connection_signal_cb,
655 g_object_ref (proxy),
656 (GDestroyNotify) g_object_unref);
660 _signal_unsubscribe (GDBusProxy *proxy, guint signal_id)
662 GDBusConnection *connection = g_dbus_proxy_get_connection (proxy);
663 g_dbus_connection_signal_unsubscribe (connection, signal_id);
666 static GInitableIface *initable_iface_parent = NULL;
669 initable_init (GInitable *initable,
670 GCancellable *cancellable,
673 if (!initable_iface_parent->init (initable, cancellable, error))
676 IBusConfig *config = IBUS_CONFIG (initable);
677 config->priv->watch_config_signal_id =
678 _signal_subscribe (G_DBUS_PROXY (initable));
680 gboolean retval = ibus_config_watch (config, NULL, NULL);
685 "Cannot watch configuration change.");
690 initable_iface_init (GInitableIface *initable_iface)
692 initable_iface_parent = g_type_interface_peek_parent (initable_iface);
693 initable_iface->init = initable_init;
696 static GAsyncInitableIface *async_initable_iface_parent = NULL;
699 async_initable_init_async (GAsyncInitable *initable,
701 GCancellable *cancellable,
702 GAsyncReadyCallback callback,
705 async_initable_iface_parent->init_async (initable,
713 async_initable_init_finish (GAsyncInitable *initable,
717 if (!async_initable_iface_parent->init_finish (initable, res, error))
720 IBusConfig *config = IBUS_CONFIG (initable);
721 config->priv->watch_config_signal_id =
722 _signal_subscribe (G_DBUS_PROXY (initable));
723 return ibus_config_watch (config, NULL, NULL);
727 async_initable_iface_init (GAsyncInitableIface *async_initable_iface)
729 async_initable_iface_parent =
730 g_type_interface_peek_parent (async_initable_iface);
731 async_initable_iface->init_async = async_initable_init_async;
732 async_initable_iface->init_finish = async_initable_init_finish;