/* GDBus - GLib D-Bus Library * * Copyright (C) 2008-2010 Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General * Public License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. * * Author: David Zeuthen */ #include "config.h" #include "gdbusobjectproxy.h" /** * SECTION:gdbusobjectproxy * @short_description: A group of D-Bus interface proxies * @include: gio/gio.h * * A #GDBusObjectProxy is an object used client-side to represent a * remote object with one or more D-Bus interfaces. You cannot * instantiate a #GDBusObjectProxy yourself - you need to use a * #GDBusProxyManager. */ struct _GDBusObjectProxyPrivate { GHashTable *map_name_to_iface; gchar *object_path; GDBusConnection *connection; }; enum { PROP_0, PROP_OBJECT_PATH, PROP_CONNECTION }; enum { INTERFACE_PROXY_ADDED_SIGNAL, INTERFACE_PROXY_REMOVED_SIGNAL, LAST_SIGNAL, }; static guint signals[LAST_SIGNAL] = { 0 }; G_DEFINE_TYPE (GDBusObjectProxy, g_dbus_object_proxy, G_TYPE_OBJECT); static void g_dbus_object_proxy_finalize (GObject *object) { GDBusObjectProxy *proxy = G_DBUS_OBJECT_PROXY (object); g_hash_table_unref (proxy->priv->map_name_to_iface); if (G_OBJECT_CLASS (g_dbus_object_proxy_parent_class)->finalize != NULL) G_OBJECT_CLASS (g_dbus_object_proxy_parent_class)->finalize (object); } static void g_dbus_object_proxy_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { GDBusObjectProxy *proxy = G_DBUS_OBJECT_PROXY (object); switch (prop_id) { case PROP_OBJECT_PATH: g_value_set_string (value, g_dbus_object_proxy_get_object_path (proxy)); break; case PROP_CONNECTION: g_value_set_object (value, g_dbus_object_proxy_get_connection (proxy)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (_object, prop_id, pspec); break; } } static void g_dbus_object_proxy_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { switch (prop_id) { default: G_OBJECT_WARN_INVALID_PROPERTY_ID (_object, prop_id, pspec); break; } } static void g_dbus_object_proxy_class_init (GDBusObjectProxyClass *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); gobject_class->finalize = g_dbus_object_proxy_finalize; gobject_class->set_property = g_dbus_object_proxy_set_property; gobject_class->get_property = g_dbus_object_proxy_get_property; /** * GDBusObjectProxy:object-path: * * The object path of the proxy. */ g_object_class_install_property (gobject_class, PROP_OBJECT_PATH, g_param_spec_string ("object-path", "Object Path", "The object path of the proxy", NULL, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); /** * GDBusObjectProxy:connection: * * The connection of the proxy. */ g_object_class_install_property (gobject_class, PROP_CONNECTION, g_param_spec_string ("connection", "Connection", "The connection of the proxy", NULL, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); /** * GDBusObjectProxy::interface-proxy-added: * @proxy: The #GDBusObjectProxy emitting the signal. * @interface_proxy: The #GDBusProxy that was added. * * Emitted when @interface_proxy is added to @proxy. * * This signal is emitted in the * thread-default main loop * that the #GDBusProxyManager owning @proxy was constructed in. */ signals[INTERFACE_PROXY_ADDED_SIGNAL] = g_signal_new ("interface-proxy-added", G_TYPE_DBUS_OBJECT_PROXY, G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GDBusObjectProxyClass, interface_proxy_added), NULL, NULL, g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, G_TYPE_DBUS_PROXY); /** * GDBusObjectProxy::interface-proxy-removed: * @proxy: The #GDBusObjectProxy emitting the signal. * @interface_proxy: The #GDBusProxy that was removed. * * Emitted when @interface_proxy is removed from @proxy. * * This signal is emitted in the * thread-default main loop * that the #GDBusProxyManager owning @proxy was constructed in. */ signals[INTERFACE_PROXY_REMOVED_SIGNAL] = g_signal_new ("interface-proxy-removed", G_TYPE_DBUS_OBJECT_PROXY, G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GDBusObjectProxyClass, interface_proxy_removed), NULL, NULL, g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, G_TYPE_DBUS_PROXY); g_type_class_add_private (klass, sizeof (GDBusObjectProxyPrivate)); } static void g_dbus_object_proxy_init (GDBusObjectProxy *proxy) { proxy->priv = G_TYPE_INSTANCE_GET_PRIVATE (proxy, G_TYPE_DBUS_OBJECT_PROXY, GDBusObjectProxyPrivate); proxy->priv->map_name_to_iface = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_object_unref); } /** * g_dbus_object_proxy_get_object_path: * @proxy: A #GDBusObjectProxy. * * Gets the object path that @proxy is for. * * Returns: An object path. Do not free, the string is owned by @proxy. */ const gchar * g_dbus_object_proxy_get_object_path (GDBusObjectProxy *proxy) { g_return_val_if_fail (G_IS_DBUS_OBJECT_PROXY (proxy), NULL); return proxy->priv->object_path; } /** * g_dbus_object_proxy_get_connection: * @proxy: A #GDBusObjectProxy. * * Gets the connection that @proxy is for. * * Returns: A #GDBusConnection. Do not free, the object is owned by @proxy. */ GDBusConnection * g_dbus_object_proxy_get_connection (GDBusObjectProxy *proxy) { g_return_val_if_fail (G_IS_DBUS_OBJECT_PROXY (proxy), NULL); return proxy->priv->connection; } /** * g_dbus_object_proxy_lookup: * @proxy: A #GDBusObjectProxy. * @interface_name: A D-Bus interface name. * * Looks up the interface proxy (A #GDBusProxy object) on @proxy for * @interface_name. If no such interface exists, %NULL is returned. * * The type of returned interface proxy may be a subtype of * #GDBusProxy - it is determined by the #GDBusProxyTypeFunc that the * #GDBusProxyManager object for @proxy was constructed with. * * Returns: A #GDBusProxy or %NULL if not found. Free with * g_object_unref(). */ GDBusProxy * g_dbus_object_proxy_lookup (GDBusObjectProxy *proxy, const gchar *interface_name) { GDBusProxy *ret; g_return_val_if_fail (G_IS_DBUS_OBJECT_PROXY (proxy), NULL); g_return_val_if_fail (g_dbus_is_interface_name (interface_name), NULL); ret = g_hash_table_lookup (proxy->priv->map_name_to_iface, interface_name); if (ret != NULL) g_object_ref (ret); return ret; } /** * g_dbus_object_proxy_get_all: * @proxy: A #GDBusObjectProxy. * * Gets all interface proxies (#GDBusProxy objects) that are associated with #proxy, if any. * * Returns: A list of #GDBusProxy objects. The returned list should be * freed with g_list_free() after each element has been freed with * g_object_unref(). */ GList * g_dbus_object_proxy_get_all (GDBusObjectProxy *proxy) { GList *ret; GHashTableIter iter; GDBusProxy *interface_proxy; g_return_val_if_fail (G_IS_DBUS_OBJECT_PROXY (proxy), NULL); ret = NULL; g_hash_table_iter_init (&iter, proxy->priv->map_name_to_iface); while (g_hash_table_iter_next (&iter, NULL, (gpointer) &interface_proxy)) ret = g_list_prepend (ret, g_object_ref (interface_proxy)); return ret; } /* ---------------------------------------------------------------------------------------------------- */ GDBusObjectProxy *_g_dbus_object_proxy_new (GDBusConnection *connection, const gchar *object_path); void _g_dbus_object_proxy_add_interface (GDBusObjectProxy *proxy, GDBusProxy *interface_proxy); void _g_dbus_object_proxy_remove_interface (GDBusObjectProxy *proxy, const gchar *interface_name); GDBusObjectProxy * _g_dbus_object_proxy_new (GDBusConnection *connection, const gchar *object_path) { GDBusObjectProxy *proxy; g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL); g_return_val_if_fail (g_variant_is_object_path (object_path), NULL); proxy = G_DBUS_OBJECT_PROXY (g_object_new (G_TYPE_DBUS_OBJECT_PROXY, NULL)); proxy->priv->object_path = g_strdup (object_path); proxy->priv->connection = g_object_ref (connection); return proxy; } void _g_dbus_object_proxy_add_interface (GDBusObjectProxy *proxy, GDBusProxy *interface_proxy) { const gchar *interface_name; g_return_if_fail (G_IS_DBUS_OBJECT_PROXY (proxy)); g_return_if_fail (G_IS_DBUS_PROXY (interface_proxy)); interface_name = g_dbus_proxy_get_interface_name (interface_proxy); _g_dbus_object_proxy_remove_interface (proxy, interface_name); g_hash_table_insert (proxy->priv->map_name_to_iface, g_strdup (interface_name), g_object_ref (interface_proxy)); g_signal_emit (proxy, signals[INTERFACE_PROXY_ADDED_SIGNAL], 0, interface_proxy); } void _g_dbus_object_proxy_remove_interface (GDBusObjectProxy *proxy, const gchar *interface_name) { GDBusProxy *interface_proxy; g_return_if_fail (G_IS_DBUS_OBJECT_PROXY (proxy)); g_return_if_fail (g_dbus_is_interface_name (interface_name)); interface_proxy = g_hash_table_lookup (proxy->priv->map_name_to_iface, interface_name); if (interface_proxy != NULL) { g_object_ref (interface_proxy); g_warn_if_fail (g_hash_table_remove (proxy->priv->map_name_to_iface, interface_name)); g_signal_emit (proxy, signals[INTERFACE_PROXY_REMOVED_SIGNAL], 0, interface_proxy); g_object_unref (interface_proxy); } }