aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libempathy/empathy-tp-contact-list.c285
1 files changed, 172 insertions, 113 deletions
diff --git a/libempathy/empathy-tp-contact-list.c b/libempathy/empathy-tp-contact-list.c
index d5fa9c3e2..93f81e8fd 100644
--- a/libempathy/empathy-tp-contact-list.c
+++ b/libempathy/empathy-tp-contact-list.c
@@ -385,12 +385,13 @@ tp_contact_list_add_channel (EmpathyTpContactList *list,
guint handle)
{
EmpathyTpContactListPriv *priv = GET_PRIV (list);
- EmpathyTpGroup *group;
TpChannel *channel;
+ EmpathyTpGroup *group;
+ const gchar *group_name;
+ GList *contacts, *l;
if (strcmp (channel_type, TP_IFACE_CHANNEL_TYPE_CONTACT_LIST) != 0 ||
- (handle_type != TP_HANDLE_TYPE_LIST &&
- handle_type != TP_HANDLE_TYPE_GROUP)) {
+ handle_type != TP_HANDLE_TYPE_GROUP) {
return;
}
@@ -402,117 +403,35 @@ tp_contact_list_add_channel (EmpathyTpContactList *list,
empathy_run_until_ready (group);
g_object_unref (channel);
- if (handle_type == TP_HANDLE_TYPE_LIST) {
- TpContactListType list_type;
- GList *contacts, *l;
-
- list_type = tp_contact_list_get_type (list, group);
- if (list_type == TP_CONTACT_LIST_TYPE_PUBLISH && !priv->publish) {
- priv->publish = g_object_ref (group);
-
- /* Publish is the list of contacts to who we send our
- * presence. Makes no sense to be in remote-pending */
- g_signal_connect (group, "local-pending",
- G_CALLBACK (tp_contact_list_pending_cb),
- list);
-
- contacts = empathy_tp_group_get_local_pendings (group);
- for (l = contacts; l; l = l->next) {
- EmpathyPendingInfo *info = l->data;
-
- tp_contact_list_pending_cb (group,
- info->member,
- info->actor,
- 0,
- info->message,
- list);
- empathy_pending_info_free (info);
- }
- g_list_free (contacts);
- }
- else if (list_type == TP_CONTACT_LIST_TYPE_SUBSCRIBE && !priv->subscribe) {
- priv->subscribe = g_object_ref (group);
-
- /* Subscribe is the list of contacts from who we
- * receive presence. Makes no sense to be in
- * local-pending */
- g_signal_connect (group, "remote-pending",
- G_CALLBACK (tp_contact_list_pending_cb),
- list);
-
- contacts = empathy_tp_group_get_remote_pendings (group);
- for (l = contacts; l; l = l->next) {
- tp_contact_list_pending_cb (group,
- l->data,
- NULL, 0,
- NULL, list);
- g_object_unref (l->data);
- }
- g_list_free (contacts);
- } else {
- DEBUG ("Type of contact list channel unknown or aleady "
- "have that list: %s",
- empathy_tp_group_get_name (group));
- goto OUT;
- }
- DEBUG ("New contact list channel of type: %d", list_type);
-
- g_signal_connect (group, "member-added",
- G_CALLBACK (tp_contact_list_added_cb),
- list);
- g_signal_connect (group, "member-removed",
- G_CALLBACK (tp_contact_list_removed_cb),
- list);
-
- contacts = empathy_tp_group_get_members (group);
- for (l = contacts; l; l = l->next) {
- tp_contact_list_added_cb (group,
- l->data,
- NULL, 0, NULL,
- list);
- g_object_unref (l->data);
- }
- g_list_free (contacts);
+ /* Check if already exists */
+ group_name = empathy_tp_group_get_name (group);
+ if (tp_contact_list_find_group (list, group_name)) {
+ g_object_unref (group);
+ return;
}
- else if (handle_type == TP_HANDLE_TYPE_GROUP) {
- const gchar *group_name;
- GList *contacts, *l;
-
- /* Check if already exists */
- group_name = empathy_tp_group_get_name (group);
- if (tp_contact_list_find_group (list, group_name)) {
- goto OUT;
- }
- DEBUG ("New server-side group channel: %s", group_name);
-
- priv->groups = g_list_prepend (priv->groups, g_object_ref (group));
-
- g_signal_connect (group, "member-added",
- G_CALLBACK (tp_contact_list_group_member_added_cb),
- list);
- g_signal_connect (group, "member-removed",
- G_CALLBACK (tp_contact_list_group_member_removed_cb),
- list);
- g_signal_connect (group, "destroy",
- G_CALLBACK (tp_contact_list_group_destroy_cb),
- list);
+ /* Add the group */
+ DEBUG ("New server-side group: %s", group_name);
+ priv->groups = g_list_prepend (priv->groups, group);
+ g_signal_connect (group, "member-added",
+ G_CALLBACK (tp_contact_list_group_member_added_cb),
+ list);
+ g_signal_connect (group, "member-removed",
+ G_CALLBACK (tp_contact_list_group_member_removed_cb),
+ list);
+ g_signal_connect (group, "destroy",
+ G_CALLBACK (tp_contact_list_group_destroy_cb),
+ list);
- contacts = empathy_tp_group_get_members (group);
- for (l = contacts; l; l = l->next) {
- tp_contact_list_group_member_added_cb (group, l->data,
- NULL, 0, NULL,
- list);
- g_object_unref (l->data);
- }
- g_list_free (contacts);
- } else {
- DEBUG ("Unknown handle type (%d) for contact list channel",
- handle_type);
+ /* Get initial members */
+ contacts = empathy_tp_group_get_members (group);
+ for (l = contacts; l; l = l->next) {
+ tp_contact_list_group_member_added_cb (group, l->data,
+ NULL, 0, NULL,
+ list);
+ g_object_unref (l->data);
}
-
-OUT:
- g_object_unref (group);
+ g_list_free (contacts);
}
static void
@@ -545,8 +464,7 @@ tp_contact_list_list_channels_cb (TpConnection *connection,
guint i;
if (error) {
- DEBUG ("Failed to get list of open channels: %s",
- error ? error->message : "No error given");
+ DEBUG ("Error: %s", error->message);
return;
}
@@ -572,6 +490,145 @@ tp_contact_list_list_channels_cb (TpConnection *connection,
}
static void
+tp_contact_list_request_channel_cb (TpConnection *connection,
+ const gchar *object_path,
+ const GError *error,
+ gpointer user_data,
+ GObject *weak_object)
+{
+ EmpathyTpContactList *list = EMPATHY_TP_CONTACT_LIST (weak_object);
+ EmpathyTpContactListPriv *priv = GET_PRIV (list);
+ EmpathyTpGroup *group;
+ TpChannel *channel;
+ TpContactListType list_type;
+ GList *contacts, *l;
+
+ if (error) {
+ DEBUG ("Error: %s", error->message);
+ return;
+ }
+
+ channel = tp_channel_new (connection, object_path,
+ TP_IFACE_CHANNEL_TYPE_CONTACT_LIST,
+ TP_HANDLE_TYPE_LIST,
+ GPOINTER_TO_UINT (user_data),
+ NULL);
+ group = empathy_tp_group_new (channel);
+ empathy_run_until_ready (group);
+
+ list_type = tp_contact_list_get_type (list, group);
+ if (list_type == TP_CONTACT_LIST_TYPE_PUBLISH && !priv->publish) {
+ DEBUG ("Got publish list");
+ priv->publish = group;
+
+ /* Publish is the list of contacts to who we send our
+ * presence. Makes no sense to be in remote-pending */
+ g_signal_connect (group, "local-pending",
+ G_CALLBACK (tp_contact_list_pending_cb),
+ list);
+
+ contacts = empathy_tp_group_get_local_pendings (group);
+ for (l = contacts; l; l = l->next) {
+ EmpathyPendingInfo *info = l->data;
+ tp_contact_list_pending_cb (group,
+ info->member,
+ info->actor,
+ 0,
+ info->message,
+ list);
+ empathy_pending_info_free (info);
+ }
+ g_list_free (contacts);
+ }
+ else if (list_type == TP_CONTACT_LIST_TYPE_SUBSCRIBE && !priv->subscribe) {
+ DEBUG ("Got subscribe list");
+ priv->subscribe = group;
+
+ /* Subscribe is the list of contacts from who we
+ * receive presence. Makes no sense to be in
+ * local-pending */
+ g_signal_connect (group, "remote-pending",
+ G_CALLBACK (tp_contact_list_pending_cb),
+ list);
+
+ contacts = empathy_tp_group_get_remote_pendings (group);
+ for (l = contacts; l; l = l->next) {
+ tp_contact_list_pending_cb (group,
+ l->data,
+ NULL, 0,
+ NULL, list);
+ g_object_unref (l->data);
+ }
+ g_list_free (contacts);
+ } else {
+ DEBUG ("Type of contact list channel unknown or aleady "
+ "have that list: %s",
+ empathy_tp_group_get_name (group));
+ g_object_unref (group);
+ return;
+ }
+
+ /* For all list types when need to get members */
+ g_signal_connect (group, "member-added",
+ G_CALLBACK (tp_contact_list_added_cb),
+ list);
+ g_signal_connect (group, "member-removed",
+ G_CALLBACK (tp_contact_list_removed_cb),
+ list);
+
+ contacts = empathy_tp_group_get_members (group);
+ for (l = contacts; l; l = l->next) {
+ tp_contact_list_added_cb (group,
+ l->data,
+ NULL, 0, NULL,
+ list);
+ g_object_unref (l->data);
+ }
+ g_list_free (contacts);
+}
+
+static void
+tp_contact_list_request_handle_cb (TpConnection *connection,
+ const GArray *handles,
+ const GError *error,
+ gpointer user_data,
+ GObject *list)
+{
+ guint handle;
+
+ if (error) {
+ DEBUG ("Error: %s", error->message);
+ return;
+ }
+
+ handle = g_array_index (handles, guint, 0);
+ tp_cli_connection_call_request_channel (connection, -1,
+ TP_IFACE_CHANNEL_TYPE_CONTACT_LIST,
+ TP_HANDLE_TYPE_LIST,
+ handle,
+ TRUE,
+ tp_contact_list_request_channel_cb,
+ GUINT_TO_POINTER (handle), NULL,
+ list);
+}
+
+static void
+tp_contact_list_request_list (EmpathyTpContactList *list,
+ const gchar *type)
+{
+ EmpathyTpContactListPriv *priv = GET_PRIV (list);
+ const gchar *names[] = {type, NULL};
+
+ tp_cli_connection_call_request_handles (priv->connection,
+ -1,
+ TP_HANDLE_TYPE_LIST,
+ names,
+ tp_contact_list_request_handle_cb,
+ NULL, NULL,
+ G_OBJECT (list));
+}
+
+static void
tp_contact_list_finalize (GObject *object)
{
EmpathyTpContactListPriv *priv;
@@ -629,6 +686,9 @@ tp_contact_list_connection_ready (TpConnection *connection,
G_CALLBACK (tp_contact_list_invalidated_cb),
list);
+ tp_contact_list_request_list (list, "publish");
+ tp_contact_list_request_list (list, "subscribe");
+
tp_cli_connection_call_list_channels (priv->connection, -1,
tp_contact_list_list_channels_cb,
NULL, NULL,
@@ -647,7 +707,6 @@ tp_contact_list_constructed (GObject *list)
EmpathyTpContactListPriv *priv = GET_PRIV (list);
MissionControl *mc;
guint status;
- gboolean ready;
McProfile *profile;
const gchar *protocol_name;