diff options
author | Simon McVittie <simon.mcvittie@collabora.co.uk> | 2014-04-10 12:34:30 +0100 |
---|---|---|
committer | Simon McVittie <simon.mcvittie@collabora.co.uk> | 2014-04-10 20:21:00 +0100 |
commit | 20c539c2fa0ba663a4c7e7811a26571bf37ff595 (patch) | |
tree | 67c76876617fefd1514e900210439cf83ac8d726 | |
parent | 05f0d4bd3d8ca9dfae377754d2dbd53cff9cf228 (diff) |
TpSvcInterfaceSkeleton: move to the -dbus library
This requires some careful juggling to make it able to call methods
on the TpDBusPropertiesMixin without having to move the entire
TpDBusPropertiesMixin to the -dbus library.
-rw-r--r-- | docs/reference/telepathy-glib/telepathy-glib-sections.txt | 3 | ||||
-rw-r--r-- | telepathy-glib/Makefile.am | 6 | ||||
-rw-r--r-- | telepathy-glib/core-dbus-properties-mixin-internal.h | 67 | ||||
-rw-r--r-- | telepathy-glib/core-dbus-properties-mixin.c | 95 | ||||
-rw-r--r-- | telepathy-glib/dbus-properties-mixin.c | 82 | ||||
-rw-r--r-- | telepathy-glib/dbus.c | 2 | ||||
-rw-r--r-- | telepathy-glib/svc-interface-skeleton-internal.h | 4 | ||||
-rw-r--r-- | telepathy-glib/svc-interface-skeleton.c | 51 | ||||
-rw-r--r-- | telepathy-glib/svc-interface.h | 3 |
9 files changed, 278 insertions, 35 deletions
diff --git a/docs/reference/telepathy-glib/telepathy-glib-sections.txt b/docs/reference/telepathy-glib/telepathy-glib-sections.txt index dacfb66a8..81a067687 100644 --- a/docs/reference/telepathy-glib/telepathy-glib-sections.txt +++ b/docs/reference/telepathy-glib/telepathy-glib-sections.txt @@ -6268,10 +6268,11 @@ TpLoggerPriv </SECTION> <SECTION> -<INCLUDE>telepathy-glib/telepathy-glib.h</INCLUDE> +<INCLUDE>telepathy-glib/telepathy-glib-dbus.h</INCLUDE> <TITLE>TpSvcInterface</TITLE> <FILE>svc-interface</FILE> TpSvcInterfaceInfo tp_svc_interface_peek_dbus_interface_info tp_svc_interface_set_dbus_interface_info +tp_svc_interface_skeleton_new </SECTION> diff --git a/telepathy-glib/Makefile.am b/telepathy-glib/Makefile.am index 6f9973deb..a882a0392 100644 --- a/telepathy-glib/Makefile.am +++ b/telepathy-glib/Makefile.am @@ -196,12 +196,16 @@ libtelepathy_glib_dbus_internal_la_SOURCES = \ cli-channel.c \ cli-connection.c \ cli-misc.c \ + core-dbus-properties-mixin-internal.h \ + core-dbus-properties-mixin.c \ core-proxy.c \ gnio-util.c \ gtypes.c \ interfaces.c \ sliced-gvalue.c \ svc-interface.c \ + svc-interface-skeleton.c \ + svc-interface-skeleton-internal.h \ value-array.c \ $(NULL) @@ -333,8 +337,6 @@ libtelepathy_glib_main_internal_la_SOURCES = \ stream-tube-channel.c \ stream-tube-connection-internal.h \ stream-tube-connection.c \ - svc-interface-skeleton.c \ - svc-interface-skeleton-internal.h \ text-channel.c \ tls-certificate.c \ tls-certificate-rejection.c \ diff --git a/telepathy-glib/core-dbus-properties-mixin-internal.h b/telepathy-glib/core-dbus-properties-mixin-internal.h new file mode 100644 index 000000000..359fe2462 --- /dev/null +++ b/telepathy-glib/core-dbus-properties-mixin-internal.h @@ -0,0 +1,67 @@ +/*<private_header>*/ +/* + * Copyright © 2014 Collabora Ltd. + * + * 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.1 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __TP_CORE_DBUS_PROPERTIES_MIXIN_H__ +#define __TP_CORE_DBUS_PROPERTIES_MIXIN_H__ + +#include <glib.h> +#include <glib-object.h> + +G_BEGIN_DECLS + +typedef struct { + const gchar *version; + + GVariant *(*dup_variant) (GObject *object, + const gchar *interface_name, + const gchar *property_name, + GError **error); + + gboolean (*set_variant) (GObject *object, + const gchar *interface_name, + const gchar *property_name, + GVariant *value, + GError **error); + + GVariant *(*dup_all_vardict) (GObject *object, + const gchar *interface_name); + + gsize size; +} TpDBusPropertiesMixinImpl; + +GVariant *_tp_dbus_properties_mixin_dup_in_dbus_lib (GObject *object, + const gchar *interface_name, + const gchar *property_name, + GError **error); + +gboolean _tp_dbus_properties_mixin_set_in_dbus_lib (GObject *object, + const gchar *interface_name, + const gchar *property_name, + GVariant *value, + GError **error); + +GVariant *_tp_dbus_properties_mixin_dup_all_in_dbus_lib (GObject *object, + const gchar *interface_name); + +void tp_private_dbus_properties_mixin_set_implementation ( + const TpDBusPropertiesMixinImpl *real_impl); + +G_END_DECLS + +#endif diff --git a/telepathy-glib/core-dbus-properties-mixin.c b/telepathy-glib/core-dbus-properties-mixin.c new file mode 100644 index 000000000..5aba77cb3 --- /dev/null +++ b/telepathy-glib/core-dbus-properties-mixin.c @@ -0,0 +1,95 @@ +/* + * Copyright © 2014 Collabora Ltd. + * + * 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.1 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#include <telepathy-glib/core-dbus-properties-mixin-internal.h> + +#include <gio/gio.h> + +#include <telepathy-glib/errors.h> + +static TpDBusPropertiesMixinImpl impl = { NULL }; + +GVariant * +_tp_dbus_properties_mixin_dup_in_dbus_lib (GObject *object, + const gchar *interface_name, + const gchar *property_name, + GError **error) +{ + if (impl.version == NULL) + { + /* deliberately not using TP_ERROR to avoid a cross-library reference + * in the wrong direction */ + g_dbus_error_set_dbus_error (error, TP_ERROR_STR_NOT_IMPLEMENTED, + "No properties registered with TpDBusPropertiesMixin", NULL); + return NULL; + } + else + { + return impl.dup_variant (object, interface_name, property_name, error); + } +} + +gboolean +_tp_dbus_properties_mixin_set_in_dbus_lib (GObject *object, + const gchar *interface_name, + const gchar *property_name, + GVariant *value, + GError **error) +{ + if (impl.version == NULL) + { + g_dbus_error_set_dbus_error (error, TP_ERROR_STR_NOT_IMPLEMENTED, + "No properties registered with TpDBusPropertiesMixin", NULL); + return FALSE; + } + else + { + return impl.set_variant (object, interface_name, property_name, + value, error); + } +} + +GVariant * +_tp_dbus_properties_mixin_dup_all_in_dbus_lib (GObject *object, + const gchar *interface_name) +{ + if (impl.version == NULL) + { + /* GetAll() always succeeds */ + return g_variant_new ("a{sv}", NULL); + } + else + { + return impl.dup_all_vardict (object, interface_name); + } +} + +void +tp_private_dbus_properties_mixin_set_implementation ( + const TpDBusPropertiesMixinImpl *real_impl) +{ + g_assert (g_str_equal (real_impl->version, VERSION)); + g_assert (real_impl->size == sizeof (impl)); + g_assert (real_impl->dup_variant != NULL); + g_assert (real_impl->set_variant != NULL); + g_assert (real_impl->dup_all_vardict != NULL); + + impl = *real_impl; +} diff --git a/telepathy-glib/dbus-properties-mixin.c b/telepathy-glib/dbus-properties-mixin.c index 7130c9726..690942458 100644 --- a/telepathy-glib/dbus-properties-mixin.c +++ b/telepathy-glib/dbus-properties-mixin.c @@ -22,6 +22,7 @@ #include <telepathy-glib/dbus-properties-mixin.h> +#include <telepathy-glib/asv.h> #include <telepathy-glib/errors.h> #include <telepathy-glib/sliced-gvalue.h> #include <telepathy-glib/svc-generic.h> @@ -29,6 +30,7 @@ #include <telepathy-glib/util.h> #define DEBUG_FLAG TP_DEBUG_PROPERTIES +#include <telepathy-glib/core-dbus-properties-mixin-internal.h> #include "telepathy-glib/dbus-internal.h" #include "telepathy-glib/debug-internal.h" @@ -262,6 +264,8 @@ tp_dbus_properties_mixin_setter_gobject_properties (GObject *object, * Since: 0.7.3 */ +static void tp_dbus_properties_mixin_hook_to_dbus_library (void); + static GQuark _prop_mixin_offset_quark (void) { @@ -413,6 +417,8 @@ tp_dbus_properties_mixin_implement_interface (GObjectClass *cls, g_return_if_fail (G_IS_OBJECT_CLASS (cls)); + tp_dbus_properties_mixin_hook_to_dbus_library (); + /* never freed - intentional per-class leak */ iface_impl = g_new0 (TpDBusPropertiesMixinIfaceImpl, 1); iface_impl->name = g_quark_to_string (iface); @@ -531,6 +537,8 @@ tp_dbus_properties_mixin_class_init (GObjectClass *cls, g_return_if_fail (g_type_get_qdata (type, q) == NULL); g_type_set_qdata (type, q, GSIZE_TO_POINTER (offset)); + tp_dbus_properties_mixin_hook_to_dbus_library (); + if (offset == 0) return; @@ -1203,3 +1211,77 @@ out: return ret; } + +static GVariant * +_tp_dbus_properties_mixin_dup_variant (GObject *object, + const gchar *interface_name, + const gchar *property_name, + GError **error) +{ + GValue value = G_VALUE_INIT; + GVariant *ret = NULL; + + if (tp_dbus_properties_mixin_get (object, interface_name, property_name, + &value, error)) + { + ret = g_variant_ref_sink (dbus_g_value_build_g_variant (&value)); + g_value_unset (&value); + } + + return ret; +} + +static gboolean +_tp_dbus_properties_mixin_set_variant (GObject *object, + const gchar *interface_name, + const gchar *property_name, + GVariant *value, + GError **error) +{ + gboolean ret; + GValue gvalue = G_VALUE_INIT; + + g_variant_ref_sink (value); + + dbus_g_value_parse_g_variant (value, &gvalue); + ret = tp_dbus_properties_mixin_set (object, interface_name, property_name, + &gvalue, error); + + g_value_unset (&gvalue); + g_variant_unref (value); + return ret; +} + +static GVariant * +_tp_dbus_properties_mixin_dup_all_vardict (GObject *object, + const gchar *interface_name) +{ + GVariant *ret; + GHashTable *asv; + + asv = tp_dbus_properties_mixin_dup_all (object, interface_name); + ret = g_variant_ref_sink (tp_asv_to_vardict (asv)); + g_hash_table_unref (asv); + return ret; +} + +static TpDBusPropertiesMixinImpl impl = { NULL }; + +static void +tp_dbus_properties_mixin_hook_to_dbus_library (void) +{ + static gsize done = 0; + + if (g_once_init_enter (&done)) + { + impl.dup_variant = _tp_dbus_properties_mixin_dup_variant; + impl.set_variant = _tp_dbus_properties_mixin_set_variant; + impl.dup_all_vardict = _tp_dbus_properties_mixin_dup_all_vardict; + impl.version = VERSION; + impl.size = sizeof (impl); + + tp_private_dbus_properties_mixin_set_implementation (&impl); + + g_once_init_leave (&done, 1); + } +} diff --git a/telepathy-glib/dbus.c b/telepathy-glib/dbus.c index 100f5bec8..3a7f61477 100644 --- a/telepathy-glib/dbus.c +++ b/telepathy-glib/dbus.c @@ -958,7 +958,7 @@ tp_dbus_connection_try_register_object (GDBusConnection *dbus_connection, continue; } - skeleton = _tp_svc_interface_skeleton_new (object, iface, iinfo); + skeleton = tp_svc_interface_skeleton_new (object, iface); DEBUG ("- %s skeleton %p (wrapping %s %p)", iinfo->interface_info->name, skeleton, g_type_name (iface), diff --git a/telepathy-glib/svc-interface-skeleton-internal.h b/telepathy-glib/svc-interface-skeleton-internal.h index f95e0db5b..0dd760bc7 100644 --- a/telepathy-glib/svc-interface-skeleton-internal.h +++ b/telepathy-glib/svc-interface-skeleton-internal.h @@ -62,10 +62,6 @@ struct _TpSvcInterfaceSkeleton TpSvcInterfaceSkeletonPrivate *priv; }; -TpSvcInterfaceSkeleton *_tp_svc_interface_skeleton_new (gpointer object, - GType iface, - const TpSvcInterfaceInfo *iinfo); - G_END_DECLS #endif diff --git a/telepathy-glib/svc-interface-skeleton.c b/telepathy-glib/svc-interface-skeleton.c index b1f6144a7..246baac51 100644 --- a/telepathy-glib/svc-interface-skeleton.c +++ b/telepathy-glib/svc-interface-skeleton.c @@ -22,11 +22,13 @@ #include <dbus/dbus-glib.h> #include <telepathy-glib/asv.h> +#include <telepathy-glib/core-dbus-properties-mixin-internal.h> #include <telepathy-glib/dbus-properties-mixin.h> #include <telepathy-glib/variant-util.h> -#define DEBUG_FLAG TP_DEBUG_SVC -#include "debug-internal.h" +#define DEBUG(format, ...) \ + g_log (G_LOG_DOMAIN "/svc", G_LOG_LEVEL_DEBUG, "%s: " format, \ + G_STRFUNC, ##__VA_ARGS__) struct _TpSvcInterfaceSkeletonPrivate { @@ -101,7 +103,6 @@ tp_svc_interface_skeleton_get_property (GDBusConnection *connection, { TpSvcInterfaceSkeleton *self = TP_SVC_INTERFACE_SKELETON (user_data); GObject *object; - GValue value = G_VALUE_INIT; GVariant *ret = NULL; DEBUG ("Get(%s.%s) on %s %p from %s", interface_name, property_name, @@ -110,12 +111,8 @@ tp_svc_interface_skeleton_get_property (GDBusConnection *connection, object = g_weak_ref_get (&self->priv->object); g_return_val_if_fail (object != NULL, NULL); - if (tp_dbus_properties_mixin_get (object, interface_name, property_name, - &value, error)) - { - ret = dbus_g_value_build_g_variant (&value); - g_value_unset (&value); - } + ret = _tp_dbus_properties_mixin_dup_in_dbus_lib (object, interface_name, + property_name, error); g_object_unref (object); @@ -134,7 +131,6 @@ tp_svc_interface_skeleton_set_property (GDBusConnection *connection, { TpSvcInterfaceSkeleton *self = TP_SVC_INTERFACE_SKELETON (user_data); GObject *object; - GValue value = G_VALUE_INIT; gboolean ret; DEBUG ("Set(%s.%s) on %s %p from %s", interface_name, property_name, @@ -143,11 +139,9 @@ tp_svc_interface_skeleton_set_property (GDBusConnection *connection, object = g_weak_ref_get (&self->priv->object); g_return_val_if_fail (object != NULL, FALSE); - dbus_g_value_parse_g_variant (variant, &value); - ret = tp_dbus_properties_mixin_set (object, interface_name, property_name, - &value, error); + ret = _tp_dbus_properties_mixin_set_in_dbus_lib (object, interface_name, + property_name, variant, error); - g_value_unset (&value); g_object_unref (object); return ret; @@ -169,20 +163,17 @@ static GVariant * tp_svc_interface_skeleton_get_properties (GDBusInterfaceSkeleton *skel) { TpSvcInterfaceSkeleton *self = TP_SVC_INTERFACE_SKELETON (skel); - GVariant *ret; - GHashTable *asv; const gchar *iface_name = self->priv->iinfo->interface_info->name; GObject *object; + GVariant *ret; object = g_weak_ref_get (&self->priv->object); g_return_val_if_fail (object != NULL, NULL); /* For now assume we have the TpDBusPropertiesMixin if we have * any properties at all. This never returns NULL. */ - asv = tp_dbus_properties_mixin_dup_all (object, iface_name); - ret = g_variant_ref_sink (tp_asv_to_vardict (asv)); - g_hash_table_unref (asv); + ret = _tp_dbus_properties_mixin_dup_all_in_dbus_lib (object, iface_name); g_object_unref (object); return ret; } @@ -257,21 +248,27 @@ tp_svc_interface_skeleton_emit_signal (GClosure *closure, NULL); } -/* - * _tp_svc_interface_skeleton_new: (skip) +/** + * tp_svc_interface_skeleton_new: (skip) * @object: (type GObject.Object): a #GObject * @iface: a `TpSvc` interface on the object - * @iinfo: a description of the corresponding D-Bus interface + * + * Return a GDBus interface skeleton whose methods and signals + * are implemented by @iface on @object, and whose properties + * are implemented by a #TpDBusPropertiesMixin on @object. * * Returns: (transfer full): a new interface skeleton wrapping @iface * on @object */ -TpSvcInterfaceSkeleton * -_tp_svc_interface_skeleton_new (gpointer object, - GType iface, - const TpSvcInterfaceInfo *iinfo) +GDBusInterfaceSkeleton * +tp_svc_interface_skeleton_new (gpointer object, + GType iface) { TpSvcInterfaceSkeleton *self; + const TpSvcInterfaceInfo *iinfo = + tp_svc_interface_peek_dbus_interface_info (iface); + + g_return_val_if_fail (iinfo != NULL, NULL); /* not bothering to refcount it, it must be static for now */ g_return_val_if_fail (iinfo->ref_count == -1, NULL); @@ -308,5 +305,5 @@ _tp_svc_interface_skeleton_new (gpointer object, } } - return self; + return G_DBUS_INTERFACE_SKELETON (self); } diff --git a/telepathy-glib/svc-interface.h b/telepathy-glib/svc-interface.h index 7fee22661..863f70086 100644 --- a/telepathy-glib/svc-interface.h +++ b/telepathy-glib/svc-interface.h @@ -55,6 +55,9 @@ TpDBusPropertiesMixinIfaceInfo *tp_svc_interface_get_dbus_properties_info ( void tp_dbus_g_method_return_not_implemented (GDBusMethodInvocation *context); +GDBusInterfaceSkeleton *tp_svc_interface_skeleton_new (gpointer object, + GType iface); + G_END_DECLS #endif |