soc.2009.telepathy: e32efd08: Break telepathy.c into smaller files. Ab...
sttwister at soc.pidgin.im
sttwister at soc.pidgin.im
Tue Jun 16 14:50:32 EDT 2009
-----------------------------------------------------------------
Revision: e32efd08d7d6e23c94ba5ffd8d2577845946b1c3
Ancestor: ec8545dc30d048802c19bc685b6cf6449a24bad9
Author: sttwister at soc.pidgin.im
Date: 2009-06-16T18:48:23
Branch: im.pidgin.soc.2009.telepathy
URL: http://d.pidgin.im/viewmtn/revision/info/e32efd08d7d6e23c94ba5ffd8d2577845946b1c3
Added files:
libpurple/protocols/telepathy/telepathy_avatar.c
libpurple/protocols/telepathy/telepathy_avatar.h
libpurple/protocols/telepathy/telepathy_channel.c
libpurple/protocols/telepathy/telepathy_channel.h
libpurple/protocols/telepathy/telepathy_channel_list.c
libpurple/protocols/telepathy/telepathy_channel_list.h
libpurple/protocols/telepathy/telepathy_channel_text.c
libpurple/protocols/telepathy/telepathy_channel_text.h
libpurple/protocols/telepathy/telepathy_connection.c
libpurple/protocols/telepathy/telepathy_connection.h
libpurple/protocols/telepathy/telepathy_contact.c
libpurple/protocols/telepathy/telepathy_contact.h
Modified files:
libpurple/protocols/telepathy/Makefile.am
libpurple/protocols/telepathy/Makefile.mingw
libpurple/protocols/telepathy/telepathy.c
Modified attrs:
libpurple/protocols/telepathy/telepathy_avatar.c
libpurple/protocols/telepathy/telepathy_avatar.h
libpurple/protocols/telepathy/telepathy_channel.c
libpurple/protocols/telepathy/telepathy_channel.h
libpurple/protocols/telepathy/telepathy_channel_list.c
libpurple/protocols/telepathy/telepathy_channel_list.h
libpurple/protocols/telepathy/telepathy_channel_text.c
libpurple/protocols/telepathy/telepathy_channel_text.h
libpurple/protocols/telepathy/telepathy_connection.c
libpurple/protocols/telepathy/telepathy_connection.h
libpurple/protocols/telepathy/telepathy_contact.c
libpurple/protocols/telepathy/telepathy_contact.h
ChangeLog:
Break telepathy.c into smaller files. About time...
-------------- next part --------------
============================================================
--- libpurple/protocols/telepathy/telepathy_avatar.c 8079ed553f9a14f3f926fffb1e9e4c086a4016d2
+++ libpurple/protocols/telepathy/telepathy_avatar.c 8079ed553f9a14f3f926fffb1e9e4c086a4016d2
@@ -0,0 +1,296 @@
+/**
+ * purple - Telepathy Protocol Plugin
+ *
+ * Copyright (C) 2009, Felix Kerekes <sttwister at soc.pidgin.im>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+ */
+
+#include "telepathy_avatar.h"
+
+#include "debug.h"
+
+#include "telepathy_connection.h"
+#include "telepathy_contact.h"
+
+void
+request_avatars_cb (TpConnection *proxy,
+ const GError *error,
+ gpointer user_data,
+ GObject *weak_object)
+{
+ if (error != NULL)
+ {
+ purple_debug_error("telepathy", "RequestAvatars error: %s\n", error->message);
+ }
+}
+
+void
+get_known_avatar_tokens_cb (TpConnection *proxy,
+ GHashTable *out_Tokens,
+ const GError *error,
+ gpointer user_data,
+ GObject *weak_object)
+{
+ if (error != NULL)
+ {
+ purple_debug_error("telepathy", "GetAvatarTokens error: %s\n", error->message);
+ }
+ else
+ {
+ GHashTableIter iter;
+ guint key;
+ gpointer value;
+
+ g_hash_table_iter_init(&iter, out_Tokens);
+
+ while (g_hash_table_iter_next(&iter, (gpointer)&key, &value))
+ {
+ purple_debug_info("telepathy", "Known token: %u -> (%s)\n", key, (gchar *)value);
+ }
+ }
+}
+
+void
+avatar_retrieved_cb (TpConnection *proxy,
+ guint arg_Contact,
+ const gchar *arg_Token,
+ const GArray *arg_Avatar,
+ const gchar *arg_Type,
+ gpointer user_data,
+ GObject *weak_object)
+{
+ telepathy_connection *data = user_data;
+ PurpleBuddyIcon *icon;
+ telepathy_contact *contact_data = g_hash_table_lookup(data->contacts, (gpointer)arg_Contact);
+ TpContact *contact;
+ gpointer avatar;
+
+ if (contact_data == NULL)
+ {
+ purple_debug_warning("telepathy", "Updated avatar for handle %u which has no contact_data struct cached!\n", arg_Contact);
+ return;
+ }
+
+ contact = contact_data->contact;
+
+ if (contact == NULL)
+ {
+ purple_debug_warning("telepathy", "Retrieved avatar for handle %u which has no TpContact proxy cached!\n", arg_Contact);
+ return;
+ }
+
+ purple_debug_info("telepathy", "Got avatar token for %u: (%s - %s)\n", arg_Contact, arg_Token, arg_Type);
+
+ avatar = g_memdup(arg_Avatar->data, arg_Avatar->len);
+
+ icon = purple_buddy_icon_new(data->acct, tp_contact_get_identifier(contact), avatar, arg_Avatar->len, arg_Token);
+}
+
+void
+avatar_updated_cb (TpConnection *proxy,
+ guint arg_Contact,
+ const gchar *arg_New_Avatar_Token,
+ gpointer user_data,
+ GObject *weak_object)
+{
+ telepathy_connection *data = user_data;
+ telepathy_contact *contact_data = g_hash_table_lookup(data->contacts, (gpointer)arg_Contact);
+ TpContact *contact;
+ PurpleBuddy *buddy;
+ PurpleBuddyIcon *icon;
+
+ purple_debug_warning("telepathy", "Avatar token updated for %u: (%s)\n", arg_Contact, arg_New_Avatar_Token);
+
+ if (contact_data == NULL)
+ {
+ purple_debug_warning("telepathy", "Updated avatar for handle %u which has no contact_data struct cached!\n", arg_Contact);
+ return;
+ }
+
+ contact = contact_data->contact;
+
+ if (contact == NULL)
+ {
+ purple_debug_warning("telepathy", "Updated avatar for handle %u which has no TpContact proxy chaced!\n", arg_Contact);
+ return;
+ }
+
+ buddy = purple_find_buddy(data->acct, tp_contact_get_identifier(contact));
+
+ if (buddy == NULL)
+ {
+ purple_debug_warning("telepathy", "AvatarUpdated: There's no buddy named %s\n", tp_contact_get_identifier(contact));
+ return;
+ }
+
+ /* clear the avatar in case of an empty token */
+ if (*arg_New_Avatar_Token == 0)
+ {
+ purple_buddy_icons_set_for_user(data->acct, tp_contact_get_identifier(contact), NULL, 0, "");
+ return;
+ }
+
+
+ icon = purple_buddy_get_icon(buddy);
+
+ if (g_strcmp0(purple_buddy_icon_get_checksum(icon), arg_New_Avatar_Token) != 0)
+ {
+ /* updated the buddy avatar */
+ GArray *avatar_handles;
+
+ purple_debug_info("telepathy", "Avatar for %u (%s) has changed! Calling RequestAvatars\n", arg_Contact, tp_contact_get_identifier(contact));
+
+ avatar_handles = g_array_new(FALSE, FALSE, sizeof(guint));
+
+ g_array_append_val(avatar_handles, arg_Contact);
+
+ tp_cli_connection_interface_avatars_call_request_avatars(data->connection, -1,
+ avatar_handles,
+ request_avatars_cb, data,
+ NULL, NULL);
+
+ g_array_free(avatar_handles, TRUE);
+ }
+}
+
+void
+get_avatar_properties_cb (TpProxy *proxy,
+ GHashTable *out_Properties,
+ const GError *error,
+ gpointer user_data,
+ GObject *weak_object)
+{
+ if (error != NULL)
+ {
+ purple_debug_error("telepathy", "Error getting avatar properties: %s\n", error->message);
+ }
+ else
+ {
+ telepathy_connection *data = user_data;
+ PurplePlugin *plugin = purple_connection_get_prpl(data->gc);
+ PurplePluginProtocolInfo *prpl_info = plugin->info->extra_info;
+
+
+ GHashTableIter iter;
+ gpointer key, value;
+
+ PurpleBuddyIconSpec icon_spec = NO_BUDDY_ICONS;
+ icon_spec.scale_rules = PURPLE_ICON_SCALE_SEND;
+
+ purple_debug_info("telepathy", "Got avatar properties!\n");
+
+ g_hash_table_iter_init(&iter, out_Properties);
+
+ /* iterate over all properties */
+ while (g_hash_table_iter_next(&iter, &key, &value))
+ {
+ gchar *name = key;
+ GValue *val = value;
+
+ if (g_strcmp0("SupportedAvatarMIMETypes", name) == 0)
+ {
+ /* This parameter is of dbus type "as"
+ * It's exposed as a GValue holding a (gchar **)
+ * Or is it now??? wtf!?
+ */
+
+ gchar *format = NULL;
+
+ int i;
+ gchar **arr = g_value_get_boxed(val);
+
+ for (i = 0; arr[i] != NULL; ++i)
+ {
+ const gchar *mime_type = arr[i];
+
+ int j;
+
+ /* We want to get the part after the /
+ * Split the string using / as a delimiter and use the last part
+ */
+ gchar **split = g_strsplit(mime_type, "/", 0);
+ gchar *old = format;
+
+ /* j will be the last non-NULL token */
+ for (j = 0; split[j] != NULL; ++j);
+ --j;
+
+
+ /* if this is the first type, don't prepend a comma */
+ if (i == 0)
+ format = g_strdup(split[j]);
+ else
+ format = g_strdup_printf("%s,%s", format, split[j]);
+
+ g_free(old);
+ g_strfreev(split);
+ }
+
+ purple_debug_info("telepathy", " Supported types: %s\n", format);
+
+ icon_spec.format = format;
+ }
+ else if (g_strcmp0("MinimumAvatarWidth", name) == 0)
+ {
+ icon_spec.min_width = g_value_get_uint(val);
+ }
+ else if (g_strcmp0("MinimumAvatarHeight", name) == 0)
+ {
+ icon_spec.min_height = g_value_get_uint(val);
+ }
+ else if (g_strcmp0("MaximumAvatarWidth", name) == 0)
+ {
+ icon_spec.max_width = g_value_get_uint(val);
+ }
+ else if (g_strcmp0("MaximumAvatarHeight", name) == 0)
+ {
+ icon_spec.max_height = g_value_get_uint(val);
+ }
+ else if (g_strcmp0("MaximumAvatarBytes", name) == 0)
+ {
+ icon_spec.max_filesize = g_value_get_uint(val);
+ }
+ }
+
+ prpl_info->icon_spec = icon_spec;
+ }
+}
+
+void
+set_avatar_cb (TpConnection *proxy,
+ const gchar *out_Token,
+ const GError *error,
+ gpointer user_data,
+ GObject *weak_object)
+{
+ if (error != NULL)
+ {
+ purple_debug_error("telepathy", "SetAvatar error: %s\n", error->message);
+ }
+}
+
+void
+clear_avatar_cb (TpConnection *proxy,
+ const GError *error,
+ gpointer user_data,
+ GObject *weak_object)
+{
+ if (error != NULL)
+ {
+ purple_debug_error("telepathy", "ClearAvatar error: %s\n", error->message);
+ }
+}
+
============================================================
--- libpurple/protocols/telepathy/telepathy_avatar.h 048d468f7657812529d266cf20f8afccc7e80364
+++ libpurple/protocols/telepathy/telepathy_avatar.h 048d468f7657812529d266cf20f8afccc7e80364
@@ -0,0 +1,76 @@
+/**
+ * purple - Telepathy Protocol Plugin
+ *
+ * Copyright (C); 2009, Felix Kerekes <sttwister at soc.pidgin.im>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option); any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+ */
+
+#ifndef _TELEPATHY_AVATAR_H_
+#define _TELEPATHY_AVATAR_H_
+
+#include <telepathy-glib/connection.h>
+
+void
+request_avatars_cb (TpConnection *proxy,
+ const GError *error,
+ gpointer user_data,
+ GObject *weak_object);
+
+void
+get_known_avatar_tokens_cb (TpConnection *proxy,
+ GHashTable *out_Tokens,
+ const GError *error,
+ gpointer user_data,
+ GObject *weak_object);
+
+void
+avatar_retrieved_cb (TpConnection *proxy,
+ guint arg_Contact,
+ const gchar *arg_Token,
+ const GArray *arg_Avatar,
+ const gchar *arg_Type,
+ gpointer user_data,
+ GObject *weak_object);
+
+void
+avatar_updated_cb (TpConnection *proxy,
+ guint arg_Contact,
+ const gchar *arg_New_Avatar_Token,
+ gpointer user_data,
+ GObject *weak_object);
+
+void
+get_avatar_properties_cb (TpProxy *proxy,
+ GHashTable *out_Properties,
+ const GError *error,
+ gpointer user_data,
+ GObject *weak_object);
+
+void
+set_avatar_cb (TpConnection *proxy,
+ const gchar *out_Token,
+ const GError *error,
+ gpointer user_data,
+ GObject *weak_object);
+
+void
+clear_avatar_cb (TpConnection *proxy,
+ const GError *error,
+ gpointer user_data,
+ GObject *weak_object);
+
+
+#endif /* _TELEPATHY_AVATAR_H_ */
============================================================
--- libpurple/protocols/telepathy/telepathy_channel.c bfd65c2c37f142efbd42435199415da13ba532a0
+++ libpurple/protocols/telepathy/telepathy_channel.c bfd65c2c37f142efbd42435199415da13ba532a0
@@ -0,0 +1,162 @@
+/**
+ * purple - Telepathy Protocol Plugin
+ *
+ * Copyright (C) 2009, Felix Kerekes <sttwister at soc.pidgin.im>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+ */
+
+#include "telepathy_channel.h"
+
+#include <telepathy-glib/interfaces.h>
+
+#include "internal.h"
+
+#include "debug.h"
+
+#include "telepathy_avatar.h"
+#include "telepathy_channel_list.h"
+#include "telepathy_channel_text.h"
+#include "telepathy_contact.h"
+
+void
+channel_ready_cb (TpChannel *channel,
+ const GError *error,
+ gpointer user_data)
+{
+ if (error != NULL)
+ {
+ purple_debug_error("telepathy", "Channel ready error: %s\n", error->message);
+ }
+ else
+ {
+ GQuark handle_Type;
+
+ handle_Type = tp_channel_get_channel_type_id(channel);
+
+ if (handle_Type == TP_IFACE_QUARK_CHANNEL_TYPE_CONTACT_LIST)
+ {
+ handle_list_channel(channel, user_data);
+ }
+ else if (handle_Type == TP_IFACE_QUARK_CHANNEL_TYPE_TEXT)
+ {
+ handle_text_channel(channel, user_data);
+ }
+ }
+}
+
+void
+channel_invalidated_cb (TpProxy *self,
+ guint domain,
+ gint code,
+ gchar *message,
+ gpointer user_data)
+{
+ purple_debug_info("telepathy", "Channel invalidated: %s\n", message);
+
+ g_object_unref(self);
+}
+
+void
+handle_new_channel (telepathy_connection *data,
+ const GValueArray *channel_Properties)
+{
+ char *object_Path = g_value_get_boxed(g_value_array_get_nth((GValueArray *)channel_Properties, 0));
+ GHashTable *map = g_value_get_boxed(g_value_array_get_nth((GValueArray *)channel_Properties, 1));
+
+ GError *error = NULL;
+ TpConnection *connection = data->connection;
+ TpChannel *channel = tp_channel_new_from_properties(connection, object_Path, map, &error);
+
+ if (error != NULL)
+ {
+ purple_debug_error("telepathy", "Error while creating TpChannel: %s\n", error->message);
+ g_error_free(error);
+ return;
+ }
+
+ purple_debug_info("telepathy", "New channel: %s\n", object_Path);
+
+ tp_channel_call_when_ready(channel, channel_ready_cb, data);
+
+ g_signal_connect(channel, "invalidated", G_CALLBACK (channel_invalidated_cb), data);
+}
+
+void
+new_channels_cb (TpConnection *proxy,
+ const GPtrArray *arg_Channels,
+ gpointer user_data,
+ GObject *weak_object)
+{
+ int i;
+ telepathy_connection *data = user_data;
+
+ if (data->listing_channels)
+ return;
+
+ purple_debug_info("telepathy", "NewChannels:\n");
+
+ for (i = 0; i < arg_Channels->len; i++)
+ {
+ GValueArray *channel = g_ptr_array_index(arg_Channels, i);
+
+ handle_new_channel(user_data, channel);
+ }
+}
+
+void
+ensure_channel_cb (TpConnection *proxy,
+ gboolean out_Yours,
+ const gchar *out_Channel,
+ GHashTable *out_Properties,
+ const GError *error,
+ gpointer user_data,
+ GObject *weak_object)
+{
+ if (error != NULL)
+ {
+ purple_debug_error("telepathy", "EnsureChannel error: %s\n", error->message);
+ }
+}
+
+void
+get_channels_cb (TpProxy *proxy,
+ const GValue *out_Value,
+ const GError *error,
+ gpointer user_data,
+ GObject *weak_object)
+{
+ if (error != NULL)
+ {
+ purple_debug_error("telepathy", "Get Channels error: %s\n", error->message);
+ }
+ else
+ {
+ telepathy_connection *data = user_data;
+
+ /* unpack the a(oa{sv}) struct */
+ const GPtrArray *channels = g_value_get_boxed(out_Value);
+ int i;
+
+ data->listing_channels = FALSE;
+
+ for (i = 0; i < channels->len; i++)
+ {
+ const GValueArray *channel = g_ptr_array_index(channels, i);
+ handle_new_channel(user_data, channel);
+ }
+
+ }
+}
============================================================
--- libpurple/protocols/telepathy/telepathy_channel.h 826f04d11dd59ace93e28ce1c4d7b495230938cd
+++ libpurple/protocols/telepathy/telepathy_channel.h 826f04d11dd59ace93e28ce1c4d7b495230938cd
@@ -0,0 +1,68 @@
+/**
+ * purple - Telepathy Protocol Plugin
+ *
+ * Copyright (C) 2009, Felix Kerekes <sttwister at soc.pidgin.im>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+ */
+
+#ifndef _TELEPATHY_CHANNEL_H_
+#define _TELEPATHY_CHANNEL_H_
+
+#include <glib.h>
+
+#include <telepathy-glib/channel.h>
+
+#include "telepathy_connection.h"
+
+void
+channel_ready_cb (TpChannel *channel,
+ const GError *error,
+ gpointer user_data);
+
+void
+channel_invalidated_cb (TpProxy *self,
+ guint domain,
+ gint code,
+ gchar *message,
+ gpointer user_data);
+
+void
+handle_new_channel (telepathy_connection *data,
+ const GValueArray *channel_Properties);
+
+void
+new_channels_cb (TpConnection *proxy,
+ const GPtrArray *arg_Channels,
+ gpointer user_data,
+ GObject *weak_object);
+
+void
+ensure_channel_cb (TpConnection *proxy,
+ gboolean out_Yours,
+ const gchar *out_Channel,
+ GHashTable *out_Properties,
+ const GError *error,
+ gpointer user_data,
+ GObject *weak_object);
+
+void
+get_channels_cb (TpProxy *proxy,
+ const GValue *out_Value,
+ const GError *error,
+ gpointer user_data,
+ GObject *weak_object);
+
+#endif /* _TELEPATHY_CHANNEL_H_ */
============================================================
--- libpurple/protocols/telepathy/telepathy_channel_list.c dea5894e4316434a1a8f6553717e8dea3d76757f
+++ libpurple/protocols/telepathy/telepathy_channel_list.c dea5894e4316434a1a8f6553717e8dea3d76757f
@@ -0,0 +1,97 @@
+/**
+ * purple - Telepathy Protocol Plugin
+ *
+ * Copyright (C) 2009, Felix Kerekes <sttwister at soc.pidgin.im>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+ */
+
+#include "telepathy_channel_list.h"
+
+#include "debug.h"
+
+#include "telepathy_avatar.h"
+#include "telepathy_contact.h"
+
+void
+handle_list_channel (TpChannel *channel,
+ telepathy_connection *data)
+{
+ TpConnection *connection = data->connection;
+ const TpIntSet *members;
+ TpIntSetIter iter;
+ GArray *handles;
+
+ const TpContactFeature features[] = {
+ TP_CONTACT_FEATURE_ALIAS,
+ TP_CONTACT_FEATURE_PRESENCE
+ };
+
+ guint handle;
+ guint handle_type;
+
+ handle = tp_channel_get_handle(channel, &handle_type);
+
+ members = tp_channel_group_get_members(channel);
+
+ if (members == NULL)
+ {
+ purple_debug_error("telepathy", "Error while getting member list\n");
+ return;
+ }
+
+ iter.set = members;
+ iter.element = (guint)(-1);
+
+ handles = tp_intset_to_array (members);
+
+ /* we want to create a TpContact for each member of this channel */
+ if (handles->len)
+ {
+ /* this struct is needed to pass both the connection data and the channel proxy */
+ telepathy_group *group = g_new0(telepathy_group, 1);
+
+ group->channel = channel;
+ group->connection_data = data;
+
+ if (handle_type == TP_HANDLE_TYPE_GROUP)
+ {
+ /* this is a user-defined group */
+ tp_connection_get_contacts_by_handle (connection,
+ handles->len, (const TpHandle *) handles->data,
+ G_N_ELEMENTS (features), features,
+ group_contacts_ready_cb,
+ group, NULL, NULL);
+ }
+ else
+ {
+ tp_connection_get_contacts_by_handle (connection,
+ handles->len, (const TpHandle *) handles->data,
+ G_N_ELEMENTS (features), features,
+ contacts_ready_cb,
+ group, NULL, NULL);
+ }
+
+ }
+
+ tp_cli_connection_interface_avatars_call_get_known_avatar_tokens(data->connection, -1,
+ handles,
+ get_known_avatar_tokens_cb, data,
+ NULL, NULL);
+
+ g_array_free (handles, TRUE);
+
+}
+
============================================================
--- libpurple/protocols/telepathy/telepathy_channel_list.h 889f520fc1896209dc1f214ed12dacc588876258
+++ libpurple/protocols/telepathy/telepathy_channel_list.h 889f520fc1896209dc1f214ed12dacc588876258
@@ -0,0 +1,40 @@
+/**
+ * purple - Telepathy Protocol Plugin
+ *
+ * Copyright (C) 2009, Felix Kerekes <sttwister at soc.pidgin.im>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+ */
+
+#ifndef _TELEPATHY_CHANNEL_LIST_H_
+#define _TELEPATHY_CHANNEL_LIST_H_
+
+#include <telepathy-glib/channel.h>
+
+#include "telepathy_connection.h"
+
+typedef struct
+{
+ telepathy_connection *connection_data;
+ TpChannel *channel;
+
+} telepathy_group;
+
+
+void
+handle_list_channel (TpChannel *channel,
+ telepathy_connection *data);
+
+#endif /* _TELEPATHY_CHANNEL_LIST_H_ */
============================================================
--- libpurple/protocols/telepathy/telepathy_channel_text.c 32d4445150ef43b626735b3073040d42677bf89b
+++ libpurple/protocols/telepathy/telepathy_channel_text.c 32d4445150ef43b626735b3073040d42677bf89b
@@ -0,0 +1,442 @@
+/**
+ * purple - Telepathy Protocol Plugin
+ *
+ * Copyright (C) 2009, Felix Kerekes <sttwister at soc.pidgin.im>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+ */
+
+#include "telepathy_channel_text.h"
+
+#include <telepathy-glib/interfaces.h>
+
+#include "internal.h"
+
+#include "debug.h"
+
+#include "telepathy_connection.h"
+#include "telepathy_contact.h"
+
+void
+destroy_text_channel(telepathy_text_channel *tp_channel)
+{
+ g_free(tp_channel);
+}
+
+void
+write_message_to_conversation (const gchar *from,
+ guint timestamp,
+ const gchar *msg,
+ gpointer user_data)
+{
+ telepathy_connection *data = user_data;
+
+ /* if a conversation was not yet establish, create a new one */
+ PurpleConversation *conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, from, data->acct);
+ PurpleConvIm *im;
+
+ /* escape HTML special characters */
+ gchar *escaped_message = g_markup_escape_text(msg, -1);
+
+ /* also change \n to <br> */
+ gchar *final_message = purple_strdup_withhtml(escaped_message);
+ g_free(escaped_message);
+
+ if (conv == NULL)
+ {
+ conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, data->acct, from);
+ }
+ im = purple_conversation_get_im_data(conv);
+
+ purple_debug_info("telepathy", "Contact %s says \"%s\" (escaped: \"%s\")\n", from, msg, final_message);
+
+ /* transmit the message to the UI */
+ purple_conv_im_write(im, from, final_message, 0, timestamp);
+
+ g_free(final_message);
+}
+
+void
+acknowledge_pending_messages_cb (TpChannel *proxy,
+ const GError *error,
+ gpointer user_data,
+ GObject *weak_object)
+{
+ if (error != NULL)
+ {
+ purple_debug_error("telepathy", "AcknowledgePendingMessages error: %s\n", error->message);
+ }
+}
+
+void
+list_pending_messages_cb (TpChannel *proxy,
+ const GPtrArray *out_Pending_Messages,
+ const GError *error,
+ gpointer user_data,
+ GObject *weak_object)
+{
+ if (error != NULL)
+ {
+ purple_debug_error("telepathy", "ListPendingMessages error: %s\n", error->message);
+ }
+ else
+ {
+ telepathy_connection *data = user_data;
+ GArray *message_IDs;
+
+ int i;
+
+ GHashTable *properties = tp_channel_borrow_immutable_properties(proxy);
+ gchar *who = (gchar *)tp_asv_get_string(properties, TP_IFACE_CHANNEL ".TargetID");
+
+ telepathy_text_channel *tp_channel = g_hash_table_lookup(data->text_Channels, who);
+
+ if (tp_channel == NULL)
+ {
+ purple_debug_warning("telepathy", "Received message from %s, but there's no channel struct for the buddy!\n", who);
+ }
+ else
+ {
+ /* we should now allow received_cb to handle incoming messages */
+ tp_channel->received_Pending_Messages = TRUE;
+ }
+
+ /* this will hold the IDs of message that will be acknowledged */
+ message_IDs = g_array_new(FALSE, FALSE, sizeof(guint));
+
+ for (i = 0; i<out_Pending_Messages->len; ++i)
+ {
+ /* unpack the relevant info from (uuuuus) */
+ GValueArray *arr = g_ptr_array_index(out_Pending_Messages, i);
+ guint msg_id = g_value_get_uint(g_value_array_get_nth(arr, 0));
+ guint timestamp = g_value_get_uint(g_value_array_get_nth(arr, 1));
+ guint flags = g_value_get_uint(g_value_array_get_nth(arr, 4));
+ gchar *msg = (gchar *)g_value_get_string(g_value_array_get_nth(arr, 5));
+
+ /* get the identifier from channel instead of contact since contact might not be ready for offline messages */
+ gchar *from = (gchar *)tp_channel_get_identifier(proxy);
+
+ /* drop message if it's not text */
+ if ((flags & TP_CHANNEL_TEXT_MESSAGE_FLAG_NON_TEXT_CONTENT) == 0)
+ write_message_to_conversation(from, timestamp, msg, user_data);
+
+ /* add the id to the array of acknowledge messages */
+ g_array_append_val(message_IDs, msg_id);
+ }
+
+ /* acknowledge the messages now */
+ tp_cli_channel_type_text_call_acknowledge_pending_messages(proxy, -1, message_IDs,
+ acknowledge_pending_messages_cb, user_data, NULL, NULL);
+
+ g_array_free(message_IDs, TRUE);
+
+ }
+}
+
+void
+received_cb (TpChannel *proxy,
+ guint arg_ID,
+ guint arg_Timestamp,
+ guint arg_Sender,
+ guint arg_Type,
+ guint arg_Flags,
+ const gchar *arg_Text,
+ gpointer user_data,
+ GObject *weak_object)
+{
+ telepathy_connection *data = user_data;
+
+ GHashTable *properties = tp_channel_borrow_immutable_properties(proxy);
+ gchar *who = (gchar *)tp_asv_get_string(properties, TP_IFACE_CHANNEL ".TargetID");
+
+ telepathy_text_channel *tp_channel = g_hash_table_lookup(data->text_Channels, who);
+
+ if (tp_channel == NULL)
+ {
+ purple_debug_warning("telepathy", "Received message from %s, but there's no channel struct for the buddy!\n", who);
+ }
+ else
+ {
+ GArray *message_IDs;
+
+ /* will this message get caught by ListPendingMessages? */
+ if (!tp_channel->received_Pending_Messages)
+ return;
+
+ /* drop this message if it's not text */
+ if ((arg_Flags & TP_CHANNEL_TEXT_MESSAGE_FLAG_NON_TEXT_CONTENT) == 0)
+ write_message_to_conversation(who, arg_Timestamp, arg_Text, user_data);
+
+ /* acknowledge receiving the message */
+ message_IDs = g_array_new(FALSE, FALSE, sizeof(guint));
+
+ g_array_append_val(message_IDs, arg_ID);
+
+ tp_cli_channel_type_text_call_acknowledge_pending_messages(proxy, -1, message_IDs,
+ acknowledge_pending_messages_cb, user_data, NULL, NULL);
+
+ g_array_free(message_IDs, TRUE);
+
+ }
+}
+
+void
+send_error_cb (TpChannel *proxy,
+ guint arg_Error,
+ guint arg_Timestamp,
+ guint arg_Type,
+ const gchar *arg_Text,
+ gpointer user_data,
+ GObject *weak_object)
+{
+ telepathy_connection *data = user_data;
+
+ const gchar *who = tp_channel_get_identifier(proxy);
+
+ const gchar *error_reason = NULL;
+ gchar *error_message;
+ gchar *error_message2;
+
+ switch (arg_Error)
+ {
+ case TP_CHANNEL_TEXT_SEND_ERROR_UNKNOWN:
+ error_reason = _("Unknown error");
+ break;
+
+ case TP_CHANNEL_TEXT_SEND_ERROR_OFFLINE:
+ error_reason = _("Contact is offline");
+ break;
+
+ case TP_CHANNEL_TEXT_SEND_ERROR_INVALID_CONTACT:
+ error_reason = _("Contact is invalid");
+ break;
+
+ case TP_CHANNEL_TEXT_SEND_ERROR_PERMISSION_DENIED:
+ error_reason = _("Permission denied");
+ break;
+
+ case TP_CHANNEL_TEXT_SEND_ERROR_TOO_LONG:
+ error_reason = _("The message is too long");
+ break;
+
+ case TP_CHANNEL_TEXT_SEND_ERROR_NOT_IMPLEMENTED:
+ error_reason = _("Not implemented");
+ break;
+ }
+
+ error_message = g_strdup_printf(_("There was an error sending your message to %s"), who);
+ error_message2 = g_strdup_printf("%s: %s", error_message, error_reason);
+
+ /* display the error in the conversation */
+ if (!purple_conv_present_error(who, data->acct, error_message2))
+ {
+ /* display as a popup if there is no active conversation with the user */
+ purple_notify_error(purple_connections_get_handle(),
+ _("Error sending message"),
+ error_message,
+ error_reason);
+ }
+
+ g_free(error_message2);
+ g_free(error_message);
+
+ purple_debug_error("telepathy", "SendError: %s\n", error_reason);
+}
+
+void
+send_cb (TpChannel *proxy,
+ const GError *error,
+ gpointer user_data,
+ GObject *weak_object)
+{
+ if (error != NULL)
+ {
+ telepathy_connection *data = user_data;
+
+ const gchar *who = tp_channel_get_identifier(proxy);
+
+ gchar *error_message = g_strdup_printf(_("There was an error sending your message to %s"), who);
+ gchar *error_message2 = g_strdup_printf("%s: %s", error_message, error->message);
+
+ /* display the error in the conversation */
+ if (!purple_conv_present_error(who, data->acct, error_message2))
+ {
+ /* display as a popup if there is no active conversation with the user */
+ purple_notify_error(purple_connections_get_handle(),
+ _("Error sending message"),
+ error_message,
+ error->message);
+ }
+
+ g_free(error_message2);
+ g_free(error_message);
+
+ purple_debug_error("telepathy", "Send error: %s\n", error->message);
+ }
+}
+
+void
+text_channel_invalidated_cb (TpProxy *self,
+ guint domain,
+ gint code,
+ gchar *message,
+ gpointer user_data)
+{
+ telepathy_connection *data = user_data;
+
+ /* remove the cached TpChannel proxy when the channel closes */
+ const gchar *who = tp_channel_get_identifier((TpChannel *)self);
+
+ telepathy_text_channel *tp_channel = NULL;
+
+ if (data->text_Channels)
+ tp_channel = g_hash_table_lookup(data->text_Channels, who);
+
+ purple_debug_info("telepathy", "Text channel with %s closed!\n", who);
+
+ if (tp_channel)
+ {
+ tp_channel->channel = NULL;
+ }
+}
+
+void
+chat_state_changed_cb (TpChannel *proxy,
+ guint arg_Contact,
+ guint arg_State,
+ gpointer user_data,
+ GObject *weak_object)
+{
+ telepathy_connection *data = user_data;
+
+ telepathy_contact *contact_data = g_hash_table_lookup(data->contacts, (gpointer)arg_Contact);
+
+ PurpleTypingState state;
+ const gchar *name;
+
+ if (contact_data == NULL)
+ {
+ purple_debug_warning("telepathy", "Chat state changed for %u who isn't cached!\n", arg_Contact);
+ return;
+ }
+
+ name = tp_contact_get_identifier(contact_data->contact);
+
+ purple_debug_info("telepathy", "Chat state changed for %s\n", name);
+
+ switch (arg_State)
+ {
+ case TP_CHANNEL_CHAT_STATE_PAUSED:
+ state = PURPLE_TYPED;
+ break;
+
+ case TP_CHANNEL_CHAT_STATE_COMPOSING:
+ state = PURPLE_TYPING;
+ break;
+
+ default:
+ state = PURPLE_NOT_TYPING;
+ break;
+ }
+
+ if (state == PURPLE_NOT_TYPING)
+ {
+ serv_got_typing_stopped(data->gc, name);
+ }
+ else
+ {
+ serv_got_typing(data->gc, name, -1, state);
+ }
+}
+
+void
+handle_text_channel (TpChannel *channel,
+ telepathy_connection *data)
+{
+ GError *error = NULL;
+
+ GHashTable *properties = tp_channel_borrow_immutable_properties(channel);
+ gchar *who = (gchar *)tp_asv_get_string(properties, TP_IFACE_CHANNEL ".TargetID");
+
+ telepathy_text_channel *tp_channel;
+
+ purple_debug_info("telepathy", "Saving TpChannel proxy for %s\n", who);
+
+ tp_channel = g_hash_table_lookup(data->text_Channels, who);
+
+ /* if tp_channel exists, then we requested this channel, else it's an incoming request so we must cache it */
+ if (tp_channel == NULL)
+ {
+ tp_channel = g_new0(telepathy_text_channel, 1);
+ g_hash_table_insert(data->text_Channels, who, tp_channel);
+ }
+
+ tp_channel->channel = channel;
+
+ tp_cli_channel_interface_chat_state_connect_to_chat_state_changed(channel, chat_state_changed_cb, data, NULL, NULL, &error);
+
+ if (error != NULL)
+ {
+ purple_debug_error("telepathy", "Error connecting to ChatStateChanged signal: %s\n", error->message);
+ }
+
+ tp_cli_channel_type_text_connect_to_received(channel, received_cb, data, NULL, NULL, &error);
+
+ if (error != NULL)
+ {
+ purple_debug_error("telepathy", "Error connecting to Received signal: %s\n", error->message);
+ }
+
+ tp_channel->received_Pending_Messages = FALSE;
+
+ g_signal_connect(channel, "invalidated", G_CALLBACK(text_channel_invalidated_cb), data);
+
+ /* the Clear parameter is deprecated, we need to use AcknowledgePendingMessages */
+ tp_cli_channel_type_text_call_list_pending_messages(channel, -1, FALSE, list_pending_messages_cb, data, NULL, NULL);
+
+ /* send pending messages */
+ while (tp_channel->pending_Messages != NULL)
+ {
+ purple_debug_info("telepathy", "Sending pending message \"%s\" to %s\n", (gchar *)tp_channel->pending_Messages->data, who);
+
+ tp_cli_channel_type_text_call_send(channel, -1, TP_CHANNEL_TEXT_MESSAGE_TYPE_NORMAL, tp_channel->pending_Messages->data, send_cb, data, NULL, NULL);
+
+ /* the message was duped */
+ g_free(tp_channel->pending_Messages->data);
+
+ tp_channel->pending_Messages = g_list_delete_link(tp_channel->pending_Messages, tp_channel->pending_Messages);
+ }
+
+ tp_cli_channel_type_text_connect_to_send_error(channel, send_error_cb, data, NULL, NULL, &error);
+
+ if (error != NULL)
+ {
+ purple_debug_error("telepathy", "Error connecting to SendError signal: %s\n", error->message);
+ g_error_free(error);
+ }
+}
+
+void
+set_chat_state_cb (TpChannel *proxy,
+ const GError *error,
+ gpointer user_data,
+ GObject *weak_object)
+{
+ if (error != NULL)
+ {
+ purple_debug_error("telepathy", "SetChatState error: %s\n", error->message);
+ }
+}
+
============================================================
--- libpurple/protocols/telepathy/telepathy_channel_text.h 5f8653276d3406e59f03892e33ab0ede95f16daf
+++ libpurple/protocols/telepathy/telepathy_channel_text.h 5f8653276d3406e59f03892e33ab0ede95f16daf
@@ -0,0 +1,111 @@
+/**
+ * purple - Telepathy Protocol Plugin
+ *
+ * Copyright (C) 2009, Felix Kerekes <sttwister at soc.pidgin.im>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+ */
+
+#ifndef _TELEPATHY_CHANNEL_TEXT_H_
+#define _TELEPATHY_CHANNEL_TEXT_H_
+
+#include <glib.h>
+
+#include <telepathy-glib/channel.h>
+
+#include "telepathy_connection.h"
+
+typedef struct
+{
+ GList *pending_Messages;
+ TpChannel *channel;
+
+ /* This flag avoids having a message processed twice via both Received signal and ListPendingMessages */
+ gboolean received_Pending_Messages;
+} telepathy_text_channel;
+
+void
+destroy_text_channel(telepathy_text_channel *tp_channel);
+
+void
+write_message_to_conversation (const gchar *from,
+ guint timestamp,
+ const gchar *msg,
+ gpointer user_data);
+
+void
+acknowledge_pending_messages_cb (TpChannel *proxy,
+ const GError *error,
+ gpointer user_data,
+ GObject *weak_object);
+
+void
+list_pending_messages_cb (TpChannel *proxy,
+ const GPtrArray *out_Pending_Messages,
+ const GError *error,
+ gpointer user_data,
+ GObject *weak_object);
+
+void
+received_cb (TpChannel *proxy,
+ guint arg_ID,
+ guint arg_Timestamp,
+ guint arg_Sender,
+ guint arg_Type,
+ guint arg_Flags,
+ const gchar *arg_Text,
+ gpointer user_data,
+ GObject *weak_object);
+
+void
+send_error_cb (TpChannel *proxy,
+ guint arg_Error,
+ guint arg_Timestamp,
+ guint arg_Type,
+ const gchar *arg_Text,
+ gpointer user_data,
+ GObject *weak_object);
+
+void
+send_cb (TpChannel *proxy,
+ const GError *error,
+ gpointer user_data,
+ GObject *weak_object);
+
+void
+text_channel_invalidated_cb (TpProxy *self,
+ guint domain,
+ gint code,
+ gchar *message,
+ gpointer user_data);
+
+void
+chat_state_changed_cb (TpChannel *proxy,
+ guint arg_Contact,
+ guint arg_State,
+ gpointer user_data,
+ GObject *weak_object);
+
+void
+handle_text_channel (TpChannel *channel,
+ telepathy_connection *data);
+
+void
+set_chat_state_cb (TpChannel *proxy,
+ const GError *error,
+ gpointer user_data,
+ GObject *weak_object);
+
+#endif /* _TELEPATHY_CHANNEL_TEXT_H_ */
============================================================
--- libpurple/protocols/telepathy/telepathy_connection.c f3c079f3499d8926582ed5dac3d782932756d700
+++ libpurple/protocols/telepathy/telepathy_connection.c f3c079f3499d8926582ed5dac3d782932756d700
@@ -0,0 +1,333 @@
+/**
+ * purple - Telepathy Protocol Plugin
+ *
+ * Copyright (C) 2009, Felix Kerekes <sttwister at soc.pidgin.im>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+ */
+
+#include "telepathy_connection.h"
+
+#include <telepathy-glib/interfaces.h>
+
+#include "internal.h"
+
+#include "connection.h"
+#include "debug.h"
+
+#include "telepathy_avatar.h"
+#include "telepathy_channel.h"
+#include "telepathy_channel_text.h"
+#include "telepathy_contact.h"
+
+void
+status_changed_cb (TpConnection *proxy,
+ guint arg_Status,
+ guint arg_Reason,
+ gpointer user_data,
+ GObject *weak_object)
+{
+ telepathy_connection *data = user_data;
+
+ if (arg_Status == TP_CONNECTION_STATUS_CONNECTED)
+ {
+ purple_debug_info("telepathy", "Connected!\n");
+
+ purple_connection_update_progress(data->gc, _("Connected"),
+ 1, /* which connection step this is */
+ 2); /* total number of steps */
+
+ purple_connection_set_state(data->gc, PURPLE_CONNECTED);
+
+ data->text_Channels = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, (GDestroyNotify) destroy_text_channel);
+ data->contacts = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, (GDestroyNotify) destroy_contact);
+ }
+ else if (arg_Status == TP_CONNECTION_STATUS_DISCONNECTED)
+ {
+ gchar *reason = NULL;
+ PurpleConnectionError error = PURPLE_CONNECTION_ERROR_OTHER_ERROR;
+ purple_debug_info("telepathy", "Disconnected! Reason: %d\n", arg_Reason);
+
+ switch (arg_Reason)
+ {
+ case TP_CONNECTION_STATUS_REASON_NETWORK_ERROR:
+ reason = "Network error";
+ error = PURPLE_CONNECTION_ERROR_NETWORK_ERROR;
+ break;
+
+ case TP_CONNECTION_STATUS_REASON_AUTHENTICATION_FAILED:
+ reason = "Authentication failed";
+ error = PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED;
+ break;
+
+ case TP_CONNECTION_STATUS_REASON_ENCRYPTION_ERROR:
+ reason = "Encryption error";
+ error = PURPLE_CONNECTION_ERROR_ENCRYPTION_ERROR;
+ break;
+
+ case TP_CONNECTION_STATUS_REASON_NAME_IN_USE:
+ reason = "Name in use";
+ error = PURPLE_CONNECTION_ERROR_NAME_IN_USE;
+ break;
+
+ case TP_CONNECTION_STATUS_REASON_CERT_NOT_PROVIDED:
+ reason = "SSL Certificate not provided";
+ error = PURPLE_CONNECTION_ERROR_CERT_NOT_PROVIDED;
+ break;
+
+ case TP_CONNECTION_STATUS_REASON_CERT_UNTRUSTED:
+ reason = "SSL Certificate is isnged by an untrusted certifying authority";
+ error = PURPLE_CONNECTION_ERROR_CERT_UNTRUSTED;
+ break;
+
+ case TP_CONNECTION_STATUS_REASON_CERT_EXPIRED:
+ reason = "SSL Certificate expired";
+ error = PURPLE_CONNECTION_ERROR_CERT_EXPIRED;
+ break;
+
+ case TP_CONNECTION_STATUS_REASON_CERT_NOT_ACTIVATED:
+ reason = "SSL Certificate is not yet valid";
+ error = PURPLE_CONNECTION_ERROR_CERT_NOT_ACTIVATED;
+ break;
+
+ case TP_CONNECTION_STATUS_REASON_CERT_HOSTNAME_MISMATCH:
+ reason = "SSL Certificate hostname mismatch";
+ error = PURPLE_CONNECTION_ERROR_CERT_HOSTNAME_MISMATCH;
+ break;
+
+ case TP_CONNECTION_STATUS_REASON_CERT_FINGERPRINT_MISMATCH:
+ reason = "SSL Certificate fingerprint mismatch";
+ error = PURPLE_CONNECTION_ERROR_CERT_FINGERPRINT_MISMATCH;
+ break;
+
+ case TP_CONNECTION_STATUS_REASON_CERT_SELF_SIGNED:
+ reason = "SSL Certificate is self-signed";
+ error = PURPLE_CONNECTION_ERROR_CERT_SELF_SIGNED;
+ break;
+
+ case TP_CONNECTION_STATUS_REASON_CERT_OTHER_ERROR:
+ reason = "Error while validating the server's SSL Certificate";
+ error = PURPLE_CONNECTION_ERROR_CERT_OTHER_ERROR;
+ break;
+ }
+
+ if (data)
+ {
+ purple_connection_set_protocol_data(data->gc, NULL);
+
+ if (reason != NULL && data->gc)
+ purple_connection_error_reason(data->gc, error, reason);
+
+ if (data->connection != NULL)
+ {
+ g_object_unref(data->connection);
+ data->connection = NULL;
+ }
+
+ if (data->text_Channels != NULL)
+ {
+ g_hash_table_destroy(data->text_Channels);
+ data->text_Channels = NULL;
+ }
+ if (data->contacts != NULL)
+ {
+ g_hash_table_destroy(data->contacts);
+ data->contacts = NULL;
+ }
+
+ g_free(data);
+ }
+
+ }
+ else if (arg_Status == TP_CONNECTION_STATUS_CONNECTING)
+ {
+ purple_debug_info("telepathy", "Connecting! Reason: %d\n", arg_Reason);
+ purple_connection_set_state(data->gc, PURPLE_CONNECTING);
+ purple_connection_update_progress(data->gc, _("Connecting"),
+ 0, /* which connection step this is */
+ 2); /* total number of steps */
+
+ }
+}
+
+void
+set_presence_cb (TpConnection *proxy,
+ const GError *error,
+ gpointer user_data,
+ GObject *weak_object)
+{
+ if (error != NULL)
+ {
+ purple_debug_error("telepathy", "SetStatus error: %s\n", error->message);
+ }
+}
+
+void
+connection_connect_cb (TpConnection *proxy,
+ const GError *error,
+ gpointer user_data,
+ GObject *weak_object)
+{
+ /* if this fails, something must be broken somewhere */
+ if (error != NULL)
+ {
+ purple_debug_error("telepathy", "Connect error: %s\n", error->message);
+ }
+}
+
+void
+request_connection_cb (TpConnectionManager *proxy,
+ const gchar *out_Bus_Name,
+ const gchar *out_Object_Path,
+ const GError *error,
+ gpointer user_data,
+ GObject *weak_object)
+{
+ PurpleConnection *gc = user_data;
+
+ if (error != NULL)
+ {
+ purple_debug_info("telepathy", "RequestConnection error: %s\n", error->message);
+
+ purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, error->message);
+ }
+ else
+ {
+ GError *error = NULL;
+ telepathy_connection *connection_data;
+
+ TpDBusDaemon *daemon = tp_dbus_daemon_dup(&error);
+
+ if (error != NULL)
+ {
+ purple_debug_error("telepathy", "Error creating dbus daemon: %s\n", error->message);
+ g_error_free(error);
+ return;
+ }
+
+ connection_data = g_new0(telepathy_connection, 1);
+
+ /* get the connection proxy straight out of the dbus interface */
+ connection_data->connection = tp_connection_new(daemon, out_Bus_Name, out_Object_Path, &error);
+ connection_data->gc = gc;
+ connection_data->acct = purple_connection_get_account(gc);
+ purple_connection_set_protocol_data(gc, connection_data);
+
+ if (error != NULL)
+ {
+ purple_debug_error("telepathy", "Error creating TpConnection object: %s\n", error->message);
+ g_error_free(error);
+
+ g_object_unref(connection_data->connection);
+ connection_data->connection = NULL;
+ g_free(connection_data);
+ return;
+ }
+
+ tp_connection_call_when_ready(connection_data->connection, connection_ready_cb, connection_data);
+
+ /* this will indicate any connection status change, also providing a reason */
+ tp_cli_connection_connect_to_status_changed(connection_data->connection, status_changed_cb, connection_data, NULL, NULL, &error);
+
+ if (error != NULL)
+ {
+ purple_debug_error("telepathy", "Error conencting to StatusChanged: %s\n", error->message);
+ g_error_free(error);
+
+ tp_cli_connection_call_disconnect(connection_data->connection, -1, NULL, NULL, NULL, NULL);
+ g_object_unref(connection_data->connection);
+ connection_data->connection = NULL;
+ g_free(connection_data);
+ }
+ else
+ {
+ /* do some magic now :) */
+ tp_cli_connection_call_connect(connection_data->connection, -1, connection_connect_cb, connection_data, NULL, NULL);
+ }
+
+ if (daemon != NULL)
+ g_object_unref(daemon);
+ }
+}
+
+void
+connection_ready_cb (TpConnection *connection,
+ const GError *error,
+ gpointer user_data)
+{
+ if (error != NULL)
+ {
+ purple_debug_info("telepathy", "Connection ready error: %s\n", error->message);
+ }
+ else
+ {
+ char **interfaces, **ptr;
+ GError *error = NULL;
+ telepathy_connection *data = user_data;
+
+ purple_debug_info("telepathy", "Connection is ready. Interfaces implemented:\n");
+
+ /* query interfaces */
+ g_object_get(connection, "interfaces", &interfaces, NULL);
+ for (ptr = interfaces; ptr && *ptr; ptr++)
+ {
+ purple_debug_info("telepathy", " %s\n", *ptr);
+ }
+ g_strfreev(interfaces);
+
+ tp_cli_connection_interface_requests_connect_to_new_channels(connection, new_channels_cb, user_data, NULL, NULL, &error);
+
+ if (error != NULL)
+ {
+ purple_debug_error("telepathy", "Error while connecting to NewChannels signal: %s\n", error->message);
+ g_error_free(error);
+ error = NULL;
+ return;
+ }
+
+ data->listing_channels = TRUE;
+
+ /* query the Channels property of the Requests interface */
+ tp_cli_dbus_properties_call_get(connection, -1, TP_IFACE_CONNECTION_INTERFACE_REQUESTS, "Channels", get_channels_cb, user_data, NULL, NULL);
+
+
+ /* query supported avatar formats */
+ tp_cli_dbus_properties_call_get_all(connection, -1, TP_IFACE_CONNECTION_INTERFACE_AVATARS, get_avatar_properties_cb, user_data, NULL, NULL);
+
+ /* this will be fired when an avatar for a buddy has been received */
+ tp_cli_connection_interface_avatars_connect_to_avatar_retrieved(connection,
+ avatar_retrieved_cb, data,
+ NULL, NULL,
+ &error);
+
+ if (error != NULL)
+ {
+ purple_debug_error("telepathy", "Error connecting to AvatarRetrieved signal: %s\n", error->message);
+ g_error_free(error);
+ }
+
+ tp_cli_connection_interface_avatars_connect_to_avatar_updated(connection,
+ avatar_updated_cb, data,
+ NULL, NULL,
+ &error);
+
+ if (error != NULL)
+ {
+ purple_debug_error("telepathy", "Error connecting to AvatarUpdated signal: %s\n", error->message);
+ g_error_free(error);
+ }
+
+ }
+}
============================================================
--- libpurple/protocols/telepathy/telepathy_connection.h 5d102e163e859228142e40a25054c14af7a10ab1
+++ libpurple/protocols/telepathy/telepathy_connection.h 5d102e163e859228142e40a25054c14af7a10ab1
@@ -0,0 +1,82 @@
+/**
+ * purple - Telepathy Protocol Plugin
+ *
+ * Copyright (C) 2009, Felix Kerekes <sttwister at soc.pidgin.im>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+ */
+
+#ifndef _TELEPATHY_CONNECTION_H_
+#define _TELEPATHY_CONNECTION_H_
+
+#include <glib.h>
+
+#include <telepathy-glib/channel.h>
+#include <telepathy-glib/connection-manager.h>
+#include <telepathy-glib/connection.h>
+#include <telepathy-glib/contact.h>
+
+#include "connection.h"
+
+typedef struct
+{
+ TpConnection *connection;
+ PurpleConnection *gc;
+ PurpleAccount *acct;
+
+ /* This flag avoids having a channel processed twice via both NewChannels and quering the Channels property */
+ gboolean listing_channels;
+
+ /* This will hold pointers to telepathy_text_channel for buddies that have an active conversation */
+ GHashTable *text_Channels;
+
+ /* This will map contact handles to telepathy_contact */
+ GHashTable *contacts;
+
+} telepathy_connection;
+
+void
+status_changed_cb (TpConnection *proxy,
+ guint arg_Status,
+ guint arg_Reason,
+ gpointer user_data,
+ GObject *weak_object);
+
+void
+set_presence_cb (TpConnection *proxy,
+ const GError *error,
+ gpointer user_data,
+ GObject *weak_object);
+
+void
+connection_connect_cb (TpConnection *proxy,
+ const GError *error,
+ gpointer user_data,
+ GObject *weak_object);
+
+void
+request_connection_cb (TpConnectionManager *proxy,
+ const gchar *out_Bus_Name,
+ const gchar *out_Object_Path,
+ const GError *error,
+ gpointer user_data,
+ GObject *weak_object);
+
+void
+connection_ready_cb (TpConnection *connection,
+ const GError *error,
+ gpointer user_data);
+
+#endif /* _TELEPATHY_CONNECTION_H_ */
============================================================
--- libpurple/protocols/telepathy/telepathy_contact.c 05502690e0f19e4758b11c66149d8dee0aa83303
+++ libpurple/protocols/telepathy/telepathy_contact.c 05502690e0f19e4758b11c66149d8dee0aa83303
@@ -0,0 +1,215 @@
+/**
+ * purple - Telepathy Protocol Plugin
+ *
+ * Copyright (C) 2009, Felix Kerekes <sttwister at soc.pidgin.im>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+ */
+
+#include "telepathy_contact.h"
+
+#include "debug.h"
+
+#include "telepathy_avatar.h"
+#include "telepathy_channel_list.h"
+
+void
+destroy_contact(telepathy_contact *contact_data)
+{
+ g_object_unref(contact_data->contact);
+ g_free(contact_data);
+}
+
+void
+contact_notify_cb (TpContact *contact,
+ GParamSpec *pspec,
+ gpointer user_data)
+{
+ telepathy_connection *data = user_data;
+
+ const gchar *name = tp_contact_get_identifier(contact);
+ const gchar *presence_status = tp_contact_get_presence_status(contact);
+ const gchar *presence_message = tp_contact_get_presence_message(contact);
+ const gchar *alias = tp_contact_get_alias(contact);
+
+ PurpleBuddy *buddy = purple_find_buddy(data->acct, tp_contact_get_identifier(contact));
+
+ if (buddy == NULL)
+ {
+ purple_debug_warning("telepathy", "Received TpContact notify for non-existent buddy (%s)!\n", name);
+ return;
+ }
+
+ purple_blist_alias_buddy(buddy, alias);
+
+ purple_prpl_got_user_status(data->acct, name, presence_status,
+ "message", presence_message, NULL);
+}
+
+void
+handle_contacts (telepathy_connection *connection_data,
+ guint n_contacts,
+ TpContact * const *contacts,
+ guint n_failed,
+ PurpleGroup *group)
+{
+ int i;
+ GArray *avatar_handles = g_array_new(FALSE, FALSE, sizeof(guint));
+
+ purple_debug_info("telepathy", "Contacts ready: %u (%u failed)\n", n_contacts, n_failed);
+
+ for (i = 0; i<n_contacts; ++i)
+ {
+ TpContact *contact = contacts[i];
+ PurpleBuddy *buddy;
+ guint handle;
+ telepathy_contact *contact_data;
+
+ /* the buddy might already be stored locally */
+ buddy = purple_find_buddy(connection_data->acct, tp_contact_get_identifier(contact));
+
+ if (buddy == NULL)
+ {
+ /* Buddy was not stored locally */
+ buddy = purple_buddy_new(connection_data->acct, tp_contact_get_identifier(contact), tp_contact_get_alias(contact));
+ purple_blist_add_buddy(buddy, NULL, group, NULL);
+ }
+ else
+ {
+ PurpleGroup *buddy_group = purple_buddy_get_group(buddy);
+ PurplePresence *presence = purple_buddy_get_presence(buddy);
+
+ /* is this buddy in the right group */
+ if (group != NULL && buddy_group != group)
+ {
+ purple_debug_info("telepathy", "Contact %s is not in the right group, moving him to %s\n",
+ tp_contact_get_identifier(contact), purple_group_get_name(group));
+
+ /* we should move the buddy to the right group */
+ purple_blist_remove_buddy(buddy);
+
+ buddy = purple_buddy_new(connection_data->acct, tp_contact_get_identifier(contact), tp_contact_get_alias(contact));
+ purple_blist_add_buddy(buddy, NULL, group, NULL);
+ }
+
+
+ /* we should check if it has statuses for the presence,
+ * since the prpl was not yet loaded when status_types was being called
+ */
+ if (presence != NULL)
+ {
+ if (purple_presence_get_statuses(presence) == NULL)
+ {
+ purple_presence_add_list(presence, purple_prpl_get_statuses(connection_data->acct, presence));
+ }
+ }
+ }
+
+ /* save the contact data to be later accessible by using only the handle */
+ handle = tp_contact_get_handle(contact);
+
+ contact_data = g_hash_table_lookup(connection_data->contacts, (gpointer)handle);
+
+ if (contact_data == NULL)
+ {
+ contact_data = g_new0(telepathy_contact, 1);
+ contact_data-> contact = contact;
+
+ g_hash_table_insert(connection_data->contacts, (gpointer)handle, contact_data);
+
+ /* the notify signal will fire for any changed parameter of the contact (status, presence, avatar, alias etc.) */
+ g_object_ref(contact);
+ g_signal_connect(contact, "notify", G_CALLBACK (contact_notify_cb), connection_data);
+ contact_notify_cb (contact, NULL, connection_data);
+ }
+
+ if (!contact_data->requested_avatar)
+ {
+ g_array_append_val(avatar_handles, handle);
+ contact_data->requested_avatar = TRUE;
+ }
+ }
+
+ tp_cli_connection_interface_avatars_call_request_avatars(connection_data->connection, -1,
+ avatar_handles,
+ request_avatars_cb, connection_data,
+ NULL, NULL);
+
+ g_array_free(avatar_handles, TRUE);
+}
+
+/* this the ContactsReady callback for group channels */
+void
+group_contacts_ready_cb (TpConnection *connection,
+ guint n_contacts,
+ TpContact * const *contacts,
+ guint n_failed,
+ const TpHandle *failed,
+ const GError *error,
+ gpointer user_data,
+ GObject *weak_object)
+{
+ telepathy_group *data = user_data;
+
+ if (error != NULL)
+ {
+ purple_debug_error("telepathy", "Contacts ready error: %s\n", error->message);
+ }
+ else
+ {
+ PurpleGroup *group;
+
+ const gchar *group_name = tp_channel_get_identifier(data->channel);
+ group = purple_find_group(group_name);
+
+ if (group == NULL)
+ {
+ group = purple_group_new(group_name);
+ purple_blist_add_group(group, NULL);
+ }
+
+ handle_contacts(data->connection_data, n_contacts, contacts, n_failed, group);
+ }
+
+ /* this isn't used anywhere else except this callback */
+ g_free(data);
+}
+
+/* this the ContactsReady callback for list channels */
+void
+contacts_ready_cb (TpConnection *connection,
+ guint n_contacts,
+ TpContact * const *contacts,
+ guint n_failed,
+ const TpHandle *failed,
+ const GError *error,
+ gpointer user_data,
+ GObject *weak_object)
+{
+ telepathy_group *data = user_data;
+
+ if (error != NULL)
+ {
+ purple_debug_error("telepathy", "Contacts ready error: %s\n", error->message);
+ }
+ else
+ {
+ handle_contacts(data->connection_data, n_contacts, contacts, n_failed, NULL);
+ }
+
+ /* this isn't used anywhere else except this callback */
+ g_free(data);
+}
+
============================================================
--- libpurple/protocols/telepathy/telepathy_contact.h 95d4b16d635c033886107217341da3e29c397329
+++ libpurple/protocols/telepathy/telepathy_contact.h 95d4b16d635c033886107217341da3e29c397329
@@ -0,0 +1,72 @@
+/**
+ * purple - Telepathy Protocol Plugin
+ *
+ * Copyright (C); 2009, Felix Kerekes <sttwister at soc.pidgin.im>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option); any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+ */
+
+#ifndef _TELEPATHY_CONTACT_H_
+#define _TELEPATHY_CONTACT_H_
+
+#include <telepathy-glib/contact.h>
+
+#include "telepathy_connection.h"
+
+typedef struct
+{
+ TpContact *contact;
+
+ gboolean requested_avatar;
+} telepathy_contact;
+
+void
+destroy_contact(telepathy_contact *contact_data);
+
+void
+contact_notify_cb (TpContact *contact,
+ GParamSpec *pspec,
+ gpointer user_data);
+
+void
+handle_contacts (telepathy_connection *connection_data,
+ guint n_contacts,
+ TpContact * const *contacts,
+ guint n_failed,
+ PurpleGroup *group);
+
+/* this the ContactsReady callback for group channels */
+void
+group_contacts_ready_cb (TpConnection *connection,
+ guint n_contacts,
+ TpContact * const *contacts,
+ guint n_failed,
+ const TpHandle *failed,
+ const GError *error,
+ gpointer user_data,
+ GObject *weak_object);
+
+/* this the ContactsReady callback for list channels */
+void
+contacts_ready_cb (TpConnection *connection,
+ guint n_contacts,
+ TpContact * const *contacts,
+ guint n_failed,
+ const TpHandle *failed,
+ const GError *error,
+ gpointer user_data,
+ GObject *weak_object);
+
+#endif /* _TELEPATHY_CONTACT_H_ */
============================================================
--- libpurple/protocols/telepathy/Makefile.am 9084a1a81d3abd8c1c34d13271e194bc8dda3d83
+++ libpurple/protocols/telepathy/Makefile.am edcf56f9ef554e4a09fc722f263fc08735e970bb
@@ -3,7 +3,14 @@ pkgdir = $(libdir)/purple-$(PURPLE_MAJOR
pkgdir = $(libdir)/purple-$(PURPLE_MAJOR_VERSION)
-TELEPATHYSOURCES = telepathy.c
+TELEPATHYSOURCES = \
+ telepathy.c \
+ telepathy_avatar.c \
+ telepathy_channel.c \
+ telepathy_channel_list.c \
+ telepathy_channel_text.c \
+ telepathy_connection.c \
+ telepathy_contact.c
AM_CFLAGS = $(st)
============================================================
--- libpurple/protocols/telepathy/Makefile.mingw b110ba9c3c0d85bf0d12445f5dc0606926905b5b
+++ libpurple/protocols/telepathy/Makefile.mingw 1380667637d60efc3f54357b12c07a4a36a5b402
@@ -37,7 +37,13 @@ LIB_PATHS += -L$(GTK_TOP)/lib \
##
## SOURCES, OBJECTS
##
-C_SRC = telepathy.c
+C_SRC = telepathy.c \
+ telepathy_avatar.c \
+ telepathy_channel.c \
+ telepathy_channel_list.c \
+ telepathy_channel_text.c \
+ telepathy_connection.c \
+ telepathy_contact.c
OBJECTS = $(C_SRC:%.c=%.o)
============================================================
--- libpurple/protocols/telepathy/telepathy.c badfa5c36462e3257efb74e98eabbf56f4d205de
+++ libpurple/protocols/telepathy/telepathy.c 2fd9b36e01f333c263d79b7fa9bce00efe276617
@@ -38,6 +38,12 @@
#include "util.h"
#include "version.h"
+#include "telepathy_avatar.h"
+#include "telepathy_channel.h"
+#include "telepathy_channel_text.h"
+#include "telepathy_connection.h"
+#include "telepathy_contact.h"
+
#define TELEPATHY_ID "prpl-telepathy"
#define TELEPATHY_DISPLAY_VERSION "1.0"
@@ -54,60 +60,6 @@ typedef struct
typedef struct
{
- TpConnection *connection;
- PurpleConnection *gc;
- PurpleAccount *acct;
-
- /* This flag avoids having a channel processed twice via both NewChannels and quering the Channels property */
- gboolean listing_channels;
-
- /* This will hold pointers to telepathy_text_channel for buddies that have an active conversation */
- GHashTable *text_Channels;
-
- /* This will map contact handles to telepathy_contact */
- GHashTable *contacts;
-
-} telepathy_connection;
-
-typedef struct
-{
- GList *pending_Messages;
- TpChannel *channel;
-
- /* This flag avoids having a message processed twice via both Received signal and ListPendingMessages */
- gboolean received_Pending_Messages;
-} telepathy_text_channel;
-
-static void
-destroy_text_channel(telepathy_text_channel *tp_channel)
-{
- g_free(tp_channel);
-}
-
-typedef struct
-{
- TpContact *contact;
-
- gboolean requested_avatar;
-} telepathy_contact;
-
-
-static void
-destroy_contact(telepathy_contact *contact_data)
-{
- g_object_unref(contact_data->contact);
- g_free(contact_data);
-}
-
-typedef struct
-{
- telepathy_connection *connection_data;
- TpChannel *channel;
-
-} telepathy_group;
-
-typedef struct
-{
const gchar *telepathy_name;
const gchar *dbus_type;
const gchar *human_name;
@@ -274,1297 +226,6 @@ static void
}
static void
-contact_notify_cb (TpContact *contact,
- GParamSpec *pspec,
- gpointer user_data)
-{
- telepathy_connection *data = user_data;
-
- const gchar *name = tp_contact_get_identifier(contact);
- const gchar *presence_status = tp_contact_get_presence_status(contact);
- const gchar *presence_message = tp_contact_get_presence_message(contact);
- const gchar *alias = tp_contact_get_alias(contact);
-
- PurpleBuddy *buddy = purple_find_buddy(data->acct, tp_contact_get_identifier(contact));
-
- if (buddy == NULL)
- {
- purple_debug_warning("telepathy", "Received TpContact notify for non-existent buddy (%s)!\n", name);
- return;
- }
-
- purple_blist_alias_buddy(buddy, alias);
-
- purple_prpl_got_user_status(data->acct, name, presence_status,
- "message", presence_message, NULL);
-}
-
-static void
-request_avatars_cb (TpConnection *proxy,
- const GError *error,
- gpointer user_data,
- GObject *weak_object)
-{
- if (error != NULL)
- {
- purple_debug_error("telepathy", "RequestAvatars error: %s\n", error->message);
- }
-}
-
-static void
-handle_contacts (telepathy_connection *connection_data,
- guint n_contacts,
- TpContact * const *contacts,
- guint n_failed,
- PurpleGroup *group)
-{
- int i;
- GArray *avatar_handles = g_array_new(FALSE, FALSE, sizeof(guint));
-
- purple_debug_info("telepathy", "Contacts ready: %u (%u failed)\n", n_contacts, n_failed);
-
- for (i = 0; i<n_contacts; ++i)
- {
- TpContact *contact = contacts[i];
- PurpleBuddy *buddy;
- guint handle;
- telepathy_contact *contact_data;
-
- /* the buddy might already be stored locally */
- buddy = purple_find_buddy(connection_data->acct, tp_contact_get_identifier(contact));
-
- if (buddy == NULL)
- {
- /* Buddy was not stored locally */
- buddy = purple_buddy_new(connection_data->acct, tp_contact_get_identifier(contact), tp_contact_get_alias(contact));
- purple_blist_add_buddy(buddy, NULL, group, NULL);
- }
- else
- {
- PurpleGroup *buddy_group = purple_buddy_get_group(buddy);
- PurplePresence *presence = purple_buddy_get_presence(buddy);
-
- /* is this buddy in the right group */
- if (group != NULL && buddy_group != group)
- {
- purple_debug_info("telepathy", "Contact %s is not in the right group, moving him to %s\n",
- tp_contact_get_identifier(contact), purple_group_get_name(group));
-
- /* we should move the buddy to the right group */
- purple_blist_remove_buddy(buddy);
-
- buddy = purple_buddy_new(connection_data->acct, tp_contact_get_identifier(contact), tp_contact_get_alias(contact));
- purple_blist_add_buddy(buddy, NULL, group, NULL);
- }
-
-
- /* we should check if it has statuses for the presence,
- * since the prpl was not yet loaded when status_types was being called
- */
- if (presence != NULL)
- {
- if (purple_presence_get_statuses(presence) == NULL)
- {
- purple_presence_add_list(presence, purple_prpl_get_statuses(connection_data->acct, presence));
- }
- }
- }
-
- /* save the contact data to be later accessible by using only the handle */
- handle = tp_contact_get_handle(contact);
-
- contact_data = g_hash_table_lookup(connection_data->contacts, (gpointer)handle);
-
- if (contact_data == NULL)
- {
- contact_data = g_new0(telepathy_contact, 1);
- contact_data-> contact = contact;
-
- g_hash_table_insert(connection_data->contacts, (gpointer)handle, contact_data);
-
- /* the notify signal will fire for any changed parameter of the contact (status, presence, avatar, alias etc.) */
- g_object_ref(contact);
- g_signal_connect(contact, "notify", G_CALLBACK (contact_notify_cb), connection_data);
- contact_notify_cb (contact, NULL, connection_data);
- }
-
- if (!contact_data->requested_avatar)
- {
- g_array_append_val(avatar_handles, handle);
- contact_data->requested_avatar = TRUE;
- }
- }
-
- tp_cli_connection_interface_avatars_call_request_avatars(connection_data->connection, -1,
- avatar_handles,
- request_avatars_cb, connection_data,
- NULL, NULL);
-
- g_array_free(avatar_handles, TRUE);
-}
-
-/* this the ContactsReady callback for group channels */
-static void
-group_contacts_ready_cb (TpConnection *connection,
- guint n_contacts,
- TpContact * const *contacts,
- guint n_failed,
- const TpHandle *failed,
- const GError *error,
- gpointer user_data,
- GObject *weak_object)
-{
- telepathy_group *data = user_data;
-
- if (error != NULL)
- {
- purple_debug_error("telepathy", "Contacts ready error: %s\n", error->message);
- }
- else
- {
- PurpleGroup *group;
-
- const gchar *group_name = tp_channel_get_identifier(data->channel);
- group = purple_find_group(group_name);
-
- if (group == NULL)
- {
- group = purple_group_new(group_name);
- purple_blist_add_group(group, NULL);
- }
-
- handle_contacts(data->connection_data, n_contacts, contacts, n_failed, group);
- }
-
- /* this isn't used anywhere else except this callback */
- g_free(data);
-}
-
-/* this the ContactsReady callback for list channels */
-static void
-contacts_ready_cb (TpConnection *connection,
- guint n_contacts,
- TpContact * const *contacts,
- guint n_failed,
- const TpHandle *failed,
- const GError *error,
- gpointer user_data,
- GObject *weak_object)
-{
- telepathy_group *data = user_data;
-
- if (error != NULL)
- {
- purple_debug_error("telepathy", "Contacts ready error: %s\n", error->message);
- }
- else
- {
- handle_contacts(data->connection_data, n_contacts, contacts, n_failed, NULL);
- }
-
- /* this isn't used anywhere else except this callback */
- g_free(data);
-}
-
-static void
-get_known_avatar_tokens_cb (TpConnection *proxy,
- GHashTable *out_Tokens,
- const GError *error,
- gpointer user_data,
- GObject *weak_object)
-{
- if (error != NULL)
- {
- purple_debug_error("telepathy", "GetAvatarTokens error: %s\n", error->message);
- }
- else
- {
- GHashTableIter iter;
- guint key;
- gpointer value;
-
- g_hash_table_iter_init(&iter, out_Tokens);
-
- while (g_hash_table_iter_next(&iter, (gpointer)&key, &value))
- {
- purple_debug_info("telepathy", "Known token: %u -> (%s)\n", key, (gchar *)value);
- }
- }
-}
-
-static void
-avatar_retrieved_cb (TpConnection *proxy,
- guint arg_Contact,
- const gchar *arg_Token,
- const GArray *arg_Avatar,
- const gchar *arg_Type,
- gpointer user_data,
- GObject *weak_object)
-{
- telepathy_connection *data = user_data;
- PurpleBuddyIcon *icon;
- telepathy_contact *contact_data = g_hash_table_lookup(data->contacts, (gpointer)arg_Contact);
- TpContact *contact;
- gpointer avatar;
-
- if (contact_data == NULL)
- {
- purple_debug_warning("telepathy", "Updated avatar for handle %u which has no contact_data struct cached!\n", arg_Contact);
- return;
- }
-
- contact = contact_data->contact;
-
- if (contact == NULL)
- {
- purple_debug_warning("telepathy", "Retrieved avatar for handle %u which has no TpContact proxy cached!\n", arg_Contact);
- return;
- }
-
- purple_debug_info("telepathy", "Got avatar token for %u: (%s - %s)\n", arg_Contact, arg_Token, arg_Type);
-
- avatar = g_memdup(arg_Avatar->data, arg_Avatar->len);
-
- icon = purple_buddy_icon_new(data->acct, tp_contact_get_identifier(contact), avatar, arg_Avatar->len, arg_Token);
-}
-
-static void
-avatar_updated_cb (TpConnection *proxy,
- guint arg_Contact,
- const gchar *arg_New_Avatar_Token,
- gpointer user_data,
- GObject *weak_object)
-{
- telepathy_connection *data = user_data;
- telepathy_contact *contact_data = g_hash_table_lookup(data->contacts, (gpointer)arg_Contact);
- TpContact *contact;
- PurpleBuddy *buddy;
- PurpleBuddyIcon *icon;
-
- purple_debug_warning("telepathy", "Avatar token updated for %u: (%s)\n", arg_Contact, arg_New_Avatar_Token);
-
- if (contact_data == NULL)
- {
- purple_debug_warning("telepathy", "Updated avatar for handle %u which has no contact_data struct cached!\n", arg_Contact);
- return;
- }
-
- contact = contact_data->contact;
-
- if (contact == NULL)
- {
- purple_debug_warning("telepathy", "Updated avatar for handle %u which has no TpContact proxy chaced!\n", arg_Contact);
- return;
- }
-
- buddy = purple_find_buddy(data->acct, tp_contact_get_identifier(contact));
-
- if (buddy == NULL)
- {
- purple_debug_warning("telepathy", "AvatarUpdated: There's no buddy named %s\n", tp_contact_get_identifier(contact));
- return;
- }
-
- /* clear the avatar in case of an empty token */
- if (*arg_New_Avatar_Token == 0)
- {
- purple_buddy_icons_set_for_user(data->acct, tp_contact_get_identifier(contact), NULL, 0, "");
- return;
- }
-
-
- icon = purple_buddy_get_icon(buddy);
-
- if (g_strcmp0(purple_buddy_icon_get_checksum(icon), arg_New_Avatar_Token) != 0)
- {
- /* updated the buddy avatar */
- GArray *avatar_handles;
-
- purple_debug_info("telepathy", "Avatar for %u (%s) has changed! Calling RequestAvatars\n", arg_Contact, tp_contact_get_identifier(contact));
-
- avatar_handles = g_array_new(FALSE, FALSE, sizeof(guint));
-
- g_array_append_val(avatar_handles, arg_Contact);
-
- tp_cli_connection_interface_avatars_call_request_avatars(data->connection, -1,
- avatar_handles,
- request_avatars_cb, data,
- NULL, NULL);
-
- g_array_free(avatar_handles, TRUE);
- }
-}
-
-static void
-handle_list_channel (TpChannel *channel,
- telepathy_connection *data)
-{
- TpConnection *connection = data->connection;
- const TpIntSet *members;
- TpIntSetIter iter;
- GArray *handles;
-
- static const TpContactFeature features[] = {
- TP_CONTACT_FEATURE_ALIAS,
- TP_CONTACT_FEATURE_PRESENCE
- };
-
- guint handle;
- guint handle_type;
-
- handle = tp_channel_get_handle(channel, &handle_type);
-
- members = tp_channel_group_get_members(channel);
-
- if (members == NULL)
- {
- purple_debug_error("telepathy", "Error while getting member list\n");
- return;
- }
-
- iter.set = members;
- iter.element = (guint)(-1);
-
- handles = tp_intset_to_array (members);
-
- /* we want to create a TpContact for each member of this channel */
- if (handles->len)
- {
- /* this struct is needed to pass both the connection data and the channel proxy */
- telepathy_group *group = g_new0(telepathy_group, 1);
-
- group->channel = channel;
- group->connection_data = data;
-
- if (handle_type == TP_HANDLE_TYPE_GROUP)
- {
- /* this is a user-defined group */
- tp_connection_get_contacts_by_handle (connection,
- handles->len, (const TpHandle *) handles->data,
- G_N_ELEMENTS (features), features,
- group_contacts_ready_cb,
- group, NULL, NULL);
- }
- else
- {
- tp_connection_get_contacts_by_handle (connection,
- handles->len, (const TpHandle *) handles->data,
- G_N_ELEMENTS (features), features,
- contacts_ready_cb,
- group, NULL, NULL);
- }
-
- }
-
- tp_cli_connection_interface_avatars_call_get_known_avatar_tokens(data->connection, -1,
- handles,
- get_known_avatar_tokens_cb, data,
- NULL, NULL);
-
- g_array_free (handles, TRUE);
-
-}
-
-static void
-write_message_to_conversation (const gchar *from,
- guint timestamp,
- const gchar *msg,
- gpointer user_data)
-{
- telepathy_connection *data = user_data;
-
- /* if a conversation was not yet establish, create a new one */
- PurpleConversation *conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, from, data->acct);
- PurpleConvIm *im;
-
- /* escape HTML special characters */
- gchar *escaped_message = g_markup_escape_text(msg, -1);
-
- /* also change \n to <br> */
- gchar *final_message = purple_strdup_withhtml(escaped_message);
- g_free(escaped_message);
-
- if (conv == NULL)
- {
- conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, data->acct, from);
- }
- im = purple_conversation_get_im_data(conv);
-
- purple_debug_info("telepathy", "Contact %s says \"%s\" (escaped: \"%s\")\n", from, msg, final_message);
-
- /* transmit the message to the UI */
- purple_conv_im_write(im, from, final_message, 0, timestamp);
-
- g_free(final_message);
-}
-
-static void
-acknowledge_pending_messages_cb (TpChannel *proxy,
- const GError *error,
- gpointer user_data,
- GObject *weak_object)
-{
- if (error != NULL)
- {
- purple_debug_error("telepathy", "AcknowledgePendingMessages error: %s\n", error->message);
- }
-}
-
-static void
-list_pending_messages_cb (TpChannel *proxy,
- const GPtrArray *out_Pending_Messages,
- const GError *error,
- gpointer user_data,
- GObject *weak_object)
-{
- if (error != NULL)
- {
- purple_debug_error("telepathy", "ListPendingMessages error: %s\n", error->message);
- }
- else
- {
- telepathy_connection *data = user_data;
- GArray *message_IDs;
-
- int i;
-
- GHashTable *properties = tp_channel_borrow_immutable_properties(proxy);
- gchar *who = (gchar *)tp_asv_get_string(properties, TP_IFACE_CHANNEL ".TargetID");
-
- telepathy_text_channel *tp_channel = g_hash_table_lookup(data->text_Channels, who);
-
- if (tp_channel == NULL)
- {
- purple_debug_warning("telepathy", "Received message from %s, but there's no channel struct for the buddy!\n", who);
- }
- else
- {
- /* we should now allow received_cb to handle incoming messages */
- tp_channel->received_Pending_Messages = TRUE;
- }
-
- /* this will hold the IDs of message that will be acknowledged */
- message_IDs = g_array_new(FALSE, FALSE, sizeof(guint));
-
- for (i = 0; i<out_Pending_Messages->len; ++i)
- {
- /* unpack the relevant info from (uuuuus) */
- GValueArray *arr = g_ptr_array_index(out_Pending_Messages, i);
- guint msg_id = g_value_get_uint(g_value_array_get_nth(arr, 0));
- guint timestamp = g_value_get_uint(g_value_array_get_nth(arr, 1));
- guint flags = g_value_get_uint(g_value_array_get_nth(arr, 4));
- gchar *msg = (gchar *)g_value_get_string(g_value_array_get_nth(arr, 5));
-
- /* get the identifier from channel instead of contact since contact might not be ready for offline messages */
- gchar *from = (gchar *)tp_channel_get_identifier(proxy);
-
- /* drop message if it's not text */
- if ((flags & TP_CHANNEL_TEXT_MESSAGE_FLAG_NON_TEXT_CONTENT) == 0)
- write_message_to_conversation(from, timestamp, msg, user_data);
-
- /* add the id to the array of acknowledge messages */
- g_array_append_val(message_IDs, msg_id);
- }
-
- /* acknowledge the messages now */
- tp_cli_channel_type_text_call_acknowledge_pending_messages(proxy, -1, message_IDs,
- acknowledge_pending_messages_cb, user_data, NULL, NULL);
-
- g_array_free(message_IDs, TRUE);
-
- }
-}
-
-static void
-received_cb (TpChannel *proxy,
- guint arg_ID,
- guint arg_Timestamp,
- guint arg_Sender,
- guint arg_Type,
- guint arg_Flags,
- const gchar *arg_Text,
- gpointer user_data,
- GObject *weak_object)
-{
- telepathy_connection *data = user_data;
-
- GHashTable *properties = tp_channel_borrow_immutable_properties(proxy);
- gchar *who = (gchar *)tp_asv_get_string(properties, TP_IFACE_CHANNEL ".TargetID");
-
- telepathy_text_channel *tp_channel = g_hash_table_lookup(data->text_Channels, who);
-
- if (tp_channel == NULL)
- {
- purple_debug_warning("telepathy", "Received message from %s, but there's no channel struct for the buddy!\n", who);
- }
- else
- {
- GArray *message_IDs;
-
- /* will this message get caught by ListPendingMessages? */
- if (!tp_channel->received_Pending_Messages)
- return;
-
- /* drop this message if it's not text */
- if ((arg_Flags & TP_CHANNEL_TEXT_MESSAGE_FLAG_NON_TEXT_CONTENT) == 0)
- write_message_to_conversation(who, arg_Timestamp, arg_Text, user_data);
-
- /* acknowledge receiving the message */
- message_IDs = g_array_new(FALSE, FALSE, sizeof(guint));
-
- g_array_append_val(message_IDs, arg_ID);
-
- tp_cli_channel_type_text_call_acknowledge_pending_messages(proxy, -1, message_IDs,
- acknowledge_pending_messages_cb, user_data, NULL, NULL);
-
- g_array_free(message_IDs, TRUE);
-
- }
-}
-
-static void
-send_error_cb (TpChannel *proxy,
- guint arg_Error,
- guint arg_Timestamp,
- guint arg_Type,
- const gchar *arg_Text,
- gpointer user_data,
- GObject *weak_object)
-{
- telepathy_connection *data = user_data;
-
- const gchar *who = tp_channel_get_identifier(proxy);
-
- const gchar *error_reason = NULL;
- gchar *error_message;
- gchar *error_message2;
-
- switch (arg_Error)
- {
- case TP_CHANNEL_TEXT_SEND_ERROR_UNKNOWN:
- error_reason = _("Unknown error");
- break;
-
- case TP_CHANNEL_TEXT_SEND_ERROR_OFFLINE:
- error_reason = _("Contact is offline");
- break;
-
- case TP_CHANNEL_TEXT_SEND_ERROR_INVALID_CONTACT:
- error_reason = _("Contact is invalid");
- break;
-
- case TP_CHANNEL_TEXT_SEND_ERROR_PERMISSION_DENIED:
- error_reason = _("Permission denied");
- break;
-
- case TP_CHANNEL_TEXT_SEND_ERROR_TOO_LONG:
- error_reason = _("The message is too long");
- break;
-
- case TP_CHANNEL_TEXT_SEND_ERROR_NOT_IMPLEMENTED:
- error_reason = _("Not implemented");
- break;
- }
-
- error_message = g_strdup_printf(_("There was an error sending your message to %s"), who);
- error_message2 = g_strdup_printf("%s: %s", error_message, error_reason);
-
- /* display the error in the conversation */
- if (!purple_conv_present_error(who, data->acct, error_message2))
- {
- /* display as a popup if there is no active conversation with the user */
- purple_notify_error(purple_connections_get_handle(),
- _("Error sending message"),
- error_message,
- error_reason);
- }
-
- g_free(error_message2);
- g_free(error_message);
-
- purple_debug_error("telepathy", "SendError: %s\n", error_reason);
-}
-
-static void
-send_cb (TpChannel *proxy,
- const GError *error,
- gpointer user_data,
- GObject *weak_object)
-{
- if (error != NULL)
- {
- telepathy_connection *data = user_data;
-
- const gchar *who = tp_channel_get_identifier(proxy);
-
- gchar *error_message = g_strdup_printf(_("There was an error sending your message to %s"), who);
- gchar *error_message2 = g_strdup_printf("%s: %s", error_message, error->message);
-
- /* display the error in the conversation */
- if (!purple_conv_present_error(who, data->acct, error_message2))
- {
- /* display as a popup if there is no active conversation with the user */
- purple_notify_error(purple_connections_get_handle(),
- _("Error sending message"),
- error_message,
- error->message);
- }
-
- g_free(error_message2);
- g_free(error_message);
-
- purple_debug_error("telepathy", "Send error: %s\n", error->message);
- }
-}
-
-static void
-text_channel_invalidated_cb (TpProxy *self,
- guint domain,
- gint code,
- gchar *message,
- gpointer user_data)
-{
- telepathy_connection *data = user_data;
-
- /* remove the cached TpChannel proxy when the channel closes */
- const gchar *who = tp_channel_get_identifier((TpChannel *)self);
-
- telepathy_text_channel *tp_channel = NULL;
-
- if (data->text_Channels)
- tp_channel = g_hash_table_lookup(data->text_Channels, who);
-
- purple_debug_info("telepathy", "Text channel with %s closed!\n", who);
-
- if (tp_channel)
- {
- tp_channel->channel = NULL;
- }
-}
-
-static void
-chat_state_changed_cb (TpChannel *proxy,
- guint arg_Contact,
- guint arg_State,
- gpointer user_data,
- GObject *weak_object)
-{
- telepathy_connection *data = user_data;
-
- telepathy_contact *contact_data = g_hash_table_lookup(data->contacts, (gpointer)arg_Contact);
-
- PurpleTypingState state;
- const gchar *name;
-
- if (contact_data == NULL)
- {
- purple_debug_warning("telepathy", "Chat state changed for %u who isn't cached!\n", arg_Contact);
- return;
- }
-
- name = tp_contact_get_identifier(contact_data->contact);
-
- purple_debug_info("telepathy", "Chat state changed for %s\n", name);
-
- switch (arg_State)
- {
- case TP_CHANNEL_CHAT_STATE_PAUSED:
- state = PURPLE_TYPED;
- break;
-
- case TP_CHANNEL_CHAT_STATE_COMPOSING:
- state = PURPLE_TYPING;
- break;
-
- default:
- state = PURPLE_NOT_TYPING;
- break;
- }
-
- if (state == PURPLE_NOT_TYPING)
- {
- serv_got_typing_stopped(data->gc, name);
- }
- else
- {
- serv_got_typing(data->gc, name, -1, state);
- }
-}
-
-static void
-handle_text_channel (TpChannel *channel,
- telepathy_connection *data)
-{
- GError *error = NULL;
-
- GHashTable *properties = tp_channel_borrow_immutable_properties(channel);
- gchar *who = (gchar *)tp_asv_get_string(properties, TP_IFACE_CHANNEL ".TargetID");
-
- telepathy_text_channel *tp_channel;
-
- purple_debug_info("telepathy", "Saving TpChannel proxy for %s\n", who);
-
- tp_channel = g_hash_table_lookup(data->text_Channels, who);
-
- /* if tp_channel exists, then we requested this channel, else it's an incoming request so we must cache it */
- if (tp_channel == NULL)
- {
- tp_channel = g_new0(telepathy_text_channel, 1);
- g_hash_table_insert(data->text_Channels, who, tp_channel);
- }
-
- tp_channel->channel = channel;
-
- tp_cli_channel_interface_chat_state_connect_to_chat_state_changed(channel, chat_state_changed_cb, data, NULL, NULL, &error);
-
- if (error != NULL)
- {
- purple_debug_error("telepathy", "Error connecting to ChatStateChanged signal: %s\n", error->message);
- }
-
- tp_cli_channel_type_text_connect_to_received(channel, received_cb, data, NULL, NULL, &error);
-
- if (error != NULL)
- {
- purple_debug_error("telepathy", "Error connecting to Received signal: %s\n", error->message);
- }
-
- tp_channel->received_Pending_Messages = FALSE;
-
- g_signal_connect(channel, "invalidated", G_CALLBACK(text_channel_invalidated_cb), data);
-
- /* the Clear parameter is deprecated, we need to use AcknowledgePendingMessages */
- tp_cli_channel_type_text_call_list_pending_messages(channel, -1, FALSE, list_pending_messages_cb, data, NULL, NULL);
-
- /* send pending messages */
- while (tp_channel->pending_Messages != NULL)
- {
- purple_debug_info("telepathy", "Sending pending message \"%s\" to %s\n", (gchar *)tp_channel->pending_Messages->data, who);
-
- tp_cli_channel_type_text_call_send(channel, -1, TP_CHANNEL_TEXT_MESSAGE_TYPE_NORMAL, tp_channel->pending_Messages->data, send_cb, data, NULL, NULL);
-
- /* the message was duped */
- g_free(tp_channel->pending_Messages->data);
-
- tp_channel->pending_Messages = g_list_delete_link(tp_channel->pending_Messages, tp_channel->pending_Messages);
- }
-
- tp_cli_channel_type_text_connect_to_send_error(channel, send_error_cb, data, NULL, NULL, &error);
-
- if (error != NULL)
- {
- purple_debug_error("telepathy", "Error connecting to SendError signal: %s\n", error->message);
- g_error_free(error);
- }
-}
-
-static void
-channel_ready_cb (TpChannel *channel,
- const GError *error,
- gpointer user_data)
-{
- if (error != NULL)
- {
- purple_debug_error("telepathy", "Channel ready error: %s\n", error->message);
- }
- else
- {
- GQuark handle_Type;
-
- handle_Type = tp_channel_get_channel_type_id(channel);
-
- if (handle_Type == TP_IFACE_QUARK_CHANNEL_TYPE_CONTACT_LIST)
- {
- handle_list_channel(channel, user_data);
- }
- else if (handle_Type == TP_IFACE_QUARK_CHANNEL_TYPE_TEXT)
- {
- handle_text_channel(channel, user_data);
- }
- }
-}
-
-static void
-channel_invalidated_cb (TpProxy *self,
- guint domain,
- gint code,
- gchar *message,
- gpointer user_data)
-{
- purple_debug_info("telepathy", "Channel invalidated: %s\n", message);
-
- g_object_unref(self);
-}
-
-static void
-handle_new_channel (telepathy_connection *data,
- const GValueArray *channel_Properties)
-{
- char *object_Path = g_value_get_boxed(g_value_array_get_nth((GValueArray *)channel_Properties, 0));
- GHashTable *map = g_value_get_boxed(g_value_array_get_nth((GValueArray *)channel_Properties, 1));
-
- GError *error = NULL;
- TpConnection *connection = data->connection;
- TpChannel *channel = tp_channel_new_from_properties(connection, object_Path, map, &error);
-
- if (error != NULL)
- {
- purple_debug_error("telepathy", "Error while creating TpChannel: %s\n", error->message);
- g_error_free(error);
- return;
- }
-
- purple_debug_info("telepathy", "New channel: %s\n", object_Path);
-
- tp_channel_call_when_ready(channel, channel_ready_cb, data);
-
- g_signal_connect(channel, "invalidated", G_CALLBACK (channel_invalidated_cb), data);
-}
-
-static void
-new_channels_cb (TpConnection *proxy,
- const GPtrArray *arg_Channels,
- gpointer user_data,
- GObject *weak_object)
-{
- int i;
- telepathy_connection *data = user_data;
-
- if (data->listing_channels)
- return;
-
- purple_debug_info("telepathy", "NewChannels:\n");
-
- for (i = 0; i < arg_Channels->len; i++)
- {
- GValueArray *channel = g_ptr_array_index(arg_Channels, i);
-
- handle_new_channel(user_data, channel);
- }
-}
-
-static void
-get_channels_cb (TpProxy *proxy,
- const GValue *out_Value,
- const GError *error,
- gpointer user_data,
- GObject *weak_object)
-{
- if (error != NULL)
- {
- purple_debug_error("telepathy", "Get Channels error: %s\n", error->message);
- }
- else
- {
- telepathy_connection *data = user_data;
-
- /* unpack the a(oa{sv}) struct */
- const GPtrArray *channels = g_value_get_boxed(out_Value);
- int i;
-
- data->listing_channels = FALSE;
-
- for (i = 0; i < channels->len; i++)
- {
- const GValueArray *channel = g_ptr_array_index(channels, i);
- handle_new_channel(user_data, channel);
- }
-
- }
-}
-
-static void
-get_avatar_properties_cb (TpProxy *proxy,
- GHashTable *out_Properties,
- const GError *error,
- gpointer user_data,
- GObject *weak_object)
-{
- if (error != NULL)
- {
- purple_debug_error("telepathy", "Error getting avatar properties: %s\n", error->message);
- }
- else
- {
- telepathy_connection *data = user_data;
- PurplePlugin *plugin = purple_connection_get_prpl(data->gc);
- PurplePluginProtocolInfo *prpl_info = plugin->info->extra_info;
-
-
- GHashTableIter iter;
- gpointer key, value;
-
- PurpleBuddyIconSpec icon_spec = NO_BUDDY_ICONS;
- icon_spec.scale_rules = PURPLE_ICON_SCALE_SEND;
-
- purple_debug_info("telepathy", "Got avatar properties!\n");
-
- g_hash_table_iter_init(&iter, out_Properties);
-
- /* iterate over all properties */
- while (g_hash_table_iter_next(&iter, &key, &value))
- {
- gchar *name = key;
- GValue *val = value;
-
- if (g_strcmp0("SupportedAvatarMIMETypes", name) == 0)
- {
- /* This parameter is of dbus type "as"
- * It's exposed as a GValue holding a (gchar **)
- * Or is it now??? wtf!?
- */
-
- gchar *format = NULL;
-
- int i;
- gchar **arr = g_value_get_boxed(val);
-
- for (i = 0; arr[i] != NULL; ++i)
- {
- const gchar *mime_type = arr[i];
-
- int j;
-
- /* We want to get the part after the /
- * Split the string using / as a delimiter and use the last part
- */
- gchar **split = g_strsplit(mime_type, "/", 0);
- gchar *old = format;
-
- /* j will be the last non-NULL token */
- for (j = 0; split[j] != NULL; ++j);
- --j;
-
-
- /* if this is the first type, don't prepend a comma */
- if (i == 0)
- format = g_strdup(split[j]);
- else
- format = g_strdup_printf("%s,%s", format, split[j]);
-
- g_free(old);
- g_strfreev(split);
- }
-
- purple_debug_info("telepathy", " Supported types: %s\n", format);
-
- icon_spec.format = format;
- }
- else if (g_strcmp0("MinimumAvatarWidth", name) == 0)
- {
- icon_spec.min_width = g_value_get_uint(val);
- }
- else if (g_strcmp0("MinimumAvatarHeight", name) == 0)
- {
- icon_spec.min_height = g_value_get_uint(val);
- }
- else if (g_strcmp0("MaximumAvatarWidth", name) == 0)
- {
- icon_spec.max_width = g_value_get_uint(val);
- }
- else if (g_strcmp0("MaximumAvatarHeight", name) == 0)
- {
- icon_spec.max_height = g_value_get_uint(val);
- }
- else if (g_strcmp0("MaximumAvatarBytes", name) == 0)
- {
- icon_spec.max_filesize = g_value_get_uint(val);
- }
- }
-
- prpl_info->icon_spec = icon_spec;
- }
-}
-
-static void
-connection_ready_cb (TpConnection *connection,
- const GError *error,
- gpointer user_data)
-{
- if (error != NULL)
- {
- purple_debug_info("telepathy", "Connection ready error: %s\n", error->message);
- }
- else
- {
- char **interfaces, **ptr;
- GError *error = NULL;
- telepathy_connection *data = user_data;
-
- purple_debug_info("telepathy", "Connection is ready. Interfaces implemented:\n");
-
- /* query interfaces */
- g_object_get(connection, "interfaces", &interfaces, NULL);
- for (ptr = interfaces; ptr && *ptr; ptr++)
- {
- purple_debug_info("telepathy", " %s\n", *ptr);
- }
- g_strfreev(interfaces);
-
- tp_cli_connection_interface_requests_connect_to_new_channels(connection, new_channels_cb, user_data, NULL, NULL, &error);
-
- if (error != NULL)
- {
- purple_debug_error("telepathy", "Error while connecting to NewChannels signal: %s\n", error->message);
- g_error_free(error);
- error = NULL;
- return;
- }
-
- data->listing_channels = TRUE;
-
- /* query the Channels property of the Requests interface */
- tp_cli_dbus_properties_call_get(connection, -1, TP_IFACE_CONNECTION_INTERFACE_REQUESTS, "Channels", get_channels_cb, user_data, NULL, NULL);
-
-
- /* query supported avatar formats */
- tp_cli_dbus_properties_call_get_all(connection, -1, TP_IFACE_CONNECTION_INTERFACE_AVATARS, get_avatar_properties_cb, user_data, NULL, NULL);
-
- /* this will be fired when an avatar for a buddy has been received */
- tp_cli_connection_interface_avatars_connect_to_avatar_retrieved(connection,
- avatar_retrieved_cb, data,
- NULL, NULL,
- &error);
-
- if (error != NULL)
- {
- purple_debug_error("telepathy", "Error connecting to AvatarRetrieved signal: %s\n", error->message);
- g_error_free(error);
- }
-
- tp_cli_connection_interface_avatars_connect_to_avatar_updated(connection,
- avatar_updated_cb, data,
- NULL, NULL,
- &error);
-
- if (error != NULL)
- {
- purple_debug_error("telepathy", "Error connecting to AvatarUpdated signal: %s\n", error->message);
- g_error_free(error);
- }
-
- }
-}
-
-static void
-status_changed_cb (TpConnection *proxy,
- guint arg_Status,
- guint arg_Reason,
- gpointer user_data,
- GObject *weak_object)
-{
- telepathy_connection *data = user_data;
-
- if (arg_Status == TP_CONNECTION_STATUS_CONNECTED)
- {
- purple_debug_info("telepathy", "Connected!\n");
-
- purple_connection_update_progress(data->gc, _("Connected"),
- 1, /* which connection step this is */
- 2); /* total number of steps */
-
- purple_connection_set_state(data->gc, PURPLE_CONNECTED);
-
- data->text_Channels = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, (GDestroyNotify) destroy_text_channel);
- data->contacts = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, (GDestroyNotify) destroy_contact);
- }
- else if (arg_Status == TP_CONNECTION_STATUS_DISCONNECTED)
- {
- gchar *reason = NULL;
- PurpleConnectionError error = PURPLE_CONNECTION_ERROR_OTHER_ERROR;
- purple_debug_info("telepathy", "Disconnected! Reason: %d\n", arg_Reason);
-
- switch (arg_Reason)
- {
- case TP_CONNECTION_STATUS_REASON_NETWORK_ERROR:
- reason = "Network error";
- error = PURPLE_CONNECTION_ERROR_NETWORK_ERROR;
- break;
-
- case TP_CONNECTION_STATUS_REASON_AUTHENTICATION_FAILED:
- reason = "Authentication failed";
- error = PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED;
- break;
-
- case TP_CONNECTION_STATUS_REASON_ENCRYPTION_ERROR:
- reason = "Encryption error";
- error = PURPLE_CONNECTION_ERROR_ENCRYPTION_ERROR;
- break;
-
- case TP_CONNECTION_STATUS_REASON_NAME_IN_USE:
- reason = "Name in use";
- error = PURPLE_CONNECTION_ERROR_NAME_IN_USE;
- break;
-
- case TP_CONNECTION_STATUS_REASON_CERT_NOT_PROVIDED:
- reason = "SSL Certificate not provided";
- error = PURPLE_CONNECTION_ERROR_CERT_NOT_PROVIDED;
- break;
-
- case TP_CONNECTION_STATUS_REASON_CERT_UNTRUSTED:
- reason = "SSL Certificate is isnged by an untrusted certifying authority";
- error = PURPLE_CONNECTION_ERROR_CERT_UNTRUSTED;
- break;
-
- case TP_CONNECTION_STATUS_REASON_CERT_EXPIRED:
- reason = "SSL Certificate expired";
- error = PURPLE_CONNECTION_ERROR_CERT_EXPIRED;
- break;
-
- case TP_CONNECTION_STATUS_REASON_CERT_NOT_ACTIVATED:
- reason = "SSL Certificate is not yet valid";
- error = PURPLE_CONNECTION_ERROR_CERT_NOT_ACTIVATED;
- break;
-
- case TP_CONNECTION_STATUS_REASON_CERT_HOSTNAME_MISMATCH:
- reason = "SSL Certificate hostname mismatch";
- error = PURPLE_CONNECTION_ERROR_CERT_HOSTNAME_MISMATCH;
- break;
-
- case TP_CONNECTION_STATUS_REASON_CERT_FINGERPRINT_MISMATCH:
- reason = "SSL Certificate fingerprint mismatch";
- error = PURPLE_CONNECTION_ERROR_CERT_FINGERPRINT_MISMATCH;
- break;
-
- case TP_CONNECTION_STATUS_REASON_CERT_SELF_SIGNED:
- reason = "SSL Certificate is self-signed";
- error = PURPLE_CONNECTION_ERROR_CERT_SELF_SIGNED;
- break;
-
- case TP_CONNECTION_STATUS_REASON_CERT_OTHER_ERROR:
- reason = "Error while validating the server's SSL Certificate";
- error = PURPLE_CONNECTION_ERROR_CERT_OTHER_ERROR;
- break;
- }
-
- if (data)
- {
- purple_connection_set_protocol_data(data->gc, NULL);
-
- if (reason != NULL && data->gc)
- purple_connection_error_reason(data->gc, error, reason);
-
- if (data->connection != NULL)
- {
- g_object_unref(data->connection);
- data->connection = NULL;
- }
-
- if (data->text_Channels != NULL)
- {
- g_hash_table_destroy(data->text_Channels);
- data->text_Channels = NULL;
- }
- if (data->contacts != NULL)
- {
- g_hash_table_destroy(data->contacts);
- data->contacts = NULL;
- }
-
- g_free(data);
- }
-
- }
- else if (arg_Status == TP_CONNECTION_STATUS_CONNECTING)
- {
- purple_debug_info("telepathy", "Connecting! Reason: %d\n", arg_Reason);
- purple_connection_set_state(data->gc, PURPLE_CONNECTING);
- purple_connection_update_progress(data->gc, _("Connecting"),
- 0, /* which connection step this is */
- 2); /* total number of steps */
-
- }
-}
-
-static void
-connection_connect_cb (TpConnection *proxy,
- const GError *error,
- gpointer user_data,
- GObject *weak_object)
-{
- /* if this fails, something must be broken somewhere */
- if (error != NULL)
- {
- purple_debug_error("telepathy", "Connect error: %s\n", error->message);
- }
-}
-
-static void
-request_connection_cb (TpConnectionManager *proxy,
- const gchar *out_Bus_Name,
- const gchar *out_Object_Path,
- const GError *error,
- gpointer user_data,
- GObject *weak_object)
-{
- PurpleConnection *gc = user_data;
-
- if (error != NULL)
- {
- purple_debug_info("telepathy", "RequestConnection error: %s\n", error->message);
-
- purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, error->message);
- }
- else
- {
- GError *error = NULL;
- telepathy_connection *connection_data;
-
- TpDBusDaemon *daemon = tp_dbus_daemon_dup(&error);
-
- if (error != NULL)
- {
- purple_debug_error("telepathy", "Error creating dbus daemon: %s\n", error->message);
- g_error_free(error);
- return;
- }
-
- connection_data = g_new0(telepathy_connection, 1);
-
- /* get the connection proxy straight out of the dbus interface */
- connection_data->connection = tp_connection_new(daemon, out_Bus_Name, out_Object_Path, &error);
- connection_data->gc = gc;
- connection_data->acct = purple_connection_get_account(gc);
- purple_connection_set_protocol_data(gc, connection_data);
-
- if (error != NULL)
- {
- purple_debug_error("telepathy", "Error creating TpConnection object: %s\n", error->message);
- g_error_free(error);
-
- g_object_unref(connection_data->connection);
- connection_data->connection = NULL;
- g_free(connection_data);
- return;
- }
-
- tp_connection_call_when_ready(connection_data->connection, connection_ready_cb, connection_data);
-
- /* this will indicate any connection status change, also providing a reason */
- tp_cli_connection_connect_to_status_changed(connection_data->connection, status_changed_cb, connection_data, NULL, NULL, &error);
-
- if (error != NULL)
- {
- purple_debug_error("telepathy", "Error conencting to StatusChanged: %s\n", error->message);
- g_error_free(error);
-
- tp_cli_connection_call_disconnect(connection_data->connection, -1, NULL, NULL, NULL, NULL);
- g_object_unref(connection_data->connection);
- connection_data->connection = NULL;
- g_free(connection_data);
- }
- else
- {
- /* do some magic now :) */
- tp_cli_connection_call_connect(connection_data->connection, -1, connection_connect_cb, connection_data, NULL, NULL);
- }
-
- if (daemon != NULL)
- g_object_unref(daemon);
- }
-}
-
-static void
telepathy_login(PurpleAccount *acct)
{
PurpleConnection *gc = purple_account_get_connection(acct);
@@ -1649,21 +310,6 @@ telepathy_close(PurpleConnection *gc)
}
}
-static void
-ensure_channel_cb (TpConnection *proxy,
- gboolean out_Yours,
- const gchar *out_Channel,
- GHashTable *out_Properties,
- const GError *error,
- gpointer user_data,
- GObject *weak_object)
-{
- if (error != NULL)
- {
- purple_debug_error("telepathy", "EnsureChannel error: %s\n", error->message);
- }
-}
-
static int
telepathy_send_im (PurpleConnection *gc,
const char *who,
@@ -1718,18 +364,6 @@ telepathy_send_im (PurpleConnection *gc,
return 1;
}
-static void
-set_chat_state_cb (TpChannel *proxy,
- const GError *error,
- gpointer user_data,
- GObject *weak_object)
-{
- if (error != NULL)
- {
- purple_debug_error("telepathy", "SetChatState error: %s\n", error->message);
- }
-}
-
static unsigned int
telepathy_send_typing (PurpleConnection *gc, const char *name, PurpleTypingState state)
{
@@ -1781,18 +415,6 @@ static void
}
static void
-set_presence_cb (TpConnection *proxy,
- const GError *error,
- gpointer user_data,
- GObject *weak_object)
-{
- if (error != NULL)
- {
- purple_debug_error("telepathy", "SetStatus error: %s\n", error->message);
- }
-}
-
-static void
telepathy_set_status (PurpleAccount *account, PurpleStatus *status)
{
PurpleConnection *gc = purple_account_get_connection(account);
@@ -1811,31 +433,6 @@ static void
}
static void
-set_avatar_cb (TpConnection *proxy,
- const gchar *out_Token,
- const GError *error,
- gpointer user_data,
- GObject *weak_object)
-{
- if (error != NULL)
- {
- purple_debug_error("telepathy", "SetAvatar error: %s\n", error->message);
- }
-}
-
-static void
-clear_avatar_cb (TpConnection *proxy,
- const GError *error,
- gpointer user_data,
- GObject *weak_object)
-{
- if (error != NULL)
- {
- purple_debug_error("telepathy", "ClearAvatar error: %s\n", error->message);
- }
-}
-
-static void
telepathy_set_buddy_icon (PurpleConnection *gc, PurpleStoredImage *img)
{
telepathy_connection *data = purple_connection_get_protocol_data(gc);
More information about the Commits
mailing list