summaryrefslogtreecommitdiff
path: root/src/tube-dbus.c
diff options
context:
space:
mode:
authorGuillaume Desmottes <guillaume.desmottes@collabora.co.uk>2009-05-28 16:20:50 +0100
committerGuillaume Desmottes <guillaume.desmottes@collabora.co.uk>2009-06-26 15:21:29 +0100
commit9118a7d1c582e1a2a61ab8a433da2878a6e77a12 (patch)
treec8813428ba669e8cdf2614342118a3763eeada5b /src/tube-dbus.c
parent1efd67d7f2163e241272a23852ea10c9fab153a5 (diff)
downloadtelepathy-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.c267
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
+}