diff options
Diffstat (limited to 'libempathy')
-rw-r--r-- | libempathy/empathy-tp-chatroom.c | 163 | ||||
-rw-r--r-- | libempathy/empathy-tp-chatroom.h | 13 | ||||
-rw-r--r-- | libempathy/empathy-tp-contact-list.c | 46 | ||||
-rw-r--r-- | libempathy/gossip-telepathy-group.c | 57 | ||||
-rw-r--r-- | libempathy/gossip-telepathy-group.h | 10 |
5 files changed, 248 insertions, 41 deletions
diff --git a/libempathy/empathy-tp-chatroom.c b/libempathy/empathy-tp-chatroom.c index 6feef549d..34875c10c 100644 --- a/libempathy/empathy-tp-chatroom.c +++ b/libempathy/empathy-tp-chatroom.c @@ -30,6 +30,7 @@ #include "empathy-contact-manager.h" #include "gossip-telepathy-group.h" #include "gossip-utils.h" +#include "gossip-debug.h" #define GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \ EMPATHY_TYPE_TP_CHATROOM, EmpathyTpChatroomPriv)) @@ -40,12 +41,28 @@ struct _EmpathyTpChatroomPriv { EmpathyContactManager *manager; EmpathyTpContactList *list; GossipTelepathyGroup *group; + + gboolean is_invited; + GossipContact *invitor; + gchar *invit_message; }; static void empathy_tp_chatroom_class_init (EmpathyTpChatroomClass *klass); static void tp_chatroom_iface_init (EmpathyContactListIface *iface); static void empathy_tp_chatroom_init (EmpathyTpChatroom *chatroom); static void tp_chatroom_finalize (GObject *object); +static void tp_chatroom_members_added_cb (GossipTelepathyGroup *group, + GArray *handles, + guint actor_handle, + guint reason, + const gchar *message, + EmpathyTpChatroom *list); +static void tp_chatroom_members_removed_cb (GossipTelepathyGroup *group, + GArray *handles, + guint actor_handle, + guint reason, + const gchar *message, + EmpathyTpChatroom *list); static void tp_chatroom_setup (EmpathyContactList *list); static GossipContact * tp_chatroom_find (EmpathyContactList *list, const gchar *id); @@ -97,7 +114,12 @@ tp_chatroom_finalize (GObject *object) g_object_unref (priv->group); g_object_unref (priv->manager); - g_object_unref (priv->list); + + if (priv->invitor) { + g_object_unref (priv->invitor); + } + + g_free (priv->invit_message); G_OBJECT_CLASS (empathy_tp_chatroom_parent_class)->finalize (object); } @@ -110,6 +132,8 @@ empathy_tp_chatroom_new (McAccount *account, EmpathyTpChatroom *chatroom; TpConn *tp_conn; MissionControl *mc; + GList *members, *l; + guint self_handle; g_return_val_if_fail (MC_IS_ACCOUNT (account), NULL); g_return_val_if_fail (TELEPATHY_IS_CHAN (tp_chan), NULL); @@ -124,18 +148,139 @@ empathy_tp_chatroom_new (McAccount *account, mc = gossip_mission_control_new (); tp_conn = mission_control_get_connection (mc, account, NULL); priv->manager = empathy_contact_manager_new (); - priv->group = gossip_telepathy_group_new (tp_chan, tp_conn); priv->list = empathy_contact_manager_get_list (priv->manager, account); + priv->group = gossip_telepathy_group_new (tp_chan, tp_conn); + + g_signal_connect (priv->group, "members-added", + G_CALLBACK (tp_chatroom_members_added_cb), + chatroom); + g_signal_connect (priv->group, "members-removed", + G_CALLBACK (tp_chatroom_members_removed_cb), + chatroom); + + /* Check if we are invited to join the chat */ + self_handle = gossip_telepathy_group_get_self_handle (priv->group); + members = gossip_telepathy_group_get_local_pending_members_with_info (priv->group); + for (l = members; l; l = l->next) { + GossipTpGroupInfo *info; + info = l->data; + + if (info->member != self_handle) { + continue; + } + + priv->invitor = empathy_tp_contact_list_get_from_handle (priv->list, + info->actor); + priv->invit_message = g_strdup (info->message); + priv->is_invited = TRUE; + + gossip_debug (DEBUG_DOMAIN, "We are invited to join by %s: %s", + gossip_contact_get_name (priv->invitor), + priv->invit_message); + } + + gossip_telepathy_group_info_list_free (members); g_object_unref (mc); g_object_unref (tp_conn); return chatroom; } +gboolean +empathy_tp_chatroom_get_invitation (EmpathyTpChatroom *chatroom, + GossipContact **contact, + const gchar **message) +{ + EmpathyTpChatroomPriv *priv; + + g_return_val_if_fail (EMPATHY_IS_TP_CHATROOM (chatroom), FALSE); + + priv = GET_PRIV (chatroom); + + if (*contact) { + *contact = priv->invitor; + } + if (*message) { + *message = priv->invit_message; + } + + return priv->is_invited; +} + +void +empathy_tp_chatroom_accept_invitation (EmpathyTpChatroom *chatroom) +{ + EmpathyTpChatroomPriv *priv; + guint self_handle; + + g_return_if_fail (EMPATHY_IS_TP_CHATROOM (chatroom)); + + priv = GET_PRIV (chatroom); + + /* Clear invitation data */ + priv->is_invited = FALSE; + if (priv->invitor) { + g_object_unref (priv->invitor); + priv->invitor = NULL; + } + g_free (priv->invit_message); + priv->invit_message = NULL; + + /* Add ourself in the members of the room */ + self_handle = gossip_telepathy_group_get_self_handle (priv->group); + gossip_telepathy_group_add_member (priv->group, self_handle, + "Just for fun"); +} + +void +empathy_tp_chatroom_set_topic (EmpathyTpChatroom *chatroom, + const gchar *topic) +{ +} + +static void +tp_chatroom_members_added_cb (GossipTelepathyGroup *group, + GArray *handles, + guint actor_handle, + guint reason, + const gchar *message, + EmpathyTpChatroom *chatroom) +{ + EmpathyTpChatroomPriv *priv; + GList *contacts, *l; + + g_return_if_fail (EMPATHY_IS_TP_CHATROOM (chatroom)); + + priv = GET_PRIV (chatroom); + + contacts = empathy_tp_contact_list_get_from_handles (priv->list, handles); + for (l = contacts; l; l = l->next) { + GossipContact *contact; + + contact = l->data; + + g_signal_emit_by_name (chatroom, "contact-added", contact); + + g_object_unref (contact); + } + g_list_free (contacts); +} + +static void +tp_chatroom_members_removed_cb (GossipTelepathyGroup *group, + GArray *handles, + guint actor_handle, + guint reason, + const gchar *message, + EmpathyTpChatroom *chatroom) +{ +} + static void tp_chatroom_setup (EmpathyContactList *list) { + /* Nothing to do */ } static GossipContact * @@ -162,6 +307,18 @@ tp_chatroom_remove (EmpathyContactList *list, static GList * tp_chatroom_get_contacts (EmpathyContactList *list) { - return NULL; + EmpathyTpChatroomPriv *priv; + GArray *members; + GList *contacts; + + g_return_val_if_fail (EMPATHY_IS_TP_CHATROOM (list), NULL); + + priv = GET_PRIV (list); + + members = gossip_telepathy_group_get_members (priv->group); + contacts = empathy_tp_contact_list_get_from_handles (priv->list, members); + g_array_free (members, TRUE); + + return contacts; } diff --git a/libempathy/empathy-tp-chatroom.h b/libempathy/empathy-tp-chatroom.h index 75ccc58c1..488ac74fb 100644 --- a/libempathy/empathy-tp-chatroom.h +++ b/libempathy/empathy-tp-chatroom.h @@ -52,10 +52,15 @@ struct _EmpathyTpChatroomClass { EmpathyTpChatClass parent_class; }; -GType empathy_tp_chatroom_get_type (void) G_GNUC_CONST; -EmpathyTpChatroom *empathy_tp_chatroom_new (McAccount *account, - TpChan *tp_chan); - +GType empathy_tp_chatroom_get_type (void) G_GNUC_CONST; +EmpathyTpChatroom *empathy_tp_chatroom_new (McAccount *account, + TpChan *tp_chan); +gboolean empathy_tp_chatroom_get_invitation (EmpathyTpChatroom *chatroom, + GossipContact **contact, + const gchar **message); +void empathy_tp_chatroom_accept_invitation (EmpathyTpChatroom *chatroom); +void empathy_tp_chatroom_set_topic (EmpathyTpChatroom *chatroom, + const gchar *topic); G_END_DECLS #endif /* __EMPATHY_TP_CHATROOM_H__ */ diff --git a/libempathy/empathy-tp-contact-list.c b/libempathy/empathy-tp-contact-list.c index 60a7fd535..2ebb648a3 100644 --- a/libempathy/empathy-tp-contact-list.c +++ b/libempathy/empathy-tp-contact-list.c @@ -622,6 +622,11 @@ empathy_tp_contact_list_get_from_handles (EmpathyTpContactList *list, guint handle; handle = g_array_index (handles, guint, i); + + if (handle == 0) { + continue; + } + contact = g_hash_table_lookup (priv->contacts, GUINT_TO_POINTER (handle)); @@ -974,49 +979,34 @@ tp_contact_list_newchannel_cb (DBusGProxy *proxy, g_array_free (members, TRUE); } if (list_type == TP_CONTACT_LIST_TYPE_PUBLISH) { - GPtrArray *info; - GArray *pending; - guint i; + GList *members, *l; + GArray *pending; g_signal_connect (group, "local-pending", G_CALLBACK (tp_contact_list_local_pending_cb), list); - info = gossip_telepathy_group_get_local_pending_members_with_info (group); - - if (!info) { - /* This happens with butterfly because - * GetLocalPendingMembersWithInfo is not - * implemented */ + members = gossip_telepathy_group_get_local_pending_members_with_info (group); + if (!members) { g_object_unref (new_chan); return; } pending = g_array_sized_new (FALSE, FALSE, sizeof (guint), 1); - for (i = 0; info->len > i; i++) { - GValueArray *pending_struct; - guint member; - guint invitor; - guint reason; - const gchar *message; - - pending_struct = g_ptr_array_index (info, i); - member = g_value_get_uint (g_value_array_get_nth (pending_struct, 0)); - invitor = g_value_get_uint (g_value_array_get_nth (pending_struct, 1)); - reason = g_value_get_uint (g_value_array_get_nth (pending_struct, 2)); - message = g_value_get_string (g_value_array_get_nth (pending_struct, 3)); + for (l = members; l; l = l->next) { + GossipTpGroupInfo *info; - g_array_insert_val (pending, 0, member); + info = l->data; + g_array_insert_val (pending, 0, info->member); tp_contact_list_local_pending_cb (group, pending, - invitor, - reason, - message, list); - - g_value_array_free (pending_struct); + info->actor, + info->reason, + info->message, + list); } - g_ptr_array_free (info, TRUE); + gossip_telepathy_group_info_list_free (members); g_array_free (pending, TRUE); } } diff --git a/libempathy/gossip-telepathy-group.c b/libempathy/gossip-telepathy-group.c index 3f9998c0d..5d6bff670 100644 --- a/libempathy/gossip-telepathy-group.c +++ b/libempathy/gossip-telepathy-group.c @@ -314,11 +314,13 @@ gossip_telepathy_group_get_all_members (GossipTelepathyGroup *group, } } -GPtrArray * -gossip_telepathy_group_get_local_pending_members_with_info (GossipTelepathyGroup *group) +GList * +gossip_telepathy_group_get_local_pending_members_with_info (GossipTelepathyGroup *group) { GossipTelepathyGroupPriv *priv; - GPtrArray *info = NULL; + GPtrArray *array; + guint i; + GList *infos = NULL; GError *error = NULL; g_return_val_if_fail (GOSSIP_IS_TELEPATHY_GROUP (group), NULL); @@ -326,17 +328,62 @@ gossip_telepathy_group_get_local_pending_members_with_info (GossipTelepathyGroup priv = GET_PRIV (group); if (!tp_chan_iface_group_get_local_pending_members_with_info (priv->group_iface, - &info, + &array, &error)) { gossip_debug (DEBUG_DOMAIN, "GetLocalPendingMembersWithInfo failed: %s", error ? error->message : "No error given"); g_clear_error (&error); + + return NULL; + } + + if (!array) { + /* This happens with butterfly because + * GetLocalPendingMembersWithInfo is not + * implemented */ + return NULL; + } + + for (i = 0; array->len > i; i++) { + GValueArray *pending_struct; + GossipTpGroupInfo *info; + const gchar *message; + + info = g_slice_new (GossipTpGroupInfo); + + pending_struct = g_ptr_array_index (array, i); + info->member = g_value_get_uint (g_value_array_get_nth (pending_struct, 0)); + info->actor = g_value_get_uint (g_value_array_get_nth (pending_struct, 1)); + info->reason = g_value_get_uint (g_value_array_get_nth (pending_struct, 2)); + message = g_value_get_string (g_value_array_get_nth (pending_struct, 3)); + info->message = g_strdup (message); + g_value_array_free (pending_struct); + + infos = g_list_prepend (infos, info); } + g_ptr_array_free (array, TRUE); - return info; + return infos; } +void +gossip_telepathy_group_info_list_free (GList *infos) +{ + GList *l; + + for (l = infos; l; l = l->next) { + GossipTpGroupInfo *info; + + info = l->data; + + g_free (info->message); + g_slice_free (GossipTpGroupInfo, info); + } + g_list_free (infos); +} + + static void telepathy_group_destroy_cb (DBusGProxy *proxy, GossipTelepathyGroup *group) diff --git a/libempathy/gossip-telepathy-group.h b/libempathy/gossip-telepathy-group.h index 9c61bdbc4..17b96de2e 100644 --- a/libempathy/gossip-telepathy-group.h +++ b/libempathy/gossip-telepathy-group.h @@ -46,6 +46,13 @@ struct _GossipTelepathyGroupClass { GObjectClass parent_class; }; +typedef struct { + guint member; + guint actor; + guint reason; + gchar *message; +} GossipTpGroupInfo; + GType gossip_telepathy_group_get_type (void) G_GNUC_CONST; GossipTelepathyGroup *gossip_telepathy_group_new (TpChan *tp_chan, TpConn *tp_conn); @@ -66,8 +73,9 @@ void gossip_telepathy_group_get_all_members (GossipTelepathyGro GArray **members, GArray **local_pending, GArray **remote_pending); -GPtrArray * gossip_telepathy_group_get_local_pending_members_with_info +GList * gossip_telepathy_group_get_local_pending_members_with_info (GossipTelepathyGroup *group); +void gossip_telepathy_group_info_list_free (GList *infos); const gchar * gossip_telepathy_group_get_name (GossipTelepathyGroup *group); guint gossip_telepathy_group_get_self_handle (GossipTelepathyGroup *group); const gchar * gossip_telepathy_group_get_object_path (GossipTelepathyGroup *group); |