1 /* GDBus - GLib D-Bus Library
3 * Copyright (C) 2008-2010 Red Hat, Inc.
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General
16 * Public License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18 * Boston, MA 02111-1307, USA.
20 * Author: David Zeuthen <davidz@redhat.com>
25 #include "gdbusobjectmanager.h"
26 #include "gdbusobjectmanagerclient.h"
27 #include "gdbusobject.h"
28 #include "gdbusprivate.h"
29 #include "gio-marshal.h"
30 #include "gioenumtypes.h"
31 #include "ginitable.h"
32 #include "gasyncresult.h"
33 #include "gsimpleasyncresult.h"
34 #include "gasyncinitable.h"
35 #include "gdbusconnection.h"
36 #include "gdbusutils.h"
37 #include "gdbusobject.h"
38 #include "gdbusobjectproxy.h"
39 #include "gdbusproxy.h"
40 #include "gdbusinterface.h"
45 * SECTION:gdbusobjectmanagerclient
46 * @short_description: Client-side object manager
49 * #GDBusObjectManagerClient is used to create, monitor and delete object
50 * proxies for remote objects exported by a #GDBusObjectManagerServer (or any
51 * code implementing the <ulink
52 * url="http://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-objectmanager">org.freedesktop.DBus.ObjectManager</ulink>
55 * Once an instance of this type has been created, you can connect to
56 * the #GDBusObjectManager::object-added and
57 * #GDBusObjectManager::object-removed signals and inspect the
58 * #GDBusObjectProxy objects returned by
59 * g_dbus_object_manager_get_objects().
61 * If the name for a #GDBusObjectManagerClient is not owned by anyone at
62 * object construction time, the default behavior is to request the
63 * message bus to launch an owner for the name. This behavior can be
64 * disabled using the %G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_DO_NOT_AUTO_START
65 * flag. It's also worth noting that this only works if the name of
66 * interest is activatable in the first place. E.g. in some cases it
67 * is not possible to launch an owner for the requested name. In this
68 * case, #GDBusObjectManagerClient object construction still succeeds but
69 * there will be no object proxies
70 * (e.g. g_dbus_object_manager_get_objects() returns the empty list) and
71 * the #GDBusObjectManagerClient:name-owner property is %NULL.
73 * The owner of the requested name can come and go (for example
74 * consider a system service being restarted) – #GDBusObjectManagerClient
75 * handles this case too; simply connect to the #GObject::notify
76 * signal to watch for changes on the #GDBusObjectManagerClient:name-owner
77 * property. When the name owner vanishes, the behavior is that
78 * #GDBusObjectManagerClient:name-owner is set to %NULL (this includes
79 * emission of the #GObject::notify signal) and then
80 * #GDBusObjectManager::object-removed signals are synthesized
81 * for all currently existing object proxies. Since
82 * #GDBusObjectManagerClient:name-owner is %NULL when this happens, you can
83 * use this information to disambiguate a synthesized signal from a
84 * genuine signal caused by object removal on the remote
85 * #GDBusObjectManager. Similarly, when a new name owner appears,
86 * #GDBusObjectManager::object-added signals are synthesized
87 * while #GDBusObjectManagerClient:name-owner is still %NULL. Only when all
88 * object proxies have been added, the #GDBusObjectManagerClient:name-owner
89 * is set to the new name owner (this includes emission of the
90 * #GObject::notify signal). Furthermore, you are guaranteed that
91 * #GDBusObjectManagerClient:name-owner will alternate between a name owner
92 * (e.g. <literal>:1.42</literal>) and %NULL even in the case where
93 * the name of interest is atomically replaced
95 * Ultimately, #GDBusObjectManagerClient is used to obtain #GDBusProxy
96 * instances. All signals (including the
97 * <literal>org.freedesktop.DBus.Properties::PropertiesChanged</literal>
98 * signal) delivered to #GDBusProxy instances are guaranteed to
99 * originate from the name owner. This guarantee along with the
100 * behavior described above, means that certain race conditions
101 * including the <emphasis><quote>half the proxy is from the old owner
102 * and the other half is from the new owner</quote></emphasis> problem
105 * To avoid having the application connect to signals on the returned
106 * #GDBusObjectProxy and #GDBusProxy objects, the
107 * #GDBusObject::interface-added,
108 * #GDBusObject::interface-removed,
109 * #GDBusProxy::g-properties-changed and
110 * #GDBusProxy::g-signal signals
111 * are also emitted on the #GDBusObjectManagerClient instance managing these
112 * objects. The signals emitted are
113 * #GDBusObjectManager::interface-added,
114 * #GDBusObjectManager::interface-removed,
115 * #GDBusObjectManagerClient::interface-proxy-properties-changed and
116 * #GDBusObjectManagerClient::interface-proxy-signal.
118 * Note that all callbacks and signals are emitted in the
119 * <link linkend="g-main-context-push-thread-default">thread-default main loop</link>
120 * that the #GDBusObjectManagerClient object was constructed
121 * in. Additionally, the #GDBusObjectProxy and #GDBusProxy objects
122 * originating from the #GDBusObjectManagerClient object will be created in
123 * the same context and, consequently, will deliver signals in the
127 struct _GDBusObjectManagerClientPrivate
130 GDBusConnection *connection;
134 GDBusObjectManagerClientFlags flags;
136 GDBusProxy *control_proxy;
138 GHashTable *map_object_path_to_object_proxy;
140 guint signal_subscription_id;
143 GDBusProxyTypeFunc get_proxy_type_func;
144 gpointer get_proxy_type_user_data;
156 PROP_GET_PROXY_TYPE_FUNC,
157 PROP_GET_PROXY_TYPE_USER_DATA
162 INTERFACE_PROXY_SIGNAL_SIGNAL,
163 INTERFACE_PROXY_PROPERTIES_CHANGED_SIGNAL,
167 static guint signals[LAST_SIGNAL] = { 0 };
169 static void initable_iface_init (GInitableIface *initable_iface);
170 static void async_initable_iface_init (GAsyncInitableIface *async_initable_iface);
171 static void dbus_object_manager_interface_init (GDBusObjectManagerIface *iface);
173 G_DEFINE_TYPE_WITH_CODE (GDBusObjectManagerClient, g_dbus_object_manager_client, G_TYPE_OBJECT,
174 G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, initable_iface_init)
175 G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE, async_initable_iface_init)
176 G_IMPLEMENT_INTERFACE (G_TYPE_DBUS_OBJECT_MANAGER, dbus_object_manager_interface_init));
178 static void maybe_unsubscribe_signals (GDBusObjectManagerClient *manager);
180 static void on_control_proxy_g_signal (GDBusProxy *proxy,
181 const gchar *sender_name,
182 const gchar *signal_name,
183 GVariant *parameters,
186 static void process_get_all_result (GDBusObjectManagerClient *manager,
188 const gchar *name_owner);
191 g_dbus_object_manager_client_finalize (GObject *object)
193 GDBusObjectManagerClient *manager = G_DBUS_OBJECT_MANAGER_CLIENT (object);
195 maybe_unsubscribe_signals (manager);
197 g_hash_table_unref (manager->priv->map_object_path_to_object_proxy);
199 if (manager->priv->control_proxy != NULL)
201 g_warn_if_fail (g_signal_handlers_disconnect_by_func (manager->priv->control_proxy,
202 on_control_proxy_g_signal,
204 g_object_unref (manager->priv->control_proxy);
206 g_object_unref (manager->priv->connection);
207 g_free (manager->priv->object_path);
208 g_free (manager->priv->name);
209 g_free (manager->priv->name_owner);
211 if (G_OBJECT_CLASS (g_dbus_object_manager_client_parent_class)->finalize != NULL)
212 G_OBJECT_CLASS (g_dbus_object_manager_client_parent_class)->finalize (object);
216 g_dbus_object_manager_client_get_property (GObject *_object,
221 GDBusObjectManagerClient *manager = G_DBUS_OBJECT_MANAGER_CLIENT (_object);
225 case PROP_CONNECTION:
226 g_value_set_object (value, g_dbus_object_manager_client_get_connection (manager));
229 case PROP_OBJECT_PATH:
230 g_value_set_string (value, g_dbus_object_manager_get_object_path (G_DBUS_OBJECT_MANAGER (manager)));
234 g_value_set_string (value, g_dbus_object_manager_client_get_name (manager));
238 g_value_set_flags (value, g_dbus_object_manager_client_get_flags (manager));
241 case PROP_NAME_OWNER:
242 g_value_take_string (value, g_dbus_object_manager_client_get_name_owner (manager));
246 G_OBJECT_WARN_INVALID_PROPERTY_ID (_object, prop_id, pspec);
252 g_dbus_object_manager_client_set_property (GObject *_object,
257 GDBusObjectManagerClient *manager = G_DBUS_OBJECT_MANAGER_CLIENT (_object);
262 manager->priv->bus_type = g_value_get_enum (value);
265 case PROP_CONNECTION:
266 if (g_value_get_object (value) != NULL)
268 g_assert (manager->priv->connection == NULL);
269 g_assert (G_IS_DBUS_CONNECTION (g_value_get_object (value)));
270 manager->priv->connection = g_value_dup_object (value);
274 case PROP_OBJECT_PATH:
275 g_assert (manager->priv->object_path == NULL);
276 g_assert (g_variant_is_object_path (g_value_get_string (value)));
277 manager->priv->object_path = g_value_dup_string (value);
281 g_assert (manager->priv->name == NULL);
282 g_assert (g_dbus_is_name (g_value_get_string (value)));
283 manager->priv->name = g_value_dup_string (value);
287 manager->priv->flags = g_value_get_flags (value);
290 case PROP_GET_PROXY_TYPE_FUNC:
291 manager->priv->get_proxy_type_func = g_value_get_pointer (value);
294 case PROP_GET_PROXY_TYPE_USER_DATA:
295 manager->priv->get_proxy_type_user_data = g_value_get_pointer (value);
299 G_OBJECT_WARN_INVALID_PROPERTY_ID (_object, prop_id, pspec);
305 g_dbus_object_manager_client_class_init (GDBusObjectManagerClientClass *klass)
307 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
309 gobject_class->finalize = g_dbus_object_manager_client_finalize;
310 gobject_class->set_property = g_dbus_object_manager_client_set_property;
311 gobject_class->get_property = g_dbus_object_manager_client_get_property;
314 * GDBusObjectManagerClient:connection:
316 * The #GDBusConnection to use.
320 g_object_class_install_property (gobject_class,
322 g_param_spec_object ("connection",
324 "The connection to use",
325 G_TYPE_DBUS_CONNECTION,
328 G_PARAM_CONSTRUCT_ONLY |
329 G_PARAM_STATIC_STRINGS));
332 * GDBusObjectManagerClient:bus-type:
334 * If this property is not %G_BUS_TYPE_NONE, then
335 * #GDBusObjectManagerClient:connection must be %NULL and will be set to the
336 * #GDBusConnection obtained by calling g_bus_get() with the value
341 g_object_class_install_property (gobject_class,
343 g_param_spec_enum ("bus-type",
345 "The bus to connect to, if any",
349 G_PARAM_CONSTRUCT_ONLY |
350 G_PARAM_STATIC_NAME |
351 G_PARAM_STATIC_BLURB |
352 G_PARAM_STATIC_NICK));
355 * GDBusObjectManagerClient:flags:
357 * Flags from the #GDBusObjectManagerClientFlags enumeration.
361 g_object_class_install_property (gobject_class,
363 g_param_spec_flags ("flags",
365 "Flags for the proxy manager",
366 G_TYPE_DBUS_OBJECT_MANAGER_CLIENT_FLAGS,
367 G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_NONE,
370 G_PARAM_CONSTRUCT_ONLY |
371 G_PARAM_STATIC_NAME |
372 G_PARAM_STATIC_BLURB |
373 G_PARAM_STATIC_NICK));
376 * GDBusObjectManagerClient:object-path:
378 * The object path the manager is for.
382 g_object_class_install_property (gobject_class,
384 g_param_spec_string ("object-path",
386 "The object path of the control object",
390 G_PARAM_CONSTRUCT_ONLY |
391 G_PARAM_STATIC_STRINGS));
394 * GDBusObjectManagerClient:name:
396 * The well-known name or unique name that the manager is for.
400 g_object_class_install_property (gobject_class,
402 g_param_spec_string ("name",
404 "Name that the manager is for",
408 G_PARAM_CONSTRUCT_ONLY |
409 G_PARAM_STATIC_STRINGS));
412 * GDBusObjectManagerClient:name-owner:
414 * The unique name that owns #GDBusObjectManagerClient:name or %NULL if
415 * no-one is currently owning the name. Connect to the
416 * #GObject::notify signal to track changes to this property.
420 g_object_class_install_property (gobject_class,
422 g_param_spec_string ("name-owner",
424 "The owner of the name we are watching",
427 G_PARAM_STATIC_STRINGS));
430 * GDBusObjectManagerClient:get-proxy-type-func:
432 * The #GDBusProxyTypeFunc to use when determining what #GType to
433 * use for interface proxies or %NULL.
437 g_object_class_install_property (gobject_class,
438 PROP_GET_PROXY_TYPE_FUNC,
439 g_param_spec_pointer ("get-proxy-type-func",
440 "GDBusProxyTypeFunc Function Pointer",
441 "The GDBusProxyTypeFunc pointer to use",
444 G_PARAM_CONSTRUCT_ONLY |
445 G_PARAM_STATIC_STRINGS));
448 * GDBusObjectManagerClient:get-proxy-type-user-data:
450 * The #gpointer user_data to pass to #GDBusObjectManagerClient:get-proxy-type-func.
454 g_object_class_install_property (gobject_class,
455 PROP_GET_PROXY_TYPE_USER_DATA,
456 g_param_spec_pointer ("get-proxy-type-user-data",
457 "GDBusProxyTypeFunc User Data",
458 "The GDBusProxyTypeFunc user_data",
461 G_PARAM_CONSTRUCT_ONLY |
462 G_PARAM_STATIC_STRINGS));
465 * GDBusObjectManagerClient::interface-proxy-signal:
466 * @manager: The #GDBusObjectManagerClient emitting the signal.
467 * @object_proxy: The #GDBusObjectProxy on which an interface is emitting a D-Bus signal.
468 * @interface_proxy: The #GDBusProxy that is emitting a D-Bus signal.
469 * @sender_name: The sender of the signal or NULL if the connection is not a bus connection.
470 * @signal_name: The signal name.
471 * @parameters: A #GVariant tuple with parameters for the signal.
473 * Emitted when a D-Bus signal is received on @interface_proxy.
475 * This signal exists purely as a convenience to avoid having to
476 * connect signals to all interface proxies managed by @manager.
478 * This signal is emitted in the
479 * <link linkend="g-main-context-push-thread-default">thread-default main loop</link>
480 * that @manager was constructed in.
484 signals[INTERFACE_PROXY_SIGNAL_SIGNAL] =
485 g_signal_new ("interface-proxy-signal",
486 G_TYPE_DBUS_OBJECT_MANAGER_CLIENT,
488 G_STRUCT_OFFSET (GDBusObjectManagerClientClass, interface_proxy_signal),
491 _gio_marshal_VOID__OBJECT_OBJECT_STRING_STRING_VARIANT,
494 G_TYPE_DBUS_OBJECT_PROXY,
501 * GDBusObjectManagerClient::interface-proxy-properties-changed:
502 * @manager: The #GDBusObjectManagerClient emitting the signal.
503 * @object_proxy: The #GDBusObjectProxy on which an interface has properties that are changing.
504 * @interface_proxy: The #GDBusProxy that has properties that are changing.
505 * @changed_properties: A #GVariant containing the properties that changed.
506 * @invalidated_properties: A %NULL terminated array of properties that was invalidated.
508 * Emitted when one or more D-Bus properties on proxy changes. The
509 * local cache has already been updated when this signal fires. Note
510 * that both @changed_properties and @invalidated_properties are
511 * guaranteed to never be %NULL (either may be empty though).
513 * This signal exists purely as a convenience to avoid having to
514 * connect signals to all interface proxies managed by @manager.
516 * This signal is emitted in the
517 * <link linkend="g-main-context-push-thread-default">thread-default main loop</link>
518 * that @manager was constructed in.
522 signals[INTERFACE_PROXY_PROPERTIES_CHANGED_SIGNAL] =
523 g_signal_new ("interface-proxy-properties-changed",
524 G_TYPE_DBUS_OBJECT_MANAGER_CLIENT,
526 G_STRUCT_OFFSET (GDBusObjectManagerClientClass, interface_proxy_properties_changed),
529 _gio_marshal_VOID__OBJECT_OBJECT_VARIANT_BOXED,
532 G_TYPE_DBUS_OBJECT_PROXY,
537 g_type_class_add_private (klass, sizeof (GDBusObjectManagerClientPrivate));
541 g_dbus_object_manager_client_init (GDBusObjectManagerClient *manager)
543 manager->priv = G_TYPE_INSTANCE_GET_PRIVATE (manager,
544 G_TYPE_DBUS_OBJECT_MANAGER_CLIENT,
545 GDBusObjectManagerClientPrivate);
546 manager->priv->map_object_path_to_object_proxy = g_hash_table_new_full (g_str_hash,
549 (GDestroyNotify) g_object_unref);
552 /* ---------------------------------------------------------------------------------------------------- */
555 * g_dbus_object_manager_client_new_sync:
556 * @connection: A #GDBusConnection.
557 * @flags: Zero or more flags from the #GDBusObjectManagerClientFlags enumeration.
558 * @name: The owner of the control object (unique or well-known name).
559 * @object_path: The object path of the control object.
560 * @get_proxy_type_func: A #GDBusProxyTypeFunc function or %NULL to always construct #GDBusProxy proxies.
561 * @get_proxy_type_user_data: User data to pass to @get_proxy_type_func.
562 * @cancellable: A #GCancellable or %NULL
563 * @error: Return location for error or %NULL.
565 * Creates a new #GDBusObjectManagerClient object.
567 * This is a synchronous failable constructor - the calling thread is
568 * blocked until a reply is received. See g_dbus_object_manager_client_new()
569 * for the asynchronous version.
571 * Returns: (transfer full) (type GDBusObjectManagerClient): A
572 * #GDBusObjectManagerClient object or %NULL if @error is set. Free
573 * with g_object_unref().
578 g_dbus_object_manager_client_new_sync (GDBusConnection *connection,
579 GDBusObjectManagerClientFlags flags,
581 const gchar *object_path,
582 GDBusProxyTypeFunc get_proxy_type_func,
583 gpointer get_proxy_type_user_data,
584 GCancellable *cancellable,
589 g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL);
590 g_return_val_if_fail ((name == NULL && g_dbus_connection_get_unique_name (connection) == NULL) ||
591 g_dbus_is_name (name), NULL);
592 g_return_val_if_fail (g_variant_is_object_path (object_path), NULL);
593 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
595 initable = g_initable_new (G_TYPE_DBUS_OBJECT_MANAGER_CLIENT,
598 "connection", connection,
601 "object-path", object_path,
602 "get-proxy-type-func", get_proxy_type_func,
603 "get-proxy-type-user-data", get_proxy_type_user_data,
605 if (initable != NULL)
606 return G_DBUS_OBJECT_MANAGER (initable);
612 * g_dbus_object_manager_client_new:
613 * @connection: A #GDBusConnection.
614 * @flags: Zero or more flags from the #GDBusObjectManagerClientFlags enumeration.
615 * @name: The owner of the control object (unique or well-known name).
616 * @object_path: The object path of the control object.
617 * @get_proxy_type_func: A #GDBusProxyTypeFunc function or %NULL to always construct #GDBusProxy proxies.
618 * @get_proxy_type_user_data: User data to pass to @get_proxy_type_func.
619 * @cancellable: A #GCancellable or %NULL
620 * @callback: A #GAsyncReadyCallback to call when the request is satisfied.
621 * @user_data: The data to pass to @callback.
623 * Asynchronously creates a new #GDBusObjectManagerClient object.
625 * This is an asynchronous failable constructor. When the result is
626 * ready, @callback will be invoked in the
627 * <link linkend="g-main-context-push-thread-default">thread-default main loop</link>
628 * of the thread you are calling this method from. You can
629 * then call g_dbus_object_manager_client_new_finish() to get the result. See
630 * g_dbus_object_manager_client_new_sync() for the synchronous version.
635 g_dbus_object_manager_client_new (GDBusConnection *connection,
636 GDBusObjectManagerClientFlags flags,
638 const gchar *object_path,
639 GDBusProxyTypeFunc get_proxy_type_func,
640 gpointer get_proxy_type_user_data,
641 GCancellable *cancellable,
642 GAsyncReadyCallback callback,
645 g_return_if_fail (G_IS_DBUS_CONNECTION (connection));
646 g_return_if_fail ((name == NULL && g_dbus_connection_get_unique_name (connection) == NULL) ||
647 g_dbus_is_name (name));
648 g_return_if_fail (g_variant_is_object_path (object_path));
650 g_async_initable_new_async (G_TYPE_DBUS_OBJECT_MANAGER_CLIENT,
655 "connection", connection,
658 "object-path", object_path,
659 "get-proxy-type-func", get_proxy_type_func,
660 "get-proxy-type-user-data", get_proxy_type_user_data,
665 * g_dbus_object_manager_client_new_finish:
666 * @res: A #GAsyncResult obtained from the #GAsyncReadyCallback passed to g_dbus_object_manager_client_new().
667 * @error: Return location for error or %NULL.
669 * Finishes an operation started with g_dbus_object_manager_client_new().
671 * Returns: (transfer full) (type GDBusObjectManagerClient): A
672 * #GDBusObjectManagerClient object or %NULL if @error is set. Free
673 * with g_object_unref().
678 g_dbus_object_manager_client_new_finish (GAsyncResult *res,
682 GObject *source_object;
684 source_object = g_async_result_get_source_object (res);
685 g_assert (source_object != NULL);
687 object = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object),
690 g_object_unref (source_object);
693 return G_DBUS_OBJECT_MANAGER (object);
698 /* ---------------------------------------------------------------------------------------------------- */
701 * g_dbus_object_manager_client_new_for_bus_sync:
702 * @bus_type: A #GBusType.
703 * @flags: Zero or more flags from the #GDBusObjectManagerClientFlags enumeration.
704 * @name: The owner of the control object (unique or well-known name).
705 * @object_path: The object path of the control object.
706 * @get_proxy_type_func: A #GDBusProxyTypeFunc function or %NULL to always construct #GDBusProxy proxies.
707 * @get_proxy_type_user_data: User data to pass to @get_proxy_type_func.
708 * @cancellable: A #GCancellable or %NULL
709 * @error: Return location for error or %NULL.
711 * Like g_dbus_object_manager_client_new_sync() but takes a #GBusType instead
712 * of a #GDBusConnection.
714 * This is a synchronous failable constructor - the calling thread is
715 * blocked until a reply is received. See g_dbus_object_manager_client_new_for_bus()
716 * for the asynchronous version.
718 * Returns: (transfer full) (type GDBusObjectManagerClient): A
719 * #GDBusObjectManagerClient object or %NULL if @error is set. Free
720 * with g_object_unref().
725 g_dbus_object_manager_client_new_for_bus_sync (GBusType bus_type,
726 GDBusObjectManagerClientFlags flags,
728 const gchar *object_path,
729 GDBusProxyTypeFunc get_proxy_type_func,
730 gpointer get_proxy_type_user_data,
731 GCancellable *cancellable,
736 g_return_val_if_fail (bus_type != G_BUS_TYPE_NONE, NULL);
737 g_return_val_if_fail (g_dbus_is_name (name), NULL);
738 g_return_val_if_fail (g_variant_is_object_path (object_path), NULL);
739 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
741 initable = g_initable_new (G_TYPE_DBUS_OBJECT_MANAGER_CLIENT,
744 "bus-type", bus_type,
747 "object-path", object_path,
748 "get-proxy-type-func", get_proxy_type_func,
749 "get-proxy-type-user-data", get_proxy_type_user_data,
751 if (initable != NULL)
752 return G_DBUS_OBJECT_MANAGER (initable);
758 * g_dbus_object_manager_client_new_for_bus:
759 * @bus_type: A #GBusType.
760 * @flags: Zero or more flags from the #GDBusObjectManagerClientFlags enumeration.
761 * @name: The owner of the control object (unique or well-known name).
762 * @object_path: The object path of the control object.
763 * @get_proxy_type_func: A #GDBusProxyTypeFunc function or %NULL to always construct #GDBusProxy proxies.
764 * @get_proxy_type_user_data: User data to pass to @get_proxy_type_func.
765 * @cancellable: A #GCancellable or %NULL
766 * @callback: A #GAsyncReadyCallback to call when the request is satisfied.
767 * @user_data: The data to pass to @callback.
769 * Like g_dbus_object_manager_client_new() but takes a #GBusType instead of a
772 * This is an asynchronous failable constructor. When the result is
773 * ready, @callback will be invoked in the
774 * <link linkend="g-main-context-push-thread-default">thread-default main loop</link>
775 * of the thread you are calling this method from. You can
776 * then call g_dbus_object_manager_client_new_for_bus_finish() to get the result. See
777 * g_dbus_object_manager_client_new_for_bus_sync() for the synchronous version.
782 g_dbus_object_manager_client_new_for_bus (GBusType bus_type,
783 GDBusObjectManagerClientFlags flags,
785 const gchar *object_path,
786 GDBusProxyTypeFunc get_proxy_type_func,
787 gpointer get_proxy_type_user_data,
788 GCancellable *cancellable,
789 GAsyncReadyCallback callback,
792 g_return_if_fail (bus_type != G_BUS_TYPE_NONE);
793 g_return_if_fail (g_dbus_is_name (name));
794 g_return_if_fail (g_variant_is_object_path (object_path));
796 g_async_initable_new_async (G_TYPE_DBUS_OBJECT_MANAGER_CLIENT,
801 "bus-type", bus_type,
804 "object-path", object_path,
805 "get-proxy-type-func", get_proxy_type_func,
806 "get-proxy-type-user-data", get_proxy_type_user_data,
811 * g_dbus_object_manager_client_new_for_bus_finish:
812 * @res: A #GAsyncResult obtained from the #GAsyncReadyCallback passed to g_dbus_object_manager_client_new_for_bus().
813 * @error: Return location for error or %NULL.
815 * Finishes an operation started with g_dbus_object_manager_client_new_for_bus().
817 * Returns: (transfer full) (type GDBusObjectManagerClient): A
818 * #GDBusObjectManagerClient object or %NULL if @error is set. Free
819 * with g_object_unref().
824 g_dbus_object_manager_client_new_for_bus_finish (GAsyncResult *res,
828 GObject *source_object;
830 source_object = g_async_result_get_source_object (res);
831 g_assert (source_object != NULL);
833 object = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object),
836 g_object_unref (source_object);
839 return G_DBUS_OBJECT_MANAGER (object);
844 /* ---------------------------------------------------------------------------------------------------- */
847 * g_dbus_object_manager_client_get_connection:
848 * @manager: A #GDBusObjectManagerClient
850 * Gets the #GDBusConnection used by @manager.
852 * Returns: (transfer none): A #GDBusConnection object. Do not free,
853 * the object belongs to @manager.
858 g_dbus_object_manager_client_get_connection (GDBusObjectManagerClient *manager)
860 g_return_val_if_fail (G_IS_DBUS_OBJECT_MANAGER_CLIENT (manager), NULL);
861 return manager->priv->connection;
865 * g_dbus_object_manager_client_get_name:
866 * @manager: A #GDBusObjectManagerClient
868 * Gets the name that @manager is for.
870 * Returns: A unique or well-known name. Do not free, the string
871 * belongs to @manager.
876 g_dbus_object_manager_client_get_name (GDBusObjectManagerClient *manager)
878 g_return_val_if_fail (G_IS_DBUS_OBJECT_MANAGER_CLIENT (manager), NULL);
879 return manager->priv->name;
883 * g_dbus_object_manager_client_get_flags:
884 * @manager: A #GDBusObjectManagerClient
886 * Gets the flags that @manager was constructed with.
888 * Returns: Zero of more flags from the #GDBusObjectManagerClientFlags
893 GDBusObjectManagerClientFlags
894 g_dbus_object_manager_client_get_flags (GDBusObjectManagerClient *manager)
896 g_return_val_if_fail (G_IS_DBUS_OBJECT_MANAGER_CLIENT (manager), G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_NONE);
897 return manager->priv->flags;
901 * g_dbus_object_manager_client_get_name_owner:
902 * @manager: A #GDBusObjectManagerClient.
904 * The unique name that owns the name that @manager is for or %NULL if
905 * no-one currently owns that name. You can connect to the
906 * #GObject::notify signal to track changes to the
907 * #GDBusObjectManagerClient:name-owner property.
909 * Returns: The name owner or %NULL if no name owner exists. Free with
915 g_dbus_object_manager_client_get_name_owner (GDBusObjectManagerClient *manager)
917 g_return_val_if_fail (G_IS_DBUS_OBJECT_MANAGER_CLIENT (manager), NULL);
918 return g_strdup (manager->priv->name_owner);
921 /* ---------------------------------------------------------------------------------------------------- */
923 /* signal handler for all objects we manage - we dispatch signals
924 * from here to the objects
927 signal_cb (GDBusConnection *connection,
928 const gchar *sender_name,
929 const gchar *object_path,
930 const gchar *interface_name,
931 const gchar *signal_name,
932 GVariant *parameters,
935 GDBusObjectManagerClient *manager = G_DBUS_OBJECT_MANAGER_CLIENT (user_data);
936 GDBusObjectProxy *object_proxy;
937 GDBusInterface *interface;
939 object_proxy = g_hash_table_lookup (manager->priv->map_object_path_to_object_proxy, object_path);
940 if (object_proxy == NULL)
943 //g_debug ("yay, signal_cb %s %s: %s\n", signal_name, object_path, g_variant_print (parameters, TRUE));
945 if (g_strcmp0 (interface_name, "org.freedesktop.DBus.Properties") == 0)
947 if (g_strcmp0 (signal_name, "PropertiesChanged") == 0)
949 const gchar *interface_name;
950 GVariant *changed_properties;
951 const gchar **invalidated_properties;
953 g_variant_get (parameters,
957 &invalidated_properties);
959 interface = g_dbus_object_get_interface (G_DBUS_OBJECT (object_proxy), interface_name);
960 if (interface != NULL)
962 GVariantIter property_iter;
963 const gchar *property_name;
964 GVariant *property_value;
967 /* update caches... */
968 g_variant_iter_init (&property_iter, changed_properties);
969 while (g_variant_iter_next (&property_iter,
974 g_dbus_proxy_set_cached_property (G_DBUS_PROXY (interface),
977 g_variant_unref (property_value);
980 for (n = 0; invalidated_properties[n] != NULL; n++)
982 g_dbus_proxy_set_cached_property (G_DBUS_PROXY (interface),
983 invalidated_properties[n],
986 /* ... and then synthesize the signal */
987 g_signal_emit (manager,
988 signals[INTERFACE_PROXY_PROPERTIES_CHANGED_SIGNAL],
993 invalidated_properties);
994 g_signal_emit_by_name (interface,
995 "g-properties-changed",
997 invalidated_properties);
998 g_object_unref (interface);
1000 g_variant_unref (changed_properties);
1001 g_free (invalidated_properties);
1006 /* regular signal - just dispatch it */
1007 interface = g_dbus_object_get_interface (G_DBUS_OBJECT (object_proxy), interface_name);
1008 if (interface != NULL)
1010 g_signal_emit (manager,
1011 signals[INTERFACE_PROXY_SIGNAL_SIGNAL],
1018 g_signal_emit_by_name (interface,
1023 g_object_unref (interface);
1032 subscribe_signals (GDBusObjectManagerClient *manager,
1033 const gchar *name_owner)
1038 g_return_if_fail (G_IS_DBUS_OBJECT_MANAGER_CLIENT (manager));
1039 g_return_if_fail (manager->priv->signal_subscription_id == 0);
1040 g_return_if_fail (g_dbus_is_unique_name (name_owner));
1042 /* the bus daemon may not implement path_prefix so gracefully
1043 * handle this by using a fallback
1045 manager->priv->match_rule = g_strdup_printf ("type='signal',sender='%s',path_namespace='%s'",
1047 manager->priv->object_path);
1050 ret = g_dbus_connection_call_sync (manager->priv->connection,
1051 "org.freedesktop.DBus",
1052 "/org/freedeskop/DBus",
1053 "org.freedesktop.DBus",
1055 g_variant_new ("(s)",
1056 manager->priv->match_rule),
1057 NULL, /* reply_type */
1058 G_DBUS_CALL_FLAGS_NONE,
1059 -1, /* default timeout */
1060 NULL, /* TODO: Cancellable */
1064 /* yay, bus daemon supports path_namespace */
1065 g_variant_unref (ret);
1067 /* still need to ask GDBusConnection for the callbacks */
1068 manager->priv->signal_subscription_id =
1069 g_dbus_connection_signal_subscribe (manager->priv->connection,
1071 NULL, /* interface */
1073 NULL, /* path - TODO: really want wilcard support here */
1075 G_DBUS_SIGNAL_FLAGS_NONE |
1076 G_DBUS_SIGNAL_FLAGS_NO_MATCH_RULE,
1079 NULL); /* user_data_free_func */
1084 /* TODO: we could report this to the user
1085 g_warning ("Message bus daemon does not support path_namespace: %s (%s %d)",
1087 g_quark_to_string (error->domain),
1091 g_error_free (error);
1093 /* no need to call RemoveMatch when done since it didn't work */
1094 g_free (manager->priv->match_rule);
1095 manager->priv->match_rule = NULL;
1097 /* Fallback is to subscribe to *all* signals from the name owner which
1098 * is rather wasteful. It's probably not a big practical problem because
1099 * users typically want all objects that the name owner supplies.
1101 manager->priv->signal_subscription_id =
1102 g_dbus_connection_signal_subscribe (manager->priv->connection,
1104 NULL, /* interface */
1106 NULL, /* path - TODO: really want wilcard support here */
1108 G_DBUS_SIGNAL_FLAGS_NONE,
1111 NULL); /* user_data_free_func */
1116 maybe_unsubscribe_signals (GDBusObjectManagerClient *manager)
1118 g_return_if_fail (G_IS_DBUS_OBJECT_MANAGER_CLIENT (manager));
1120 if (manager->priv->signal_subscription_id > 0)
1122 g_dbus_connection_signal_unsubscribe (manager->priv->connection,
1123 manager->priv->signal_subscription_id);
1124 manager->priv->signal_subscription_id = 0;
1127 if (manager->priv->match_rule != NULL)
1129 /* Since the AddMatch call succeeded this is guaranteed to not
1130 * fail - therefore, don't bother checking the return value
1132 g_dbus_connection_call (manager->priv->connection,
1133 "org.freedesktop.DBus",
1134 "/org/freedeskop/DBus",
1135 "org.freedesktop.DBus",
1137 g_variant_new ("(s)",
1138 manager->priv->match_rule),
1139 NULL, /* reply_type */
1140 G_DBUS_CALL_FLAGS_NONE,
1141 -1, /* default timeout */
1142 NULL, /* GCancellable */
1143 NULL, /* GAsyncReadyCallback */
1144 NULL); /* user data */
1145 g_free (manager->priv->match_rule);
1146 manager->priv->match_rule = NULL;
1151 /* ---------------------------------------------------------------------------------------------------- */
1154 on_notify_g_name_owner (GObject *object,
1158 GDBusObjectManagerClient *manager = G_DBUS_OBJECT_MANAGER_CLIENT (user_data);
1159 gchar *old_name_owner;
1160 gchar *new_name_owner;
1162 old_name_owner = manager->priv->name_owner;
1163 new_name_owner = g_dbus_proxy_get_name_owner (manager->priv->control_proxy);
1164 manager->priv->name_owner = NULL;
1166 if (g_strcmp0 (old_name_owner, new_name_owner) != 0)
1171 /* do the :name-owner notify with a NULL name - this way the user knows
1172 * the ::object-proxy-removed following is because the name owner went
1175 g_object_notify (G_OBJECT (manager), "name-owner");
1177 /* remote manager changed; nuke all local proxies */
1178 proxies = g_hash_table_get_values (manager->priv->map_object_path_to_object_proxy);
1179 g_list_foreach (proxies, (GFunc) g_object_ref, NULL);
1180 g_hash_table_remove_all (manager->priv->map_object_path_to_object_proxy);
1181 for (l = proxies; l != NULL; l = l->next)
1183 GDBusObjectProxy *object_proxy = G_DBUS_OBJECT_PROXY (l->data);
1184 g_signal_emit_by_name (manager, "object-removed", object_proxy);
1186 g_list_foreach (proxies, (GFunc) g_object_unref, NULL);
1187 g_list_free (proxies);
1189 /* nuke local filter */
1190 maybe_unsubscribe_signals (manager);
1193 if (new_name_owner != NULL)
1198 //g_debug ("repopulating for %s", new_name_owner);
1200 /* TODO: do this async! */
1201 subscribe_signals (manager,
1204 value = g_dbus_proxy_call_sync (manager->priv->control_proxy,
1205 "GetManagedObjects",
1206 NULL, /* parameters */
1207 G_DBUS_CALL_FLAGS_NONE,
1213 maybe_unsubscribe_signals (manager);
1214 g_warning ("Error calling GetManagedObjects() when name owner %s for name %s came back: %s",
1216 manager->priv->name,
1218 g_error_free (error);
1222 process_get_all_result (manager, value, new_name_owner);
1223 g_variant_unref (value);
1226 /* do the :name-owner notify *AFTER* emitting ::object-proxy-added signals - this
1227 * way the user knows that the signals were emitted because the name owner came back
1229 manager->priv->name_owner = new_name_owner;
1230 g_object_notify (G_OBJECT (manager), "name-owner");
1233 g_free (old_name_owner);
1237 initable_init (GInitable *initable,
1238 GCancellable *cancellable,
1241 GDBusObjectManagerClient *manager = G_DBUS_OBJECT_MANAGER_CLIENT (initable);
1244 GDBusProxyFlags proxy_flags;
1248 if (manager->priv->bus_type != G_BUS_TYPE_NONE)
1250 g_assert (manager->priv->connection == NULL);
1251 manager->priv->connection = g_bus_get_sync (manager->priv->bus_type, cancellable, error);
1252 if (manager->priv->connection == NULL)
1256 proxy_flags = G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES;
1257 if (manager->priv->flags & G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_DO_NOT_AUTO_START)
1258 proxy_flags |= G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START;;
1260 manager->priv->control_proxy = g_dbus_proxy_new_sync (manager->priv->connection,
1262 NULL, /* GDBusInterfaceInfo* */
1263 manager->priv->name,
1264 manager->priv->object_path,
1265 "org.freedesktop.DBus.ObjectManager",
1268 if (manager->priv->control_proxy == NULL)
1271 g_signal_connect (G_OBJECT (manager->priv->control_proxy),
1272 "notify::g-name-owner",
1273 G_CALLBACK (on_notify_g_name_owner),
1276 manager->priv->name_owner = g_dbus_proxy_get_name_owner (manager->priv->control_proxy);
1277 if (manager->priv->name_owner == NULL)
1279 /* it's perfectly fine if there's no name owner.. we're just going to
1280 * wait until one is ready
1285 /* yay, we have a name owner */
1286 g_signal_connect (manager->priv->control_proxy,
1288 G_CALLBACK (on_control_proxy_g_signal),
1290 subscribe_signals (manager,
1291 manager->priv->name_owner);
1292 value = g_dbus_proxy_call_sync (manager->priv->control_proxy,
1293 "GetManagedObjects",
1294 NULL, /* parameters */
1295 G_DBUS_CALL_FLAGS_NONE,
1301 maybe_unsubscribe_signals (manager);
1302 g_warn_if_fail (g_signal_handlers_disconnect_by_func (manager->priv->control_proxy,
1303 on_control_proxy_g_signal,
1305 g_object_unref (manager->priv->control_proxy);
1306 manager->priv->control_proxy = NULL;
1310 process_get_all_result (manager, value, manager->priv->name_owner);
1311 g_variant_unref (value);
1321 initable_iface_init (GInitableIface *initable_iface)
1323 initable_iface->init = initable_init;
1327 async_initable_iface_init (GAsyncInitableIface *async_initable_iface)
1329 /* for now, just use default: run GInitable code in thread */
1332 /* ---------------------------------------------------------------------------------------------------- */
1335 add_interfaces (GDBusObjectManagerClient *manager,
1336 const gchar *object_path,
1337 GVariant *ifaces_and_properties,
1338 const gchar *name_owner)
1340 GDBusObjectProxy *op;
1343 const gchar *interface_name;
1344 GVariant *properties;
1346 g_return_if_fail (g_dbus_is_unique_name (name_owner));
1349 op = g_hash_table_lookup (manager->priv->map_object_path_to_object_proxy, object_path);
1352 op = _g_dbus_object_proxy_new (manager->priv->connection, object_path);
1356 g_variant_iter_init (&iter, ifaces_and_properties);
1357 while (g_variant_iter_next (&iter,
1362 GDBusProxy *interface_proxy;
1364 GType interface_proxy_type;
1366 if (manager->priv->get_proxy_type_func != NULL)
1368 interface_proxy_type = manager->priv->get_proxy_type_func (manager,
1371 manager->priv->get_proxy_type_user_data);
1372 g_warn_if_fail (g_type_is_a (interface_proxy_type, G_TYPE_DBUS_PROXY));
1376 interface_proxy_type = G_TYPE_DBUS_PROXY;
1379 /* this is fine - there is no blocking IO because we pass DO_NOT_LOAD_PROPERTIES and
1380 * DO_NOT_CONNECT_SIGNALS and use a unique name
1383 interface_proxy = g_initable_new (interface_proxy_type,
1384 NULL, /* GCancellable */
1386 "g-connection", manager->priv->connection,
1387 "g-flags", G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES |
1388 G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS,
1389 "g-name", name_owner,
1390 "g-object-path", object_path,
1391 "g-interface-name", interface_name,
1393 if (interface_proxy == NULL)
1395 g_warning ("%s: Error constructing proxy for path %s and interface %s: %s",
1400 g_error_free (error);
1404 GVariantIter property_iter;
1405 const gchar *property_name;
1406 GVariant *property_value;
1408 /* associate the interface proxy with the object */
1409 g_dbus_interface_set_object (G_DBUS_INTERFACE (interface_proxy),
1410 G_DBUS_OBJECT (op));
1412 g_variant_iter_init (&property_iter, properties);
1413 while (g_variant_iter_next (&property_iter,
1418 g_dbus_proxy_set_cached_property (interface_proxy,
1421 g_variant_unref (property_value);
1424 _g_dbus_object_proxy_add_interface (op, interface_proxy);
1426 g_signal_emit_by_name (manager, "interface-added", op, interface_proxy);
1427 g_object_unref (interface_proxy);
1429 g_variant_unref (properties);
1434 g_hash_table_insert (manager->priv->map_object_path_to_object_proxy,
1435 g_strdup (object_path),
1437 g_signal_emit_by_name (manager, "object-added", op);
1442 remove_interfaces (GDBusObjectManagerClient *manager,
1443 const gchar *object_path,
1444 const gchar *const *interface_names)
1446 GDBusObjectProxy *op;
1449 guint num_interfaces;
1450 guint num_interfaces_to_remove;
1452 op = g_hash_table_lookup (manager->priv->map_object_path_to_object_proxy, object_path);
1455 g_warning ("%s: Processing InterfaceRemoved signal for path %s but no object proxy exists",
1461 interfaces = g_dbus_object_get_interfaces (G_DBUS_OBJECT (op));
1462 num_interfaces = g_list_length (interfaces);
1463 g_list_foreach (interfaces, (GFunc) g_object_unref, NULL);
1464 g_list_free (interfaces);
1466 num_interfaces_to_remove = g_strv_length ((gchar **) interface_names);
1468 /* see if we are going to completety remove the object */
1469 if (num_interfaces_to_remove == num_interfaces)
1472 g_warn_if_fail (g_hash_table_remove (manager->priv->map_object_path_to_object_proxy, object_path));
1473 g_signal_emit_by_name (manager, "object-removed", op);
1474 g_object_unref (op);
1478 for (n = 0; interface_names != NULL && interface_names[n] != NULL; n++)
1480 GDBusInterface *interface;
1481 interface = g_dbus_object_get_interface (G_DBUS_OBJECT (op), interface_names[n]);
1482 _g_dbus_object_proxy_remove_interface (op, interface_names[n]);
1483 if (interface != NULL)
1485 g_signal_emit_by_name (manager, "interface-removed", op, interface);
1486 g_object_unref (interface);
1495 process_get_all_result (GDBusObjectManagerClient *manager,
1497 const gchar *name_owner)
1500 const gchar *object_path;
1501 GVariant *ifaces_and_properties;
1504 g_return_if_fail (g_dbus_is_unique_name (name_owner));
1506 arg0 = g_variant_get_child_value (value, 0);
1507 g_variant_iter_init (&iter, arg0);
1508 while (g_variant_iter_next (&iter,
1511 &ifaces_and_properties))
1513 add_interfaces (manager, object_path, ifaces_and_properties, name_owner);
1514 g_variant_unref (ifaces_and_properties);
1516 g_variant_unref (arg0);
1520 on_control_proxy_g_signal (GDBusProxy *proxy,
1521 const gchar *sender_name,
1522 const gchar *signal_name,
1523 GVariant *parameters,
1526 GDBusObjectManagerClient *manager = G_DBUS_OBJECT_MANAGER_CLIENT (user_data);
1527 const gchar *object_path;
1529 //g_debug ("yay, g_signal %s: %s\n", signal_name, g_variant_print (parameters, TRUE));
1531 if (g_strcmp0 (signal_name, "InterfacesAdded") == 0)
1533 GVariant *ifaces_and_properties;
1534 g_variant_get (parameters,
1537 &ifaces_and_properties);
1538 add_interfaces (manager, object_path, ifaces_and_properties, manager->priv->name_owner);
1539 g_variant_unref (ifaces_and_properties);
1541 else if (g_strcmp0 (signal_name, "InterfacesRemoved") == 0)
1543 const gchar **ifaces;
1544 g_variant_get (parameters,
1548 remove_interfaces (manager, object_path, ifaces);
1553 /* ---------------------------------------------------------------------------------------------------- */
1555 static const gchar *
1556 g_dbus_object_manager_client_get_object_path (GDBusObjectManager *_manager)
1558 GDBusObjectManagerClient *manager = G_DBUS_OBJECT_MANAGER_CLIENT (_manager);
1559 return manager->priv->object_path;
1562 static GDBusObject *
1563 g_dbus_object_manager_client_get_object (GDBusObjectManager *_manager,
1564 const gchar *object_path)
1566 GDBusObjectManagerClient *manager = G_DBUS_OBJECT_MANAGER_CLIENT (_manager);
1569 ret = g_hash_table_lookup (manager->priv->map_object_path_to_object_proxy, object_path);
1575 static GDBusInterface *
1576 g_dbus_object_manager_client_get_interface (GDBusObjectManager *_manager,
1577 const gchar *object_path,
1578 const gchar *interface_name)
1580 GDBusInterface *ret;
1581 GDBusObject *object;
1585 object = g_dbus_object_manager_get_object (_manager, object_path);
1589 ret = g_dbus_object_get_interface (object, interface_name);
1590 g_object_unref (object);
1597 g_dbus_object_manager_client_get_objects (GDBusObjectManager *_manager)
1599 GDBusObjectManagerClient *manager = G_DBUS_OBJECT_MANAGER_CLIENT (_manager);
1602 g_return_val_if_fail (G_IS_DBUS_OBJECT_MANAGER_CLIENT (manager), NULL);
1604 ret = g_hash_table_get_values (manager->priv->map_object_path_to_object_proxy);
1605 g_list_foreach (ret, (GFunc) g_object_ref, NULL);
1611 dbus_object_manager_interface_init (GDBusObjectManagerIface *iface)
1613 iface->get_object_path = g_dbus_object_manager_client_get_object_path;
1614 iface->get_objects = g_dbus_object_manager_client_get_objects;
1615 iface->get_object = g_dbus_object_manager_client_get_object;
1616 iface->get_interface = g_dbus_object_manager_client_get_interface;
1619 /* ---------------------------------------------------------------------------------------------------- */