summaryrefslogtreecommitdiff
path: root/gio/gdbusobjectproxy.c
diff options
context:
space:
mode:
Diffstat (limited to 'gio/gdbusobjectproxy.c')
-rw-r--r--gio/gdbusobjectproxy.c315
1 files changed, 315 insertions, 0 deletions
diff --git a/gio/gdbusobjectproxy.c b/gio/gdbusobjectproxy.c
new file mode 100644
index 000000000..3c26495db
--- /dev/null
+++ b/gio/gdbusobjectproxy.c
@@ -0,0 +1,315 @@
+/* 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 <davidz@redhat.com>
+ */
+
+#include "config.h"
+
+#include "gdbusobject.h"
+#include "gdbusobjectproxy.h"
+#include "gdbusconnection.h"
+#include "gdbusprivate.h"
+#include "gdbusutils.h"
+#include "gdbusproxy.h"
+
+#include "glibintl.h"
+
+/**
+ * SECTION:gdbusobjectproxy
+ * @short_description: Client-side D-Bus object
+ * @include: gio/gio.h
+ *
+ * A #GDBusObjectProxy is an object used to represent a remote object
+ * with one or more D-Bus interfaces. You cannot instantiate a
+ * #GDBusObjectProxy yourself - you need to use a
+ * #GDBusObjectManagerClient to get one.
+ */
+
+struct _GDBusObjectProxyPrivate
+{
+ GHashTable *map_name_to_iface;
+ gchar *object_path;
+ GDBusConnection *connection;
+};
+
+enum
+{
+ PROP_0,
+ PROP_OBJECT_PATH,
+ PROP_CONNECTION
+};
+
+static void dbus_object_interface_init (GDBusObjectIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GDBusObjectProxy, g_dbus_object_proxy, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (G_TYPE_DBUS_OBJECT, dbus_object_interface_init));
+
+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, proxy->priv->object_path);
+ 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));
+
+ 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);
+}
+
+static const gchar *
+g_dbus_object_proxy_get_object_path (GDBusObject *object)
+{
+ GDBusObjectProxy *proxy = G_DBUS_OBJECT_PROXY (object);
+ 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;
+}
+
+static GDBusInterface *
+g_dbus_object_proxy_get_interface (GDBusObject *object,
+ const gchar *interface_name)
+{
+ GDBusObjectProxy *proxy = G_DBUS_OBJECT_PROXY (object);
+ 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 (GDBusInterface *) ret; /* TODO: proper cast */
+}
+
+static GList *
+g_dbus_object_proxy_get_interfaces (GDBusObject *object)
+{
+ GDBusObjectProxy *proxy = G_DBUS_OBJECT_PROXY (object);
+ 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)
+{
+ 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_by_name (proxy, "interface-added", 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_by_name (proxy, "interface-removed", interface_proxy);
+ g_object_unref (interface_proxy);
+ }
+}
+
+static gpointer
+g_dbus_object_proxy_lookup_with_typecheck (GDBusObject *object,
+ const gchar *interface_name,
+ GType type)
+{
+ GDBusObjectProxy *proxy = G_DBUS_OBJECT_PROXY (object);
+ 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_warn_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (ret, type));
+ g_object_ref (ret);
+ }
+ return ret;
+}
+
+static gpointer
+g_dbus_object_proxy_peek_with_typecheck (GDBusObject *object,
+ const gchar *interface_name,
+ GType type)
+{
+ GDBusProxy *ret;
+ ret = g_dbus_object_proxy_lookup_with_typecheck (object, interface_name, type);
+ if (ret != NULL)
+ g_object_unref (ret);
+ return ret;
+}
+
+static void
+dbus_object_interface_init (GDBusObjectIface *iface)
+{
+ iface->get_object_path = g_dbus_object_proxy_get_object_path;
+ iface->get_interfaces = g_dbus_object_proxy_get_interfaces;
+ iface->get_interface = g_dbus_object_proxy_get_interface;
+ iface->peek_with_typecheck = g_dbus_object_proxy_peek_with_typecheck;
+ iface->lookup_with_typecheck = g_dbus_object_proxy_lookup_with_typecheck;
+}