Start merging gdbus-codegen code

Signed-off-by: David Zeuthen <davidz@redhat.com>
This commit is contained in:
David Zeuthen 2011-04-08 15:14:47 -04:00
parent 0729260141
commit 94b9071344
26 changed files with 5774 additions and 18 deletions

View File

@ -82,6 +82,14 @@ gdbus_headers = \
gdbusintrospection.h \
gdbusmethodinvocation.h \
gdbusserver.h \
gdbusinterface.h \
gdbusinterfacestub.h \
gdbusobject.h \
gdbusobjectstub.h \
gdbusobjectproxy.h \
gdbusobjectmanager.h \
gdbusobjectmanagerclient.h \
gdbusobjectmanagerserver.h \
$(NULL)
gdbus_sources = \
@ -103,6 +111,14 @@ gdbus_sources = \
gdbusintrospection.h gdbusintrospection.c \
gdbusmethodinvocation.h gdbusmethodinvocation.c \
gdbusserver.h gdbusserver.c \
gdbusinterface.h gdbusinterface.c \
gdbusinterfacestub.h gdbusinterfacestub.c \
gdbusobject.h gdbusobject.c \
gdbusobjectstub.h gdbusobjectstub.c \
gdbusobjectproxy.h gdbusobjectproxy.c \
gdbusobjectmanager.h gdbusobjectmanager.c \
gdbusobjectmanagerclient.h gdbusobjectmanagerclient.c \
gdbusobjectmanagerserver.h gdbusobjectmanagerserver.c \
$(NULL)
settings_headers = \

View File

@ -27,6 +27,7 @@
#include "gcredentials.h"
#include "gioenumtypes.h"
#include "giostream.h"
#include "gdbusprivate.h"
#include "glibintl.h"
@ -130,22 +131,6 @@ g_dbus_auth_observer_authorize_authenticated_peer_real (GDBusAuthObserver *obse
return TRUE;
}
gboolean
_g_signal_accumulator_false_handled (GSignalInvocationHint *ihint,
GValue *return_accu,
const GValue *handler_return,
gpointer dummy)
{
gboolean continue_emission;
gboolean signal_handled;
signal_handled = g_value_get_boolean (handler_return);
g_value_set_boolean (return_accu, signal_handled);
continue_emission = signal_handled;
return continue_emission;
}
static void
g_dbus_auth_observer_class_init (GDBusAuthObserverClass *klass)
{

410
gio/gdbusinterface.c Normal file
View File

@ -0,0 +1,410 @@
/* 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 "gdbusinterface.h"
#include "gio-marshal.h"
#include "glibintl.h"
/**
* SECTION:gdbusinterface
* @short_description: Base type for D-Bus interfaces
* @include: gio/gio.h
*
* The #GDBusInterface type is the base type for D-Bus interfaces both
* on the service side (see #GDBusInterfaceStub) and client side (see
* #GDBusProxy).
*/
typedef GDBusInterfaceIface GDBusInterfaceInterface;
G_DEFINE_INTERFACE (GDBusInterface, g_dbus_interface, G_TYPE_OBJECT)
static void
g_dbus_interface_default_init (GDBusInterfaceIface *iface)
{
}
/* ---------------------------------------------------------------------------------------------------- */
/**
* g_dbus_interface_get_info:
* @interface: An exported D-Bus interface.
*
* Gets D-Bus introspection information for the D-Bus interface
* implemented by @interface.
*
* Returns: (transfer none): A #GDBusInterfaceInfo. Do not free.
*/
GDBusInterfaceInfo *
g_dbus_interface_get_info (GDBusInterface *interface)
{
g_return_val_if_fail (G_IS_DBUS_INTERFACE (interface), NULL);
return G_DBUS_INTERFACE_GET_IFACE (interface)->get_info (interface);
}
/**
* g_dbus_interface_get_object:
* @interface: An exported D-Bus interface.
*
* Gets the #GDBusObject that @interface belongs to, if any.
*
* Returns: (transfer none): A #GDBusObject or %NULL. The returned
* reference belongs to @interface and should not be freed.
*/
GDBusObject *
g_dbus_interface_get_object (GDBusInterface *interface)
{
g_return_val_if_fail (G_IS_DBUS_INTERFACE (interface), NULL);
return G_DBUS_INTERFACE_GET_IFACE (interface)->get_object (interface);
}
/**
* g_dbus_interface_set_object:
* @interface: An exported D-Bus interface.
* @object: A #GDBusObject or %NULL.
*
* Sets the #GDBusObject for @interface to @object.
*
* Note that @interface will hold a weak reference to @object.
*/
void
g_dbus_interface_set_object (GDBusInterface *interface,
GDBusObject *object)
{
g_return_if_fail (G_IS_DBUS_INTERFACE (interface));
g_return_if_fail (object == NULL || G_IS_DBUS_OBJECT (object));
G_DBUS_INTERFACE_GET_IFACE (interface)->set_object (interface, object);
}
/* Keep it here for now. TODO: move */
#include <string.h>
/**
* g_dbus_gvariant_to_gvalue:
* @value: A #GVariant.
* @out_gvalue: Return location for the #GValue.
*
* Convert a #GVariant to a #GValue. If @value is floating, it is consumed.
*
* Note that the passed @out_gvalue does not have to have a #GType set.
*
* Returns: %TRUE if the conversion succeeded, %FALSE otherwise.
*/
gboolean
g_dbus_gvariant_to_gvalue (GVariant *value,
GValue *out_gvalue)
{
gboolean ret;
const GVariantType *type;
gchar **array;
g_return_val_if_fail (value != NULL, FALSE);
g_return_val_if_fail (out_gvalue != NULL, FALSE);
ret = FALSE;
memset (out_gvalue, '\0', sizeof (GValue));
switch (g_variant_classify (value))
{
case G_VARIANT_CLASS_BOOLEAN:
g_value_init (out_gvalue, G_TYPE_BOOLEAN);
g_value_set_boolean (out_gvalue, g_variant_get_boolean (value));
break;
case G_VARIANT_CLASS_BYTE:
g_value_init (out_gvalue, G_TYPE_UCHAR);
g_value_set_uchar (out_gvalue, g_variant_get_byte (value));
break;
case G_VARIANT_CLASS_INT16:
g_value_init (out_gvalue, G_TYPE_INT);
g_value_set_int (out_gvalue, g_variant_get_int16 (value));
break;
case G_VARIANT_CLASS_UINT16:
g_value_init (out_gvalue, G_TYPE_UINT);
g_value_set_uint (out_gvalue, g_variant_get_uint16 (value));
break;
case G_VARIANT_CLASS_INT32:
g_value_init (out_gvalue, G_TYPE_INT);
g_value_set_int (out_gvalue, g_variant_get_int32 (value));
break;
case G_VARIANT_CLASS_UINT32:
g_value_init (out_gvalue, G_TYPE_UINT);
g_value_set_uint (out_gvalue, g_variant_get_uint32 (value));
break;
case G_VARIANT_CLASS_INT64:
g_value_init (out_gvalue, G_TYPE_INT64);
g_value_set_int64 (out_gvalue, g_variant_get_int64 (value));
break;
case G_VARIANT_CLASS_UINT64:
g_value_init (out_gvalue, G_TYPE_UINT64);
g_value_set_uint64 (out_gvalue, g_variant_get_uint64 (value));
break;
case G_VARIANT_CLASS_HANDLE:
g_value_init (out_gvalue, G_TYPE_INT);
g_value_set_int (out_gvalue, g_variant_get_int32 (value));
break;
case G_VARIANT_CLASS_DOUBLE:
g_value_init (out_gvalue, G_TYPE_DOUBLE);
g_value_set_double (out_gvalue, g_variant_get_double (value));
break;
case G_VARIANT_CLASS_STRING:
g_value_init (out_gvalue, G_TYPE_STRING);
g_value_set_string (out_gvalue, g_variant_get_string (value, NULL));
break;
case G_VARIANT_CLASS_OBJECT_PATH:
g_value_init (out_gvalue, G_TYPE_STRING);
g_value_set_string (out_gvalue, g_variant_get_string (value, NULL));
break;
case G_VARIANT_CLASS_SIGNATURE:
g_value_init (out_gvalue, G_TYPE_STRING);
g_value_set_string (out_gvalue, g_variant_get_string (value, NULL));
break;
case G_VARIANT_CLASS_ARRAY:
type = g_variant_get_type (value);
switch (g_variant_type_peek_string (type)[1])
{
case G_VARIANT_CLASS_BYTE:
g_value_init (out_gvalue, G_TYPE_STRING);
g_value_set_string (out_gvalue, g_variant_get_bytestring (value));
break;
case G_VARIANT_CLASS_STRING:
g_value_init (out_gvalue, G_TYPE_STRV);
array = g_variant_dup_strv (value, NULL);
g_value_take_boxed (out_gvalue, array);
break;
case G_VARIANT_CLASS_ARRAY:
switch (g_variant_type_peek_string (type)[2])
{
case G_VARIANT_CLASS_BYTE:
g_value_init (out_gvalue, G_TYPE_STRV);
array = g_variant_dup_bytestring_array (value, NULL);
g_value_take_boxed (out_gvalue, array);
break;
default:
g_value_init (out_gvalue, G_TYPE_VARIANT);
g_value_set_variant (out_gvalue, value);
break;
}
break;
default:
g_value_init (out_gvalue, G_TYPE_VARIANT);
g_value_set_variant (out_gvalue, value);
break;
}
break;
case G_VARIANT_CLASS_VARIANT:
case G_VARIANT_CLASS_MAYBE:
case G_VARIANT_CLASS_TUPLE:
case G_VARIANT_CLASS_DICT_ENTRY:
g_value_init (out_gvalue, G_TYPE_VARIANT);
g_value_set_variant (out_gvalue, value);
break;
}
ret = TRUE;
return ret;
}
/**
* g_dbus_gvalue_to_gvariant:
* @gvalue: A #GValue to convert to a #GVariant.
* @expected_type: The #GVariantType to create.
*
* Convert a #GValue to #GVariant.
*
* Returns: A #GVariant (never floating) holding the data from @gvalue
* or %NULL in case of error. Free with g_variant_unref().
*/
GVariant *
g_dbus_gvalue_to_gvariant (const GValue *gvalue,
const GVariantType *expected_type)
{
GVariant *ret;
const gchar *s;
const gchar * const *as;
const gchar *empty_strv[1] = {NULL};
g_return_val_if_fail (gvalue != NULL, NULL);
g_return_val_if_fail (expected_type != NULL, NULL);
ret = NULL;
/* The expected type could easily be e.g. "s" with the GValue holding a string.
* because of the UseGVariant annotation
*/
if (G_VALUE_TYPE (gvalue) == G_TYPE_VARIANT)
{
ret = g_value_dup_variant (gvalue);
}
else
{
switch (g_variant_type_peek_string (expected_type)[0])
{
case G_VARIANT_CLASS_BOOLEAN:
ret = g_variant_ref_sink (g_variant_new_boolean (g_value_get_boolean (gvalue)));
break;
case G_VARIANT_CLASS_BYTE:
ret = g_variant_ref_sink (g_variant_new_byte (g_value_get_uchar (gvalue)));
break;
case G_VARIANT_CLASS_INT16:
ret = g_variant_ref_sink (g_variant_new_int16 (g_value_get_int (gvalue)));
break;
case G_VARIANT_CLASS_UINT16:
ret = g_variant_ref_sink (g_variant_new_uint16 (g_value_get_uint (gvalue)));
break;
case G_VARIANT_CLASS_INT32:
ret = g_variant_ref_sink (g_variant_new_int32 (g_value_get_int (gvalue)));
break;
case G_VARIANT_CLASS_UINT32:
ret = g_variant_ref_sink (g_variant_new_uint32 (g_value_get_uint (gvalue)));
break;
case G_VARIANT_CLASS_INT64:
ret = g_variant_ref_sink (g_variant_new_int64 (g_value_get_int64 (gvalue)));
break;
case G_VARIANT_CLASS_UINT64:
ret = g_variant_ref_sink (g_variant_new_uint64 (g_value_get_uint64 (gvalue)));
break;
case G_VARIANT_CLASS_HANDLE:
ret = g_variant_ref_sink (g_variant_new_handle (g_value_get_int (gvalue)));
break;
case G_VARIANT_CLASS_DOUBLE:
ret = g_variant_ref_sink (g_variant_new_double (g_value_get_double (gvalue)));
break;
case G_VARIANT_CLASS_STRING:
s = g_value_get_string (gvalue);
if (s == NULL)
s = "";
ret = g_variant_ref_sink (g_variant_new_string (s));
break;
case G_VARIANT_CLASS_OBJECT_PATH:
s = g_value_get_string (gvalue);
if (s == NULL)
s = "/";
ret = g_variant_ref_sink (g_variant_new_object_path (s));
break;
case G_VARIANT_CLASS_SIGNATURE:
s = g_value_get_string (gvalue);
if (s == NULL)
s = "";
ret = g_variant_ref_sink (g_variant_new_signature (s));
break;
case G_VARIANT_CLASS_ARRAY:
switch (g_variant_type_peek_string (expected_type)[1])
{
case G_VARIANT_CLASS_BYTE:
s = g_value_get_string (gvalue);
if (s == NULL)
s = "";
ret = g_variant_ref_sink (g_variant_new_bytestring (s));
break;
case G_VARIANT_CLASS_STRING:
as = g_value_get_boxed (gvalue);
if (as == NULL)
as = empty_strv;
ret = g_variant_ref_sink (g_variant_new_strv (as, -1));
break;
case G_VARIANT_CLASS_ARRAY:
switch (g_variant_type_peek_string (expected_type)[2])
{
case G_VARIANT_CLASS_BYTE:
as = g_value_get_boxed (gvalue);
if (as == NULL)
as = empty_strv;
ret = g_variant_ref_sink (g_variant_new_bytestring_array (as, -1));
break;
default:
ret = g_value_dup_variant (gvalue);
break;
}
break;
default:
ret = g_value_dup_variant (gvalue);
break;
}
break;
default:
case G_VARIANT_CLASS_VARIANT:
case G_VARIANT_CLASS_MAYBE:
case G_VARIANT_CLASS_TUPLE:
case G_VARIANT_CLASS_DICT_ENTRY:
ret = g_value_dup_variant (gvalue);
break;
}
}
/* Could be that the GValue is holding a NULL GVariant - in that case,
* we return an "empty" GVariant instead of a NULL GVariant
*/
if (ret == NULL)
{
GVariant *untrusted_empty;
untrusted_empty = g_variant_new_from_data (expected_type, NULL, 0, FALSE, NULL, NULL);
ret = g_variant_ref_sink (g_variant_get_normal_form (untrusted_empty));
g_variant_unref (untrusted_empty);
}
g_assert (!g_variant_is_floating (ret));
return ret;
}

79
gio/gdbusinterface.h Normal file
View File

@ -0,0 +1,79 @@
/* 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>
*/
#ifndef __G_DBUS_INTERFACE_H__
#define __G_DBUS_INTERFACE_H__
#include <gio/giotypes.h>
G_BEGIN_DECLS
#define G_TYPE_DBUS_INTERFACE (g_dbus_interface_get_type())
#define G_DBUS_INTERFACE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_DBUS_INTERFACE, GDBusInterface))
#define G_IS_DBUS_INTERFACE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_DBUS_INTERFACE))
#define G_DBUS_INTERFACE_GET_IFACE(o) (G_TYPE_INSTANCE_GET_INTERFACE((o), G_TYPE_DBUS_INTERFACE, GDBusInterfaceIface))
/**
* GDBusInterface:
*
* Base type for D-Bus interfaces.
*/
typedef struct _GDBusInterface GDBusInterface; /* Dummy typedef */
typedef struct _GDBusInterfaceIface GDBusInterfaceIface;
/**
* GDBusInterfaceIface:
* @parent_iface: The parent interface.
* @get_info: Returns a #GDBusInterfaceInfo. See g_dbus_interface_get_info().
* @get_object: Gets the enclosing #GDBusObject. See g_dbus_interface_get_object().
* @set_object: Sets the enclosing #GDBusObject. See g_dbus_interface_set_object().
*
* Base type for D-Bus interfaces.
*/
struct _GDBusInterfaceIface
{
GTypeInterface parent_iface;
/* Virtual Functions */
GDBusInterfaceInfo *(*get_info) (GDBusInterface *interface);
GDBusObject *(*get_object) (GDBusInterface *interface);
void (*set_object) (GDBusInterface *interface,
GDBusObject *object);
};
GType g_dbus_interface_get_type (void) G_GNUC_CONST;
GDBusInterfaceInfo *g_dbus_interface_get_info (GDBusInterface *interface);
GDBusObject *g_dbus_interface_get_object (GDBusInterface *interface);
void g_dbus_interface_set_object (GDBusInterface *interface,
GDBusObject *object);
/* Keep it here for now. TODO: move */
gboolean g_dbus_gvariant_to_gvalue (GVariant *value,
GValue *out_gvalue);
GVariant *g_dbus_gvalue_to_gvariant (const GValue *gvalue,
const GVariantType *expected_type);
G_END_DECLS
#endif /* __G_DBUS_INTERFACE_H__ */

693
gio/gdbusinterfacestub.c Normal file
View File

@ -0,0 +1,693 @@
/* 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 "gdbusinterface.h"
#include "gdbusinterfacestub.h"
#include "gdbusobjectstub.h"
#include "gio-marshal.h"
#include "gioenumtypes.h"
#include "gdbusprivate.h"
#include "gdbusmethodinvocation.h"
#include "gdbusconnection.h"
#include "gioscheduler.h"
#include "gioerror.h"
#include "glibintl.h"
/**
* SECTION:gdbusinterfacestub
* @short_description: Service-side D-Bus interface
* @include: gio/gio.h
*
* Abstract base class for D-Bus interfaces on the service side.
*/
struct _GDBusInterfaceStubPrivate
{
GDBusObject *object;
GDBusInterfaceStubFlags flags;
guint registration_id;
GDBusConnection *connection;
gchar *object_path;
GDBusInterfaceVTable *hooked_vtable;
};
enum
{
G_AUTHORIZE_METHOD_SIGNAL,
LAST_SIGNAL
};
enum
{
PROP_0,
PROP_G_FLAGS
};
static guint signals[LAST_SIGNAL] = {0};
static void dbus_interface_interface_init (GDBusInterfaceIface *iface);
G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GDBusInterfaceStub, g_dbus_interface_stub, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (G_TYPE_DBUS_INTERFACE, dbus_interface_interface_init));
static void
g_dbus_interface_stub_finalize (GObject *object)
{
GDBusInterfaceStub *stub = G_DBUS_INTERFACE_STUB (object);
/* unexport if already exported */
if (stub->priv->registration_id > 0)
g_dbus_interface_stub_unexport (stub);
g_assert (stub->priv->connection == NULL);
g_assert (stub->priv->object_path == NULL);
g_assert (stub->priv->hooked_vtable == NULL);
if (stub->priv->object != NULL)
g_object_remove_weak_pointer (G_OBJECT (stub->priv->object), (gpointer *) &stub->priv->object);
G_OBJECT_CLASS (g_dbus_interface_stub_parent_class)->finalize (object);
}
static void
g_dbus_interface_stub_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
GDBusInterfaceStub *stub = G_DBUS_INTERFACE_STUB (object);
switch (prop_id)
{
case PROP_G_FLAGS:
g_value_set_flags (value, g_dbus_interface_stub_get_flags (stub));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
g_dbus_interface_stub_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
GDBusInterfaceStub *stub = G_DBUS_INTERFACE_STUB (object);
switch (prop_id)
{
case PROP_G_FLAGS:
g_dbus_interface_stub_set_flags (stub, g_value_get_flags (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static gboolean
g_dbus_interface_stub_g_authorize_method_default (GDBusInterfaceStub *stub,
GDBusMethodInvocation *invocation)
{
return TRUE;
}
static void
g_dbus_interface_stub_class_init (GDBusInterfaceStubClass *klass)
{
GObjectClass *gobject_class;
gobject_class = G_OBJECT_CLASS (klass);
gobject_class->finalize = g_dbus_interface_stub_finalize;
gobject_class->set_property = g_dbus_interface_stub_set_property;
gobject_class->get_property = g_dbus_interface_stub_get_property;
klass->g_authorize_method = g_dbus_interface_stub_g_authorize_method_default;
/**
* GDBusInterfaceStub:g-flags:
*
* Flags from the #GDBusInterfaceStubFlags enumeration.
*/
g_object_class_install_property (gobject_class,
PROP_G_FLAGS,
g_param_spec_flags ("g-flags",
"g-flags",
"Flags for the interface stub",
G_TYPE_DBUS_INTERFACE_STUB_FLAGS,
G_DBUS_INTERFACE_STUB_FLAGS_NONE,
G_PARAM_READABLE |
G_PARAM_WRITABLE |
G_PARAM_STATIC_STRINGS));
/**
* GDBusInterfaceStub::g-authorize-method:
* @interface: The #GDBusInterfaceStub emitting the signal.
* @invocation: A #GDBusMethodInvocation.
*
* Emitted when a method is invoked by a remote caller and used to
* determine if the method call is authorized.
*
* Note that this signal is emitted in a thread dedicated to
* handling the method call so handlers are allowed to perform
* blocking IO. This means that it is appropriate to call
* e.g. <ulink
* url="http://hal.freedesktop.org/docs/polkit/PolkitAuthority.html#polkit-authority-check-authorization-sync">polkit_authority_check_authorization_sync()</ulink>
* with the <ulink
* url="http://hal.freedesktop.org/docs/polkit/PolkitAuthority.html#POLKIT-CHECK-AUTHORIZATION-FLAGS-ALLOW-USER-INTERACTION:CAPS">POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION</ulink> flag set.
*
* If %FALSE is returned then no further handlers are run and the
* signal handler must take ownership of @invocation and finish
* handling the call (e.g. return an error via
* g_dbus_method_invocation_return_error()).
*
* Otherwise, if %TRUE is returned, signal emission continues. If no
* handlers return %FALSE, then the method is dispatched. If
* @interface has an enclosing #GDBusObjectStub, then the
* #GDBusObjectStub::authorize-method signal handlers run before the
* handlers for this signal.
*
* The default class handler just returns %TRUE.
*
* Please note that the common case is optimized: if no signals
* handlers are connected and the default class handler isn't
* overridden (for both @interface and the enclosing
* #GDBusObjectStub, if any) and #GDBusInterfaceStub:g-flags does
* not have the
* %G_DBUS_INTERFACE_STUB_FLAGS_HANDLE_METHOD_INVOCATIONS_IN_THREAD
* flags set, no dedicated thread is ever used and the call will be
* handled in the same thread as the object that @interface belongs
* to was exported in.
*
* Returns: %TRUE if the call is authorized, %FALSE otherwise.
*/
signals[G_AUTHORIZE_METHOD_SIGNAL] =
g_signal_new ("g-authorize-method",
G_TYPE_DBUS_INTERFACE_STUB,
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GDBusInterfaceStubClass, g_authorize_method),
_g_signal_accumulator_false_handled,
NULL,
_gio_marshal_BOOLEAN__OBJECT,
G_TYPE_BOOLEAN,
1,
G_TYPE_DBUS_METHOD_INVOCATION);
g_type_class_add_private (klass, sizeof (GDBusInterfaceStubPrivate));
}
static void
g_dbus_interface_stub_init (GDBusInterfaceStub *stub)
{
stub->priv = G_TYPE_INSTANCE_GET_PRIVATE (stub, G_TYPE_DBUS_INTERFACE_STUB, GDBusInterfaceStubPrivate);
}
/* ---------------------------------------------------------------------------------------------------- */
/**
* g_dbus_interface_stub_get_flags:
* @stub: A #GDBusInterfaceStub.
*
* Gets the #GDBusInterfaceStubFlags that describes what the behavior
* of @stub
*
* Returns: One or more flags from the #GDBusInterfaceStubFlags enumeration.
*/
GDBusInterfaceStubFlags
g_dbus_interface_stub_get_flags (GDBusInterfaceStub *stub)
{
g_return_val_if_fail (G_IS_DBUS_INTERFACE_STUB (stub), G_DBUS_INTERFACE_STUB_FLAGS_NONE);
return stub->priv->flags;
}
/**
* g_dbus_interface_stub_set_flags:
* @stub: A #GDBusInterfaceStub.
* @flags: Flags from the #GDBusInterfaceStubFlags enumeration.
*
* Sets flags describing what the behavior of @stub should be.
*/
void
g_dbus_interface_stub_set_flags (GDBusInterfaceStub *stub,
GDBusInterfaceStubFlags flags)
{
g_return_if_fail (G_IS_DBUS_INTERFACE_STUB (stub));
if (stub->priv->flags != flags)
{
stub->priv->flags = flags;
g_object_notify (G_OBJECT (stub), "g-flags");
}
}
/**
* g_dbus_interface_stub_get_info:
* @stub: A #GDBusInterfaceStub.
*
* Gets D-Bus introspection information for the D-Bus interface
* implemented by @interface.
*
* Returns: (transfer none): A #GDBusInterfaceInfo (never %NULL). Do not free.
*/
GDBusInterfaceInfo *
g_dbus_interface_stub_get_info (GDBusInterfaceStub *stub)
{
GDBusInterfaceInfo *ret;
g_return_val_if_fail (G_IS_DBUS_INTERFACE_STUB (stub), NULL);
ret = G_DBUS_INTERFACE_STUB_GET_CLASS (stub)->get_info (stub);
g_warn_if_fail (ret != NULL);
return ret;
}
/**
* g_dbus_interface_stub_get_vtable:
* @stub: A #GDBusInterfaceStub.
*
* Gets the interface vtable for the D-Bus interface implemented by
* @interface. The returned function pointers should expect @stub
* itself to be passed as @user_data.
*
* Returns: A #GDBusInterfaceVTable (never %NULL).
*/
GDBusInterfaceVTable *
g_dbus_interface_stub_get_vtable (GDBusInterfaceStub *stub)
{
GDBusInterfaceVTable *ret;
g_return_val_if_fail (G_IS_DBUS_INTERFACE_STUB (stub), NULL);
ret = G_DBUS_INTERFACE_STUB_GET_CLASS (stub)->get_vtable (stub);
g_warn_if_fail (ret != NULL);
return ret;
}
/**
* g_dbus_interface_stub_get_properties:
* @stub: A #GDBusInterfaceStub.
*
* Gets all D-Bus properties for @stub.
*
* Returns: A new, floating, #GVariant. Free with g_variant_unref().
*/
GVariant *
g_dbus_interface_stub_get_properties (GDBusInterfaceStub *stub)
{
GVariant *ret;
g_return_val_if_fail (G_IS_DBUS_INTERFACE_STUB (stub), NULL);
ret = G_DBUS_INTERFACE_STUB_GET_CLASS (stub)->get_properties (stub);
g_warn_if_fail (g_variant_is_floating (ret));
return ret;
}
/**
* g_dbus_interface_stub_flush:
* @stub: A #GDBusInterfaceStub.
*
* If @stub has outstanding changes, request for these changes to be
* emitted immediately.
*
* For example, an exported D-Bus interface may queue up property
* changes and emit the
* <literal>org.freedesktop.DBus.Properties::PropertiesChanged</literal>
* signal later (e.g. in an idle handler). This technique is useful
* for collapsing multiple property changes into one.
*/
void
g_dbus_interface_stub_flush (GDBusInterfaceStub *stub)
{
g_return_if_fail (G_IS_DBUS_INTERFACE_STUB (stub));
G_DBUS_INTERFACE_STUB_GET_CLASS (stub)->flush (stub);
}
/* ---------------------------------------------------------------------------------------------------- */
static GDBusInterfaceInfo *
_g_dbus_interface_stub_get_info (GDBusInterface *interface)
{
GDBusInterfaceStub *stub = G_DBUS_INTERFACE_STUB (interface);
return g_dbus_interface_stub_get_info (stub);
}
static GDBusObject *
g_dbus_interface_stub_get_object (GDBusInterface *interface)
{
GDBusInterfaceStub *stub = G_DBUS_INTERFACE_STUB (interface);
return stub->priv->object;
}
static void
g_dbus_interface_stub_set_object (GDBusInterface *interface,
GDBusObject *object)
{
GDBusInterfaceStub *stub = G_DBUS_INTERFACE_STUB (interface);
if (stub->priv->object != NULL)
g_object_remove_weak_pointer (G_OBJECT (stub->priv->object), (gpointer *) &stub->priv->object);
stub->priv->object = object;
if (object != NULL)
g_object_add_weak_pointer (G_OBJECT (stub->priv->object), (gpointer *) &stub->priv->object);
}
static void
dbus_interface_interface_init (GDBusInterfaceIface *iface)
{
iface->get_info = _g_dbus_interface_stub_get_info;
iface->get_object = g_dbus_interface_stub_get_object;
iface->set_object = g_dbus_interface_stub_set_object;
}
/* ---------------------------------------------------------------------------------------------------- */
typedef struct
{
volatile gint ref_count;
GDBusInterfaceStub *stub;
GDBusInterfaceMethodCallFunc method_call_func;
GDBusMethodInvocation *invocation;
GMainContext *context;
} DispatchData;
static void
dispatch_data_unref (DispatchData *data)
{
if (g_atomic_int_dec_and_test (&data->ref_count))
{
if (data->context != NULL)
g_main_context_unref (data->context);
g_free (data);
}
}
static DispatchData *
dispatch_data_ref (DispatchData *data)
{
g_atomic_int_inc (&data->ref_count);
return data;
}
static gboolean
dispatch_invoke_in_context_func (gpointer user_data)
{
DispatchData *data = user_data;
data->method_call_func (g_dbus_method_invocation_get_connection (data->invocation),
g_dbus_method_invocation_get_sender (data->invocation),
g_dbus_method_invocation_get_object_path (data->invocation),
g_dbus_method_invocation_get_interface_name (data->invocation),
g_dbus_method_invocation_get_method_name (data->invocation),
g_dbus_method_invocation_get_parameters (data->invocation),
data->invocation,
g_dbus_method_invocation_get_user_data (data->invocation));
return FALSE;
}
static gboolean
dispatch_in_thread_func (GIOSchedulerJob *job,
GCancellable *cancellable,
gpointer user_data)
{
DispatchData *data = user_data;
gboolean authorized;
/* first check on the enclosing object (if any), then the interface */
authorized = TRUE;
if (data->stub->priv->object != NULL)
{
g_signal_emit_by_name (data->stub->priv->object,
"authorize-method",
data->stub,
data->invocation,
&authorized);
}
if (authorized)
{
g_signal_emit (data->stub,
signals[G_AUTHORIZE_METHOD_SIGNAL],
0,
data->invocation,
&authorized);
}
if (authorized)
{
gboolean run_in_thread;
run_in_thread = (data->stub->priv->flags & G_DBUS_INTERFACE_STUB_FLAGS_HANDLE_METHOD_INVOCATIONS_IN_THREAD);
if (run_in_thread)
{
/* might as well just re-use the existing thread */
data->method_call_func (g_dbus_method_invocation_get_connection (data->invocation),
g_dbus_method_invocation_get_sender (data->invocation),
g_dbus_method_invocation_get_object_path (data->invocation),
g_dbus_method_invocation_get_interface_name (data->invocation),
g_dbus_method_invocation_get_method_name (data->invocation),
g_dbus_method_invocation_get_parameters (data->invocation),
data->invocation,
g_dbus_method_invocation_get_user_data (data->invocation));
}
else
{
/* bah, back to original context */
g_main_context_invoke_full (data->context,
G_PRIORITY_DEFAULT,
dispatch_invoke_in_context_func,
dispatch_data_ref (data),
(GDestroyNotify) dispatch_data_unref);
}
}
else
{
/* do nothing */
}
return FALSE;
}
static void
g_dbus_interface_method_dispatch_helper (GDBusInterfaceStub *stub,
GDBusInterfaceMethodCallFunc method_call_func,
GDBusMethodInvocation *invocation)
{
gboolean has_handlers;
gboolean has_default_class_handler;
gboolean emit_authorized_signal;
gboolean run_in_thread;
g_return_if_fail (G_IS_DBUS_INTERFACE_STUB (stub));
g_return_if_fail (method_call_func != NULL);
g_return_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation));
/* optimization for the common case where
*
* a) no handler is connected and class handler is not overridden (both interface and object); and
* b) method calls are not dispatched in a thread
*/
has_handlers = g_signal_has_handler_pending (stub,
signals[G_AUTHORIZE_METHOD_SIGNAL],
0,
TRUE);
has_default_class_handler = (G_DBUS_INTERFACE_STUB_GET_CLASS (stub)->g_authorize_method ==
g_dbus_interface_stub_g_authorize_method_default);
emit_authorized_signal = (has_handlers || !has_default_class_handler);
if (!emit_authorized_signal)
{
if (stub->priv->object != NULL)
emit_authorized_signal = _g_dbus_object_stub_has_authorize_method_handlers (G_DBUS_OBJECT_STUB (stub->priv->object));
}
run_in_thread = (stub->priv->flags & G_DBUS_INTERFACE_STUB_FLAGS_HANDLE_METHOD_INVOCATIONS_IN_THREAD);
if (!emit_authorized_signal && !run_in_thread)
{
method_call_func (g_dbus_method_invocation_get_connection (invocation),
g_dbus_method_invocation_get_sender (invocation),
g_dbus_method_invocation_get_object_path (invocation),
g_dbus_method_invocation_get_interface_name (invocation),
g_dbus_method_invocation_get_method_name (invocation),
g_dbus_method_invocation_get_parameters (invocation),
invocation,
g_dbus_method_invocation_get_user_data (invocation));
}
else
{
DispatchData *data;
data = g_new0 (DispatchData, 1);
data->stub = stub;
data->method_call_func = method_call_func;
data->invocation = invocation;
data->context = g_main_context_get_thread_default ();
data->ref_count = 1;
if (data->context != NULL)
g_main_context_ref (data->context);
g_io_scheduler_push_job (dispatch_in_thread_func,
data,
(GDestroyNotify) dispatch_data_unref,
G_PRIORITY_DEFAULT,
NULL); /* GCancellable* */
}
}
static void
stub_intercept_handle_method_call(GDBusConnection *connection,
const gchar *sender,
const gchar *object_path,
const gchar *interface_name,
const gchar *method_name,
GVariant *parameters,
GDBusMethodInvocation *invocation,
gpointer user_data)
{
GDBusInterfaceStub *stub = G_DBUS_INTERFACE_STUB (user_data);
g_dbus_interface_method_dispatch_helper (stub,
g_dbus_interface_stub_get_vtable (stub)->method_call,
invocation);
}
/* ---------------------------------------------------------------------------------------------------- */
/**
* g_dbus_interface_stub_get_connection:
* @stub: A #GDBusInterfaceStub.
*
* Gets the connection that @stub is exported on, if any.
*
* Returns: (transfer none): A #GDBusConnection or %NULL if @stub is
* not exported anywhere. Do not free, the object belongs to @stub.
*/
GDBusConnection *
g_dbus_interface_stub_get_connection (GDBusInterfaceStub *stub)
{
g_return_val_if_fail (G_IS_DBUS_INTERFACE_STUB (stub), NULL);
return stub->priv->connection;
}
/**
* g_dbus_interface_stub_get_object_path:
* @stub: A #GDBusInterfaceStub.
*
* Gets the object that that @stub is exported on, if any.
*
* Returns: A string owned by @stub or %NULL if stub is not exported
* anywhere. Do not free, the string belongs to @stub.
*/
const gchar *
g_dbus_interface_stub_get_object_path (GDBusInterfaceStub *stub)
{
g_return_val_if_fail (G_IS_DBUS_INTERFACE_STUB (stub), NULL);
return stub->priv->object_path;
}
/**
* g_dbus_interface_stub_export:
* @stub: The D-Bus interface to export.
* @connection: A #GDBusConnection to export @stub on.
* @object_path: The path to export the interface at.
* @error: Return location for error or %NULL.
*
* Exports @stubs at @object_path on @connection.
*
* Use g_dbus_interface_stub_unexport() to unexport the object.
*
* Returns: %TRUE if the interface was exported, other %FALSE with
* @error set.
*/
gboolean
g_dbus_interface_stub_export (GDBusInterfaceStub *stub,
GDBusConnection *connection,
const gchar *object_path,
GError **error)
{
gboolean ret;
g_return_val_if_fail (G_IS_DBUS_INTERFACE_STUB (stub), 0);
g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), 0);
g_return_val_if_fail (g_variant_is_object_path (object_path), 0);
g_return_val_if_fail (error == NULL || *error == NULL, 0);
ret = FALSE;
if (stub->priv->registration_id > 0)
{
g_set_error_literal (error,
G_IO_ERROR,
G_IO_ERROR_FAILED, /* TODO: new error code */
"The object is already exported");
goto out;
}
g_assert (stub->priv->connection == NULL);
g_assert (stub->priv->object_path == NULL);
g_assert (stub->priv->hooked_vtable == NULL);
/* Hook the vtable since we need to intercept method calls for
* ::g-authorize-method and for dispatching in thread vs
* context
*/
stub->priv->hooked_vtable = g_memdup (g_dbus_interface_stub_get_vtable (stub), sizeof (GDBusInterfaceVTable));
stub->priv->hooked_vtable->method_call = stub_intercept_handle_method_call;
stub->priv->connection = g_object_ref (connection);
stub->priv->object_path = g_strdup (object_path);
stub->priv->registration_id = g_dbus_connection_register_object (connection,
object_path,
g_dbus_interface_stub_get_info (stub),
stub->priv->hooked_vtable,
stub,
NULL, /* user_data_free_func */
error);
if (stub->priv->registration_id == 0)
goto out;
ret = TRUE;
out:
return ret;
}
/**
* g_dbus_interface_stub_unexport:
* @stub: A #GDBusInterfaceStub.
*
* Stops exporting an interface previously exported with
* g_dbus_interface_stub_export().
*/
void
g_dbus_interface_stub_unexport (GDBusInterfaceStub *stub)
{
g_return_if_fail (G_IS_DBUS_INTERFACE_STUB (stub));
g_return_if_fail (stub->priv->registration_id > 0);
g_assert (stub->priv->connection != NULL);
g_assert (stub->priv->object_path != NULL);
g_assert (stub->priv->hooked_vtable != NULL);
g_warn_if_fail (g_dbus_connection_unregister_object (stub->priv->connection,
stub->priv->registration_id));
g_object_unref (stub->priv->connection);
g_free (stub->priv->object_path);
stub->priv->connection = NULL;
stub->priv->object_path = NULL;
stub->priv->hooked_vtable = NULL;
stub->priv->registration_id = 0;
}
/* ---------------------------------------------------------------------------------------------------- */

105
gio/gdbusinterfacestub.h Normal file
View File

@ -0,0 +1,105 @@
/* 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>
*/
#ifndef __G_DBUS_INTERFACE_STUB_H__
#define __G_DBUS_INTERFACE_STUB_H__
#include <gio/giotypes.h>
G_BEGIN_DECLS
#define G_TYPE_DBUS_INTERFACE_STUB (g_dbus_interface_stub_get_type ())
#define G_DBUS_INTERFACE_STUB(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_DBUS_INTERFACE_STUB, GDBusInterfaceStub))
#define G_DBUS_INTERFACE_STUB_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_DBUS_INTERFACE_STUB, GDBusInterfaceStubClass))
#define G_DBUS_INTERFACE_STUB_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_DBUS_INTERFACE_STUB, GDBusInterfaceStubClass))
#define G_IS_DBUS_INTERFACE_STUB(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_DBUS_INTERFACE_STUB))
#define G_IS_DBUS_INTERFACE_STUB_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_DBUS_INTERFACE_STUB))
typedef struct _GDBusInterfaceStubClass GDBusInterfaceStubClass;
typedef struct _GDBusInterfaceStubPrivate GDBusInterfaceStubPrivate;
/**
* GDBusInterfaceStub:
*
* The #GDBusInterfaceStub structure contains private data and should
* only be accessed using the provided API.
*/
struct _GDBusInterfaceStub
{
/*< private >*/
GObject parent_instance;
GDBusInterfaceStubPrivate *priv;
};
/**
* GDBusInterfaceStubClass:
* @parent_class: The parent class.
* @get_info: Returns a #GDBusInterfaceInfo. See g_dbus_interface_stub_get_info() for details.
* @get_vtable: Returns a #GDBusInterfaceVTable. See g_dbus_interface_stub_get_vtable() for details.
* @get_properties: Returns a new, floating, #GVariant with all properties. See g_dbus_interface_stub_get_properties().
* @flush: Emits outstanding changes, if any. See g_dbus_interface_stub_flush().
* @g_authorize_method: Signal class handler for the #GDBusInterfaceStub::g-authorize-method signal.
*
* Class structure for #GDBusInterfaceStub.
*/
struct _GDBusInterfaceStubClass
{
GObjectClass parent_class;
/* Virtual Functions */
GDBusInterfaceInfo *(*get_info) (GDBusInterfaceStub *stub);
GDBusInterfaceVTable *(*get_vtable) (GDBusInterfaceStub *stub);
GVariant *(*get_properties) (GDBusInterfaceStub *stub);
void (*flush) (GDBusInterfaceStub *stub);
/*< private >*/
gpointer vfunc_padding[8];
/*< public >*/
/* Signals */
gboolean (*g_authorize_method) (GDBusInterfaceStub *stub,
GDBusMethodInvocation *invocation);
/*< private >*/
gpointer signal_padding[8];
};
GType g_dbus_interface_stub_get_type (void) G_GNUC_CONST;
GDBusInterfaceStubFlags g_dbus_interface_stub_get_flags (GDBusInterfaceStub *stub);
void g_dbus_interface_stub_set_flags (GDBusInterfaceStub *stub,
GDBusInterfaceStubFlags flags);
GDBusInterfaceInfo *g_dbus_interface_stub_get_info (GDBusInterfaceStub *stub);
GDBusInterfaceVTable *g_dbus_interface_stub_get_vtable (GDBusInterfaceStub *stub);
GVariant *g_dbus_interface_stub_get_properties (GDBusInterfaceStub *stub);
void g_dbus_interface_stub_flush (GDBusInterfaceStub *stub);
gboolean g_dbus_interface_stub_export (GDBusInterfaceStub *stub,
GDBusConnection *connection,
const gchar *object_path,
GError **error);
void g_dbus_interface_stub_unexport (GDBusInterfaceStub *stub);
GDBusConnection *g_dbus_interface_stub_get_connection (GDBusInterfaceStub *stub);
const gchar *g_dbus_interface_stub_get_object_path (GDBusInterfaceStub *stub);
G_END_DECLS
#endif /* __G_DBUS_INTERFACE_STUB_H */

191
gio/gdbusobject.c Normal file
View File

@ -0,0 +1,191 @@
/* 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 "gdbusinterface.h"
#include "gdbusutils.h"
#include "gio-marshal.h"
#include "glibintl.h"
/**
* SECTION:gdbusobject
* @short_description: Base type for D-Bus objects
* @include: gio/gio.h
*
* The #GDBusObject type is the base type for D-Bus objects on both
* the service side (see #GDBusObjectStub) and the client side (see
* #GDBusObjectProxy). It is essentially just a container of
* interfaces.
*/
typedef GDBusObjectIface GDBusObjectInterface;
G_DEFINE_INTERFACE (GDBusObject, g_dbus_object, G_TYPE_OBJECT)
static void
g_dbus_object_default_init (GDBusObjectIface *iface)
{
/**
* GDBusObject::interface-added:
* @object: The #GDBusObject emitting the signal.
* @interface: The #GDBusInterface that was added.
*
* Emitted when @interface is added to @object.
*/
g_signal_new ("interface-added",
G_TYPE_FROM_INTERFACE (iface),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GDBusObjectIface, interface_added),
NULL,
NULL,
g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE,
1,
G_TYPE_DBUS_INTERFACE);
/**
* GDBusObject::interface-removed:
* @object: The #GDBusObject emitting the signal.
* @interface: The #GDBusInterface that was removed.
*
* Emitted when @interface is removed from @object.
*/
g_signal_new ("interface-removed",
G_TYPE_FROM_INTERFACE (iface),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GDBusObjectIface, interface_removed),
NULL,
NULL,
g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE,
1,
G_TYPE_DBUS_INTERFACE);
}
/* ---------------------------------------------------------------------------------------------------- */
/**
* g_dbus_object_get_object_path:
* @object: A #GDBusObject.
*
* Gets the object path for @object.
*
* Returns: A string owned by @object. Do not free.
*/
const gchar *
g_dbus_object_get_object_path (GDBusObject *object)
{
GDBusObjectIface *iface = G_DBUS_OBJECT_GET_IFACE (object);
return iface->get_object_path (object);
}
/**
* g_dbus_object_get_interfaces:
* @object: A #GDBusObject.
*
* Gets the D-Bus interfaces associated with @object.
*
* Returns: (element-type GDBusInterface) (transfer full) : A list of #GDBusInterface instances.
* The returned list must be freed by g_list_free() after each element has been freed
* with g_object_unref().
*/
GList *
g_dbus_object_get_interfaces (GDBusObject *object)
{
GDBusObjectIface *iface = G_DBUS_OBJECT_GET_IFACE (object);
return iface->get_interfaces (object);
}
/**
* g_dbus_object_get_interface:
* @object: A #GDBusObject.
* @interface_name: A D-Bus interface name.
*
* Gets the D-Bus interface with name @interface_name associated with
* @object, if any.
*
* Returns: %NULL if not found, otherwise a #GDBusInterface that must
* be freed with g_object_unref().
*/
GDBusInterface *
g_dbus_object_get_interface (GDBusObject *object,
const gchar *interface_name)
{
GDBusObjectIface *iface = G_DBUS_OBJECT_GET_IFACE (object);
g_return_val_if_fail (g_dbus_is_interface_name (interface_name), NULL);
return iface->get_interface (object, interface_name);
}
/**
* g_dbus_object_peek_with_typecheck:
* @object: A #GDBusObject.
* @interface_name: A D-Bus interface name.
* @type: The #GType that the returned object must conform to.
*
* Like g_dbus_object_lookup_with_typecheck() except that the caller
* does not own a reference to the returned object.
*
* <note><para>This function is intended to only be used in type
* implementations.</para></note>
*
* Returns: A #GDBusInterface implementing @type or %NULL if
* not found. Do not free the returned object, it is owned by
* @object.
*/
gpointer
g_dbus_object_peek_with_typecheck (GDBusObject *object,
const gchar *interface_name,
GType type)
{
GDBusObjectIface *iface = G_DBUS_OBJECT_GET_IFACE (object);
g_return_val_if_fail (g_dbus_is_interface_name (interface_name), NULL);
return iface->peek_with_typecheck (object, interface_name, type);
}
/**
* g_dbus_object_lookup_with_typecheck:
* @object: A #GDBusObject.
* @interface_name: A D-Bus interface name.
* @type: The #GType that the returned object must conform to.
*
* Like g_dbus_object_get_interface() but warns on stderr if the
* returned object, if any, does not conform to @type.
*
* <note><para>This function is intended to only be used in type
* implementations.</para></note>
*
* Returns: A #GDBusInterface implementing @type or %NULL if
* not found. Free with g_object_unref().
*/
gpointer
g_dbus_object_lookup_with_typecheck (GDBusObject *object,
const gchar *interface_name,
GType type)
{
GDBusObjectIface *iface = G_DBUS_OBJECT_GET_IFACE (object);
g_return_val_if_fail (g_dbus_is_interface_name (interface_name), NULL);
return iface->lookup_with_typecheck (object, interface_name, type);
}

95
gio/gdbusobject.h Normal file
View File

@ -0,0 +1,95 @@
/* 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>
*/
#ifndef __G_DBUS_OBJECT_H__
#define __G_DBUS_OBJECT_H__
#include <gio/giotypes.h>
G_BEGIN_DECLS
#define G_TYPE_DBUS_OBJECT (g_dbus_object_get_type())
#define G_DBUS_OBJECT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_DBUS_OBJECT, GDBusObject))
#define G_IS_DBUS_OBJECT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_DBUS_OBJECT))
#define G_DBUS_OBJECT_GET_IFACE(o) (G_TYPE_INSTANCE_GET_INTERFACE((o), G_TYPE_DBUS_OBJECT, GDBusObjectIface))
typedef struct _GDBusObjectIface GDBusObjectIface;
/**
* GDBusObjectIface:
* @parent_iface: The parent interface.
* @get_object_path: Returns the object path. See g_dbus_object_get_object_path().
* @get_interfaces: Returns all interfaces. See g_dbus_object_get_interfaces().
* @get_interface: Returns an interface by name. See g_dbus_object_get_interface().
* @lookup_with_typecheck: Like @get_interface but warns on stderr if the returned object, if any,
* does not conform to @type. Returned object must be freed by the caller.
* @peek_with_typecheck: Like @lookup_with_typecheck but does not transfer the reference.
* @interface_added: Signal handler for the #GDBusObject::interface-added signal.
* @interface_removed: Signal handler for the #GDBusObject::interface-removed signal.
*
* Base object type for D-Bus objects.
*
* <note><para>The @lookup_with_typecheck and @peek_with_typecheck
* virtual functions should only be used by D-Bus interface
* implementations.</para></note>
*/
struct _GDBusObjectIface
{
GTypeInterface parent_iface;
/* Virtual Functions */
const gchar *(*get_object_path) (GDBusObject *object);
GList *(*get_interfaces) (GDBusObject *object);
GDBusInterface *(*get_interface) (GDBusObject *object,
const gchar *interface_name);
gpointer (*lookup_with_typecheck) (GDBusObject *object,
const gchar *interface_name,
GType type);
gpointer (*peek_with_typecheck) (GDBusObject *object,
const gchar *interface_name,
GType type);
/* Signals */
void (*interface_added) (GDBusObject *object,
GDBusInterface *interface);
void (*interface_removed) (GDBusObject *object,
GDBusInterface *interface);
};
GType g_dbus_object_get_type (void) G_GNUC_CONST;
const gchar *g_dbus_object_get_object_path (GDBusObject *object);
GList *g_dbus_object_get_interfaces (GDBusObject *object);
GDBusInterface *g_dbus_object_get_interface (GDBusObject *object,
const gchar *interface_name);
gpointer g_dbus_object_peek_with_typecheck (GDBusObject *object,
const gchar *interface_name,
GType type);
gpointer g_dbus_object_lookup_with_typecheck (GDBusObject *object,
const gchar *interface_name,
GType type);
G_END_DECLS
#endif /* __G_DBUS_OBJECT_H__ */

216
gio/gdbusobjectmanager.c Normal file
View File

@ -0,0 +1,216 @@
/* 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 "gdbusobjectmanager.h"
#include "gio-marshal.h"
#include "gdbusinterface.h"
#include "gdbusutils.h"
#include "glibintl.h"
/**
* SECTION:gdbusobjectmanager
* @short_description: Base type for D-Bus object managers
* @include: gio/gio.h
*
* The #GDBusObjectManager type is the base type for service- and
* client-side implementations of the standardized <ulink
* url="http://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-objectmanager">org.freedesktop.DBus.ObjectManager</ulink>
* interface.
*
* See #GDBusObjectManagerClient for the client-side implementation
* and #GDBusObjectManagerServer for the service-side implementation.
*/
/**
* GDBusObjectManager:
*
* A D-Bus object.
*/
typedef GDBusObjectManagerIface GDBusObjectManagerInterface;
G_DEFINE_INTERFACE (GDBusObjectManager, g_dbus_object_manager, G_TYPE_OBJECT)
static void
g_dbus_object_manager_default_init (GDBusObjectManagerIface *iface)
{
/**
* GDBusObjectManager::object-added:
* @manager: The #GDBusObjectManager emitting the signal.
* @object: The #GDBusObject that was added.
*
* Emitted when @object is added to @manager.
*/
g_signal_new ("object-added",
G_TYPE_FROM_INTERFACE (iface),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GDBusObjectManagerIface, object_added),
NULL,
NULL,
g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE,
1,
G_TYPE_DBUS_OBJECT);
/**
* GDBusObjectManager::object-removed:
* @manager: The #GDBusObjectManager emitting the signal.
* @object: The #GDBusObject that was removed.
*
* Emitted when @object is removed from @manager.
*/
g_signal_new ("object-removed",
G_TYPE_FROM_INTERFACE (iface),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GDBusObjectManagerIface, object_removed),
NULL,
NULL,
g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE,
1,
G_TYPE_DBUS_OBJECT);
/**
* GDBusObjectManager::interface-added:
* @manager: The #GDBusObjectManager emitting the signal.
* @object: The #GDBusObject on which an interface was added.
* @interface: The #GDBusInterface that was added.
*
* Emitted when @interface is added to @object.
*
* This signal exists purely as a convenience to avoid having to
* connect signals to all objects managed by @manager.
*/
g_signal_new ("interface-added",
G_TYPE_FROM_INTERFACE (iface),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GDBusObjectManagerIface, interface_added),
NULL,
NULL,
_gio_marshal_VOID__OBJECT_OBJECT,
G_TYPE_NONE,
2,
G_TYPE_DBUS_OBJECT,
G_TYPE_DBUS_INTERFACE);
/**
* GDBusObjectManager::interface-removed:
* @manager: The #GDBusObjectManager emitting the signal.
* @object: The #GDBusObject on which an interface was removed.
* @interface: The #GDBusInterface that was removed.
*
* Emitted when @interface has been removed from @object.
*
* This signal exists purely as a convenience to avoid having to
* connect signals to all objects managed by @manager.
*/
g_signal_new ("interface-removed",
G_TYPE_FROM_INTERFACE (iface),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GDBusObjectManagerIface, interface_removed),
NULL,
NULL,
_gio_marshal_VOID__OBJECT_OBJECT,
G_TYPE_NONE,
2,
G_TYPE_DBUS_OBJECT,
G_TYPE_DBUS_INTERFACE);
}
/* ---------------------------------------------------------------------------------------------------- */
/**
* g_dbus_object_manager_get_object_path:
* @manager: A #GDBusObjectManager.
*
* Gets the object path that @manager is for.
*
* Returns: A string owned by @manager. Do not free.
*/
const gchar *
g_dbus_object_manager_get_object_path (GDBusObjectManager *manager)
{
GDBusObjectManagerIface *iface = G_DBUS_OBJECT_MANAGER_GET_IFACE (manager);
return iface->get_object_path (manager);
}
/**
* g_dbus_object_manager_get_objects:
* @manager: A #GDBusObjectManager.
*
* Gets all #GDBusObject objects known to @manager.
*
* Returns: (transfer full) (element-type GDBusObject): A list of
* #GDBusObject 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_manager_get_objects (GDBusObjectManager *manager)
{
GDBusObjectManagerIface *iface = G_DBUS_OBJECT_MANAGER_GET_IFACE (manager);
return iface->get_objects (manager);
}
/**
* g_dbus_object_manager_get_object:
* @manager: A #GDBusObjectManager.
* @object_path: Object path to lookup.
*
* Gets the #GDBusObjectProxy at @object_path, if any.
*
* Returns: A #GDBusObject or %NULL. Free with g_object_unref().
*/
GDBusObject *
g_dbus_object_manager_get_object (GDBusObjectManager *manager,
const gchar *object_path)
{
GDBusObjectManagerIface *iface = G_DBUS_OBJECT_MANAGER_GET_IFACE (manager);
g_return_val_if_fail (g_variant_is_object_path (object_path), NULL);
return iface->get_object (manager, object_path);
}
/**
* g_dbus_object_manager_get_interface:
* @manager: A #GDBusObjectManager.
* @object_path: Object path to lookup.
* @interface_name: D-Bus interface name to lookup.
*
* Gets the interface proxy for @interface_name at @object_path, if
* any.
*
* Returns: A #GDBusInterface instance or %NULL. Free with g_object_unref().
*/
GDBusInterface *
g_dbus_object_manager_get_interface (GDBusObjectManager *manager,
const gchar *object_path,
const gchar *interface_name)
{
GDBusObjectManagerIface *iface = G_DBUS_OBJECT_MANAGER_GET_IFACE (manager);
g_return_val_if_fail (g_variant_is_object_path (object_path), NULL);
g_return_val_if_fail (g_dbus_is_interface_name (interface_name), NULL);
return iface->get_interface (manager, object_path, interface_name);
}

89
gio/gdbusobjectmanager.h Normal file
View File

@ -0,0 +1,89 @@
/* 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>
*/
#ifndef __G_DBUS_OBJECT_MANAGER_H__
#define __G_DBUS_OBJECT_MANAGER_H__
#include <gio/giotypes.h>
G_BEGIN_DECLS
#define G_TYPE_DBUS_OBJECT_MANAGER (g_dbus_object_manager_get_type())
#define G_DBUS_OBJECT_MANAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_DBUS_OBJECT_MANAGER, GDBusObjectManager))
#define G_IS_DBUS_OBJECT_MANAGER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_DBUS_OBJECT_MANAGER))
#define G_DBUS_OBJECT_MANAGER_GET_IFACE(o) (G_TYPE_INSTANCE_GET_INTERFACE((o), G_TYPE_DBUS_OBJECT_MANAGER, GDBusObjectManagerIface))
typedef struct _GDBusObjectManagerIface GDBusObjectManagerIface;
/**
* GDBusObjectManagerIface:
* @parent_iface: The parent interface.
* @get_object_path: Virtual function for g_dbus_object_manager_get_object_path().
* @get_objects: Virtual function for g_dbus_object_manager_get_objects().
* @get_object: Virtual function for g_dbus_object_manager_get_object().
* @get_interface: Virtual function for g_dbus_object_manager_get_interface().
* @object_added: Signal handler for the #GDBusObjectManager::object-added signal.
* @object_removed: Signal handler for the #GDBusObjectManager::object-removed signal.
* @interface_added: Signal handler for the #GDBusObjectManager::interface-added signal.
* @interface_removed: Signal handler for the #GDBusObjectManager::interface-removed signal.
*
* Base type for D-Bus object managers.
*/
struct _GDBusObjectManagerIface
{
GTypeInterface parent_iface;
/* Virtual Functions */
const gchar *(*get_object_path) (GDBusObjectManager *manager);
GList *(*get_objects) (GDBusObjectManager *manager);
GDBusObject *(*get_object) (GDBusObjectManager *manager,
const gchar *object_path);
GDBusInterface *(*get_interface) (GDBusObjectManager *manager,
const gchar *object_path,
const gchar *interface_name);
/* Signals */
void (*object_added) (GDBusObjectManager *manager,
GDBusObject *object);
void (*object_removed) (GDBusObjectManager *manager,
GDBusObject *object);
void (*interface_added) (GDBusObjectManager *manager,
GDBusObject *object,
GDBusInterface *interface);
void (*interface_removed) (GDBusObjectManager *manager,
GDBusObject *object,
GDBusInterface *interface);
};
GType g_dbus_object_manager_get_type (void) G_GNUC_CONST;
const gchar *g_dbus_object_manager_get_object_path (GDBusObjectManager *manager);
GList *g_dbus_object_manager_get_objects (GDBusObjectManager *manager);
GDBusObject *g_dbus_object_manager_get_object (GDBusObjectManager *manager,
const gchar *object_path);
GDBusInterface *g_dbus_object_manager_get_interface (GDBusObjectManager *manager,
const gchar *object_path,
const gchar *interface_name);
G_END_DECLS
#endif /* __G_DBUS_OBJECT_MANAGER_H__ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,129 @@
/* 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>
*/
#ifndef __G_DBUS_OBJECT_MANAGER_CLIENT_H__
#define __G_DBUS_OBJECT_MANAGER_CLIENT_H__
#include <gio/giotypes.h>
G_BEGIN_DECLS
#define G_TYPE_DBUS_OBJECT_MANAGER_CLIENT (g_dbus_object_manager_client_get_type ())
#define G_DBUS_OBJECT_MANAGER_CLIENT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_DBUS_OBJECT_MANAGER_CLIENT, GDBusObjectManagerClient))
#define G_DBUS_OBJECT_MANAGER_CLIENT_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_DBUS_OBJECT_MANAGER_CLIENT, GDBusObjectManagerClientClass))
#define G_DBUS_OBJECT_MANAGER_CLIENT_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_DBUS_OBJECT_MANAGER_CLIENT, GDBusObjectManagerClientClass))
#define G_IS_DBUS_OBJECT_MANAGER_CLIENT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_DBUS_OBJECT_MANAGER_CLIENT))
#define G_IS_DBUS_OBJECT_MANAGER_CLIENT_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_DBUS_OBJECT_MANAGER_CLIENT))
typedef struct _GDBusObjectManagerClientClass GDBusObjectManagerClientClass;
typedef struct _GDBusObjectManagerClientPrivate GDBusObjectManagerClientPrivate;
/**
* GDBusObjectManagerClient:
*
* The #GDBusObjectManagerClient structure contains private data and should
* only be accessed using the provided API.
*/
struct _GDBusObjectManagerClient
{
/*< private >*/
GObject parent_instance;
GDBusObjectManagerClientPrivate *priv;
};
/**
* GDBusObjectManagerClientClass:
* @parent_class: The parent class.
* @interface_proxy_signal: Signal class handler for the #GDBusObjectManagerClient::interface-proxy-signal signal.
* @interface_proxy_properties_changed: Signal class handler for the #GDBusObjectManagerClient::interface-proxy-properties-changed signal.
*
* Class structure for #GDBusObjectManagerClient.
*/
struct _GDBusObjectManagerClientClass
{
GObjectClass parent_class;
/* signals */
void (*interface_proxy_signal) (GDBusObjectManagerClient *manager,
GDBusObjectProxy *object_proxy,
GDBusProxy *interface_proxy,
const gchar *sender_name,
const gchar *signal_name,
GVariant *parameters);
void (*interface_proxy_properties_changed) (GDBusObjectManagerClient *manager,
GDBusObjectProxy *object_proxy,
GDBusProxy *interface_proxy,
GVariant *changed_properties,
const gchar* const *invalidated_properties);
/*< private >*/
gpointer padding[8];
};
GType g_dbus_object_manager_client_get_type (void) G_GNUC_CONST;
void g_dbus_object_manager_client_new (GDBusConnection *connection,
GDBusObjectManagerClientFlags flags,
const gchar *name,
const gchar *object_path,
GDBusProxyTypeFunc get_proxy_type_func,
gpointer get_proxy_type_user_data,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
GDBusObjectManager *g_dbus_object_manager_client_new_finish (GAsyncResult *res,
GError **error);
GDBusObjectManager *g_dbus_object_manager_client_new_sync (GDBusConnection *connection,
GDBusObjectManagerClientFlags flags,
const gchar *name,
const gchar *object_path,
GDBusProxyTypeFunc get_proxy_type_func,
gpointer get_proxy_type_user_data,
GCancellable *cancellable,
GError **error);
void g_dbus_object_manager_client_new_for_bus (GBusType bus_type,
GDBusObjectManagerClientFlags flags,
const gchar *name,
const gchar *object_path,
GDBusProxyTypeFunc get_proxy_type_func,
gpointer get_proxy_type_user_data,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
GDBusObjectManager *g_dbus_object_manager_client_new_for_bus_finish (GAsyncResult *res,
GError **error);
GDBusObjectManager *g_dbus_object_manager_client_new_for_bus_sync (GBusType bus_type,
GDBusObjectManagerClientFlags flags,
const gchar *name,
const gchar *object_path,
GDBusProxyTypeFunc get_proxy_type_func,
gpointer get_proxy_type_user_data,
GCancellable *cancellable,
GError **error);
GDBusConnection *g_dbus_object_manager_client_get_connection (GDBusObjectManagerClient *manager);
GDBusObjectManagerClientFlags g_dbus_object_manager_client_get_flags (GDBusObjectManagerClient *manager);
const gchar *g_dbus_object_manager_client_get_name (GDBusObjectManagerClient *manager);
gchar *g_dbus_object_manager_client_get_name_owner (GDBusObjectManagerClient *manager);
G_END_DECLS
#endif /* __G_DBUS_OBJECT_MANAGER_CLIENT_H */

View File

@ -0,0 +1,898 @@
/* 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 "gdbusobjectmanager.h"
#include "gdbusobjectmanagerserver.h"
#include "gdbusobject.h"
#include "gdbusobjectstub.h"
#include "gdbusinterfacestub.h"
#include "gdbusconnection.h"
#include "gdbusintrospection.h"
#include "gdbusmethodinvocation.h"
#include "gdbuserror.h"
#include "glibintl.h"
/**
* SECTION:gdbusobjectmanagerserver
* @short_description: Service-side object manager
* @include: gio/gio.h
*
* #GDBusObjectManagerServer is used to export #GDBusObject instances using
* the standardized <ulink
* url="http://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-objectmanager">org.freedesktop.DBus.ObjectManager</ulink>
* interface. For example, remote D-Bus clients can get all objects
* and properties in a single call. Additionally, any change in the
* object hierarchy is broadcast using signals. This means that D-Bus
* clients can keep caches up to date by only listening to D-Bus
* signals.
*
* See #GDBusObjectManagerClient for the client-side code that is intended to
* be used with #GDBusObjectManagerServer.
*/
typedef struct
{
GDBusObjectStub *object;
GDBusObjectManagerServer *manager;
GHashTable *map_iface_name_to_iface;
gboolean exported;
} RegistrationData;
static void registration_data_free (RegistrationData *data);
static void g_dbus_object_manager_server_emit_interfaces_added (GDBusObjectManagerServer *manager,
RegistrationData *data,
const gchar *const *interfaces);
static void g_dbus_object_manager_server_emit_interfaces_removed (GDBusObjectManagerServer *manager,
RegistrationData *data,
const gchar *const *interfaces);
struct _GDBusObjectManagerServerPrivate
{
GDBusConnection *connection;
gchar *object_path;
gchar *object_path_ending_in_slash;
GHashTable *map_object_path_to_data;
guint manager_reg_id;
};
enum
{
PROP_0,
PROP_CONNECTION,
PROP_OBJECT_PATH
};
static void dbus_object_manager_interface_init (GDBusObjectManagerIface *iface);
G_DEFINE_TYPE_WITH_CODE (GDBusObjectManagerServer, g_dbus_object_manager_server, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (G_TYPE_DBUS_OBJECT_MANAGER, dbus_object_manager_interface_init));
static void g_dbus_object_manager_server_constructed (GObject *object);
static void
g_dbus_object_manager_server_finalize (GObject *object)
{
GDBusObjectManagerServer *manager = G_DBUS_OBJECT_MANAGER_SERVER (object);
g_hash_table_unref (manager->priv->map_object_path_to_data);
if (manager->priv->manager_reg_id > 0)
g_warn_if_fail (g_dbus_connection_unregister_object (manager->priv->connection, manager->priv->manager_reg_id));
g_object_unref (manager->priv->connection);
g_free (manager->priv->object_path);
g_free (manager->priv->object_path_ending_in_slash);
if (G_OBJECT_CLASS (g_dbus_object_manager_server_parent_class)->finalize != NULL)
G_OBJECT_CLASS (g_dbus_object_manager_server_parent_class)->finalize (object);
}
static void
g_dbus_object_manager_server_get_property (GObject *_object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
GDBusObjectManagerServer *manager = G_DBUS_OBJECT_MANAGER_SERVER (_object);
switch (prop_id)
{
case PROP_CONNECTION:
g_value_set_object (value, g_dbus_object_manager_server_get_connection (manager));
break;
case PROP_OBJECT_PATH:
g_value_set_string (value, g_dbus_object_manager_get_object_path (G_DBUS_OBJECT_MANAGER (manager)));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (_object, prop_id, pspec);
break;
}
}
static void
g_dbus_object_manager_server_set_property (GObject *_object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
GDBusObjectManagerServer *manager = G_DBUS_OBJECT_MANAGER_SERVER (_object);
switch (prop_id)
{
case PROP_CONNECTION:
g_assert (manager->priv->connection == NULL);
g_assert (G_IS_DBUS_CONNECTION (g_value_get_object (value)));
manager->priv->connection = g_value_dup_object (value);
break;
case PROP_OBJECT_PATH:
g_assert (manager->priv->object_path == NULL);
g_assert (g_variant_is_object_path (g_value_get_string (value)));
manager->priv->object_path = g_value_dup_string (value);
manager->priv->object_path_ending_in_slash = g_strdup_printf ("%s/", manager->priv->object_path);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (_object, prop_id, pspec);
break;
}
}
static void
g_dbus_object_manager_server_class_init (GDBusObjectManagerServerClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
gobject_class->finalize = g_dbus_object_manager_server_finalize;
gobject_class->constructed = g_dbus_object_manager_server_constructed;
gobject_class->set_property = g_dbus_object_manager_server_set_property;
gobject_class->get_property = g_dbus_object_manager_server_get_property;
/**
* GDBusObjectManagerServer:connection:
*
* The #GDBusConnection to export objects on.
*/
g_object_class_install_property (gobject_class,
PROP_CONNECTION,
g_param_spec_object ("connection",
"Connection",
"The connection to export objects on",
G_TYPE_DBUS_CONNECTION,
G_PARAM_READABLE |
G_PARAM_WRITABLE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
/**
* GDBusObjectManagerServer:object-path:
*
* The object path to register the manager object at.
*/
g_object_class_install_property (gobject_class,
PROP_OBJECT_PATH,
g_param_spec_string ("object-path",
"Object Path",
"The object path to register the manager object at",
NULL,
G_PARAM_READABLE |
G_PARAM_WRITABLE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS));
g_type_class_add_private (klass, sizeof (GDBusObjectManagerServerPrivate));
}
static void
g_dbus_object_manager_server_init (GDBusObjectManagerServer *manager)
{
manager->priv = G_TYPE_INSTANCE_GET_PRIVATE (manager,
G_TYPE_DBUS_OBJECT_MANAGER_SERVER,
GDBusObjectManagerServerPrivate);
manager->priv->map_object_path_to_data = g_hash_table_new_full (g_str_hash,
g_str_equal,
g_free,
(GDestroyNotify) registration_data_free);
}
/**
* g_dbus_object_manager_server_new:
* @connection: A #GDBusConnection.
* @object_path: The object path to export the manager object at.
*
* Creates a new #GDBusObjectManagerServer object.
*
* TODO: make it so that the objects are not exported yet -
* e.g. start()/stop() semantics.
*
* Returns: A #GDBusObjectManagerServer object. Free with g_object_unref().
*/
GDBusObjectManagerServer *
g_dbus_object_manager_server_new (GDBusConnection *connection,
const gchar *object_path)
{
g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL);
g_return_val_if_fail (g_variant_is_object_path (object_path), NULL);
return G_DBUS_OBJECT_MANAGER_SERVER (g_object_new (G_TYPE_DBUS_OBJECT_MANAGER_SERVER,
"connection", connection,
"object-path", object_path,
NULL));
}
/**
* g_dbus_object_manager_server_get_connection:
* @manager: A #GDBusObjectManagerServer
*
* Gets the #GDBusConnection used by @manager.
*
* Returns: A #GDBusConnection object. Do not free, the object belongs
* to @manager.
*/
GDBusConnection *
g_dbus_object_manager_server_get_connection (GDBusObjectManagerServer *manager)
{
g_return_val_if_fail (G_IS_DBUS_OBJECT_MANAGER_SERVER (manager), NULL);
return manager->priv->connection;
}
/* ---------------------------------------------------------------------------------------------------- */
static void
registration_data_export_interface (RegistrationData *data,
GDBusInterfaceStub *interface_stub)
{
GDBusInterfaceInfo *info;
GError *error;
const gchar *object_path;
object_path = g_dbus_object_get_object_path (G_DBUS_OBJECT (data->object));
info = g_dbus_interface_stub_get_info (interface_stub);
error = NULL;
if (!g_dbus_interface_stub_export (interface_stub,
data->manager->priv->connection,
object_path,
&error))
{
/* TODO: probably wrong to complain on stderr */
g_warning ("%s: Error registering object at %s with interface %s: %s",
G_STRLOC,
object_path,
info->name,
error->message);
g_error_free (error);
goto out;
}
g_assert (g_hash_table_lookup (data->map_iface_name_to_iface, info->name) == NULL);
g_hash_table_insert (data->map_iface_name_to_iface,
info->name,
g_object_ref (interface_stub));
/* if we are already exported, then... */
if (data->exported)
{
const gchar *interfaces[2];
/* emit InterfacesAdded on the ObjectManager object */
interfaces[0] = info->name;
interfaces[1] = NULL;
g_dbus_object_manager_server_emit_interfaces_added (data->manager, data, interfaces);
}
out:
;
}
static void
registration_data_unexport_interface (RegistrationData *data,
GDBusInterfaceStub *interface_stub)
{
GDBusInterfaceInfo *info;
GDBusInterfaceStub *iface;
info = g_dbus_interface_stub_get_info (interface_stub);
iface = g_hash_table_lookup (data->map_iface_name_to_iface, info->name);
g_assert (iface != NULL);
g_dbus_interface_stub_unexport (iface);
g_warn_if_fail (g_hash_table_remove (data->map_iface_name_to_iface, info->name));
/* if we are already exported, then... */
if (data->exported)
{
const gchar *interfaces[2];
/* emit InterfacesRemoved on the ObjectManager object */
interfaces[0] = info->name;
interfaces[1] = NULL;
g_dbus_object_manager_server_emit_interfaces_removed (data->manager, data, interfaces);
}
}
/* ---------------------------------------------------------------------------------------------------- */
static void
on_interface_added (GDBusObject *object,
GDBusInterface *interface,
gpointer user_data)
{
RegistrationData *data = user_data;
registration_data_export_interface (data, G_DBUS_INTERFACE_STUB (interface));
}
static void
on_interface_removed (GDBusObject *object,
GDBusInterface *interface,
gpointer user_data)
{
RegistrationData *data = user_data;
registration_data_unexport_interface (data, G_DBUS_INTERFACE_STUB (interface));
}
/* ---------------------------------------------------------------------------------------------------- */
static void
registration_data_free (RegistrationData *data)
{
GHashTableIter iter;
GDBusInterfaceStub *iface;
data->exported = FALSE;
g_hash_table_iter_init (&iter, data->map_iface_name_to_iface);
while (g_hash_table_iter_next (&iter, NULL, (gpointer) &iface))
g_dbus_interface_stub_unexport (iface);
g_signal_handlers_disconnect_by_func (data->object, G_CALLBACK (on_interface_added), data);
g_signal_handlers_disconnect_by_func (data->object, G_CALLBACK (on_interface_removed), data);
g_object_unref (data->object);
g_hash_table_destroy (data->map_iface_name_to_iface);
g_free (data);
}
/* ---------------------------------------------------------------------------------------------------- */
/**
* g_dbus_object_manager_server_export:
* @manager: A #GDBusObjectManagerServer.
* @object: A #GDBusObjectStub.
*
* Exports @object on @manager.
*
* If there is already a #GDBusObject exported at the object path,
* then the old object is removed.
*
* The object path for @object must be in the hierarchy rooted by the
* object path for @manager.
*
* Note that @manager will take a reference on @object for as long as
* it is exported.
*/
void
g_dbus_object_manager_server_export (GDBusObjectManagerServer *manager,
GDBusObjectStub *object)
{
RegistrationData *data;
GList *existing_interfaces;
GList *l;
GPtrArray *interface_names;
const gchar *object_path;
object_path = g_dbus_object_get_object_path (G_DBUS_OBJECT (object));
g_return_if_fail (G_IS_DBUS_OBJECT_MANAGER_SERVER (manager));
g_return_if_fail (G_IS_DBUS_OBJECT (object));
g_return_if_fail (g_str_has_prefix (object_path, manager->priv->object_path_ending_in_slash));
interface_names = g_ptr_array_new ();
data = g_hash_table_lookup (manager->priv->map_object_path_to_data, object_path);
if (data != NULL)
g_dbus_object_manager_server_unexport (manager, object_path);
data = g_new0 (RegistrationData, 1);
data->object = g_object_ref (object);
data->manager = manager;
data->map_iface_name_to_iface = g_hash_table_new_full (g_str_hash,
g_str_equal,
NULL,
(GDestroyNotify) g_object_unref);
g_signal_connect (object,
"interface-added",
G_CALLBACK (on_interface_added),
data);
g_signal_connect (object,
"interface-removed",
G_CALLBACK (on_interface_removed),
data);
/* Register all known interfaces - note that data->exported is FALSE so
* we don't emit any InterfacesAdded signals.
*/
existing_interfaces = g_dbus_object_get_interfaces (G_DBUS_OBJECT (object));
for (l = existing_interfaces; l != NULL; l = l->next)
{
GDBusInterfaceStub *interface_stub = G_DBUS_INTERFACE_STUB (l->data);
registration_data_export_interface (data, interface_stub);
g_ptr_array_add (interface_names, g_dbus_interface_stub_get_info (interface_stub)->name);
}
g_list_foreach (existing_interfaces, (GFunc) g_object_unref, NULL);
g_list_free (existing_interfaces);
g_ptr_array_add (interface_names, NULL);
data->exported = TRUE;
/* now emit InterfacesAdded() for all the interfaces */
g_dbus_object_manager_server_emit_interfaces_added (manager, data, (const gchar *const *) interface_names->pdata);
g_ptr_array_unref (interface_names);
g_hash_table_insert (manager->priv->map_object_path_to_data,
g_strdup (object_path),
data);
}
/**
* g_dbus_object_manager_server_export_and_uniquify:
* @manager: A #GDBusObjectManagerServer.
* @object: An object.
*
* Like g_dbus_object_manager_server_export() but appends a string of
* the form <literal>_N</literal> (with N being a natural number) to
* @object<!-- -->'s object path if an object with the given path
* already exists. As such, the #GDBusObjectProxy:object-path property
* of @object may be modified.
*/
void
g_dbus_object_manager_server_export_and_uniquify (GDBusObjectManagerServer *manager,
GDBusObjectStub *object)
{
gchar *orig_object_path;
gchar *object_path;
guint count;
gboolean modified;
orig_object_path = g_strdup (g_dbus_object_get_object_path (G_DBUS_OBJECT (object)));
g_return_if_fail (G_IS_DBUS_OBJECT_MANAGER_SERVER (manager));
g_return_if_fail (G_IS_DBUS_OBJECT (object));
g_return_if_fail (g_str_has_prefix (orig_object_path, manager->priv->object_path_ending_in_slash));
object_path = g_strdup (orig_object_path);
count = 1;
modified = FALSE;
while (TRUE)
{
RegistrationData *data;
data = g_hash_table_lookup (manager->priv->map_object_path_to_data, object_path);
if (data == NULL)
{
break;
}
g_free (object_path);
object_path = g_strdup_printf ("%s_%d", orig_object_path, count++);
modified = TRUE;
}
if (modified)
g_dbus_object_stub_set_object_path (G_DBUS_OBJECT_STUB (object), object_path);
g_dbus_object_manager_server_export (manager, object);
g_free (object_path);
g_free (orig_object_path);
}
/**
* g_dbus_object_manager_server_unexport:
* @manager: A #GDBusObjectManagerServer.
* @object_path: An object path.
*
* If @manager has an object at @path, removes the object. Otherwise
* does nothing.
*
* Note that @object_path must be in the hierarchy rooted by the
* object path for @manager.
*/
void
g_dbus_object_manager_server_unexport (GDBusObjectManagerServer *manager,
const gchar *object_path)
{
RegistrationData *data;
g_return_if_fail (G_IS_DBUS_OBJECT_MANAGER_SERVER (manager));
g_return_if_fail (g_variant_is_object_path (object_path));
g_return_if_fail (g_str_has_prefix (object_path, manager->priv->object_path_ending_in_slash));
data = g_hash_table_lookup (manager->priv->map_object_path_to_data, object_path);
if (data != NULL)
{
GPtrArray *interface_names;
GHashTableIter iter;
const gchar *iface_name;
interface_names = g_ptr_array_new ();
g_hash_table_iter_init (&iter, data->map_iface_name_to_iface);
while (g_hash_table_iter_next (&iter, (gpointer) &iface_name, NULL))
g_ptr_array_add (interface_names, (gpointer) iface_name);
g_ptr_array_add (interface_names, NULL);
/* now emit InterfacesRemoved() for all the interfaces */
g_dbus_object_manager_server_emit_interfaces_removed (manager, data, (const gchar *const *) interface_names->pdata);
g_ptr_array_unref (interface_names);
g_hash_table_remove (manager->priv->map_object_path_to_data, object_path);
}
}
/* ---------------------------------------------------------------------------------------------------- */
static const GDBusArgInfo manager_interfaces_added_signal_info_arg0 =
{
-1,
"object_path",
"o",
(GDBusAnnotationInfo**) NULL,
};
static const GDBusArgInfo manager_interfaces_added_signal_info_arg1 =
{
-1,
"interfaces_and_properties",
"a{sa{sv}}",
(GDBusAnnotationInfo**) NULL,
};
static const GDBusArgInfo * const manager_interfaces_added_signal_info_arg_pointers[] =
{
&manager_interfaces_added_signal_info_arg0,
&manager_interfaces_added_signal_info_arg1,
NULL
};
static const GDBusSignalInfo manager_interfaces_added_signal_info =
{
-1,
"InterfacesAdded",
(GDBusArgInfo**) &manager_interfaces_added_signal_info_arg_pointers,
(GDBusAnnotationInfo**) NULL
};
/* ---------- */
static const GDBusArgInfo manager_interfaces_removed_signal_info_arg0 =
{
-1,
"object_path",
"o",
(GDBusAnnotationInfo**) NULL,
};
static const GDBusArgInfo manager_interfaces_removed_signal_info_arg1 =
{
-1,
"interfaces",
"as",
(GDBusAnnotationInfo**) NULL,
};
static const GDBusArgInfo * const manager_interfaces_removed_signal_info_arg_pointers[] =
{
&manager_interfaces_removed_signal_info_arg0,
&manager_interfaces_removed_signal_info_arg1,
NULL
};
static const GDBusSignalInfo manager_interfaces_removed_signal_info =
{
-1,
"InterfacesRemoved",
(GDBusArgInfo**) &manager_interfaces_removed_signal_info_arg_pointers,
(GDBusAnnotationInfo**) NULL
};
/* ---------- */
static const GDBusSignalInfo * const manager_signal_info_pointers[] =
{
&manager_interfaces_added_signal_info,
&manager_interfaces_removed_signal_info,
NULL
};
/* ---------- */
static const GDBusArgInfo manager_get_all_method_info_out_arg0 =
{
-1,
"object_paths_interfaces_and_properties",
"a{oa{sa{sv}}}",
(GDBusAnnotationInfo**) NULL,
};
static const GDBusArgInfo * const manager_get_all_method_info_out_arg_pointers[] =
{
&manager_get_all_method_info_out_arg0,
NULL
};
static const GDBusMethodInfo manager_get_all_method_info =
{
-1,
"GetManagedObjects",
(GDBusArgInfo**) NULL,
(GDBusArgInfo**) &manager_get_all_method_info_out_arg_pointers,
(GDBusAnnotationInfo**) NULL
};
static const GDBusMethodInfo * const manager_method_info_pointers[] =
{
&manager_get_all_method_info,
NULL
};
/* ---------- */
static const GDBusInterfaceInfo manager_interface_info =
{
-1,
"org.freedesktop.DBus.ObjectManager",
(GDBusMethodInfo **) manager_method_info_pointers,
(GDBusSignalInfo **) manager_signal_info_pointers,
(GDBusPropertyInfo **) NULL,
(GDBusAnnotationInfo **) NULL
};
static void
manager_method_call (GDBusConnection *connection,
const gchar *sender,
const gchar *object_path,
const gchar *interface_name,
const gchar *method_name,
GVariant *parameters,
GDBusMethodInvocation *invocation,
gpointer user_data)
{
GDBusObjectManagerServer *manager = G_DBUS_OBJECT_MANAGER_SERVER (user_data);
GVariantBuilder array_builder;
GHashTableIter object_iter;
RegistrationData *data;
if (g_strcmp0 (method_name, "GetManagedObjects") == 0)
{
g_variant_builder_init (&array_builder, G_VARIANT_TYPE ("a{oa{sa{sv}}}"));
g_hash_table_iter_init (&object_iter, manager->priv->map_object_path_to_data);
while (g_hash_table_iter_next (&object_iter, NULL, (gpointer) &data))
{
GVariantBuilder interfaces_builder;
GHashTableIter interface_iter;
GDBusInterfaceStub *iface;
const gchar *iter_object_path;
g_variant_builder_init (&interfaces_builder, G_VARIANT_TYPE ("a{sa{sv}}"));
g_hash_table_iter_init (&interface_iter, data->map_iface_name_to_iface);
while (g_hash_table_iter_next (&interface_iter, NULL, (gpointer) &iface))
{
g_variant_builder_add_value (&interfaces_builder,
g_variant_new ("{s@a{sv}}",
g_dbus_interface_stub_get_info (iface)->name,
g_dbus_interface_stub_get_properties (iface)));
}
iter_object_path = g_dbus_object_get_object_path (G_DBUS_OBJECT (data->object));
g_variant_builder_add (&array_builder,
"{oa{sa{sv}}}",
iter_object_path,
&interfaces_builder);
}
g_dbus_method_invocation_return_value (invocation,
g_variant_new ("(a{oa{sa{sv}}})",
&array_builder));
}
else
{
g_dbus_method_invocation_return_error (invocation,
G_DBUS_ERROR,
G_DBUS_ERROR_UNKNOWN_METHOD,
"Unknown method %s - only GetManagedObjects() is supported",
method_name);
}
}
static const GDBusInterfaceVTable manager_interface_vtable =
{
manager_method_call, /* handle_method_call */
NULL, /* get_property */
NULL /* set_property */
};
/* ---------------------------------------------------------------------------------------------------- */
static void
g_dbus_object_manager_server_constructed (GObject *object)
{
GDBusObjectManagerServer *manager = G_DBUS_OBJECT_MANAGER_SERVER (object);
GError *error;
error = NULL;
manager->priv->manager_reg_id = g_dbus_connection_register_object (manager->priv->connection,
manager->priv->object_path,
(GDBusInterfaceInfo *) &manager_interface_info,
&manager_interface_vtable,
manager,
NULL, /* user_data_free_func */
&error);
if (manager->priv->manager_reg_id == 0)
{
/* TODO: probably wrong to complain on stderr */
g_warning ("%s: Error registering manager at %s: %s",
G_STRLOC,
manager->priv->object_path,
error->message);
g_error_free (error);
}
if (G_OBJECT_CLASS (g_dbus_object_manager_server_parent_class)->constructed != NULL)
G_OBJECT_CLASS (g_dbus_object_manager_server_parent_class)->constructed (object);
}
static void
g_dbus_object_manager_server_emit_interfaces_added (GDBusObjectManagerServer *manager,
RegistrationData *data,
const gchar *const *interfaces)
{
GVariantBuilder array_builder;
GError *error;
guint n;
const gchar *object_path;
g_variant_builder_init (&array_builder, G_VARIANT_TYPE ("a{sa{sv}}"));
for (n = 0; interfaces[n] != NULL; n++)
{
GDBusInterfaceStub *iface;
iface = g_hash_table_lookup (data->map_iface_name_to_iface, interfaces[n]);
g_assert (iface != NULL);
g_variant_builder_add_value (&array_builder,
g_variant_new ("{s@a{sv}}",
interfaces[n],
g_dbus_interface_stub_get_properties (iface)));
}
error = NULL;
object_path = g_dbus_object_get_object_path (G_DBUS_OBJECT (data->object));
g_dbus_connection_emit_signal (data->manager->priv->connection,
NULL, /* destination_bus_name */
manager->priv->object_path,
manager_interface_info.name,
"InterfacesAdded",
g_variant_new ("(oa{sa{sv}})",
object_path,
&array_builder),
&error);
g_assert_no_error (error);
}
static void
g_dbus_object_manager_server_emit_interfaces_removed (GDBusObjectManagerServer *manager,
RegistrationData *data,
const gchar *const *interfaces)
{
GVariantBuilder array_builder;
GError *error;
guint n;
const gchar *object_path;
g_variant_builder_init (&array_builder, G_VARIANT_TYPE ("as"));
for (n = 0; interfaces[n] != NULL; n++)
g_variant_builder_add (&array_builder, "s", interfaces[n]);
error = NULL;
object_path = g_dbus_object_get_object_path (G_DBUS_OBJECT (data->object));
g_dbus_connection_emit_signal (data->manager->priv->connection,
NULL, /* destination_bus_name */
manager->priv->object_path,
manager_interface_info.name,
"InterfacesRemoved",
g_variant_new ("(oas)",
object_path,
&array_builder),
&error);
g_assert_no_error (error);
}
/* ---------------------------------------------------------------------------------------------------- */
static GList *
g_dbus_object_manager_server_get_objects (GDBusObjectManager *_manager)
{
GDBusObjectManagerServer *manager = G_DBUS_OBJECT_MANAGER_SERVER (_manager);
GList *ret;
GHashTableIter iter;
RegistrationData *data;
ret = NULL;
g_hash_table_iter_init (&iter, manager->priv->map_object_path_to_data);
while (g_hash_table_iter_next (&iter, NULL, (gpointer) &data))
{
ret = g_list_prepend (ret, g_object_ref (data->object));
}
return ret;
}
static const gchar *
g_dbus_object_manager_server_get_object_path (GDBusObjectManager *_manager)
{
GDBusObjectManagerServer *manager = G_DBUS_OBJECT_MANAGER_SERVER (_manager);
return manager->priv->object_path;
}
static GDBusObject *
g_dbus_object_manager_server_get_object (GDBusObjectManager *_manager,
const gchar *object_path)
{
GDBusObjectManagerServer *manager = G_DBUS_OBJECT_MANAGER_SERVER (_manager);
GDBusObject *ret;
RegistrationData *data;
ret = NULL;
data = g_hash_table_lookup (manager->priv->map_object_path_to_data, object_path);
if (data != NULL)
ret = g_object_ref (data->object);
return ret;
}
static GDBusInterface *
g_dbus_object_manager_server_get_interface (GDBusObjectManager *_manager,
const gchar *object_path,
const gchar *interface_name)
{
GDBusInterface *ret;
GDBusObject *object;
ret = NULL;
object = g_dbus_object_manager_get_object (_manager, object_path);
if (object == NULL)
goto out;
ret = g_dbus_object_get_interface (object, interface_name);
g_object_unref (object);
out:
return ret;
}
static void
dbus_object_manager_interface_init (GDBusObjectManagerIface *iface)
{
iface->get_object_path = g_dbus_object_manager_server_get_object_path;
iface->get_objects = g_dbus_object_manager_server_get_objects;
iface->get_object = g_dbus_object_manager_server_get_object;
iface->get_interface = g_dbus_object_manager_server_get_interface;
}

View File

@ -0,0 +1,80 @@
/* 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>
*/
#ifndef __G_DBUS_OBJECT_MANAGER_SERVER_H__
#define __G_DBUS_OBJECT_MANAGER_SERVER_H__
#include <gio/giotypes.h>
G_BEGIN_DECLS
#define G_TYPE_DBUS_OBJECT_MANAGER_SERVER (g_dbus_object_manager_server_get_type ())
#define G_DBUS_OBJECT_MANAGER_SERVER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_DBUS_OBJECT_MANAGER_SERVER, GDBusObjectManagerServer))
#define G_DBUS_OBJECT_MANAGER_SERVER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_DBUS_OBJECT_MANAGER_SERVER, GDBusObjectManagerServerClass))
#define G_DBUS_OBJECT_MANAGER_SERVER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_DBUS_OBJECT_MANAGER_SERVER, GDBusObjectManagerServerClass))
#define G_IS_DBUS_OBJECT_MANAGER_SERVER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_DBUS_OBJECT_MANAGER_SERVER))
#define G_IS_DBUS_OBJECT_MANAGER_SERVER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_DBUS_OBJECT_MANAGER_SERVER))
typedef struct _GDBusObjectManagerServerClass GDBusObjectManagerServerClass;
typedef struct _GDBusObjectManagerServerPrivate GDBusObjectManagerServerPrivate;
/**
* GDBusObjectManagerServer:
*
* The #GDBusObjectManagerServer structure contains private data and should
* only be accessed using the provided API.
*/
struct _GDBusObjectManagerServer
{
/*< private >*/
GObject parent_instance;
GDBusObjectManagerServerPrivate *priv;
};
/**
* GDBusObjectManagerServerClass:
* @parent_class: The parent class.
*
* Class structure for #GDBusObjectManagerServer.
*/
struct _GDBusObjectManagerServerClass
{
GObjectClass parent_class;
/*< private >*/
gpointer padding[8];
};
GType g_dbus_object_manager_server_get_type (void) G_GNUC_CONST;
GDBusObjectManagerServer *g_dbus_object_manager_server_new (GDBusConnection *connection,
const gchar *object_path);
GDBusConnection *g_dbus_object_manager_server_get_connection (GDBusObjectManagerServer *manager);
void g_dbus_object_manager_server_export (GDBusObjectManagerServer *manager,
GDBusObjectStub *object);
void g_dbus_object_manager_server_export_and_uniquify (GDBusObjectManagerServer *manager,
GDBusObjectStub *object);
void g_dbus_object_manager_server_unexport (GDBusObjectManagerServer *manager,
const gchar *object_path);
G_END_DECLS
#endif /* __G_DBUS_OBJECT_MANAGER_SERVER_H */

315
gio/gdbusobjectproxy.c Normal file
View File

@ -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;
}

72
gio/gdbusobjectproxy.h Normal file
View File

@ -0,0 +1,72 @@
/* 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>
*/
#ifndef __G_DBUS_OBJECT_PROXY_H__
#define __G_DBUS_OBJECT_PROXY_H__
#include <gio/giotypes.h>
G_BEGIN_DECLS
#define G_TYPE_DBUS_OBJECT_PROXY (g_dbus_object_proxy_get_type ())
#define G_DBUS_OBJECT_PROXY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_DBUS_OBJECT_PROXY, GDBusObjectProxy))
#define G_DBUS_OBJECT_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_DBUS_OBJECT_PROXY, GDBusObjectProxyClass))
#define G_DBUS_OBJECT_PROXY_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_DBUS_OBJECT_PROXY, GDBusObjectProxyClass))
#define G_IS_DBUS_OBJECT_PROXY(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_DBUS_OBJECT_PROXY))
#define G_IS_DBUS_OBJECT_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_DBUS_OBJECT_PROXY))
typedef struct _GDBusObjectProxyClass GDBusObjectProxyClass;
typedef struct _GDBusObjectProxyPrivate GDBusObjectProxyPrivate;
/**
* GDBusObjectProxy:
*
* The #GDBusObjectProxy structure contains private data and should
* only be accessed using the provided API.
*/
struct _GDBusObjectProxy
{
/*< private >*/
GObject parent_instance;
GDBusObjectProxyPrivate *priv;
};
/**
* GDBusObjectProxyClass:
* @parent_class: The parent class.
*
* Class structure for #GDBusObjectProxy.
*/
struct _GDBusObjectProxyClass
{
GObjectClass parent_class;
/*< private >*/
gpointer padding[8];
};
GType g_dbus_object_proxy_get_type (void) G_GNUC_CONST;
GDBusConnection *g_dbus_object_proxy_get_connection (GDBusObjectProxy *proxy);
G_END_DECLS
#endif /* __G_DBUS_OBJECT_PROXY_H */

475
gio/gdbusobjectstub.c Normal file
View File

@ -0,0 +1,475 @@
/* 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 "gdbusobjectstub.h"
#include "gdbusinterfacestub.h"
#include "gio-marshal.h"
#include "gdbusprivate.h"
#include "gdbusmethodinvocation.h"
#include "gdbusintrospection.h"
#include "gdbusinterface.h"
#include "gdbusutils.h"
#include "glibintl.h"
/**
* SECTION:gdbusobjectstub
* @short_description: Service-side D-Bus object
* @include: gio/gio.h
*
* A #GDBusObjectStub instance is essentially a group of D-Bus
* interfaces. The set of exported interfaces on the object may be
* dynamic and change at runtime.
*
* This type is intended to be used with #GDBusObjectManager.
*/
struct _GDBusObjectStubPrivate
{
gchar *object_path;
GHashTable *map_name_to_iface;
};
enum
{
PROP_0,
PROP_OBJECT_PATH
};
enum
{
AUTHORIZE_METHOD_SIGNAL,
LAST_SIGNAL,
};
static guint signals[LAST_SIGNAL] = {0};
static void dbus_object_interface_init (GDBusObjectIface *iface);
G_DEFINE_TYPE_WITH_CODE (GDBusObjectStub, g_dbus_object_stub, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (G_TYPE_DBUS_OBJECT, dbus_object_interface_init));
static void
g_dbus_object_stub_finalize (GObject *_object)
{
GDBusObjectStub *object = G_DBUS_OBJECT_STUB (_object);
g_free (object->priv->object_path);
g_hash_table_unref (object->priv->map_name_to_iface);
if (G_OBJECT_CLASS (g_dbus_object_stub_parent_class)->finalize != NULL)
G_OBJECT_CLASS (g_dbus_object_stub_parent_class)->finalize (_object);
}
static void
g_dbus_object_stub_get_property (GObject *_object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
GDBusObjectStub *object = G_DBUS_OBJECT_STUB (_object);
switch (prop_id)
{
case PROP_OBJECT_PATH:
g_value_take_string (value, object->priv->object_path);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (_object, prop_id, pspec);
break;
}
}
static void
g_dbus_object_stub_set_property (GObject *_object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
GDBusObjectStub *object = G_DBUS_OBJECT_STUB (_object);
switch (prop_id)
{
case PROP_OBJECT_PATH:
g_dbus_object_stub_set_object_path (object, g_value_get_string (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (_object, prop_id, pspec);
break;
}
}
static gboolean
g_dbus_object_stub_authorize_method_default (GDBusObjectStub *object,
GDBusInterfaceStub *interface,
GDBusMethodInvocation *invocation)
{
return TRUE;
}
static void
g_dbus_object_stub_class_init (GDBusObjectStubClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
gobject_class->finalize = g_dbus_object_stub_finalize;
gobject_class->set_property = g_dbus_object_stub_set_property;
gobject_class->get_property = g_dbus_object_stub_get_property;
klass->authorize_method = g_dbus_object_stub_authorize_method_default;
/**
* GDBusObjectStub:object-path:
*
* The object path where the object is exported.
*/
g_object_class_install_property (gobject_class,
PROP_OBJECT_PATH,
g_param_spec_string ("object-path",
"Object Path",
"The object path where the object is exported",
NULL,
G_PARAM_READABLE |
G_PARAM_WRITABLE |
G_PARAM_CONSTRUCT |
G_PARAM_STATIC_STRINGS));
/**
* GDBusObjectStub::authorize-method:
* @object: The #GDBusObjectStub emitting the signal.
* @interface: The #GDBusInterfaceStub that @invocation is on.
* @invocation: A #GDBusMethodInvocation.
*
* Emitted when a method is invoked by a remote caller and used to
* determine if the method call is authorized.
*
* This signal is like #GDBusInterfaceStub<!-- -->'s
* #GDBusInterfaceStub::g-authorize-method signal, except that it is
* for the enclosing object.
*
* The default class handler just returns %TRUE.
*
* Returns: %TRUE if the call is authorized, %FALSE otherwise.
*/
signals[AUTHORIZE_METHOD_SIGNAL] =
g_signal_new ("authorize-method",
G_TYPE_DBUS_OBJECT_STUB,
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GDBusObjectStubClass, authorize_method),
_g_signal_accumulator_false_handled,
NULL,
_gio_marshal_BOOLEAN__OBJECT_OBJECT,
G_TYPE_BOOLEAN,
2,
G_TYPE_DBUS_INTERFACE_STUB,
G_TYPE_DBUS_METHOD_INVOCATION);
g_type_class_add_private (klass, sizeof (GDBusObjectStubPrivate));
}
static void
g_dbus_object_stub_init (GDBusObjectStub *object)
{
object->priv = G_TYPE_INSTANCE_GET_PRIVATE (object, G_TYPE_DBUS_OBJECT_STUB, GDBusObjectStubPrivate);
object->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_stub_new:
* @object_path: An object path.
*
* Creates a new #GDBusObjectStub.
*
* Returns: A #GDBusObjectStub. Free with g_object_unref().
*/
GDBusObjectStub *
g_dbus_object_stub_new (const gchar *object_path)
{
g_return_val_if_fail (g_variant_is_object_path (object_path), NULL);
return G_DBUS_OBJECT_STUB (g_object_new (G_TYPE_DBUS_OBJECT_STUB,
"object-path", object_path,
NULL));
}
/**
* g_dbus_object_stub_set_object_path:
* @object: A #GDBusObjectStub.
* @object_path: A valid D-Bus object path.
*
* Sets the object path for @object.
*/
void
g_dbus_object_stub_set_object_path (GDBusObjectStub *object,
const gchar *object_path)
{
g_return_if_fail (G_IS_DBUS_OBJECT_STUB (object));
g_return_if_fail (object_path == NULL || g_variant_is_object_path (object_path));
/* TODO: fail if object is currently exported */
if (g_strcmp0 (object->priv->object_path, object_path) != 0)
{
g_free (object->priv->object_path);
object->priv->object_path = g_strdup (object_path);
g_object_notify (G_OBJECT (object), "object-path");
}
}
static const gchar *
g_dbus_object_stub_get_object_path (GDBusObject *_object)
{
GDBusObjectStub *object = G_DBUS_OBJECT_STUB (_object);
return object->priv->object_path;
}
/**
* g_dbus_object_stub_add_interface:
* @object: A #GDBusObjectStub.
* @interface: A #GDBusInterfaceStub.
*
* Adds @interface to @object.
*
* If @object already contains a #GDBusInterfaceStub with the same
* interface name, it is removed before @interface is added.
*
* Note that @object takes its own reference on @interface and holds
* it until removed.
*/
void
g_dbus_object_stub_add_interface (GDBusObjectStub *object,
GDBusInterfaceStub *interface)
{
GDBusInterfaceInfo *info;
g_return_if_fail (G_IS_DBUS_OBJECT_STUB (object));
g_return_if_fail (G_IS_DBUS_INTERFACE_STUB (interface));
info = g_dbus_interface_stub_get_info (interface);
g_object_ref (interface);
g_dbus_object_stub_remove_interface_by_name (object, info->name);
g_hash_table_insert (object->priv->map_name_to_iface,
g_strdup (info->name),
interface);
g_dbus_interface_set_object (G_DBUS_INTERFACE (interface), G_DBUS_OBJECT (object));
g_signal_emit_by_name (object,
"interface-added",
interface);
}
/**
* g_dbus_object_stub_remove_interface:
* @object: A #GDBusObjectStub.
* @interface: A #GDBusInterfaceStub.
*
* Removes @interface from @object.
*/
void
g_dbus_object_stub_remove_interface (GDBusObjectStub *object,
GDBusInterfaceStub *interface)
{
GDBusInterfaceStub *other_interface;
GDBusInterfaceInfo *info;
g_return_if_fail (G_IS_DBUS_OBJECT_STUB (object));
g_return_if_fail (G_IS_DBUS_INTERFACE (interface));
info = g_dbus_interface_stub_get_info (interface);
other_interface = g_hash_table_lookup (object->priv->map_name_to_iface, info->name);
if (other_interface == NULL)
{
g_warning ("Tried to remove interface with name %s from object "
"at path %s but no such interface exists",
info->name,
object->priv->object_path);
}
else if (other_interface != interface)
{
g_warning ("Tried to remove interface %p with name %s from object "
"at path %s but the object has the interface %p",
interface,
info->name,
object->priv->object_path,
other_interface);
}
else
{
g_object_ref (interface);
g_warn_if_fail (g_hash_table_remove (object->priv->map_name_to_iface, info->name));
g_dbus_interface_set_object (G_DBUS_INTERFACE (interface), NULL);
g_signal_emit_by_name (object,
"interface-removed",
interface);
g_object_unref (interface);
}
}
/**
* g_dbus_object_stub_remove_interface_by_name:
* @object: A #GDBusObjectStub.
* @interface_name: A D-Bus interface name.
*
* Removes the #GDBusInterface with @interface_name from @object.
*
* If no D-Bus interface of the given interface exists, this function
* does nothing.
*/
void
g_dbus_object_stub_remove_interface_by_name (GDBusObjectStub *object,
const gchar *interface_name)
{
GDBusInterface *interface;
g_return_if_fail (G_IS_DBUS_OBJECT_STUB (object));
g_return_if_fail (g_dbus_is_interface_name (interface_name));
interface = g_hash_table_lookup (object->priv->map_name_to_iface, interface_name);
if (interface != NULL)
{
g_object_ref (interface);
g_warn_if_fail (g_hash_table_remove (object->priv->map_name_to_iface, interface_name));
g_dbus_interface_set_object (interface, NULL);
g_signal_emit_by_name (object,
"interface-removed",
interface);
g_object_unref (interface);
}
}
static GDBusInterface *
g_dbus_object_stub_get_interface (GDBusObject *_object,
const gchar *interface_name)
{
GDBusObjectStub *object = G_DBUS_OBJECT_STUB (_object);
GDBusInterface *ret;
g_return_val_if_fail (G_IS_DBUS_OBJECT_STUB (object), NULL);
g_return_val_if_fail (g_dbus_is_interface_name (interface_name), NULL);
ret = g_hash_table_lookup (object->priv->map_name_to_iface, interface_name);
if (ret != NULL)
g_object_ref (ret);
return ret;
}
static GList *
g_dbus_object_stub_get_interfaces (GDBusObject *_object)
{
GDBusObjectStub *object = G_DBUS_OBJECT_STUB (_object);
GList *ret;
GHashTableIter iter;
GDBusInterface *interface;
g_return_val_if_fail (G_IS_DBUS_OBJECT_STUB (object), NULL);
ret = NULL;
g_hash_table_iter_init (&iter, object->priv->map_name_to_iface);
while (g_hash_table_iter_next (&iter, NULL, (gpointer) &interface))
ret = g_list_prepend (ret, g_object_ref (interface));
return ret;
}
/**
* g_dbus_object_stub_flush:
* @object: A #GDBusObjectStub.
*
* This method simply calls g_dbus_interface_stub_flush() on all
* interfaces stubs belonging to @object. See that method for when
* flushing is useful.
*/
void
g_dbus_object_stub_flush (GDBusObjectStub *object)
{
GHashTableIter iter;
GDBusInterfaceStub *interface_stub;
g_hash_table_iter_init (&iter, object->priv->map_name_to_iface);
while (g_hash_table_iter_next (&iter, NULL, (gpointer) &interface_stub))
{
g_dbus_interface_stub_flush (interface_stub);
}
}
static gpointer
g_dbus_object_stub_lookup_with_typecheck (GDBusObject *object,
const gchar *interface_name,
GType type)
{
GDBusObjectStub *stub = G_DBUS_OBJECT_STUB (object);
GDBusProxy *ret;
ret = g_hash_table_lookup (stub->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_stub_peek_with_typecheck (GDBusObject *object,
const gchar *interface_name,
GType type)
{
GDBusInterfaceStub *ret;
ret = g_dbus_object_stub_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_stub_get_object_path;
iface->get_interfaces = g_dbus_object_stub_get_interfaces;
iface->get_interface = g_dbus_object_stub_get_interface;
iface->lookup_with_typecheck = g_dbus_object_stub_lookup_with_typecheck;
iface->peek_with_typecheck = g_dbus_object_stub_peek_with_typecheck;
}
gboolean
_g_dbus_object_stub_has_authorize_method_handlers (GDBusObjectStub *stub)
{
gboolean has_handlers;
gboolean has_default_class_handler;
has_handlers = g_signal_has_handler_pending (stub,
signals[AUTHORIZE_METHOD_SIGNAL],
0,
TRUE);
has_default_class_handler = (G_DBUS_OBJECT_STUB_GET_CLASS (stub)->authorize_method ==
g_dbus_object_stub_authorize_method_default);
return has_handlers || !has_default_class_handler;
}

87
gio/gdbusobjectstub.h Normal file
View File

@ -0,0 +1,87 @@
/* 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>
*/
#ifndef __G_DBUS_OBJECT_STUB_H__
#define __G_DBUS_OBJECT_STUB_H__
#include <gio/giotypes.h>
G_BEGIN_DECLS
#define G_TYPE_DBUS_OBJECT_STUB (g_dbus_object_stub_get_type ())
#define G_DBUS_OBJECT_STUB(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_DBUS_OBJECT_STUB, GDBusObjectStub))
#define G_DBUS_OBJECT_STUB_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_DBUS_OBJECT_STUB, GDBusObjectStubClass))
#define G_DBUS_OBJECT_STUB_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_DBUS_OBJECT_STUB, GDBusObjectStubClass))
#define G_IS_DBUS_OBJECT_STUB(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_DBUS_OBJECT_STUB))
#define G_IS_DBUS_OBJECT_STUB_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_DBUS_OBJECT_STUB))
typedef struct _GDBusObjectStubClass GDBusObjectStubClass;
typedef struct _GDBusObjectStubPrivate GDBusObjectStubPrivate;
/**
* GDBusObjectStub:
*
* The #GDBusObjectStub structure contains private data and should only be
* accessed using the provided API.
*/
struct _GDBusObjectStub
{
/*< private >*/
GObject parent_instance;
GDBusObjectStubPrivate *priv;
};
/**
* GDBusObjectStubClass:
* @parent_class: The parent class.
* @authorize_method: Signal class handler for the #GDBusObjectStub::authorize-method signal.
*
* Class structure for #GDBusObjectStub.
*/
struct _GDBusObjectStubClass
{
GObjectClass parent_class;
/* Signals */
gboolean (*authorize_method) (GDBusObjectStub *stub,
GDBusInterfaceStub *interface_stub,
GDBusMethodInvocation *invocation);
/*< private >*/
gpointer padding[8];
};
GType g_dbus_object_stub_get_type (void) G_GNUC_CONST;
GDBusObjectStub *g_dbus_object_stub_new (const gchar *object_path);
void g_dbus_object_stub_flush (GDBusObjectStub *object);
void g_dbus_object_stub_add_interface (GDBusObjectStub *object,
GDBusInterfaceStub *interface);
void g_dbus_object_stub_remove_interface (GDBusObjectStub *object,
GDBusInterfaceStub *interface);
void g_dbus_object_stub_remove_interface_by_name (GDBusObjectStub *object,
const gchar *interface_name);
void g_dbus_object_stub_set_object_path (GDBusObjectStub *object,
const gchar *object_path);
G_END_DECLS
#endif /* __G_DBUS_OBJECT_STUB_H */

View File

@ -1869,3 +1869,21 @@ read_message_print_transport_debug (gssize bytes_read,
out:
;
}
/* ---------------------------------------------------------------------------------------------------- */
gboolean
_g_signal_accumulator_false_handled (GSignalInvocationHint *ihint,
GValue *return_accu,
const GValue *handler_return,
gpointer dummy)
{
gboolean continue_emission;
gboolean signal_return;
signal_return = g_value_get_boolean (handler_return);
g_value_set_boolean (return_accu, signal_return);
continue_emission = signal_return;
return continue_emission;
}

View File

@ -112,8 +112,6 @@ gchar *_g_dbus_get_machine_id (GError **error);
gchar *_g_dbus_enum_to_string (GType enum_type, gint value);
G_END_DECLS
/* ---------------------------------------------------------------------------------------------------- */
GDBusMethodInvocation *_g_dbus_method_invocation_new (const gchar *sender,
@ -126,4 +124,22 @@ GDBusMethodInvocation *_g_dbus_method_invocation_new (const gchar *sen
GVariant *parameters,
gpointer user_data);
/* ---------------------------------------------------------------------------------------------------- */
gboolean _g_signal_accumulator_false_handled (GSignalInvocationHint *ihint,
GValue *return_accu,
const GValue *handler_return,
gpointer dummy);
gboolean _g_dbus_object_stub_has_authorize_method_handlers (GDBusObjectStub *stub);
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);
G_END_DECLS
#endif /* __G_DBUS_PRIVATE_H__ */

View File

@ -38,6 +38,7 @@
#include "gasyncresult.h"
#include "gsimpleasyncresult.h"
#include "gcancellable.h"
#include "gdbusinterface.h"
#include "glibintl.h"
@ -129,10 +130,12 @@ enum
guint signals[LAST_SIGNAL] = {0};
static void dbus_interface_iface_init (GDBusInterfaceIface *dbus_interface_iface);
static void initable_iface_init (GInitableIface *initable_iface);
static void async_initable_iface_init (GAsyncInitableIface *async_initable_iface);
G_DEFINE_TYPE_WITH_CODE (GDBusProxy, g_dbus_proxy, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (G_TYPE_DBUS_INTERFACE, dbus_interface_iface_init)
G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, initable_iface_init)
G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE, async_initable_iface_init)
);
@ -2548,3 +2551,36 @@ g_dbus_proxy_call_sync (GDBusProxy *proxy,
}
/* ---------------------------------------------------------------------------------------------------- */
/* Hack until this is merged into libgio (extending types at run-time isn't really safe in any way) */
static GDBusInterfaceInfo *
_g_dbus_proxy_get_info (GDBusInterface *interface)
{
GDBusProxy *proxy = G_DBUS_PROXY (interface);
return g_dbus_proxy_get_interface_info (proxy);
}
static GDBusObject *
_g_dbus_proxy_get_object (GDBusInterface *interface)
{
/* TODO */
return g_object_get_data (G_OBJECT (interface), "-x-gdbus-binding-tool-object");
}
static void
_g_dbus_proxy_set_object (GDBusInterface *interface,
GDBusObject *object)
{
/* TODO */
g_object_set_data (G_OBJECT (interface), "-x-gdbus-binding-tool-object", object);
}
static void
dbus_interface_iface_init (GDBusInterfaceIface *dbus_interface_iface)
{
dbus_interface_iface->get_info = _g_dbus_proxy_get_info;
dbus_interface_iface->get_object = _g_dbus_proxy_get_object;
dbus_interface_iface->set_object = _g_dbus_proxy_set_object;
}
/* ---------------------------------------------------------------------------------------------------- */

View File

@ -29,3 +29,6 @@ VOID:UINT64
BOOLEAN:FLAGS
BOOLEAN:OBJECT,FLAGS
OBJECT:VOID
VOID:OBJECT,OBJECT
VOID:OBJECT,OBJECT,STRING,STRING,VARIANT
VOID:OBJECT,OBJECT,VARIANT,BOXED

View File

@ -130,6 +130,14 @@
#include <gio/gvolumemonitor.h>
#include <gio/gzlibcompressor.h>
#include <gio/gzlibdecompressor.h>
#include <gio/gdbusinterface.h>
#include <gio/gdbusinterfacestub.h>
#include <gio/gdbusobject.h>
#include <gio/gdbusobjectstub.h>
#include <gio/gdbusobjectproxy.h>
#include <gio/gdbusobjectmanager.h>
#include <gio/gdbusobjectmanagerclient.h>
#include <gio/gdbusobjectmanagerserver.h>
#undef __GIO_GIO_H_INSIDE__

View File

@ -2086,3 +2086,99 @@ g_time_zone_monitor_get_type G_GNUC_CONST
g_time_zone_monitor_get
#endif
#endif
#if IN_HEADER(__G_DBUS_INTERFACE_H__)
#if IN_FILE(__G_DBUS_INTERFACE_C__)
g_dbus_interface_get_info
g_dbus_interface_get_object
g_dbus_interface_get_type
g_dbus_interface_set_object
g_dbus_gvalue_to_gvariant
g_dbus_gvariant_to_gvalue
#endif
#endif
#if IN_HEADER(__G_DBUS_INTERFACE_STUB_H__)
#if IN_FILE(__G_DBUS_INTERFACE_STUB_C__)
g_dbus_interface_stub_export
g_dbus_interface_stub_flags_get_type
g_dbus_interface_stub_flush
g_dbus_interface_stub_get_connection
g_dbus_interface_stub_get_flags
g_dbus_interface_stub_get_info
g_dbus_interface_stub_get_object_path
g_dbus_interface_stub_get_properties
g_dbus_interface_stub_get_type
g_dbus_interface_stub_get_vtable
g_dbus_interface_stub_set_flags
g_dbus_interface_stub_unexport
#endif
#endif
#if IN_HEADER(__G_DBUS_OBJECT_H__)
#if IN_FILE(__G_DBUS_OBJECT_C__)
g_dbus_object_get_interface
g_dbus_object_get_interfaces
g_dbus_object_get_object_path
g_dbus_object_get_type
g_dbus_object_lookup_with_typecheck
g_dbus_object_peek_with_typecheck
#endif
#endif
#if IN_HEADER(__G_DBUS_OBJECT_PROXY_H__)
#if IN_FILE(__G_DBUS_OBJECT_PROXY_C__)
g_dbus_object_proxy_get_connection
g_dbus_object_proxy_get_type
#endif
#endif
#if IN_HEADER(__G_DBUS_OBJECT_STUB_H__)
#if IN_FILE(__G_DBUS_OBJECT_STUB_C__)
g_dbus_object_stub_add_interface
g_dbus_object_stub_flush
g_dbus_object_stub_get_type
g_dbus_object_stub_new
g_dbus_object_stub_remove_interface
g_dbus_object_stub_remove_interface_by_name
g_dbus_object_stub_set_object_path
#endif
#endif
#if IN_HEADER(__G_DBUS_OBJECT_MANAGER_H__)
#if IN_FILE(__G_DBUS_OBJECT_MANAGER_C__)
g_dbus_object_manager_get_interface
g_dbus_object_manager_get_object
g_dbus_object_manager_get_object_path
g_dbus_object_manager_get_objects
g_dbus_object_manager_get_type
#endif
#endif
#if IN_HEADER(__G_DBUS_OBJECT_MANAGER_CLIENT_H__)
#if IN_FILE(__G_DBUS_OBJECT_MANAGER_CLIENT_C__)
g_dbus_object_manager_client_flags_get_type
g_dbus_object_manager_client_get_connection
g_dbus_object_manager_client_get_flags
g_dbus_object_manager_client_get_name
g_dbus_object_manager_client_get_name_owner
g_dbus_object_manager_client_get_type
g_dbus_object_manager_client_new
g_dbus_object_manager_client_new_finish
g_dbus_object_manager_client_new_for_bus
g_dbus_object_manager_client_new_for_bus_finish
g_dbus_object_manager_client_new_for_bus_sync
g_dbus_object_manager_client_new_sync
#endif
#endif
#if IN_HEADER(__G_DBUS_OBJECT_MANAGER_SERVER_H__)
#if IN_FILE(__G_DBUS_OBJECT_MANAGER_SERVER_C__)
g_dbus_object_manager_server_export
g_dbus_object_manager_server_export_and_uniquify
g_dbus_object_manager_server_get_connection
g_dbus_object_manager_server_get_type
g_dbus_object_manager_server_new
g_dbus_object_manager_server_unexport
#endif
#endif

View File

@ -1383,6 +1383,42 @@ typedef enum {
G_TLS_REHANDSHAKE_UNSAFELY
} GTlsRehandshakeMode;
/**
* GDBusInterfaceStubFlags:
* @G_DBUS_INTERFACE_STUB_FLAGS_NONE: No flags set.
* @G_DBUS_INTERFACE_STUB_FLAGS_HANDLE_METHOD_INVOCATIONS_IN_THREAD: Each method invocation is handled in
* a thread dedicated to the invocation. This means that the method implementation can use blocking IO
* without blocking any other part of the process. It also means that the method implementation must
* use locking to access data structures used by other threads.
*
* Flags describing the behavior of a #GDBusInterfaceStub class.
*
* Since: 2.30
*/
typedef enum
{
G_DBUS_INTERFACE_STUB_FLAGS_NONE = 0,
G_DBUS_INTERFACE_STUB_FLAGS_HANDLE_METHOD_INVOCATIONS_IN_THREAD = (1<<0)
} GDBusInterfaceStubFlags;
/**
* GDBusObjectManagerClientFlags:
* @G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_NONE: No flags set.
* @G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_DO_NOT_AUTO_START: If not set and the
* manager is for a well-known name, then request the bus to launch
* an owner for the name if no-one owns the name. This flag can only
* be used in managers for well-known names.
*
* Flags used when constructing a #GDBusObjectManagerClient.
*
* Since: 2.30
*/
typedef enum
{
G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_NONE = 0,
G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_DO_NOT_AUTO_START = (1<<0),
} GDBusObjectManagerClientFlags;
G_END_DECLS
#endif /* __GIO_ENUMS_H__ */

View File

@ -418,6 +418,39 @@ typedef gboolean (*GCancellableSourceFunc) (GCancellable *cancellable,
typedef gboolean (*GPollableSourceFunc) (GObject *pollable_stream,
gpointer user_data);
typedef struct _GDBusInterface GDBusInterface; /* Dummy typedef */
typedef struct _GDBusInterfaceStub GDBusInterfaceStub;
typedef struct _GDBusObject GDBusObject; /* Dummy typedef */
typedef struct _GDBusObjectStub GDBusObjectStub;
typedef struct _GDBusObjectProxy GDBusObjectProxy;
typedef struct _GDBusObjectManager GDBusObjectManager; /* Dummy typedef */
typedef struct _GDBusObjectManagerClient GDBusObjectManagerClient;
typedef struct _GDBusObjectManagerServer GDBusObjectManagerServer;
/**
* GDBusProxyTypeFunc:
* @manager: A #GDBusObjectManagerClient.
* @object_path: The object path of the remote object.
* @interface_name: The interface name of the remote object.
* @user_data: User data.
*
* Function signature for a function used to determine the #GType to
* use for an interface proxy.
*
* This function is called in the
* <link linkend="g-main-context-push-thread-default">thread-default main loop</link>
* that @manager was constructed in.
*
* Returns: A #GType to use for the remote object. The returned type
* must be a #GDBusProxy derived type.
*
* Since: 2.30
*/
typedef GType (*GDBusProxyTypeFunc) (GDBusObjectManagerClient *manager,
const gchar *object_path,
const gchar *interface_name,
gpointer user_data);
G_END_DECLS
#endif /* __GIO_TYPES_H__ */