diff options
author | Guillaume Desmottes <guillaume.desmottes@collabora.co.uk> | 2009-05-28 16:20:50 +0100 |
---|---|---|
committer | Guillaume Desmottes <guillaume.desmottes@collabora.co.uk> | 2009-06-26 15:21:29 +0100 |
commit | 9118a7d1c582e1a2a61ab8a433da2878a6e77a12 (patch) | |
tree | c8813428ba669e8cdf2614342118a3763eeada5b /src/tube-dbus.c | |
parent | 1efd67d7f2163e241272a23852ea10c9fab153a5 (diff) | |
download | telepathy-salut-9118a7d1c582e1a2a61ab8a433da2878a6e77a12.tar.gz |
tube-dbus: start to implement Channel interface and DBusTube type
Diffstat (limited to 'src/tube-dbus.c')
-rw-r--r-- | src/tube-dbus.c | 267 |
1 files changed, 261 insertions, 6 deletions
diff --git a/src/tube-dbus.c b/src/tube-dbus.c index 9ab79b59..637f9360 100644 --- a/src/tube-dbus.c +++ b/src/tube-dbus.c @@ -33,7 +33,6 @@ #include <telepathy-glib/channel-iface.h> #include <telepathy-glib/dbus.h> #include <telepathy-glib/exportable-channel.h> -#include <telepathy-glib/group-mixin.h> #include <telepathy-glib/gtypes.h> #include <telepathy-glib/interfaces.h> #include <telepathy-glib/svc-channel.h> @@ -58,11 +57,30 @@ * arbitrary limit on the queue size set to 4MB. */ #define MAX_QUEUE_SIZE (4096*1024) -static void -tube_iface_init (gpointer g_iface, gpointer iface_data); +static void channel_iface_init (gpointer, gpointer); +static void tube_iface_init (gpointer g_iface, gpointer iface_data); +static void dbustube_iface_init (gpointer g_iface, gpointer iface_data); G_DEFINE_TYPE_WITH_CODE (SalutTubeDBus, salut_tube_dbus, G_TYPE_OBJECT, - G_IMPLEMENT_INTERFACE (SALUT_TYPE_TUBE_IFACE, tube_iface_init)); + G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_DBUS_PROPERTIES, + tp_dbus_properties_mixin_iface_init); + G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL, channel_iface_init); + G_IMPLEMENT_INTERFACE (SALUT_TYPE_TUBE_IFACE, tube_iface_init); + G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_TYPE_DBUS_TUBE, + dbustube_iface_init); + G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_CHANNEL_INTERFACE_TUBE, + NULL); + G_IMPLEMENT_INTERFACE (TP_TYPE_EXPORTABLE_CHANNEL, NULL); + G_IMPLEMENT_INTERFACE (TP_TYPE_CHANNEL_IFACE, NULL)); + +static const gchar *salut_tube_dbus_interfaces[] = { + TP_IFACE_CHANNEL_INTERFACE_GROUP, + /* If more interfaces are added, either keep Group as the first, or change + * the implementations of gabble_tube_dbus_get_interfaces () and + * gabble_tube_dbus_get_property () too */ + TP_IFACE_CHANNEL_INTERFACE_TUBE, + NULL +}; static const gchar * const salut_tube_dbus_channel_allowed_properties[] = { TP_IFACE_CHANNEL ".TargetHandle", @@ -85,7 +103,10 @@ static guint signals[LAST_SIGNAL] = {0}; /* properties */ enum { - PROP_CONNECTION = 1, + PROP_OBJECT_PATH = 1, + PROP_CHANNEL_TYPE, + PROP_CONNECTION, + PROP_INTERFACES, PROP_TUBES_CHANNEL, PROP_HANDLE, PROP_HANDLE_TYPE, @@ -102,6 +123,11 @@ enum PROP_DBUS_ADDRESS, PROP_DBUS_NAME, PROP_DBUS_NAMES, + PROP_CHANNEL_DESTROYED, + PROP_CHANNEL_PROPERTIES, + PROP_REQUESTED, + PROP_TARGET_ID, + PROP_INITIATOR_ID, LAST_PROPERTY }; @@ -109,6 +135,7 @@ typedef struct _SalutTubeDBusPrivate SalutTubeDBusPrivate; struct _SalutTubeDBusPrivate { SalutConnection *conn; + gchar *object_path; SalutTubesChannel *tubes_channel; TpHandle handle; TpHandleType handle_type; @@ -144,6 +171,8 @@ struct _SalutTubeDBusPrivate /* Number of bytes that will be in the next message, 0 if unknown */ guint32 reassembly_bytes_needed; + gboolean closed; + gboolean dispose_has_run; }; @@ -439,6 +468,7 @@ bytestream_state_changed_cb (GibberBytestreamIface *bytestream, priv->bytestream = NULL; } + priv->closed = TRUE; g_signal_emit (G_OBJECT (self), signals[CLOSED], 0); } else if (state == GIBBER_BYTESTREAM_STATE_OPEN) @@ -531,6 +561,7 @@ salut_tube_dbus_finalize (GObject *object) SalutTubeDBus *self = SALUT_TUBE_DBUS (object); SalutTubeDBusPrivate *priv = SALUT_TUBE_DBUS_GET_PRIVATE (self); + g_free (priv->object_path); g_free (priv->stream_id); g_free (priv->service); g_hash_table_destroy (priv->parameters); @@ -546,12 +577,32 @@ salut_tube_dbus_get_property (GObject *object, { SalutTubeDBus *self = SALUT_TUBE_DBUS (object); SalutTubeDBusPrivate *priv = SALUT_TUBE_DBUS_GET_PRIVATE (self); + TpBaseConnection *base_conn = (TpBaseConnection *) priv->conn; switch (property_id) { + case PROP_OBJECT_PATH: + g_value_set_string (value, priv->object_path); + break; + case PROP_CHANNEL_TYPE: + g_value_set_static_string (value, + TP_IFACE_CHANNEL_TYPE_DBUS_TUBE); + break; case PROP_CONNECTION: g_value_set_object (value, priv->conn); break; + case PROP_INTERFACES: + if (priv->handle_type == TP_HANDLE_TYPE_CONTACT) + { + /* 1-1 tubes - omit the Group interface */ + g_value_set_boxed (value, salut_tube_dbus_interfaces + 1); + } + else + { + /* MUC tubes */ + g_value_set_boxed (value, salut_tube_dbus_interfaces); + } + break; case PROP_TUBES_CHANNEL: g_value_set_object (value, priv->tubes_channel); break; @@ -600,6 +651,75 @@ salut_tube_dbus_get_property (GObject *object, case PROP_DBUS_NAMES: g_value_set_boxed (value, priv->dbus_names); break; + case PROP_CHANNEL_DESTROYED: + g_value_set_boolean (value, priv->closed); + break; + case PROP_CHANNEL_PROPERTIES: + { + GHashTable *properties; + + properties = tp_dbus_properties_mixin_make_properties_hash (object, + TP_IFACE_CHANNEL, "TargetHandle", + TP_IFACE_CHANNEL, "TargetHandleType", + TP_IFACE_CHANNEL, "ChannelType", + TP_IFACE_CHANNEL, "TargetID", + TP_IFACE_CHANNEL, "InitiatorHandle", + TP_IFACE_CHANNEL, "InitiatorID", + TP_IFACE_CHANNEL, "Requested", + TP_IFACE_CHANNEL, "Interfaces", + /* + * FIXME + TP_IFACE_CHANNEL_TYPE_DBUS_TUBE, "ServiceName", + TP_IFACE_CHANNEL_TYPE_DBUS_TUBE, "SupportedAccessControls", + */ + NULL); + + if (priv->initiator != priv->self_handle) + { + /* channel has not been requested so Parameters is immutable */ + GValue *prop_value = g_slice_new0 (GValue); + + /* FIXME: use tp_dbus_properties_mixin_add_properties once it's + * added in tp-glib */ + tp_dbus_properties_mixin_get (object, + TP_IFACE_CHANNEL_INTERFACE_TUBE, "Parameters", + prop_value, NULL); + g_assert (G_IS_VALUE (prop_value)); + + g_hash_table_insert (properties, + g_strdup_printf ("%s.%s", TP_IFACE_CHANNEL_INTERFACE_TUBE, + "Parameters"), prop_value); + } + + g_value_take_boxed (value, properties); + } + break; + case PROP_REQUESTED: + g_value_set_boolean (value, + (priv->initiator == priv->self_handle)); + break; + case PROP_INITIATOR_ID: + { + TpHandleRepoIface *repo = tp_base_connection_get_handles ( + base_conn, TP_HANDLE_TYPE_CONTACT); + + /* some channel can have o.f.T.Channel.InitiatorHandle == 0 but + * tubes always have an initiator */ + g_assert (priv->initiator != 0); + + g_value_set_string (value, + tp_handle_inspect (repo, priv->initiator)); + } + break; + case PROP_TARGET_ID: + { + TpHandleRepoIface *repo = tp_base_connection_get_handles ( + base_conn, priv->handle_type); + + g_value_set_string (value, + tp_handle_inspect (repo, priv->handle)); + } + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; @@ -617,6 +737,14 @@ salut_tube_dbus_set_property (GObject *object, switch (property_id) { + case PROP_OBJECT_PATH: + g_free (priv->object_path); + priv->object_path = g_value_dup_string (value); + break; + case PROP_CHANNEL_TYPE: + /* this property is writable in the interface, but not actually + * meaningfully changeable on this channel, so we do nothing */ + break; case PROP_CONNECTION: priv->conn = g_value_get_object (value); break; @@ -683,6 +811,7 @@ salut_tube_dbus_constructor (GType type, GObject *obj; SalutTubeDBus *self; SalutTubeDBusPrivate *priv; + DBusGConnection *bus; TpHandleRepoIface *contact_repo; TpHandleRepoIface *handles_repo; @@ -702,6 +831,11 @@ salut_tube_dbus_constructor (GType type, ((TpBaseConnection *) priv->conn, TP_HANDLE_TYPE_CONTACT); tp_handle_ref (contact_repo, priv->initiator); + bus = tp_get_bus (); + dbus_g_connection_register_g_object (bus, priv->object_path, obj); + + DEBUG ("Registering at '%s'", priv->object_path); + g_assert (priv->self_handle != 0); if (priv->handle_type == TP_HANDLE_TYPE_ROOM) { @@ -769,6 +903,46 @@ salut_tube_dbus_constructor (GType type, static void salut_tube_dbus_class_init (SalutTubeDBusClass *salut_tube_dbus_class) { + static TpDBusPropertiesMixinPropImpl channel_props[] = { + { "TargetHandleType", "handle-type", NULL }, + { "TargetHandle", "handle", NULL }, + { "ChannelType", "channel-type", NULL }, + { "TargetID", "target-id", NULL }, + { "Interfaces", "interfaces", NULL }, + { "Requested", "requested", NULL }, + { "InitiatorHandle", "initiator-handle", NULL }, + { "InitiatorID", "initiator-id", NULL }, + { NULL } + }; + static TpDBusPropertiesMixinPropImpl dbus_tube_props[] = { + { "ServiceName", "service", NULL }, + { "DBusNames", "dbus-names", NULL }, + { "SupportedAccessControls", "supported-access-controls", NULL }, + { NULL } + }; + static TpDBusPropertiesMixinPropImpl tube_iface_props[] = { + { "Parameters", "parameters", NULL }, + { "State", "state", NULL }, + { NULL } + }; + static TpDBusPropertiesMixinIfaceImpl prop_interfaces[] = { + { TP_IFACE_CHANNEL, + tp_dbus_properties_mixin_getter_gobject_properties, + NULL, + channel_props, + }, + { TP_IFACE_CHANNEL_TYPE_DBUS_TUBE, + tp_dbus_properties_mixin_getter_gobject_properties, + NULL, + dbus_tube_props, + }, + { TP_IFACE_CHANNEL_INTERFACE_TUBE, + tp_dbus_properties_mixin_getter_gobject_properties, + NULL, + tube_iface_props, + }, + { NULL } + }; GObjectClass *object_class = G_OBJECT_CLASS (salut_tube_dbus_class); GParamSpec *param_spec; @@ -782,6 +956,10 @@ salut_tube_dbus_class_init (SalutTubeDBusClass *salut_tube_dbus_class) object_class->dispose = salut_tube_dbus_dispose; object_class->finalize = salut_tube_dbus_finalize; + g_object_class_override_property (object_class, PROP_OBJECT_PATH, + "object-path"); + g_object_class_override_property (object_class, PROP_CHANNEL_TYPE, + "channel-type"); g_object_class_override_property (object_class, PROP_CONNECTION, "connection"); g_object_class_override_property (object_class, PROP_TUBES_CHANNEL, @@ -805,6 +983,11 @@ salut_tube_dbus_class_init (SalutTubeDBusClass *salut_tube_dbus_class) g_object_class_override_property (object_class, PROP_STATE, "state"); + g_object_class_override_property (object_class, PROP_CHANNEL_DESTROYED, + "channel-destroyed"); + g_object_class_override_property (object_class, PROP_CHANNEL_PROPERTIES, + "channel-properties"); + param_spec = g_param_spec_object ( "muc-connection", "GibberMucConnection object", @@ -857,6 +1040,31 @@ salut_tube_dbus_class_init (SalutTubeDBusClass *salut_tube_dbus_class) G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); g_object_class_install_property (object_class, PROP_DBUS_NAMES, param_spec); + param_spec = g_param_spec_boxed ("interfaces", "Extra D-Bus interfaces", + "Additional Channel.Interface.* interfaces", + G_TYPE_STRV, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + g_object_class_install_property (object_class, PROP_INTERFACES, param_spec); + + param_spec = g_param_spec_string ("target-id", "Target JID", + "The string obtained by inspecting the target handle", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + g_object_class_install_property (object_class, PROP_TARGET_ID, param_spec); + + param_spec = g_param_spec_string ("initiator-id", "Initiator's bare JID", + "The string obtained by inspecting the initiator-handle", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + g_object_class_install_property (object_class, PROP_INITIATOR_ID, + param_spec); + + param_spec = g_param_spec_boolean ("requested", "Requested?", + "True if this channel was requested by the local user", + FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + g_object_class_install_property (object_class, PROP_REQUESTED, param_spec); + signals[OPENED] = g_signal_new ("tube-opened", G_OBJECT_CLASS_TYPE (salut_tube_dbus_class), @@ -884,6 +1092,10 @@ salut_tube_dbus_class_init (SalutTubeDBusClass *salut_tube_dbus_class) NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); + + salut_tube_dbus_class->dbus_props_class.interfaces = prop_interfaces; + tp_dbus_properties_mixin_class_init (object_class, + G_STRUCT_OFFSET (SalutTubeDBusClass, dbus_props_class)); } static void @@ -1120,8 +1332,15 @@ salut_tube_dbus_new (SalutConnection *conn, GHashTable *parameters, guint id) { - SalutTubeDBus *tube = g_object_new (SALUT_TYPE_TUBE_DBUS, + SalutTubeDBus *tube; + gchar *object_path; + + object_path = g_strdup_printf ("%s/DBusTubeChannel_%u_%u", + conn->parent.object_path, handle, id); + + tube = g_object_new (SALUT_TYPE_TUBE_DBUS, "connection", conn, + "object-path", object_path, "tubes-channel", tubes_channel, "handle", handle, "handle-type", handle_type, @@ -1191,6 +1410,7 @@ salut_tube_dbus_close (SalutTubeIface *tube, gboolean closed_remotely) } else { + priv->closed = TRUE; g_signal_emit (G_OBJECT (self), signals[CLOSED], 0); } } @@ -1292,6 +1512,24 @@ salut_tube_dbus_channel_get_allowed_properties (void) } static void +channel_iface_init (gpointer g_iface, + gpointer iface_data) +{ + /* FIXME */ +#if 0 + TpSvcChannelClass *klass = (TpSvcChannelClass *) g_iface; + +#define IMPLEMENT(x, suffix) tp_svc_channel_implement_##x (\ + klass, salut_tube_dbus_##x##suffix) + IMPLEMENT(close,_async); + IMPLEMENT(get_channel_type,); + IMPLEMENT(get_handle,); + IMPLEMENT(get_interfaces,); +#undef IMPLEMENT +#endif +} + +static void tube_iface_init (gpointer g_iface, gpointer iface_data) { @@ -1302,3 +1540,20 @@ tube_iface_init (gpointer g_iface, klass->close = salut_tube_dbus_close; klass->add_bytestream = salut_tube_dbus_add_bytestream; } + +static void +dbustube_iface_init (gpointer g_iface, + gpointer iface_data) +{ + /* FIXME */ +#if 0 + TpSvcChannelTypeDBusTubeClass *klass = + (TpSvcChannelTypeDBusTubeClass *) g_iface; + +#define IMPLEMENT(x, suffix) tp_svc_channel_type_dbus_tube_implement_##x (\ + klass, salut_tube_dbus_##x##suffix) + IMPLEMENT(offer,_async); + IMPLEMENT(accept,_async); +#undef IMPLEMENT +#endif +} |