mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-12-23 22:16:16 +01:00
Start merging gdbus-codegen code
Signed-off-by: David Zeuthen <davidz@redhat.com>
This commit is contained in:
parent
0729260141
commit
94b9071344
@ -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 = \
|
||||
|
@ -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
410
gio/gdbusinterface.c
Normal 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
79
gio/gdbusinterface.h
Normal 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
693
gio/gdbusinterfacestub.c
Normal 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
105
gio/gdbusinterfacestub.h
Normal 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
191
gio/gdbusobject.c
Normal 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
95
gio/gdbusobject.h
Normal 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
216
gio/gdbusobjectmanager.c
Normal 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
89
gio/gdbusobjectmanager.h
Normal 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__ */
|
1575
gio/gdbusobjectmanagerclient.c
Normal file
1575
gio/gdbusobjectmanagerclient.c
Normal file
File diff suppressed because it is too large
Load Diff
129
gio/gdbusobjectmanagerclient.h
Normal file
129
gio/gdbusobjectmanagerclient.h
Normal 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 */
|
898
gio/gdbusobjectmanagerserver.c
Normal file
898
gio/gdbusobjectmanagerserver.c
Normal 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;
|
||||
}
|
80
gio/gdbusobjectmanagerserver.h
Normal file
80
gio/gdbusobjectmanagerserver.h
Normal 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
315
gio/gdbusobjectproxy.c
Normal 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
72
gio/gdbusobjectproxy.h
Normal 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
475
gio/gdbusobjectstub.c
Normal 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
87
gio/gdbusobjectstub.h
Normal 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 */
|
@ -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;
|
||||
}
|
||||
|
@ -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__ */
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------------- */
|
||||
|
@ -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
|
||||
|
@ -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__
|
||||
|
||||
|
@ -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
|
||||
|
@ -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__ */
|
||||
|
@ -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__ */
|
||||
|
Loading…
Reference in New Issue
Block a user