[empathy] Change EmpathyTpContactFactory API to look more like TpConnection. Add function to get only one cont



commit 9b9fcd3ce3b9c7fdc62836821d83377bec58d0a5
Author: Xavier Claessens <xclaesse gmail com>
Date:   Wed Mar 4 11:41:28 2009 +0100

    Change EmpathyTpContactFactory API to look more like TpConnection. Add function to get only one contact from
    id/handle.
---
 libempathy-gtk/empathy-contact-list-view.c  |   12 +-
 libempathy-gtk/empathy-contact-widget.c     |   15 ++-
 libempathy-gtk/empathy-new-message-dialog.c |   12 +-
 libempathy/empathy-dispatch-operation.c     |   14 ++-
 libempathy/empathy-dispatcher.c             |   16 ++-
 libempathy/empathy-tp-call.c                |   20 ++-
 libempathy/empathy-tp-chat.c                |   86 +++++++---
 libempathy/empathy-tp-contact-factory.c     |  251 ++++++++++++++++++++++-----
 libempathy/empathy-tp-contact-factory.h     |   43 ++++-
 libempathy/empathy-tp-contact-list.c        |   36 +++-
 libempathy/empathy-tp-file.c                |   16 ++-
 megaphone/src/megaphone-applet.c            |   13 +-
 src/empathy-event-manager.c                 |   30 +++-
 13 files changed, 441 insertions(+), 123 deletions(-)

diff --git a/libempathy-gtk/empathy-contact-list-view.c b/libempathy-gtk/empathy-contact-list-view.c
index 289595d..df7149b 100644
--- a/libempathy-gtk/empathy-contact-list-view.c
+++ b/libempathy-gtk/empathy-contact-list-view.c
@@ -206,15 +206,19 @@ contact_list_view_dnd_get_contact_free (DndGetContactData *data)
 
 static void
 contact_list_view_drag_got_contact (EmpathyTpContactFactory *factory,
-				    GList                   *contacts,
+				    EmpathyContact          *contact,
+				    const GError            *error,
 				    gpointer                 user_data,
 				    GObject                 *view)
 {
 	EmpathyContactListViewPriv *priv = GET_PRIV (view);
 	DndGetContactData          *data = user_data;
 	EmpathyContactList         *list;
-	EmpathyContact             *contact = contacts->data;
 
+	if (error != NULL) {
+		DEBUG ("Error: %s", error->message);
+		return;
+	}
 
 	DEBUG ("contact %s (%d) dragged from '%s' to '%s'",
 		empathy_contact_get_id (contact),
@@ -324,7 +328,9 @@ contact_list_view_drag_data_received (GtkWidget         *view,
 	data->old_group = old_group;
 	data->action = context->action;
 
-	empathy_tp_contact_factory_get_from_ids (factory, 1, &contact_id,
+	/* FIXME: We should probably wait for the cb before calling
+	 * gtk_drag_finish */
+	empathy_tp_contact_factory_get_from_id (factory, contact_id,
 		contact_list_view_drag_got_contact,
 		data, (GDestroyNotify) contact_list_view_dnd_get_contact_free,
 		G_OBJECT (view));
diff --git a/libempathy-gtk/empathy-contact-widget.c b/libempathy-gtk/empathy-contact-widget.c
index df876b6..18d7f41 100644
--- a/libempathy-gtk/empathy-contact-widget.c
+++ b/libempathy-gtk/empathy-contact-widget.c
@@ -690,13 +690,20 @@ contact_widget_contact_update (EmpathyContactWidget *information)
 
 static void
 contact_widget_got_contact_cb (EmpathyTpContactFactory *factory,
-                               GList *contacts,
+                               EmpathyContact *contact,
+                               const GError *error,
                                gpointer user_data,
                                GObject *weak_object)
 {
   EmpathyContactWidget *information = user_data;
 
-  contact_widget_set_contact (information, contacts->data);
+  if (error != NULL)
+    {
+      DEBUG ("Error: %s", error->message);
+      return;
+    }
+
+  contact_widget_set_contact (information, contact);
 }
 
 static void
@@ -715,7 +722,7 @@ contact_widget_get_self_handle_cb (TpConnection *connection,
     }
 
   factory = empathy_tp_contact_factory_dup_singleton (connection);
-  empathy_tp_contact_factory_get_from_handles (factory, 1, &self_handle,
+  empathy_tp_contact_factory_get_from_handle (factory, self_handle,
       contact_widget_got_contact_cb, information, NULL,
       weak_object);
   g_object_unref (factory);
@@ -741,7 +748,7 @@ contact_widget_change_contact (EmpathyContactWidget *information)
           EmpathyTpContactFactory *factory;
 
           factory = empathy_tp_contact_factory_dup_singleton (connection);
-          empathy_tp_contact_factory_get_from_ids (factory, 1, &id,
+          empathy_tp_contact_factory_get_from_id (factory, id,
               contact_widget_got_contact_cb, information, NULL,
               G_OBJECT (information->vbox_contact_widget));
           g_object_unref (factory);
diff --git a/libempathy-gtk/empathy-new-message-dialog.c b/libempathy-gtk/empathy-new-message-dialog.c
index 1192ecf..b1a3509 100644
--- a/libempathy-gtk/empathy-new-message-dialog.c
+++ b/libempathy-gtk/empathy-new-message-dialog.c
@@ -173,14 +173,20 @@ new_message_dialog_match_func (GtkEntryCompletion *completion,
 
 static void
 new_message_dialog_call_got_contact_cb (EmpathyTpContactFactory *factory,
-					GList                   *contacts,
+					EmpathyContact          *contact,
+					const GError            *error,
 					gpointer                 user_data,
 					GObject                 *weak_object)
 {
 	EmpathyCallFactory *call_factory;
 
+	if (error != NULL) {
+		DEBUG ("Error: %s", error->message);
+		return;
+	}
+
 	call_factory = empathy_call_factory_get();
-	empathy_call_factory_new_call (call_factory, contacts->data);
+	empathy_call_factory_new_call (call_factory, contact);
 }
 
 static void
@@ -203,7 +209,7 @@ new_message_dialog_response_cb (GtkWidget               *widget,
 		EmpathyTpContactFactory *factory;
 
 		factory = empathy_tp_contact_factory_dup_singleton (connection);
-		empathy_tp_contact_factory_get_from_ids (factory, 1, &id,
+		empathy_tp_contact_factory_get_from_id (factory, id,
 			new_message_dialog_call_got_contact_cb,
 			NULL, NULL, NULL);
 		g_object_unref (factory);
diff --git a/libempathy/empathy-dispatch-operation.c b/libempathy/empathy-dispatch-operation.c
index 80bb3df..8f6fffe 100644
--- a/libempathy/empathy-dispatch-operation.c
+++ b/libempathy/empathy-dispatch-operation.c
@@ -175,15 +175,23 @@ empathy_dispatch_operation_invalidated (TpProxy *proxy, guint domain,
 
 static void
 dispatcher_operation_got_contact_cb (EmpathyTpContactFactory *factory,
-                                     GList *contacts,
+                                     EmpathyContact *contact,
+                                     const GError *error,
                                      gpointer user_data,
                                      GObject *self)
 {
   EmpathyDispatchOperationPriv *priv = GET_PRIV (self);
 
+  if (error)
+    {
+      /* FIXME: We should cancel the operation */
+      DEBUG ("Error: %s", error->message);
+      return;
+    }
+
   if (priv->contact != NULL)
     g_object_unref (priv->contact);
-  priv->contact = g_object_ref (contacts->data);
+  priv->contact = g_object_ref (contact);
   g_object_notify (G_OBJECT (self), "contact");
 
   tp_channel_call_when_ready (priv->channel,
@@ -212,7 +220,7 @@ empathy_dispatch_operation_constructed (GObject *object)
       EmpathyTpContactFactory *factory;
 
       factory = empathy_tp_contact_factory_dup_singleton (priv->connection);
-      empathy_tp_contact_factory_get_from_handles (factory, 1, &handle,
+      empathy_tp_contact_factory_get_from_handle (factory, handle,
       	dispatcher_operation_got_contact_cb, NULL, NULL, object);
       g_object_unref (factory);
       return;
diff --git a/libempathy/empathy-dispatcher.c b/libempathy/empathy-dispatcher.c
index 8ce7630..5245bd2 100644
--- a/libempathy/empathy-dispatcher.c
+++ b/libempathy/empathy-dispatcher.c
@@ -1146,13 +1146,23 @@ typedef struct
 
 static void
 dispatcher_chat_with_contact_id_cb (EmpathyTpContactFactory *factory,
-                                    GList                   *contacts,
+                                    EmpathyContact          *contact,
+                                    const GError            *error,
                                     gpointer                 user_data,
                                     GObject                 *weak_object)
 {
   ChatWithContactIdData *data = user_data;
 
-  empathy_dispatcher_chat_with_contact (contacts->data, data->callback, data->user_data);
+  if (error)
+    {
+      /* FIXME: Should call data->callback with the error */
+      DEBUG ("Error: %s", error->message);
+    }
+  else
+    {
+      empathy_dispatcher_chat_with_contact (contact, data->callback, data->user_data);
+    }
+
   g_object_unref (data->dispatcher);
   g_slice_free (ChatWithContactIdData, data);
 }
@@ -1176,7 +1186,7 @@ empathy_dispatcher_chat_with_contact_id (TpConnection *connection,
   data->dispatcher = dispatcher;
   data->callback = callback;
   data->user_data = user_data;
-  empathy_tp_contact_factory_get_from_ids (factory, 1, &contact_id,
+  empathy_tp_contact_factory_get_from_id (factory, contact_id,
       dispatcher_chat_with_contact_id_cb, data, NULL, NULL);
 
   g_object_unref (factory);
diff --git a/libempathy/empathy-tp-call.c b/libempathy/empathy-tp-call.c
index 2cad31c..a5c0003 100644
--- a/libempathy/empathy-tp-call.c
+++ b/libempathy/empathy-tp-call.c
@@ -255,13 +255,20 @@ tp_call_request_streams_for_capabilities (EmpathyTpCall *call,
 
 static void
 tp_call_got_contact_cb (EmpathyTpContactFactory *factory,
-                        GList *contacts,
-                        gpointer user_data,
-                        GObject *call)
+                        EmpathyContact          *contact,
+                        const GError            *error,
+                        gpointer                 user_data,
+                        GObject                 *call)
 {
   EmpathyTpCallPriv *priv = GET_PRIV (call);
 
-  priv->contact = g_object_ref (contacts->data);
+  if (error)
+    {
+      DEBUG ("Error: %s", error->message);
+      return;
+    }
+
+  priv->contact = g_object_ref (contact);
   priv->is_incoming = TRUE;
   priv->status = EMPATHY_TP_CALL_STATUS_PENDING;
   g_object_notify (G_OBJECT (call), "is-incoming");
@@ -292,9 +299,8 @@ tp_call_update_status (EmpathyTpCall *call)
           /* We found the remote contact */
           connection = tp_channel_borrow_connection (priv->channel);
           factory = empathy_tp_contact_factory_dup_singleton (connection);
-          empathy_tp_contact_factory_get_from_handles (factory, 1,
-              &iter.element, tp_call_got_contact_cb, NULL, NULL,
-              G_OBJECT (call));
+          empathy_tp_contact_factory_get_from_handle (factory, iter.element,
+              tp_call_got_contact_cb, NULL, NULL, G_OBJECT (call));
           g_object_unref (factory);
         }
 
diff --git a/libempathy/empathy-tp-chat.c b/libempathy/empathy-tp-chat.c
index 8bb6567..bc99ba5 100644
--- a/libempathy/empathy-tp-chat.c
+++ b/libempathy/empathy-tp-chat.c
@@ -208,11 +208,21 @@ tp_chat_emit_queued_messages (EmpathyTpChat *chat)
 
 static void
 tp_chat_got_sender_cb (EmpathyTpContactFactory *factory,
-		       GList                   *contacts,
+		       EmpathyContact          *contact,
+		       const GError            *error,
 		       gpointer                 message,
 		       GObject                 *chat)
 {
-	empathy_message_set_sender (message, contacts->data);
+	EmpathyTpChatPriv *priv = GET_PRIV (chat);
+
+	if (error) {
+		DEBUG ("Error: %s", error->message);
+		/* Do not block the message queue, just drop this message */
+		g_queue_remove (priv->messages_queue, message);
+	} else {
+		empathy_message_set_sender (message, contact);
+	}
+
 	tp_chat_emit_queued_messages (EMPATHY_TP_CHAT (chat));
 }
 
@@ -240,8 +250,8 @@ tp_chat_build_message (EmpathyTpChat *chat,
 		empathy_message_set_sender (message, priv->user);
 		tp_chat_emit_queued_messages (chat);
 	} else {
-		empathy_tp_contact_factory_get_from_handles (priv->factory,
-			1, &from_handle,
+		empathy_tp_contact_factory_get_from_handle (priv->factory,
+			from_handle,
 			tp_chat_got_sender_cb,
 			message, NULL, G_OBJECT (chat));
 	}
@@ -362,13 +372,18 @@ typedef struct {
 
 static void
 tp_chat_state_changed_got_contact_cb (EmpathyTpContactFactory *factory,
-				      GList                   *contacts,
+				      EmpathyContact          *contact,
+				      const GError            *error,
 				      gpointer                 user_data,
 				      GObject                 *chat)
 {
-	EmpathyContact *contact = contacts->data;
 	TpChannelChatState state;
 
+	if (error) {
+		DEBUG ("Error: %s", error->message);
+		return;
+	}
+
 	state = GPOINTER_TO_UINT (user_data);
 	DEBUG ("Chat state changed for %s (%d): %d",
 		empathy_contact_get_name (contact),
@@ -386,7 +401,7 @@ tp_chat_state_changed_cb (TpChannel *channel,
 {
 	EmpathyTpChatPriv *priv = GET_PRIV (chat);
 
-	empathy_tp_contact_factory_get_from_handles (priv->factory, 1, &handle,
+	empathy_tp_contact_factory_get_from_handle (priv->factory, handle,
 		tp_chat_state_changed_got_contact_cb, GUINT_TO_POINTER (state),
 		NULL, chat);
 }
@@ -825,19 +840,28 @@ tp_chat_update_remote_contact (EmpathyTpChat *chat)
 
 static void
 tp_chat_got_added_contacts_cb (EmpathyTpContactFactory *factory,
-			       GList                   *contacts,
+			       guint                    n_contacts,
+			       EmpathyContact * const * contacts,
+			       guint                    n_failed,
+			       const TpHandle          *failed,
+			       const GError            *error,
 			       gpointer                 user_data,
 			       GObject                 *chat)
 {
 	EmpathyTpChatPriv *priv = GET_PRIV (chat);
-	GList *l;
+	guint i;
 	const TpIntSet *members;
 	TpHandle handle;
 	EmpathyContact *contact;
 
+	if (error) {
+		DEBUG ("Error: %s", error->message);
+		return;
+	}
+
 	members = tp_channel_group_get_members (priv->channel);
-	for (l = contacts; l; l = l->next) {
-		contact = l->data;
+	for (i = 0; i < n_contacts; i++) {
+		contact = contacts[i];
 		handle = empathy_contact_get_handle (contact);
 
 		/* Make sure the contact is still member */
@@ -899,13 +923,20 @@ tp_chat_group_members_changed_cb (TpChannel     *self,
 
 static void
 tp_chat_got_remote_contact_cb (EmpathyTpContactFactory *factory,
-			       GList *contacts,
-			       gpointer user_data,
-			       GObject *chat)
+			       EmpathyContact          *contact,
+			       const GError            *error,
+			       gpointer                 user_data,
+			       GObject                 *chat)
 {
 	EmpathyTpChatPriv *priv = GET_PRIV (chat);
 
-	priv->remote_contact = g_object_ref (contacts->data);
+	if (error) {
+		DEBUG ("Error: %s", error->message);
+		empathy_tp_chat_close (EMPATHY_TP_CHAT (chat));
+		return;
+	}
+
+	priv->remote_contact = g_object_ref (contact);
 	g_object_notify (chat, "remote-contact");
 
 	tp_chat_check_if_ready (EMPATHY_TP_CHAT (chat));
@@ -913,13 +944,20 @@ tp_chat_got_remote_contact_cb (EmpathyTpContactFactory *factory,
 
 static void
 tp_chat_got_self_contact_cb (EmpathyTpContactFactory *factory,
-			     GList                   *contacts,
+			     EmpathyContact          *contact,
+			     const GError            *error,
 			     gpointer                 user_data,
 			     GObject                 *chat)
 {
 	EmpathyTpChatPriv *priv = GET_PRIV (chat);
 
-	priv->user = g_object_ref (contacts->data);
+	if (error) {
+		DEBUG ("Error: %s", error->message);
+		empathy_tp_chat_close (EMPATHY_TP_CHAT (chat));
+		return;
+	}
+
+	priv->user = g_object_ref (contact);
 	empathy_contact_set_is_user (priv->user, TRUE);
 	tp_chat_check_if_ready (EMPATHY_TP_CHAT (chat));
 }
@@ -940,9 +978,8 @@ tp_chat_get_self_handle_cb (TpConnection *connection,
 		return;
 	}
 
-	empathy_tp_contact_factory_get_from_handles (priv->factory,
-		1, &self_handle,
-		tp_chat_got_self_contact_cb,
+	empathy_tp_contact_factory_get_from_handle (priv->factory,
+		self_handle, tp_chat_got_self_contact_cb,
 		NULL, NULL, chat);
 }
 
@@ -973,9 +1010,8 @@ tp_chat_constructor (GType                  type,
 
 		/* Get self contact from the group's self handle */
 		handle = tp_channel_group_get_self_handle (priv->channel);
-		empathy_tp_contact_factory_get_from_handles (priv->factory,
-			1, &handle,
-			tp_chat_got_self_contact_cb,
+		empathy_tp_contact_factory_get_from_handle (priv->factory,
+			handle, tp_chat_got_self_contact_cb,
 			NULL, NULL, chat);
 
 		/* Get initial member contacts */
@@ -994,8 +1030,8 @@ tp_chat_constructor (GType                  type,
 
 		/* Get the remote contact */
 		handle = tp_channel_get_handle (priv->channel, NULL);
-		empathy_tp_contact_factory_get_from_handles (priv->factory,
-			1, &handle, tp_chat_got_remote_contact_cb,
+		empathy_tp_contact_factory_get_from_handle (priv->factory,
+			handle, tp_chat_got_remote_contact_cb,
 			NULL, NULL, chat);
 	}
 
diff --git a/libempathy/empathy-tp-contact-factory.c b/libempathy/empathy-tp-contact-factory.c
index 7986ebb..b96af76 100644
--- a/libempathy/empathy-tp-contact-factory.c
+++ b/libempathy/empathy-tp-contact-factory.c
@@ -554,9 +554,15 @@ tp_contact_factory_add_contact (EmpathyTpContactFactory *tp_factory,
 		empathy_contact_get_handle (contact));
 }
 
+typedef union {
+	EmpathyTpContactFactoryContactsByIdCb ids_cb;
+	EmpathyTpContactFactoryContactsByHandleCb handles_cb;
+	EmpathyTpContactFactoryContactCb contact_cb;
+} GetContactsCb;
+
 typedef struct {
 	EmpathyTpContactFactory *tp_factory;
-	EmpathyTpContactFactoryGotContactsCb callback;
+	GetContactsCb callback;
 	gpointer user_data;
 	GDestroyNotify destroy;
 } GetContactsData;
@@ -574,55 +580,51 @@ get_contacts_data_free (gpointer user_data)
 	g_slice_free (GetContactsData, data);
 }
 
-static void
-got_contacts (GetContactsData *data,
-	      GObject *weak_object,
-	      guint n_contacts,
-	      TpContact * const *contacts,
-	      const GError *error)
+static EmpathyContact *
+dup_contact_for_tp_contact (EmpathyTpContactFactory *tp_factory,
+			    TpContact               *tp_contact)
 {
-	GList *ret = NULL;
-	guint i;
+	EmpathyContact *contact;
 
-	if (error) {
-		DEBUG ("Error: %s", error->message);
+	contact = tp_contact_factory_find_by_tp_contact (tp_factory,
+							 tp_contact);
+
+	if (contact != NULL) {
+		g_object_ref (contact);
+	} else {
+		contact = empathy_contact_new (tp_contact);
+		tp_contact_factory_add_contact (tp_factory, contact);
 	}
 
-	for (i = 0; i < n_contacts; i++) {
-		EmpathyContact *contact;
+	return contact;
+}
 
-		contact = tp_contact_factory_find_by_tp_contact (data->tp_factory,
-								 contacts[i]);
+static EmpathyContact **
+contacts_array_new (EmpathyTpContactFactory *tp_factory,
+		    guint                    n_contacts,
+		    TpContact * const *      contacts)
+{
+	EmpathyContact **ret;
+	guint            i;
 
-		if (contact != NULL) {
-			g_object_ref (contact);
-		} else {
-			contact = empathy_contact_new (contacts[i]);
-			tp_contact_factory_add_contact (data->tp_factory, contact);
-		}
-		ret = g_list_prepend (ret, contact);
+	ret = g_new0 (EmpathyContact *, n_contacts);
+	for (i = 0; i < n_contacts; i++) {
+		ret[i] = dup_contact_for_tp_contact (tp_factory, contacts[i]);
 	}
 
-	if (data->callback)
-		data->callback (data->tp_factory, ret, data->user_data, weak_object);
-
-	g_list_foreach (ret, (GFunc) g_object_unref, NULL);
-	g_list_free (ret);
+	return ret;
 }
 
 static void
-get_contacts_by_handle_cb (TpConnection *connection,
-			   guint n_contacts,
-			   TpContact * const *contacts,
-			   guint n_failed,
-			   const TpHandle *failed,
-			   const GError *error,
-			   gpointer user_data,
-			   GObject *weak_object)
+contacts_array_free (guint            n_contacts,
+		     EmpathyContact **contacts)
 {
-	got_contacts (user_data, weak_object,
-		      n_contacts, contacts,
-		      error);
+	guint i;
+
+	for (i = 0; i < n_contacts; i++) {
+		g_object_unref (contacts[i]);
+	}
+	g_free (contacts);
 }
 
 static void
@@ -635,16 +637,28 @@ get_contacts_by_id_cb (TpConnection *connection,
 		       gpointer user_data,
 		       GObject *weak_object)
 {
-	got_contacts (user_data, weak_object,
-		      n_contacts, contacts,
-		      error);
+	GetContactsData *data = user_data;
+	EmpathyContact **empathy_contacts;
+
+	empathy_contacts = contacts_array_new (data->tp_factory,
+					       n_contacts, contacts);
+	if (data->callback.ids_cb) {
+		data->callback.ids_cb (data->tp_factory,
+				       n_contacts, empathy_contacts,
+				       requested_ids,
+				       failed_id_errors,
+				       error,
+				       data->user_data, weak_object);
+	}
+
+	contacts_array_free (n_contacts, empathy_contacts);
 }
 
 void
 empathy_tp_contact_factory_get_from_ids (EmpathyTpContactFactory *tp_factory,
 					 guint                    n_ids,
 					 const gchar * const     *ids,
-					 EmpathyTpContactFactoryGotContactsCb callback,
+					 EmpathyTpContactFactoryContactsByIdCb callback,
 					 gpointer                 user_data,
 					 GDestroyNotify           destroy,
 					 GObject                 *weak_object)
@@ -656,7 +670,7 @@ empathy_tp_contact_factory_get_from_ids (EmpathyTpContactFactory *tp_factory,
 	g_return_if_fail (ids != NULL);
 
 	data = g_slice_new (GetContactsData);
-	data->callback = callback;
+	data->callback.ids_cb = callback;
 	data->user_data = user_data;
 	data->destroy = destroy;
 	data->tp_factory = g_object_ref (tp_factory);
@@ -670,11 +684,104 @@ empathy_tp_contact_factory_get_from_ids (EmpathyTpContactFactory *tp_factory,
 					  weak_object);
 }
 
+static void
+get_contact_by_id_cb (TpConnection *connection,
+		      guint n_contacts,
+		      TpContact * const *contacts,
+		      const gchar * const *requested_ids,
+		      GHashTable *failed_id_errors,
+		      const GError *error,
+		      gpointer user_data,
+		      GObject *weak_object)
+{
+	GetContactsData *data = user_data;
+	EmpathyContact  *contact = NULL;
+
+	if (n_contacts == 1) {
+		contact = dup_contact_for_tp_contact (data->tp_factory,
+						      contacts[0]);
+	}
+	else if (error == NULL) {
+		GHashTableIter iter;
+		gpointer       value;
+
+		g_hash_table_iter_init (&iter, failed_id_errors);
+		while (g_hash_table_iter_next (&iter, NULL, &value)) {
+			if (value) {
+				error = value;
+				break;
+			}
+		}
+	}
+
+	if (data->callback.contact_cb) {
+		data->callback.contact_cb (data->tp_factory,
+				           contact,
+				           error,
+				           data->user_data, weak_object);
+	}
+}
+
+void
+empathy_tp_contact_factory_get_from_id (EmpathyTpContactFactory *tp_factory,
+					const gchar             *id,
+					EmpathyTpContactFactoryContactCb callback,
+					gpointer                 user_data,
+					GDestroyNotify           destroy,
+					GObject                 *weak_object)
+{
+	EmpathyTpContactFactoryPriv *priv = GET_PRIV (tp_factory);
+	GetContactsData *data;
+
+	g_return_if_fail (EMPATHY_IS_TP_CONTACT_FACTORY (tp_factory));
+	g_return_if_fail (id != NULL);
+
+	data = g_slice_new (GetContactsData);
+	data->callback.contact_cb = callback;
+	data->user_data = user_data;
+	data->destroy = destroy;
+	data->tp_factory = g_object_ref (tp_factory);
+	tp_connection_get_contacts_by_id (priv->connection,
+					  1, &id,
+					  G_N_ELEMENTS (contact_features),
+					  contact_features,
+					  get_contact_by_id_cb,
+					  data,
+					  (GDestroyNotify) get_contacts_data_free,
+					  weak_object);
+}
+
+static void
+get_contacts_by_handle_cb (TpConnection *connection,
+			   guint n_contacts,
+			   TpContact * const *contacts,
+			   guint n_failed,
+			   const TpHandle *failed,
+			   const GError *error,
+			   gpointer user_data,
+			   GObject *weak_object)
+{
+	GetContactsData *data = user_data;
+	EmpathyContact **empathy_contacts;
+
+	empathy_contacts = contacts_array_new (data->tp_factory,
+					       n_contacts, contacts);
+	if (data->callback.handles_cb) {
+		data->callback.handles_cb (data->tp_factory,
+					   n_contacts, empathy_contacts,
+					   n_failed, failed,
+					   error,
+					   data->user_data, weak_object);
+	}
+
+	contacts_array_free (n_contacts, empathy_contacts);
+}
+
 void
 empathy_tp_contact_factory_get_from_handles (EmpathyTpContactFactory *tp_factory,
 					     guint n_handles,
 					     const TpHandle *handles,
-					     EmpathyTpContactFactoryGotContactsCb callback,
+					     EmpathyTpContactFactoryContactsByHandleCb callback,
 					     gpointer                 user_data,
 					     GDestroyNotify           destroy,
 					     GObject                 *weak_object)
@@ -686,7 +793,7 @@ empathy_tp_contact_factory_get_from_handles (EmpathyTpContactFactory *tp_factory
 	g_return_if_fail (handles != NULL);
 
 	data = g_slice_new (GetContactsData);
-	data->callback = callback;
+	data->callback.handles_cb = callback;
 	data->user_data = user_data;
 	data->destroy = destroy;
 	data->tp_factory = g_object_ref (tp_factory);
@@ -700,6 +807,60 @@ empathy_tp_contact_factory_get_from_handles (EmpathyTpContactFactory *tp_factory
 					      weak_object);
 }
 
+static void
+get_contact_by_handle_cb (TpConnection *connection,
+			  guint n_contacts,
+			  TpContact * const *contacts,
+			  guint n_failed,
+			  const TpHandle *failed,
+			  const GError *error,
+			  gpointer user_data,
+			  GObject *weak_object)
+{
+	GetContactsData *data = user_data;
+	EmpathyContact  *contact = NULL;
+
+	if (n_contacts == 1) {
+		contact = dup_contact_for_tp_contact (data->tp_factory,
+						      contacts[0]);
+	}
+
+	if (data->callback.contact_cb) {
+		data->callback.contact_cb (data->tp_factory,
+				           contact,
+				           error,
+				           data->user_data, weak_object);
+	}
+}
+
+void
+empathy_tp_contact_factory_get_from_handle (EmpathyTpContactFactory *tp_factory,
+					    TpHandle                 handle,
+					    EmpathyTpContactFactoryContactCb callback,
+					    gpointer                 user_data,
+					    GDestroyNotify           destroy,
+					    GObject                 *weak_object)
+{
+	EmpathyTpContactFactoryPriv *priv = GET_PRIV (tp_factory);
+	GetContactsData *data;
+
+	g_return_if_fail (EMPATHY_IS_TP_CONTACT_FACTORY (tp_factory));
+
+	data = g_slice_new (GetContactsData);
+	data->callback.contact_cb = callback;
+	data->user_data = user_data;
+	data->destroy = destroy;
+	data->tp_factory = g_object_ref (tp_factory);
+	tp_connection_get_contacts_by_handle (priv->connection,
+					      1, &handle,
+					      G_N_ELEMENTS (contact_features),
+					      contact_features,
+					      get_contact_by_handle_cb,
+					      data,
+					      (GDestroyNotify) get_contacts_data_free,
+					      weak_object);
+}
+
 void
 empathy_tp_contact_factory_set_alias (EmpathyTpContactFactory *tp_factory,
 				      EmpathyContact          *contact,
diff --git a/libempathy/empathy-tp-contact-factory.h b/libempathy/empathy-tp-contact-factory.h
index eddb315..91ff2f9 100644
--- a/libempathy/empathy-tp-contact-factory.h
+++ b/libempathy/empathy-tp-contact-factory.h
@@ -49,24 +49,55 @@ struct _EmpathyTpContactFactoryClass {
 	GObjectClass parent_class;
 };
 
-typedef void (*EmpathyTpContactFactoryGotContactsCb) (EmpathyTpContactFactory *factory,
-						      GList                   *contacts,
-						      gpointer                 user_data,
-						      GObject                 *weak_object);
+typedef void (*EmpathyTpContactFactoryContactsByIdCb) (EmpathyTpContactFactory *factory,
+						       guint                    n_contacts,
+						       EmpathyContact * const * contacts,
+						       const gchar * const *    requested_ids,
+						       GHashTable              *failed_id_errors,
+						       const GError            *error,
+						       gpointer                 user_data,
+						       GObject                 *weak_object);
+
+typedef void (*EmpathyTpContactFactoryContactsByHandleCb) (EmpathyTpContactFactory *factory,
+							   guint                    n_contacts,
+							   EmpathyContact * const * contacts,
+                                                           guint                    n_failed,
+                                                           const TpHandle          *failed,
+                                                           const GError            *error,
+						           gpointer                 user_data,
+						           GObject                 *weak_object);
+
+typedef void (*EmpathyTpContactFactoryContactCb) (EmpathyTpContactFactory *factory,
+						  EmpathyContact          *contact,
+						  const GError            *error,
+						  gpointer                 user_data,
+						  GObject                 *weak_object);
 
 GType                    empathy_tp_contact_factory_get_type         (void) G_GNUC_CONST;
 EmpathyTpContactFactory *empathy_tp_contact_factory_dup_singleton    (TpConnection *connection);
 void                     empathy_tp_contact_factory_get_from_ids     (EmpathyTpContactFactory *tp_factory,
 								      guint                    n_ids,
 								      const gchar * const     *ids,
-								      EmpathyTpContactFactoryGotContactsCb callback,
+								      EmpathyTpContactFactoryContactsByIdCb callback,
 								      gpointer                 user_data,
 								      GDestroyNotify           destroy,
 								      GObject                 *weak_object);
 void                     empathy_tp_contact_factory_get_from_handles (EmpathyTpContactFactory *tp_factory,
 								      guint                    n_handles,
 								      const TpHandle          *handles,
-								      EmpathyTpContactFactoryGotContactsCb callback,
+								      EmpathyTpContactFactoryContactsByHandleCb callback,
+								      gpointer                 user_data,
+								      GDestroyNotify           destroy,
+								      GObject                 *weak_object);
+void                     empathy_tp_contact_factory_get_from_id      (EmpathyTpContactFactory *tp_factory,
+								      const gchar             *id,
+								      EmpathyTpContactFactoryContactCb callback,
+								      gpointer                 user_data,
+								      GDestroyNotify           destroy,
+								      GObject                 *weak_object);
+void                     empathy_tp_contact_factory_get_from_handle  (EmpathyTpContactFactory *tp_factory,
+								      TpHandle                 handle,
+								      EmpathyTpContactFactoryContactCb callback,
 								      gpointer                 user_data,
 								      GDestroyNotify           destroy,
 								      GObject                 *weak_object);
diff --git a/libempathy/empathy-tp-contact-list.c b/libempathy/empathy-tp-contact-list.c
index 636f2ed..a0b40b0 100644
--- a/libempathy/empathy-tp-contact-list.c
+++ b/libempathy/empathy-tp-contact-list.c
@@ -334,15 +334,24 @@ tp_contact_list_group_add (EmpathyTpContactList *list,
 
 static void
 tp_contact_list_got_added_members_cb (EmpathyTpContactFactory *factory,
-				      GList                   *contacts,
+				      guint                    n_contacts,
+				      EmpathyContact * const * contacts,
+				      guint                    n_failed,
+				      const TpHandle          *failed,
+				      const GError            *error,
 				      gpointer                 user_data,
 				      GObject                 *list)
 {
 	EmpathyTpContactListPriv *priv = GET_PRIV (list);
-	GList *l;
+	guint i;
 
-	for (l = contacts; l; l = l->next) {
-		EmpathyContact *contact = l->data;
+	if (error) {
+		DEBUG ("Error: %s", error->message);
+		return;
+	}
+
+	for (i = 0; i < n_contacts; i++) {
+		EmpathyContact *contact = contacts[i];
 		TpHandle handle;
 
 		handle = empathy_contact_get_handle (contact);
@@ -367,15 +376,24 @@ tp_contact_list_got_added_members_cb (EmpathyTpContactFactory *factory,
 
 static void
 tp_contact_list_got_local_pending_cb (EmpathyTpContactFactory *factory,
-				      GList                   *contacts,
-				      gpointer                 info,
+				      guint                    n_contacts,
+				      EmpathyContact * const * contacts,
+				      guint                    n_failed,
+				      const TpHandle          *failed,
+				      const GError            *error,
+				      gpointer                 user_data,
 				      GObject                 *list)
 {
 	EmpathyTpContactListPriv *priv = GET_PRIV (list);
-	GList *l;
+	guint i;
+
+	if (error) {
+		DEBUG ("Error: %s", error->message);
+		return;
+	}
 
-	for (l = contacts; l; l = l->next) {
-		EmpathyContact *contact = l->data;
+	for (i = 0; i < n_contacts; i++) {
+		EmpathyContact *contact = contacts[i];
 		TpHandle handle;
 		const gchar *message;
 		TpChannelGroupChangeReason reason;
diff --git a/libempathy/empathy-tp-file.c b/libempathy/empathy-tp-file.c
index bcd35a2..913c27b 100644
--- a/libempathy/empathy-tp-file.c
+++ b/libempathy/empathy-tp-file.c
@@ -508,13 +508,21 @@ tp_file_check_if_ready (EmpathyTpFile *tp_file)
 
 static void
 tp_file_got_contact_cb (EmpathyTpContactFactory *factory,
-                        GList *contacts,
+                        EmpathyContact *contact,
+                        const GError *error,
                         gpointer user_data,
                         GObject *weak_object)
 {
   EmpathyTpFile *tp_file = EMPATHY_TP_FILE (weak_object);
 
-  tp_file->priv->contact = g_object_ref (contacts->data);
+  if (error)
+    {
+      DEBUG ("Error: %s", error->message);
+      empathy_tp_file_close (tp_file);
+      return;
+    }
+
+  tp_file->priv->contact = g_object_ref (contact);
   tp_file_check_if_ready (tp_file);
 }
 
@@ -633,8 +641,8 @@ tp_file_constructor (GType type,
       tp_file_get_all_cb, NULL, NULL, file_obj);
 
   handle = tp_channel_get_handle (tp_file->priv->channel, NULL);
-  empathy_tp_contact_factory_get_from_handles (tp_file->priv->factory,
-      1, &handle, tp_file_got_contact_cb, NULL, NULL, file_obj);
+  empathy_tp_contact_factory_get_from_handle (tp_file->priv->factory,
+      handle, tp_file_got_contact_cb, NULL, NULL, file_obj);
 
   return file_obj;
 }
diff --git a/megaphone/src/megaphone-applet.c b/megaphone/src/megaphone-applet.c
index 48b5a18..b58255f 100644
--- a/megaphone/src/megaphone-applet.c
+++ b/megaphone/src/megaphone-applet.c
@@ -172,13 +172,19 @@ megaphone_applet_update_contact (MegaphoneApplet *applet)
 
 static void
 megaphone_applet_got_contact_cb (EmpathyTpContactFactory *factory,
-				 GList                   *contacts,
+				 EmpathyContact          *contact,
+				 const GError            *error,
 				 gpointer                 user_data,
 				 GObject                 *applet)
 {
 	MegaphoneAppletPriv *priv = GET_PRIV (applet);
 
-	priv->contact = g_object_ref (contacts->data);
+	if (error != NULL) {
+		DEBUG ("Error: %s", error->message);
+		return;
+	}
+
+	priv->contact = g_object_ref (contact);
 	g_signal_connect_swapped (priv->contact, "notify",
 				  G_CALLBACK (megaphone_applet_update_contact),
 				  applet);
@@ -192,14 +198,13 @@ megaphone_applet_new_connection_cb (EmpathyAccountManager *manager,
 				    MegaphoneApplet       *applet)
 {
 	MegaphoneAppletPriv *priv = GET_PRIV (applet);
-	const gchar *id = priv->id;
 
 	if (priv->contact || !empathy_account_equal (account, priv->account)) {
 		return;
 	}
 
 	priv->factory = empathy_tp_contact_factory_dup_singleton (connection);
-	empathy_tp_contact_factory_get_from_ids (priv->factory, 1, &id,
+	empathy_tp_contact_factory_get_from_id (priv->factory, priv->id,
 		megaphone_applet_got_contact_cb,
 		NULL, NULL, G_OBJECT (applet));
 }
diff --git a/src/empathy-event-manager.c b/src/empathy-event-manager.c
index 4efb707..7d8721c 100644
--- a/src/empathy-event-manager.c
+++ b/src/empathy-event-manager.c
@@ -589,14 +589,22 @@ event_manager_tube_dispatch_ability_cb (GObject *object,
 
 static void
 event_manager_tube_got_contact_cb (EmpathyTpContactFactory *factory,
-                                   GList *contacts,
+                                   EmpathyContact *contact,
+                                   const GError *error,
                                    gpointer user_data,
                                    GObject *object)
 {
   EventManagerApproval *approval = (EventManagerApproval *)user_data;
   EmpathyTubeDispatchAbility dispatchability;
 
-  approval->contact = g_object_ref (contacts->data);
+  if (error != NULL)
+    {
+      /* FIXME: We should probably still display the event */
+      DEBUG ("Error: %s", error->message);
+      return;
+    }
+
+  approval->contact = g_object_ref (contact);
 
   dispatchability = empathy_tube_dispatch_is_dispatchable
     (approval->tube_dispatch);
@@ -705,7 +713,8 @@ event_room_channel_process_func (EventPriv *event)
 
 static void
 event_manager_muc_invite_got_contact_cb (EmpathyTpContactFactory *factory,
-                                         GList *contacts,
+                                         EmpathyContact *contact,
+                                         const GError *error,
                                          gpointer user_data,
                                          GObject *object)
 {
@@ -715,7 +724,14 @@ event_manager_muc_invite_got_contact_cb (EmpathyTpContactFactory *factory,
   gchar *msg;
   TpHandle self_handle;
 
-  approval->contact = g_object_ref (contacts->data);
+  if (error != NULL)
+    {
+      /* FIXME: We should probably still display the event */
+      DEBUG ("Error: %s", error->message);
+      return;
+    }
+
+  approval->contact = g_object_ref (contact);
   channel = empathy_dispatch_operation_get_channel (approval->operation);
 
   self_handle = tp_channel_group_get_self_handle (channel);
@@ -785,8 +801,8 @@ event_manager_approve_channel_cb (EmpathyDispatcher *dispatcher,
               connection = empathy_tp_chat_get_connection (tp_chat);
               factory = empathy_tp_contact_factory_dup_singleton (connection);
 
-              empathy_tp_contact_factory_get_from_handles (factory,
-                  1, &inviter, event_manager_muc_invite_got_contact_cb,
+              empathy_tp_contact_factory_get_from_handle (factory,
+                  inviter, event_manager_muc_invite_got_contact_cb,
                   approval, NULL, G_OBJECT (manager));
 
               g_object_unref (factory);
@@ -861,7 +877,7 @@ event_manager_approve_channel_cb (EmpathyDispatcher *dispatcher,
       approval->tube_dispatch = empathy_tube_dispatch_new (operation);
       connection = tp_channel_borrow_connection (channel);
       factory = empathy_tp_contact_factory_dup_singleton (connection);
-      empathy_tp_contact_factory_get_from_handles (factory, 1, &handle,
+      empathy_tp_contact_factory_get_from_handle (factory, handle,
         event_manager_tube_got_contact_cb, approval, NULL, G_OBJECT (manager));
     }
   else



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]