[telepathy-idle/master] Implement more mandatory properties for 1-1 channels

Will Thompson will.thompson at collabora.co.uk
Fri Aug 28 18:27:26 PDT 2009


---
 src/idle-im-channel.c |   98 ++++++++++++++++++++++++++++++++++++++++++++-----
 src/idle-im-manager.c |    8 ++-
 2 files changed, 93 insertions(+), 13 deletions(-)

diff --git a/src/idle-im-channel.c b/src/idle-im-channel.c
index a6a090e..82c74ac 100644
--- a/src/idle-im-channel.c
+++ b/src/idle-im-channel.c
@@ -51,14 +51,21 @@ G_DEFINE_TYPE_WITH_CODE(IdleIMChannel, idle_im_channel, G_TYPE_OBJECT,
 enum {
 	PROP_CONNECTION = 1,
 	PROP_OBJECT_PATH,
+	PROP_INTERFACES,
 	PROP_CHANNEL_TYPE,
 	PROP_HANDLE_TYPE,
 	PROP_HANDLE,
+	PROP_TARGET_ID,
+	PROP_REQUESTED,
+	PROP_INITIATOR_HANDLE,
+	PROP_INITIATOR_ID,
 	PROP_CHANNEL_DESTROYED,
 	PROP_CHANNEL_PROPERTIES,
 	LAST_PROPERTY_ENUM
 };
 
+const gchar *im_channel_interfaces[] = {NULL};
+
 /* private structure */
 typedef struct _IdleIMChannelPrivate IdleIMChannelPrivate;
 
@@ -66,6 +73,7 @@ struct _IdleIMChannelPrivate {
 	IdleConnection *connection;
 	gchar *object_path;
 	TpHandle handle;
+	TpHandle initiator;
 
 	gboolean closed;
 
@@ -91,6 +99,7 @@ static GObject *idle_im_channel_constructor(GType type, guint n_props, GObjectCo
 
 	handles = tp_base_connection_get_handles(TP_BASE_CONNECTION(priv->connection), TP_HANDLE_TYPE_CONTACT);
 	tp_handle_ref(handles, priv->handle);
+	tp_handle_ref(handles, priv->initiator);
 	g_assert(tp_handle_is_valid(tp_base_connection_get_handles(TP_BASE_CONNECTION(priv->connection), TP_HANDLE_TYPE_CONTACT), priv->handle, NULL));
 
 	bus = tp_get_bus();
@@ -109,12 +118,15 @@ static GObject *idle_im_channel_constructor(GType type, guint n_props, GObjectCo
 static void idle_im_channel_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec) {
 	IdleIMChannel *chan;
 	IdleIMChannelPrivate *priv;
+	TpHandleRepoIface *handles;
 
 	g_assert(object != NULL);
 	g_assert(IDLE_IS_IM_CHANNEL(object));
 
 	chan = IDLE_IM_CHANNEL(object);
 	priv = IDLE_IM_CHANNEL_GET_PRIVATE(chan);
+	handles = tp_base_connection_get_handles(
+		TP_BASE_CONNECTION(priv->connection), TP_HANDLE_TYPE_CONTACT);
 
 	switch (property_id) {
 		case PROP_CONNECTION:
@@ -125,6 +137,10 @@ static void idle_im_channel_get_property(GObject *object, guint property_id, GVa
 			g_value_set_string(value, priv->object_path);
 			break;
 
+		case PROP_INTERFACES:
+			g_value_set_static_boxed(value, im_channel_interfaces);
+			break;
+
 		case PROP_CHANNEL_TYPE:
 			g_value_set_string(value, TP_IFACE_CHANNEL_TYPE_TEXT);
 			break;
@@ -137,6 +153,24 @@ static void idle_im_channel_get_property(GObject *object, guint property_id, GVa
 			g_value_set_uint(value, priv->handle);
 			break;
 
+		case PROP_TARGET_ID:
+			g_value_set_string(value,
+				tp_handle_inspect(handles, priv->handle));
+			break;
+
+		case PROP_REQUESTED:
+			g_value_set_boolean(value, priv->initiator != priv->handle);
+			break;
+
+		case PROP_INITIATOR_HANDLE:
+			g_value_set_uint(value, priv->initiator);
+			break;
+
+		case PROP_INITIATOR_ID:
+			g_value_set_string(value,
+				tp_handle_inspect(handles, priv->initiator));
+			break;
+
 		case PROP_CHANNEL_DESTROYED:
 			/* TODO: this should be FALSE if there are still pending messages, so
 			 *       the channel manager can respawn the channel.
@@ -145,13 +179,22 @@ static void idle_im_channel_get_property(GObject *object, guint property_id, GVa
 			break;
 
 		case PROP_CHANNEL_PROPERTIES:
-			g_value_take_boxed (value,
-								tp_dbus_properties_mixin_make_properties_hash (object,
-									TP_IFACE_CHANNEL, "TargetHandle",
-									TP_IFACE_CHANNEL, "TargetHandleType",
-									TP_IFACE_CHANNEL, "ChannelType",
-									NULL));
+		{
+			GHashTable *props =
+				tp_dbus_properties_mixin_make_properties_hash (
+					object,
+					TP_IFACE_CHANNEL, "Interfaces",
+					TP_IFACE_CHANNEL, "ChannelType",
+					TP_IFACE_CHANNEL, "TargetHandleType",
+					TP_IFACE_CHANNEL, "TargetHandle",
+					TP_IFACE_CHANNEL, "TargetID",
+					TP_IFACE_CHANNEL, "InitiatorHandle",
+					TP_IFACE_CHANNEL, "InitiatorID",
+					TP_IFACE_CHANNEL, "Requested",
+					NULL);
+			g_value_take_boxed (value, props);
 			break;
+		}
 
 		default:
 			G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
@@ -184,6 +227,10 @@ static void idle_im_channel_set_property(GObject *object, guint property_id, con
 			priv->handle = g_value_get_uint(value);
 			break;
 
+		case PROP_INITIATOR_HANDLE:
+			priv->initiator = g_value_get_uint(value);
+			break;
+
 		case PROP_CHANNEL_TYPE:
 		case PROP_HANDLE_TYPE:
 			/* writeable in the interface, but setting them makes
@@ -227,10 +274,42 @@ static void idle_im_channel_class_init (IdleIMChannelClass *idle_im_channel_clas
 									 G_PARAM_STATIC_BLURB);
 	g_object_class_install_property(object_class, PROP_CONNECTION, param_spec);
 
+	param_spec = g_param_spec_boxed ("interfaces", "Extra D-Bus interfaces",
+		"Interfaces implemented by this object besides Channel",
+		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", "Contact's identifier",
+		"The name of the person we're speaking to",
+		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_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);
+
+	param_spec = g_param_spec_uint ("initiator-handle", "Initiator's handle",
+		"The contact who initiated the channel",
+		0, G_MAXUINT32, 0,
+		G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+	g_object_class_install_property (object_class, PROP_INITIATOR_HANDLE, 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);
+
 	static TpDBusPropertiesMixinPropImpl channel_props[] = {
+		{ "Interfaces", "interfaces", NULL },
+		{ "ChannelType", "channel-type", NULL },
 		{ "TargetHandleType", "handle-type", NULL },
 		{ "TargetHandle", "handle", NULL },
-		{ "ChannelType", "channel-type", NULL },
+		{ "TargetID", "target-id", NULL },
+		{ "InitiatorHandle", "initiator-handle", NULL },
+		{ "InitiatorID", "initiator-id", NULL },
+		{ "Requested", "requested", NULL },
 		{ NULL }
 	};
 	static TpDBusPropertiesMixinIfaceImpl prop_interfaces[] = {
@@ -272,6 +351,7 @@ void idle_im_channel_finalize (GObject *object) {
 
 	handles = tp_base_connection_get_handles(TP_BASE_CONNECTION(priv->connection), TP_HANDLE_TYPE_CONTACT);
 	tp_handle_unref(handles, priv->handle);
+	tp_handle_unref(handles, priv->initiator);
 
 	if (priv->object_path)
 		g_free(priv->object_path);
@@ -375,9 +455,7 @@ static void idle_im_channel_get_handle (TpSvcChannel *iface, DBusGMethodInvocati
  * Returns: TRUE if successful, FALSE if an error was thrown.
  */
 static void idle_im_channel_get_interfaces(TpSvcChannel *iface, DBusGMethodInvocation *context) {
-	const gchar *interfaces[] = {NULL};
-
-	tp_svc_channel_return_from_get_interfaces(context, interfaces);
+	tp_svc_channel_return_from_get_interfaces(context, im_channel_interfaces);
 }
 
 /**
diff --git a/src/idle-im-manager.c b/src/idle-im-manager.c
index 972445f..c8599b5 100644
--- a/src/idle-im-manager.c
+++ b/src/idle-im-manager.c
@@ -81,7 +81,7 @@ static gboolean _im_manager_create_channel(TpChannelManager *manager, gpointer r
 static gboolean _im_manager_request_channel(TpChannelManager *manager, gpointer request_token, GHashTable *request_properties);
 static gboolean _im_manager_ensure_channel(TpChannelManager *manager, gpointer request_token, GHashTable *request_properties);
 static gboolean _im_manager_requestotron (IdleIMManager *self, gpointer request_token, GHashTable *request_properties, gboolean require_new);
-static IdleIMChannel *_im_manager_new_channel (IdleIMManager *mgr, TpHandle handle, gpointer request);
+static IdleIMChannel *_im_manager_new_channel (IdleIMManager *mgr, TpHandle handle, TpHandle initiator, gpointer request);
 
 static void _im_channel_closed_cb (IdleIMChannel *chan, gpointer user_data);
 
@@ -189,7 +189,7 @@ static IdleParserHandlerResult _notice_privmsg_handler(IdleParser *parser, IdleP
 	}
 
 	if (!(chan = g_hash_table_lookup(priv->channels, GUINT_TO_POINTER(handle))))
-		chan = _im_manager_new_channel(manager, handle, NULL);
+		chan = _im_manager_new_channel(manager, handle, handle, NULL);
 
 	idle_im_channel_receive(chan, type, handle, body);
 
@@ -375,7 +375,7 @@ _im_manager_requestotron (IdleIMManager *self,
 
 	if (channel == NULL)
 	{
-		_im_manager_new_channel (self, handle, request_token);
+		_im_manager_new_channel (self, handle, base_conn->self_handle, request_token);
 		return TRUE;
 	}
 
@@ -421,6 +421,7 @@ _im_channel_closed_cb (IdleIMChannel *chan,
 static IdleIMChannel *
 _im_manager_new_channel (IdleIMManager *mgr,
 						 TpHandle handle,
+						 TpHandle initiator,
 						 gpointer request)
 {
 	IdleIMManagerPrivate *priv = IDLE_IM_MANAGER_GET_PRIVATE (mgr);
@@ -443,6 +444,7 @@ _im_manager_new_channel (IdleIMManager *mgr,
 						 "connection", priv->conn,
 						 "object-path", object_path,
 						 "handle", handle,
+						 "initiator-handle", initiator,
 						 NULL);
 	g_free (object_path);
 	g_hash_table_insert (priv->channels, GUINT_TO_POINTER (handle), chan);
-- 
1.5.6.5




More information about the telepathy-commits mailing list