From d686d05637da8d4528371e4e63c7f3c7cb27d528 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Mon, 21 Oct 2013 17:13:42 +0100 Subject: [PATCH 06/16] TpDBusPropertiesMixin: allow linking to an object via TpExportable This should let introspected code use the mixin, I think. --- docs/reference/telepathy-glib-sections.txt | 1 + telepathy-glib/dbus-properties-mixin.c | 175 ++++++++++++++++++++++++++++- telepathy-glib/dbus-properties-mixin.h | 4 + 3 files changed, 178 insertions(+), 2 deletions(-) diff --git a/docs/reference/telepathy-glib-sections.txt b/docs/reference/telepathy-glib-sections.txt index f6a8350..6452e26 100644 --- a/docs/reference/telepathy-glib-sections.txt +++ b/docs/reference/telepathy-glib-sections.txt @@ -2618,6 +2618,7 @@ tp_dbus_properties_mixin_setter_gobject_properties tp_dbus_properties_mixin_class_init tp_dbus_properties_mixin_implement_interface tp_dbus_properties_mixin_iface_init +tp_dbus_properties_mixin_init tp_dbus_properties_mixin_get tp_dbus_properties_mixin_dup_all tp_dbus_properties_mixin_set diff --git a/telepathy-glib/dbus-properties-mixin.c b/telepathy-glib/dbus-properties-mixin.c index fb9f7c8..8a5027d 100644 --- a/telepathy-glib/dbus-properties-mixin.c +++ b/telepathy-glib/dbus-properties-mixin.c @@ -23,6 +23,7 @@ #include #include +#include #include #include @@ -52,9 +53,11 @@ * tp_dbus_properties_mixin_class_init() from your class_init implementation. * * To use this mixin as the implementation of #TpSvcDBusProperties, - * call G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_DBUS_PROPERTIES, + * either call G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_DBUS_PROPERTIES, * tp_dbus_properties_mixin_iface_init) in the fourth argument to - * G_DEFINE_TYPE_WITH_CODE. + * G_DEFINE_TYPE_WITH_CODE, + * or implement #TpExportable and call tp_dbus_properties_mixin_init() + * in your init, constructor or constructed function. * * Since: 0.7.3 */ @@ -1358,3 +1361,171 @@ tp_dbus_properties_mixin_iface_init (gpointer g_iface, IMPLEMENT (set,); #undef IMPLEMENT } + +static GQuark +_prop_mixin_instance_quark (void) +{ + static GQuark q = 0; + + if (G_UNLIKELY (q == 0)) + q = g_quark_from_static_string + ("tp_dbus_properties_mixin_init@TELEPATHY_GLIB_0.23"); + + return q; +} + +static gboolean +tp_dbus_properties_mixin_exportable_get (TpExportable *exportable, + const gchar *interface_name, + const gchar *method_name, + GVariant *parameters, + TpExportableInvocation *invocation, + gpointer user_data) +{ + g_assert (user_data == (gpointer) 1); + + if (g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(ss)"))) + { + const gchar *property_interface_name; + const gchar *property_name; + GError *error = NULL; + GValue value = G_VALUE_INIT; + + g_variant_get (parameters, "(&s&s)", &property_interface_name, + &property_name); + + if (tp_dbus_properties_mixin_get (G_OBJECT (exportable), + property_interface_name, property_name, &value, &error)) + { + tp_svc_dbus_properties_return_from_get ( + tp_exportable_invocation_to_dbus_glib (invocation), &value); + g_value_unset (&value); + } + else + { + tp_exportable_invocation_return_gerror (invocation, error); + g_error_free (error); + } + } + else + { + tp_exportable_invocation_return_dbus_error (invocation, + TP_ERROR_STR_INVALID_ARGUMENT, "Expected arguments of type (ss)"); + } + + return TRUE; +} + +static gboolean +tp_dbus_properties_mixin_exportable_get_all (TpExportable *exportable, + const gchar *interface_name, + const gchar *method_name, + GVariant *parameters, + TpExportableInvocation *invocation, + gpointer user_data) +{ + g_assert (user_data == (gpointer) 1); + + if (g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(s)"))) + { + const gchar *property_interface_name; + GHashTable *ret; + + g_variant_get (parameters, "(&s)", &property_interface_name); + + ret = tp_dbus_properties_mixin_dup_all (G_OBJECT (exportable), + property_interface_name); + tp_svc_dbus_properties_return_from_get_all ( + tp_exportable_invocation_to_dbus_glib (invocation), ret); + g_hash_table_unref (ret); + } + else + { + tp_exportable_invocation_return_dbus_error (invocation, + TP_ERROR_STR_INVALID_ARGUMENT, "Expected arguments of type (ss)"); + } + + return TRUE; +} + +static gboolean +tp_dbus_properties_mixin_exportable_set (TpExportable *exportable, + const gchar *interface_name, + const gchar *method_name, + GVariant *parameters, + TpExportableInvocation *invocation, + gpointer user_data) +{ + g_assert (user_data == (gpointer) 1); + + if (g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(ssv)"))) + { + const gchar *property_interface_name; + const gchar *property_name; + GError *error = NULL; + GVariant *value_variant; + GValue value = G_VALUE_INIT; + + g_variant_get (parameters, "(&s&sv)", &property_interface_name, + &property_name, &value_variant); + dbus_g_value_parse_g_variant (value_variant, &value); + + if (tp_dbus_properties_mixin_set (G_OBJECT (exportable), + property_interface_name, property_name, &value, &error)) + { + tp_exportable_invocation_return_value (invocation, NULL); + } + else + { + tp_exportable_invocation_return_gerror (invocation, error); + g_error_free (error); + } + + g_value_unset (&value); + g_variant_unref (value_variant); + } + else + { + tp_exportable_invocation_return_dbus_error (invocation, + TP_ERROR_STR_INVALID_ARGUMENT, "Expected arguments of type (ss)"); + } + + return TRUE; +} + +static void +tp_dbus_properties_mixin_dispose (gpointer exportable) +{ + g_signal_handlers_disconnect_by_func (exportable, + tp_dbus_properties_mixin_exportable_get, (gpointer) 1); + g_signal_handlers_disconnect_by_func (exportable, + tp_dbus_properties_mixin_exportable_get_all, (gpointer) 1); + g_signal_handlers_disconnect_by_func (exportable, + tp_dbus_properties_mixin_exportable_set, (gpointer) 1); +} + +/** + * tp_dbus_properties_mixin_init: + * @exportable: (type TelepathyGLib.Exportable): a #TpExportable instance + * that will use this mixin + * + * Initialize the object @exportable to use the D-Bus Properties mixin. + */ +void +tp_dbus_properties_mixin_init (gpointer exportable) +{ + g_return_if_fail (TP_IS_EXPORTABLE (exportable)); + + g_signal_connect (exportable, + "call-method::" TP_IFACE_DBUS_PROPERTIES ".Get", + G_CALLBACK (tp_dbus_properties_mixin_exportable_get), (gpointer) 1); + g_signal_connect (exportable, + "call-method::" TP_IFACE_DBUS_PROPERTIES ".GetAll", + G_CALLBACK (tp_dbus_properties_mixin_exportable_get_all), (gpointer) 1); + g_signal_connect (exportable, + "call-method::" TP_IFACE_DBUS_PROPERTIES ".Set", + G_CALLBACK (tp_dbus_properties_mixin_exportable_set), (gpointer) 1); + + g_object_set_qdata_full (exportable, _prop_mixin_instance_quark (), + exportable, tp_dbus_properties_mixin_dispose); +} diff --git a/telepathy-glib/dbus-properties-mixin.h b/telepathy-glib/dbus-properties-mixin.h index 1151cb5..b07b966 100644 --- a/telepathy-glib/dbus-properties-mixin.h +++ b/telepathy-glib/dbus-properties-mixin.h @@ -28,6 +28,7 @@ #include #include +#include #include G_BEGIN_DECLS @@ -167,6 +168,9 @@ void tp_dbus_properties_mixin_emit_properties_changed_varargs ( ...) G_GNUC_NULL_TERMINATED; +_TP_AVAILABLE_IN_UNRELEASED +void tp_dbus_properties_mixin_init (gpointer exportable); + G_END_DECLS #endif /* #ifndef __TP_DBUS_PROPERTIES_MIXIN_H__ */ -- 1.8.4.rc3