aboutsummaryrefslogtreecommitdiffstats
path: root/libempathy
diff options
context:
space:
mode:
Diffstat (limited to 'libempathy')
-rw-r--r--libempathy/Makefile.am5
-rw-r--r--libempathy/empathy-call-handler.c43
-rw-r--r--libempathy/empathy-call-handler.h5
-rw-r--r--libempathy/empathy-chatroom-manager.c36
-rw-r--r--libempathy/empathy-chatroom.c4
-rw-r--r--libempathy/empathy-contact-manager.c6
-rw-r--r--libempathy/empathy-contact.c70
-rw-r--r--libempathy/empathy-contact.h8
-rw-r--r--libempathy/empathy-debug.c76
-rw-r--r--libempathy/empathy-debug.h6
-rw-r--r--libempathy/empathy-debugger.c270
-rw-r--r--libempathy/empathy-debugger.h88
-rw-r--r--libempathy/empathy-dispatcher.c13
-rw-r--r--libempathy/empathy-ft-handler.c19
-rw-r--r--libempathy/empathy-idle.c43
-rw-r--r--libempathy/empathy-status-presets.c49
-rw-r--r--libempathy/empathy-status-presets.h1
-rw-r--r--libempathy/empathy-time.c7
-rw-r--r--libempathy/empathy-tp-call.c37
-rw-r--r--libempathy/empathy-tp-call.h2
-rw-r--r--libempathy/empathy-tp-chat.c2
-rw-r--r--libempathy/empathy-tp-contact-list.c4
-rw-r--r--libempathy/empathy-tp-file.c191
-rw-r--r--libempathy/empathy-tp-file.h4
-rw-r--r--libempathy/empathy-tp-tube.c669
-rw-r--r--libempathy/empathy-tp-tube.h103
-rw-r--r--libempathy/empathy-tube-handler.c20
-rw-r--r--libempathy/empathy-utils.c6
28 files changed, 895 insertions, 892 deletions
diff --git a/libempathy/Makefile.am b/libempathy/Makefile.am
index 3540c88bf..87b728464 100644
--- a/libempathy/Makefile.am
+++ b/libempathy/Makefile.am
@@ -7,6 +7,7 @@ AM_CPPFLAGS = \
-I$(top_builddir) \
-DDATADIR=\""$(datadir)"\" \
-DLOCALEDIR=\""$(datadir)/locale"\" \
+ -DG_LOG_DOMAIN=\"empathy\" \
$(LIBEMPATHY_CFLAGS) \
$(GEOCLUE_CFLAGS) \
$(WARN_CFLAGS) \
@@ -33,6 +34,7 @@ libempathy_la_SOURCES = \
empathy-contact-manager.c \
empathy-contact-monitor.c \
empathy-debug.c \
+ empathy-debugger.c \
empathy-dispatcher.c \
empathy-dispatch-operation.c \
empathy-ft-factory.c \
@@ -53,7 +55,6 @@ libempathy_la_SOURCES = \
empathy-tp-contact-list.c \
empathy-tp-file.c \
empathy-tp-roomlist.c \
- empathy-tp-tube.c \
empathy-tube-handler.c \
empathy-utils.c
@@ -82,6 +83,7 @@ libempathy_headers = \
empathy-contact-manager.h \
empathy-contact-monitor.h \
empathy-debug.h \
+ empathy-debugger.h \
empathy-dispatcher.h \
empathy-dispatch-operation.h \
empathy-ft-factory.h \
@@ -103,7 +105,6 @@ libempathy_headers = \
empathy-tp-contact-list.h \
empathy-tp-file.h \
empathy-tp-roomlist.h \
- empathy-tp-tube.h \
empathy-tube-handler.h \
empathy-types.h \
empathy-utils.h
diff --git a/libempathy/empathy-call-handler.c b/libempathy/empathy-call-handler.c
index 8d70885b4..f73c41e2e 100644
--- a/libempathy/empathy-call-handler.c
+++ b/libempathy/empathy-call-handler.c
@@ -1,6 +1,6 @@
/*
* empathy-call-handler.c - Source for EmpathyCallHandler
- * Copyright (C) 2008 Collabora Ltd.
+ * Copyright (C) 2008-2009 Collabora Ltd.
* @author Sjoerd Simons <sjoerd.simons@collabora.co.uk>
*
* This library is free software; you can redistribute it and/or
@@ -304,7 +304,9 @@ EmpathyCallHandler *
empathy_call_handler_new_for_channel (EmpathyTpCall *call)
{
return EMPATHY_CALL_HANDLER (g_object_new (EMPATHY_TYPE_CALL_HANDLER,
- "tp-call", call, NULL));
+ "tp-call", call,
+ "initial-video", empathy_tp_call_is_receiving_video (call),
+ NULL));
}
void
@@ -577,3 +579,40 @@ empathy_call_handler_start_call (EmpathyCallHandler *handler)
g_object_unref (dispatcher);
}
+/**
+ * empathy_call_handler_stop_call:
+ * @handler: an #EmpathyCallHandler
+ *
+ * Closes the #EmpathyCallHandler's call and frees its resources.
+ */
+void
+empathy_call_handler_stop_call (EmpathyCallHandler *handler)
+{
+ EmpathyCallHandlerPriv *priv = GET_PRIV (handler);
+
+ if (priv->call != NULL)
+ {
+ empathy_tp_call_close (priv->call);
+ g_object_unref (priv->call);
+ }
+
+ priv->call = NULL;
+}
+
+/**
+ * empathy_call_handler_has_initial_video:
+ * @handler: an #EmpathyCallHandler
+ *
+ * Return %TRUE if the call managed by this #EmpathyCallHandler was
+ * created with video enabled
+ *
+ * Return value: %TRUE if the call was created as a video conversation.
+ */
+gboolean
+empathy_call_handler_has_initial_video (EmpathyCallHandler *handler)
+{
+ EmpathyCallHandlerPriv *priv = GET_PRIV (handler);
+
+ return priv->initial_video;
+}
+
diff --git a/libempathy/empathy-call-handler.h b/libempathy/empathy-call-handler.h
index 9a039f06a..1f67fe56b 100644
--- a/libempathy/empathy-call-handler.h
+++ b/libempathy/empathy-call-handler.h
@@ -1,6 +1,6 @@
/*
* empathy-call-handler.h - Header for EmpathyCallHandler
- * Copyright (C) 2008 Collabora Ltd.
+ * Copyright (C) 2008-2009 Collabora Ltd.
* @author Sjoerd Simons <sjoerd.simons@collabora.co.uk>
*
* This library is free software; you can redistribute it and/or
@@ -71,6 +71,9 @@ EmpathyCallHandler * empathy_call_handler_new_for_channel (
EmpathyTpCall *call);
void empathy_call_handler_start_call (EmpathyCallHandler *handler);
+void empathy_call_handler_stop_call (EmpathyCallHandler *handler);
+
+gboolean empathy_call_handler_has_initial_video (EmpathyCallHandler *handler);
void empathy_call_handler_bus_message (EmpathyCallHandler *handler,
GstBus *bus, GstMessage *message);
diff --git a/libempathy/empathy-chatroom-manager.c b/libempathy/empathy-chatroom-manager.c
index 3bdc5f154..44416670e 100644
--- a/libempathy/empathy-chatroom-manager.c
+++ b/libempathy/empathy-chatroom-manager.c
@@ -506,6 +506,27 @@ empathy_chatroom_manager_add (EmpathyChatroomManager *manager,
return FALSE;
}
+static void
+chatroom_manager_remove_link (EmpathyChatroomManager *manager,
+ GList *l)
+{
+ EmpathyChatroomManagerPriv *priv;
+ EmpathyChatroom *chatroom;
+
+ priv = GET_PRIV (manager);
+
+ chatroom = l->data;
+
+ if (empathy_chatroom_is_favorite (chatroom))
+ reset_save_timeout (manager);
+
+ g_signal_emit (manager, signals[CHATROOM_REMOVED], 0, chatroom);
+ g_signal_handlers_disconnect_by_func (chatroom, chatroom_changed_cb, manager);
+
+ priv->chatrooms = g_list_delete_link (priv->chatrooms, l);
+ g_object_unref (chatroom);
+}
+
void
empathy_chatroom_manager_remove (EmpathyChatroomManager *manager,
EmpathyChatroom *chatroom)
@@ -527,15 +548,7 @@ empathy_chatroom_manager_remove (EmpathyChatroomManager *manager,
if (this_chatroom == chatroom ||
empathy_chatroom_equal (chatroom, this_chatroom))
{
- priv->chatrooms = g_list_delete_link (priv->chatrooms, l);
- if (empathy_chatroom_is_favorite (chatroom))
- reset_save_timeout (manager);
-
- g_signal_emit (manager, signals[CHATROOM_REMOVED], 0, this_chatroom);
- g_signal_handlers_disconnect_by_func (chatroom, chatroom_changed_cb,
- manager);
-
- g_object_unref (this_chatroom);
+ chatroom_manager_remove_link (manager, l);
break;
}
}
@@ -649,13 +662,16 @@ chatroom_manager_chat_destroyed_cb (EmpathyTpChat *chat,
continue;
empathy_chatroom_set_tp_chat (chatroom, NULL);
+
if (!empathy_chatroom_is_favorite (chatroom))
{
/* Remove the chatroom from the list, unless it's in the list of
* favourites..
* FIXME this policy should probably not be in libempathy */
- empathy_chatroom_manager_remove (manager, chatroom);
+ chatroom_manager_remove_link (manager, l);
}
+
+ break;
}
}
diff --git a/libempathy/empathy-chatroom.c b/libempathy/empathy-chatroom.c
index 6575bb998..147fca0a9 100644
--- a/libempathy/empathy-chatroom.c
+++ b/libempathy/empathy-chatroom.c
@@ -407,11 +407,11 @@ empathy_chatroom_get_name (EmpathyChatroom *chatroom)
g_return_val_if_fail (EMPATHY_IS_CHATROOM (chatroom), NULL);
priv = GET_PRIV (chatroom);
-
+
if (EMP_STR_EMPTY (priv->name)) {
return priv->room;
}
-
+
return priv->name;
}
diff --git a/libempathy/empathy-contact-manager.c b/libempathy/empathy-contact-manager.c
index 412087ec0..7af2bd349 100644
--- a/libempathy/empathy-contact-manager.c
+++ b/libempathy/empathy-contact-manager.c
@@ -103,7 +103,7 @@ contact_manager_invalidated_cb (TpProxy *connection,
list = g_hash_table_lookup (priv->lists, connection);
if (list) {
empathy_tp_contact_list_remove_all (list);
- g_hash_table_remove (priv->lists, connection);
+ g_hash_table_remove (priv->lists, connection);
}
}
@@ -503,7 +503,7 @@ contact_manager_remove_group (EmpathyContactList *manager,
const gchar *group)
{
EmpathyContactManagerPriv *priv = GET_PRIV (manager);
-
+
g_return_if_fail (EMPATHY_IS_CONTACT_MANAGER (manager));
g_hash_table_foreach (priv->lists,
@@ -533,7 +533,7 @@ empathy_contact_manager_can_add (EmpathyContactManager *manager,
{
EmpathyContactManagerPriv *priv = GET_PRIV (manager);
EmpathyTpContactList *list;
-
+
g_return_val_if_fail (EMPATHY_IS_CONTACT_MANAGER (manager), FALSE);
list = g_hash_table_lookup (priv->lists, connection);
diff --git a/libempathy/empathy-contact.c b/libempathy/empathy-contact.c
index 03ce8d28a..bad6ef470 100644
--- a/libempathy/empathy-contact.c
+++ b/libempathy/empathy-contact.c
@@ -830,17 +830,16 @@ static gchar *
contact_get_avatar_filename (EmpathyContact *contact,
const gchar *token)
{
- EmpathyContactPriv *priv = GET_PRIV (contact);
McAccount *account;
gchar *avatar_path;
gchar *avatar_file;
gchar *token_escaped;
gchar *contact_escaped;
- if (EMP_STR_EMPTY (priv->id))
+ if (EMP_STR_EMPTY (empathy_contact_get_id (contact)))
return NULL;
- contact_escaped = tp_escape_as_identifier (priv->id);
+ contact_escaped = tp_escape_as_identifier (empathy_contact_get_id (contact));
token_escaped = tp_escape_as_identifier (token);
account = empathy_contact_get_account (contact);
@@ -864,7 +863,7 @@ contact_get_avatar_filename (EmpathyContact *contact,
void
empathy_contact_load_avatar_data (EmpathyContact *contact,
- const guchar *data,
+ const guchar *data,
const gsize len,
const gchar *format,
const gchar *token)
@@ -880,13 +879,13 @@ empathy_contact_load_avatar_data (EmpathyContact *contact,
g_return_if_fail (!EMP_STR_EMPTY (token));
/* Load and set the avatar */
+ filename = contact_get_avatar_filename (contact, token);
avatar = empathy_avatar_new (g_memdup (data, len), len, g_strdup (format),
- g_strdup (token));
+ g_strdup (token), filename);
empathy_contact_set_avatar (contact, avatar);
empathy_avatar_unref (avatar);
/* Save to cache if not yet in it */
- filename = contact_get_avatar_filename (contact, token);
if (filename && !g_file_test (filename, G_FILE_TEST_EXISTS))
{
if (!empathy_avatar_save_to_file (avatar, filename, &error))
@@ -898,7 +897,6 @@ empathy_contact_load_avatar_data (EmpathyContact *contact,
else
DEBUG ("Avatar saved to %s", filename);
}
- g_free (filename);
}
gboolean
@@ -929,13 +927,11 @@ empathy_contact_load_avatar_cache (EmpathyContact *contact,
if (data)
{
DEBUG ("Avatar loaded from %s", filename);
- avatar = empathy_avatar_new (data, len, NULL, g_strdup (token));
+ avatar = empathy_avatar_new (data, len, NULL, g_strdup (token), filename);
empathy_contact_set_avatar (contact, avatar);
empathy_avatar_unref (avatar);
}
- g_free (filename);
-
return data != NULL;
}
@@ -954,11 +950,25 @@ empathy_avatar_get_type (void)
return type_id;
}
+/**
+ * empathy_avatar_new:
+ * @data: the avatar data
+ * @len: the size of avatar data
+ * @format: the mime type of the avatar image
+ * @token: the token of the avatar
+ * @filename: the filename where the avatar is stored in cache
+ *
+ * Create a #EmpathyAvatar from the provided data. This function takes the
+ * ownership of @data, @format, @token and @filename.
+ *
+ * Returns: a new #EmpathyAvatar
+ */
EmpathyAvatar *
empathy_avatar_new (guchar *data,
gsize len,
gchar *format,
- gchar *token)
+ gchar *token,
+ gchar *filename)
{
EmpathyAvatar *avatar;
@@ -967,6 +977,7 @@ empathy_avatar_new (guchar *data,
avatar->len = len;
avatar->format = format;
avatar->token = token;
+ avatar->filename = filename;
avatar->refcount = 1;
return avatar;
@@ -1071,3 +1082,40 @@ empathy_contact_set_location (EmpathyContact *contact,
priv->location = g_hash_table_ref (location);
g_object_notify (G_OBJECT (contact), "location");
}
+
+/**
+ * empathy_contact_equal:
+ * @contact1: an #EmpathyContact
+ * @contact2: an #EmpathyContact
+ *
+ * Returns FALSE if one of the contacts is NULL but the other is not.
+ * Otherwise returns TRUE if both pointer are equal or if they bith
+ * refer to the same id.
+ * It's only necessary to call this function if your contact objects
+ * come from logs where contacts are created dynamically and comparing
+ * pointers is not enough.
+ */
+gboolean
+empathy_contact_equal (gconstpointer contact1,
+ gconstpointer contact2)
+{
+ EmpathyContact *c1;
+ EmpathyContact *c2;
+ const gchar *id1;
+ const gchar *id2;
+
+ if ((contact1 == NULL) != (contact2 == NULL)) {
+ return FALSE;
+ }
+ if (contact1 == contact2) {
+ return TRUE;
+ }
+ c1 = EMPATHY_CONTACT (contact1);
+ c2 = EMPATHY_CONTACT (contact2);
+ id1 = empathy_contact_get_id (c1);
+ id2 = empathy_contact_get_id (c2);
+ if (!tp_strdiff (id1, id2)) {
+ return TRUE;
+ }
+ return FALSE;
+}
diff --git a/libempathy/empathy-contact.h b/libempathy/empathy-contact.h
index ff8d426e2..f88831342 100644
--- a/libempathy/empathy-contact.h
+++ b/libempathy/empathy-contact.h
@@ -55,6 +55,7 @@ typedef struct {
gsize len;
gchar *format;
gchar *token;
+ gchar *filename;
guint refcount;
} EmpathyAvatar;
@@ -114,7 +115,8 @@ GType empathy_avatar_get_type (void) G_GNUC_CONST;
EmpathyAvatar * empathy_avatar_new (guchar *data,
gsize len,
gchar *format,
- gchar *token);
+ gchar *token,
+ gchar *filename);
EmpathyAvatar * empathy_avatar_ref (EmpathyAvatar *avatar);
void empathy_avatar_unref (EmpathyAvatar *avatar);
@@ -123,7 +125,9 @@ gboolean empathy_avatar_save_to_file (EmpathyAvatar *avatar,
GHashTable * empathy_contact_get_location (EmpathyContact *contact);
void empathy_contact_set_location (EmpathyContact *contact,
- GHashTable *location);
+ GHashTable *location);
+gboolean empathy_contact_equal (gconstpointer contact1,
+ gconstpointer contact2);
G_END_DECLS
diff --git a/libempathy/empathy-debug.c b/libempathy/empathy-debug.c
index bcfa25deb..99111deec 100644
--- a/libempathy/empathy-debug.c
+++ b/libempathy/empathy-debug.c
@@ -1,4 +1,4 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
/*
* Copyright (C) 2007 Collabora Ltd.
* Copyright (C) 2007 Nokia Corporation
@@ -33,6 +33,8 @@
#include "empathy-debug.h"
+#include "empathy-debugger.h"
+
#ifdef ENABLE_DEBUG
static EmpathyDebugFlags flags = 0;
@@ -75,18 +77,74 @@ empathy_debug_flag_is_set (EmpathyDebugFlags flag)
return (flag & flags) != 0;
}
+GHashTable *flag_to_keys = NULL;
+
+static const gchar *
+debug_flag_to_key (EmpathyDebugFlags flag)
+{
+ if (flag_to_keys == NULL)
+ {
+ guint i;
+
+ flag_to_keys = g_hash_table_new_full (g_direct_hash, g_direct_equal,
+ NULL, g_free);
+
+ for (i = 0; keys[i].value; i++)
+ {
+ GDebugKey key = (GDebugKey) keys[i];
+ g_hash_table_insert (flag_to_keys, GUINT_TO_POINTER (key.value),
+ g_strdup (key.key));
+ }
+ }
+
+ return g_hash_table_lookup (flag_to_keys, GUINT_TO_POINTER (flag));
+}
+
+void
+empathy_debug_free (void)
+{
+ if (flag_to_keys == NULL)
+ return;
+
+ g_hash_table_destroy (flag_to_keys);
+ flag_to_keys = NULL;
+}
+
+static void
+log_to_debugger (EmpathyDebugFlags flag,
+ const gchar *message)
+{
+ EmpathyDebugger *dbg = empathy_debugger_get_singleton ();
+ gchar *domain;
+ GTimeVal now;
+
+ g_get_current_time (&now);
+
+ domain = g_strdup_printf ("%s/%s", G_LOG_DOMAIN, debug_flag_to_key (flag));
+
+ empathy_debugger_add_message (dbg, &now, domain, G_LOG_LEVEL_DEBUG, message);
+
+ g_free (domain);
+}
+
void
empathy_debug (EmpathyDebugFlags flag,
- const gchar *format,
- ...)
+ const gchar *format,
+ ...)
{
+ gchar *message;
+ va_list args;
+
+ va_start (args, format);
+ message = g_strdup_vprintf (format, args);
+ va_end (args);
+
+ log_to_debugger (flag, message);
+
if (flag & flags)
- {
- va_list args;
- va_start (args, format);
- g_logv (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, format, args);
- va_end (args);
- }
+ g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "%s", message);
+
+ g_free (message);
}
#else
diff --git a/libempathy/empathy-debug.h b/libempathy/empathy-debug.h
index 787264dd0..9df728922 100644
--- a/libempathy/empathy-debug.h
+++ b/libempathy/empathy-debug.h
@@ -1,4 +1,4 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
/*
* Copyright (C) 2007 Collabora Ltd.
* Copyright (C) 2007 Nokia Corporation
@@ -46,6 +46,7 @@ typedef enum
gboolean empathy_debug_flag_is_set (EmpathyDebugFlags flag);
void empathy_debug (EmpathyDebugFlags flag, const gchar *format, ...)
G_GNUC_PRINTF (2, 3);
+void empathy_debug_free (void);
void empathy_debug_set_flags (const gchar *flags_string);
G_END_DECLS
@@ -88,4 +89,7 @@ G_END_DECLS
#define DEBUGGING 0
#endif /* !defined (ENABLE_DEBUG) */
+
+#define gabble_debug_free() G_STMT_START { } G_STMT_END
+
#endif /* defined (DEBUG_FLAG) */
diff --git a/libempathy/empathy-debugger.c b/libempathy/empathy-debugger.c
new file mode 100644
index 000000000..04873120c
--- /dev/null
+++ b/libempathy/empathy-debugger.c
@@ -0,0 +1,270 @@
+/*
+ * Telepathy debug interface implementation
+ * Copyright (C) 2009 Collabora Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "empathy-debugger.h"
+#include "config.h"
+
+#include <telepathy-glib/dbus.h>
+
+#include "extensions/extensions.h"
+
+static EmpathyDebugger *singleton = NULL;
+
+static void
+debug_iface_init (gpointer g_iface, gpointer iface_data);
+
+G_DEFINE_TYPE_WITH_CODE (EmpathyDebugger, empathy_debugger, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (TP_TYPE_SVC_DBUS_PROPERTIES,
+ tp_dbus_properties_mixin_iface_init);
+ G_IMPLEMENT_INTERFACE (EMP_TYPE_SVC_DEBUG, debug_iface_init));
+
+/* properties */
+enum
+{
+ PROP_ENABLED = 1,
+ NUM_PROPERTIES
+};
+
+static EmpDebugLevel
+log_level_flags_to_debug_level (GLogLevelFlags level)
+{
+ if (level & G_LOG_LEVEL_ERROR)
+ return EMP_DEBUG_LEVEL_ERROR;
+ else if (level & G_LOG_LEVEL_CRITICAL)
+ return EMP_DEBUG_LEVEL_CRITICAL;
+ else if (level & G_LOG_LEVEL_WARNING)
+ return EMP_DEBUG_LEVEL_WARNING;
+ else if (level & G_LOG_LEVEL_MESSAGE)
+ return EMP_DEBUG_LEVEL_MESSAGE;
+ else if (level & G_LOG_LEVEL_INFO)
+ return EMP_DEBUG_LEVEL_INFO;
+ else if (level & G_LOG_LEVEL_DEBUG)
+ return EMP_DEBUG_LEVEL_DEBUG;
+ else
+ /* Fall back to DEBUG if all else fails */
+ return EMP_DEBUG_LEVEL_DEBUG;
+}
+
+static EmpathyDebugMessage *
+debug_message_new (GTimeVal *timestamp,
+ const gchar *domain,
+ GLogLevelFlags level,
+ const gchar *string)
+{
+ EmpathyDebugMessage *msg;
+
+ msg = g_slice_new0 (EmpathyDebugMessage);
+ msg->timestamp = timestamp->tv_sec + timestamp->tv_usec / 1e6;
+ msg->domain = g_strdup (domain);
+ msg->level = log_level_flags_to_debug_level (level);
+ msg->string = g_strdup (string);
+ return msg;
+}
+
+static void
+debug_message_free (EmpathyDebugMessage *msg)
+{
+ g_free (msg->domain);
+ g_free (msg->string);
+ g_slice_free (EmpathyDebugMessage, msg);
+}
+
+static void
+empathy_debugger_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ EmpathyDebugger *self = EMPATHY_DEBUGGER (object);
+
+ switch (property_id)
+ {
+ case PROP_ENABLED:
+ g_value_set_boolean (value, self->enabled);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ }
+}
+
+static void
+empathy_debugger_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ EmpathyDebugger *self = EMPATHY_DEBUGGER (object);
+
+ switch (property_id)
+ {
+ case PROP_ENABLED:
+ self->enabled = g_value_get_boolean (value);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ }
+}
+
+static void
+empathy_debugger_finalize (GObject *object)
+{
+ EmpathyDebugger *self = EMPATHY_DEBUGGER (object);
+
+ g_queue_foreach (self->messages, (GFunc) debug_message_free, NULL);
+ g_queue_free (self->messages);
+ self->messages = NULL;
+
+ G_OBJECT_CLASS (empathy_debugger_parent_class)->finalize (object);
+}
+
+static void
+empathy_debugger_class_init (EmpathyDebuggerClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ static TpDBusPropertiesMixinPropImpl debug_props[] = {
+ { "Enabled", "enabled", "enabled" },
+ { NULL }
+ };
+ static TpDBusPropertiesMixinIfaceImpl prop_interfaces[] = {
+ { EMP_IFACE_DEBUG,
+ tp_dbus_properties_mixin_getter_gobject_properties,
+ tp_dbus_properties_mixin_setter_gobject_properties,
+ debug_props,
+ },
+ { NULL }
+ };
+
+ object_class->get_property = empathy_debugger_get_property;
+ object_class->set_property = empathy_debugger_set_property;
+ object_class->finalize = empathy_debugger_finalize;
+
+ g_object_class_install_property (object_class, PROP_ENABLED,
+ g_param_spec_boolean ("enabled", "Enabled?",
+ "True if the new-debug-message signal is enabled.",
+ FALSE,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+ klass->dbus_props_class.interfaces = prop_interfaces;
+ tp_dbus_properties_mixin_class_init (object_class,
+ G_STRUCT_OFFSET (EmpathyDebuggerClass, dbus_props_class));
+}
+
+static void
+get_messages (EmpSvcDebug *self,
+ DBusGMethodInvocation *context)
+{
+ EmpathyDebugger *dbg = EMPATHY_DEBUGGER (self);
+ GPtrArray *messages;
+ static GType struct_type = 0;
+ GList *i;
+ guint j;
+
+ if (G_UNLIKELY (struct_type == 0))
+ {
+ struct_type = dbus_g_type_get_struct (
+ "GValueArray", G_TYPE_DOUBLE, G_TYPE_STRING, G_TYPE_UINT,
+ G_TYPE_STRING, G_TYPE_INVALID);
+ }
+
+ messages = g_ptr_array_sized_new (g_queue_get_length (dbg->messages));
+
+ for (i = dbg->messages->head; i; i = i->next)
+ {
+ GValue gvalue = { 0 };
+ EmpathyDebugMessage *message = (EmpathyDebugMessage *) i->data;
+
+ g_value_init (&gvalue, struct_type);
+ g_value_take_boxed (&gvalue,
+ dbus_g_type_specialized_construct (struct_type));
+ dbus_g_type_struct_set (&gvalue,
+ 0, message->timestamp,
+ 1, message->domain,
+ 2, message->level,
+ 3, message->string,
+ G_MAXUINT);
+ g_ptr_array_add (messages, g_value_get_boxed (&gvalue));
+ }
+
+ emp_svc_debug_return_from_get_messages (context, messages);
+
+ for (j = 0; j < messages->len; j++)
+ g_boxed_free (struct_type, messages->pdata[j]);
+
+ g_ptr_array_free (messages, TRUE);
+}
+
+static void
+debug_iface_init (gpointer g_iface,
+ gpointer iface_data)
+{
+ EmpSvcDebugClass *klass = (EmpSvcDebugClass *) g_iface;
+
+ emp_svc_debug_implement_get_messages (klass, get_messages);
+}
+
+static void
+empathy_debugger_init (EmpathyDebugger *self)
+{
+ self->messages = g_queue_new ();
+}
+
+EmpathyDebugger *
+empathy_debugger_get_singleton (void)
+{
+ if (G_UNLIKELY (singleton == NULL))
+ {
+ DBusGConnection *bus;
+
+ singleton = g_object_new (EMPATHY_TYPE_DEBUGGER, NULL);
+ bus = tp_get_bus ();
+ dbus_g_connection_register_g_object (bus,
+ "/org/freedesktop/Telepathy/debug", (GObject *) singleton);
+ }
+
+ return singleton;
+}
+
+void
+empathy_debugger_add_message (EmpathyDebugger *self,
+ GTimeVal *timestamp,
+ const gchar *domain,
+ GLogLevelFlags level,
+ const gchar *string)
+{
+ EmpathyDebugMessage *new_msg;
+
+ if (g_queue_get_length (self->messages) >= DEBUG_MESSAGE_LIMIT)
+ {
+ EmpathyDebugMessage *old_head =
+ (EmpathyDebugMessage *) g_queue_pop_head (self->messages);
+
+ debug_message_free (old_head);
+ }
+
+ new_msg = debug_message_new (timestamp, domain, level, string);
+ g_queue_push_tail (self->messages, new_msg);
+
+ if (self->enabled)
+ {
+ emp_svc_debug_emit_new_debug_message (self, new_msg->timestamp,
+ domain, new_msg->level, string);
+ }
+}
diff --git a/libempathy/empathy-debugger.h b/libempathy/empathy-debugger.h
new file mode 100644
index 000000000..f3fdc7070
--- /dev/null
+++ b/libempathy/empathy-debugger.h
@@ -0,0 +1,88 @@
+/*
+ * header for Telepathy debug interface implementation
+ * Copyright (C) 2009 Collabora Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _EMPATHY_DEBUGGER
+#define _EMPATHY_DEBUGGER
+
+#include <glib-object.h>
+
+#include <telepathy-glib/properties-mixin.h>
+#include <telepathy-glib/dbus-properties-mixin.h>
+
+#include "extensions/extensions.h"
+
+G_BEGIN_DECLS
+
+#define EMPATHY_TYPE_DEBUGGER empathy_debugger_get_type()
+
+#define EMPATHY_DEBUGGER(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), EMPATHY_TYPE_DEBUGGER, EmpathyDebugger))
+
+#define EMPATHY_DEBUGGER_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), EMPATHY_TYPE_DEBUGGER, EmpathyDebuggerClass))
+
+#define EMPATHY_IS_DEBUGGER(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EMPATHY_TYPE_DEBUGGER))
+
+#define EMPATHY_IS_DEBUGGER_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), EMPATHY_TYPE_DEBUGGER))
+
+#define EMPATHY_DEBUGGER_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), EMPATHY_TYPE_DEBUGGER, EmpathyDebuggerClass))
+
+/* On the basis that messages are around 60 bytes on average, and that 50kb is
+ * a reasonable maximum size for a frame buffer.
+ */
+
+#define DEBUG_MESSAGE_LIMIT 800
+
+typedef struct {
+ gdouble timestamp;
+ gchar *domain;
+ EmpDebugLevel level;
+ gchar *string;
+} EmpathyDebugMessage;
+
+typedef struct {
+ GObject parent;
+
+ gboolean enabled;
+ GQueue *messages;
+} EmpathyDebugger;
+
+typedef struct {
+ GObjectClass parent_class;
+ TpDBusPropertiesMixinClass dbus_props_class;
+} EmpathyDebuggerClass;
+
+GType empathy_debugger_get_type (void);
+
+EmpathyDebugger *
+empathy_debugger_get_singleton (void);
+
+void
+empathy_debugger_add_message (EmpathyDebugger *self,
+ GTimeVal *timestamp,
+ const gchar *domain,
+ GLogLevelFlags level,
+ const gchar *string);
+
+G_END_DECLS
+
+#endif /* _EMPATHY_DEBUGGER */
diff --git a/libempathy/empathy-dispatcher.c b/libempathy/empathy-dispatcher.c
index f46d15f80..b51df95fa 100644
--- a/libempathy/empathy-dispatcher.c
+++ b/libempathy/empathy-dispatcher.c
@@ -112,7 +112,16 @@ typedef struct
GHashTable *dispatched_channels;
/* ObjectPath -> EmpathyDispatchOperations */
GHashTable *dispatching_channels;
- /* ObjectPath -> EmpathyDispatchOperations */
+
+ /* ObjectPath -> EmpathyDispatchOperations
+ *
+ * This holds channels which were announced with NewChannel while we have an
+ * outstanding channel request for a channel of this type. On the Requests
+ * interface, CreateChannel and EnsureChannel are guaranteed by the spec to
+ * return before NewChannels is emitted, but there was no guarantee of the
+ * ordering of RequestChannel vs. NewChannel. So if necessary, channels are
+ * held in limbo here until we know whether they were requested.
+ */
GHashTable *outstanding_channels;
/* List of DispatcherRequestData */
GList *outstanding_requests;
@@ -523,8 +532,8 @@ dispatcher_flush_outstanding_operations (EmpathyDispatcher *self,
if (dispatcher_operation_can_start (self, operation, cd))
{
- dispatcher_start_dispatching (dispatcher, operation, cd);
g_hash_table_iter_remove (&iter);
+ dispatcher_start_dispatching (dispatcher, operation, cd);
}
}
}
diff --git a/libempathy/empathy-ft-handler.c b/libempathy/empathy-ft-handler.c
index ba81fd4c7..d24467b24 100644
--- a/libempathy/empathy-ft-handler.c
+++ b/libempathy/empathy-ft-handler.c
@@ -1149,9 +1149,25 @@ ft_handler_gfile_ready_cb (GObject *source,
if (error != NULL)
goto out;
+ if (g_file_info_get_file_type (info) != G_FILE_TYPE_REGULAR)
+ {
+ error = g_error_new_literal (EMPATHY_FT_ERROR_QUARK,
+ EMPATHY_FT_ERROR_INVALID_SOURCE_FILE,
+ _("The selected file is not a regular file"));
+ goto out;
+ }
+
+ priv->total_bytes = g_file_info_get_size (info);
+ if (priv->total_bytes == 0)
+ {
+ error = g_error_new_literal (EMPATHY_FT_ERROR_QUARK,
+ EMPATHY_FT_ERROR_EMPTY_SOURCE_FILE,
+ _("The selected file is empty"));
+ goto out;
+ }
+
priv->content_type = g_strdup (g_file_info_get_content_type (info));
priv->filename = g_strdup (g_file_info_get_display_name (info));
- priv->total_bytes = g_file_info_get_size (info);
g_file_info_get_modification_time (info, &mtime);
priv->mtime = mtime.tv_sec;
priv->transferred_bytes = 0;
@@ -1303,6 +1319,7 @@ empathy_ft_handler_new_outgoing (EmpathyContact *contact,
G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME ","
G_FILE_ATTRIBUTE_STANDARD_SIZE ","
G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE ","
+ G_FILE_ATTRIBUTE_STANDARD_TYPE ","
G_FILE_ATTRIBUTE_TIME_MODIFIED,
G_FILE_QUERY_INFO_NONE, G_PRIORITY_DEFAULT,
NULL, (GAsyncReadyCallback) ft_handler_gfile_ready_cb, data);
diff --git a/libempathy/empathy-idle.c b/libempathy/empathy-idle.c
index 92ab9f39f..2ed1440fc 100644
--- a/libempathy/empathy-idle.c
+++ b/libempathy/empathy-idle.c
@@ -68,6 +68,14 @@ typedef enum {
NM_STATE_DISCONNECTED
} NMState;
+typedef enum {
+ SESSION_STATUS_AVAILABLE,
+ SESSION_STATUS_INVISIBLE,
+ SESSION_STATUS_BUSY,
+ SESSION_STATUS_IDLE,
+ SESSION_STATUS_UNKNOWN
+} SessionStatus;
+
enum {
PROP_0,
PROP_STATE,
@@ -91,6 +99,10 @@ idle_presence_changed_cb (MissionControl *mc,
priv = GET_PRIV (idle);
+ if (state == TP_CONNECTION_PRESENCE_TYPE_UNSET)
+ /* Assume our presence is offline if MC reports UNSET */
+ state = TP_CONNECTION_PRESENCE_TYPE_OFFLINE;
+
DEBUG ("Presence changed to '%s' (%d)", status, state);
g_free (priv->status);
@@ -147,14 +159,17 @@ idle_ext_away_start (EmpathyIdle *idle)
}
static void
-idle_session_idle_changed_cb (DBusGProxy *gs_proxy,
- gboolean is_idle,
- EmpathyIdle *idle)
+idle_session_status_changed_cb (DBusGProxy *gs_proxy,
+ SessionStatus status,
+ EmpathyIdle *idle)
{
EmpathyIdlePriv *priv;
+ gboolean is_idle;
priv = GET_PRIV (idle);
+ is_idle = (status == SESSION_STATUS_IDLE);
+
DEBUG ("Session idle state changed, %s -> %s",
priv->is_idle ? "yes" : "no",
is_idle ? "yes" : "no");
@@ -465,7 +480,10 @@ empathy_idle_init (EmpathyIdle *idle)
if (error) {
DEBUG ("Error getting actual presence: %s", error->message);
- priv->state = TP_CONNECTION_PRESENCE_TYPE_UNSET;
+ /* Fallback to OFFLINE as that's what mission_control_get_presence_actual
+ does. This also ensure to always display the status icon (there is no
+ unset presence icon). */
+ priv->state = TP_CONNECTION_PRESENCE_TYPE_OFFLINE;
g_clear_error (&error);
}
priv->status = mission_control_get_presence_message_actual (priv->mc, &error);
@@ -485,15 +503,14 @@ empathy_idle_init (EmpathyIdle *idle)
idle, NULL);
priv->gs_proxy = dbus_g_proxy_new_for_name (tp_get_bus (),
- "org.gnome.ScreenSaver",
- "/org/gnome/ScreenSaver",
- "org.gnome.ScreenSaver");
+ "org.gnome.SessionManager",
+ "/org/gnome/SessionManager/Presence",
+ "org.gnome.SessionManager.Presence");
if (priv->gs_proxy) {
- dbus_g_proxy_add_signal (priv->gs_proxy, "SessionIdleChanged",
- G_TYPE_BOOLEAN,
- G_TYPE_INVALID);
- dbus_g_proxy_connect_signal (priv->gs_proxy, "SessionIdleChanged",
- G_CALLBACK (idle_session_idle_changed_cb),
+ dbus_g_proxy_add_signal (priv->gs_proxy, "StatusChanged",
+ G_TYPE_UINT, G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal (priv->gs_proxy, "StatusChanged",
+ G_CALLBACK (idle_session_status_changed_cb),
idle, NULL);
} else {
DEBUG ("Failed to get gs proxy");
@@ -726,7 +743,7 @@ empathy_idle_set_use_nm (EmpathyIdle *idle,
g_clear_error (&error);
nm_status = NM_STATE_ASLEEP;
}
-
+
idle_nm_state_change_cb (priv->nm_proxy, nm_status, idle);
} else {
priv->nm_connected = TRUE;
diff --git a/libempathy/empathy-status-presets.c b/libempathy/empathy-status-presets.c
index 9f9a2030b..135212cc5 100644
--- a/libempathy/empathy-status-presets.c
+++ b/libempathy/empathy-status-presets.c
@@ -131,16 +131,17 @@ status_presets_file_parse (const gchar *filename)
if (state_str) {
state = empathy_presence_from_str (state_str);
-
- if (is_default) {
- DEBUG ("Default status preset state is:"
- " '%s', status:'%s'", state_str,
- status);
-
- status_presets_set_default (state, status);
- } else {
- preset = status_preset_new (state, status);
- presets = g_list_append (presets, preset);
+ if (empathy_status_presets_is_valid (state)) {
+ if (is_default) {
+ DEBUG ("Default status preset state is:"
+ " '%s', status:'%s'", state_str,
+ status);
+
+ status_presets_set_default (state, status);
+ } else {
+ preset = status_preset_new (state, status);
+ presets = g_list_append (presets, preset);
+ }
}
}
@@ -405,3 +406,31 @@ empathy_status_presets_clear_default (void)
status_presets_file_save ();
}
+
+/**
+ * empathy_status_presets_is_valid:
+ * @state: a #TpConnectionPresenceType
+ *
+ * Check if a presence type can be used as a preset.
+ *
+ * Returns: %TRUE if the presence type can be used as a preset.
+ */
+gboolean
+empathy_status_presets_is_valid (TpConnectionPresenceType state)
+{
+ switch (state) {
+ case TP_CONNECTION_PRESENCE_TYPE_UNSET:
+ case TP_CONNECTION_PRESENCE_TYPE_OFFLINE:
+ case TP_CONNECTION_PRESENCE_TYPE_UNKNOWN:
+ case TP_CONNECTION_PRESENCE_TYPE_ERROR:
+ return FALSE;
+
+ case TP_CONNECTION_PRESENCE_TYPE_AVAILABLE:
+ case TP_CONNECTION_PRESENCE_TYPE_AWAY:
+ case TP_CONNECTION_PRESENCE_TYPE_EXTENDED_AWAY:
+ case TP_CONNECTION_PRESENCE_TYPE_HIDDEN:
+ case TP_CONNECTION_PRESENCE_TYPE_BUSY:
+ return TRUE;
+ }
+ return FALSE;
+}
diff --git a/libempathy/empathy-status-presets.h b/libempathy/empathy-status-presets.h
index 335dbcfcb..331c630d5 100644
--- a/libempathy/empathy-status-presets.h
+++ b/libempathy/empathy-status-presets.h
@@ -40,6 +40,7 @@ const gchar * empathy_status_presets_get_default_status (void);
void empathy_status_presets_set_default (TpConnectionPresenceType state,
const gchar *status);
void empathy_status_presets_clear_default (void);
+gboolean empathy_status_presets_is_valid (TpConnectionPresenceType state);
G_END_DECLS
diff --git a/libempathy/empathy-time.c b/libempathy/empathy-time.c
index 64350404c..19397e7a9 100644
--- a/libempathy/empathy-time.c
+++ b/libempathy/empathy-time.c
@@ -42,7 +42,7 @@ empathy_time_get_local_time (struct tm *tm)
{
const gchar *timezone;
time_t t;
-
+
timezone = g_getenv ("TZ");
g_setenv ("TZ", "", TRUE);
@@ -152,6 +152,11 @@ empathy_time_to_string_relative (time_t then)
return g_strdup_printf (ngettext ("%d day ago",
"%d days ago", seconds), seconds);
}
+ else if (seconds < (60 * 60 * 24 * 30)) {
+ seconds /= 60 * 60 * 24 * 7;
+ return g_strdup_printf (ngettext ("%d week ago",
+ "%d weeks ago", seconds), seconds);
+ }
else {
seconds /= 60 * 60 * 24 * 30;
return g_strdup_printf (ngettext ("%d month ago",
diff --git a/libempathy/empathy-tp-call.c b/libempathy/empathy-tp-call.c
index 2971e0ffc..eb70c1a87 100644
--- a/libempathy/empathy-tp-call.c
+++ b/libempathy/empathy-tp-call.c
@@ -672,3 +672,40 @@ empathy_tp_call_has_dtmf (EmpathyTpCall *call)
TP_IFACE_QUARK_CHANNEL_INTERFACE_DTMF);
}
+/**
+ * empathy_tp_call_is_receiving_video:
+ * @call: the call
+ *
+ * Indicates if the call is receiving video or not.
+ *
+ * Returns: %TRUE if the call is currently receiving video, %FALSE otherwise.
+ */
+gboolean
+empathy_tp_call_is_receiving_video (EmpathyTpCall *call)
+{
+ EmpathyTpCallPriv *priv = GET_PRIV (call);
+
+ g_return_val_if_fail (EMPATHY_IS_TP_CALL (call), FALSE);
+
+ return priv->video->direction & TP_MEDIA_STREAM_DIRECTION_RECEIVE ?
+ TRUE : FALSE;
+}
+
+/**
+ * empathy_tp_call_is_sending_video:
+ * @call: the call
+ *
+ * Indicates if the call is sending video or not.
+ *
+ * Returns: %TRUE if the call is currently sending video, %FALSE otherwise.
+ */
+gboolean
+empathy_tp_call_is_sending_video (EmpathyTpCall *call)
+{
+ EmpathyTpCallPriv *priv = GET_PRIV (call);
+
+ g_return_val_if_fail (EMPATHY_IS_TP_CALL (call), FALSE);
+
+ return priv->video->direction & TP_MEDIA_STREAM_DIRECTION_SEND ?
+ TRUE : FALSE;
+}
diff --git a/libempathy/empathy-tp-call.h b/libempathy/empathy-tp-call.h
index 406ed1c3f..a00fe3e40 100644
--- a/libempathy/empathy-tp-call.h
+++ b/libempathy/empathy-tp-call.h
@@ -85,6 +85,8 @@ void empathy_tp_call_request_video_stream_direction (EmpathyTpCall *call,
void empathy_tp_call_start_tone (EmpathyTpCall *call, TpDTMFEvent event);
void empathy_tp_call_stop_tone (EmpathyTpCall *call);
gboolean empathy_tp_call_has_dtmf (EmpathyTpCall *call);
+gboolean empathy_tp_call_is_receiving_video (EmpathyTpCall *call);
+gboolean empathy_tp_call_is_sending_video (EmpathyTpCall *call);
G_END_DECLS
diff --git a/libempathy/empathy-tp-chat.c b/libempathy/empathy-tp-chat.c
index 794e3e3b7..ac61392e0 100644
--- a/libempathy/empathy-tp-chat.c
+++ b/libempathy/empathy-tp-chat.c
@@ -993,7 +993,7 @@ tp_chat_constructor (GType type,
/* Get initial member contacts */
members = tp_channel_group_get_members (priv->channel);
- handles = tp_intset_to_array (members);
+ handles = tp_intset_to_array (members);
empathy_tp_contact_factory_get_from_handles (priv->factory,
handles->len, (TpHandle *) handles->data,
tp_chat_got_added_contacts_cb, NULL, NULL, chat);
diff --git a/libempathy/empathy-tp-contact-list.c b/libempathy/empathy-tp-contact-list.c
index 58cb89cbe..cdb0431c4 100644
--- a/libempathy/empathy-tp-contact-list.c
+++ b/libempathy/empathy-tp-contact-list.c
@@ -205,7 +205,7 @@ tp_contact_list_group_members_changed_cb (TpChannel *channel,
g_signal_emit_by_name (list, "groups-changed", contact,
group_name,
TRUE);
- }
+ }
for (i = 0; i < removed->len; i++) {
EmpathyContact *contact;
@@ -224,7 +224,7 @@ tp_contact_list_group_members_changed_cb (TpChannel *channel,
g_signal_emit_by_name (list, "groups-changed", contact,
group_name,
FALSE);
- }
+ }
}
static void
diff --git a/libempathy/empathy-tp-file.c b/libempathy/empathy-tp-file.c
index 3a5826868..e60b2999d 100644
--- a/libempathy/empathy-tp-file.c
+++ b/libempathy/empathy-tp-file.c
@@ -26,6 +26,7 @@
#include <string.h>
#include <unistd.h>
#include <errno.h>
+#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
@@ -36,6 +37,7 @@
#include <gio/gunixinputstream.h>
#include <gio/gunixoutputstream.h>
+#include <telepathy-glib/gtypes.h>
#include <telepathy-glib/proxy-subclass.h>
#include <telepathy-glib/util.h>
@@ -71,11 +73,14 @@ typedef struct {
/* org.freedesktop.Telepathy.Channel.Type.FileTransfer D-Bus properties */
TpFileTransferState state;
TpFileTransferStateChangeReason state_change_reason;
+ TpSocketAddressType socket_address_type;
+ TpSocketAccessControl socket_access_control;
/* transfer properties */
gboolean incoming;
time_t start_time;
- GArray *unix_socket_path;
+ GArray *socket_address;
+ guint port;
guint64 offset;
/* GCancellable we're passed when offering/accepting the transfer */
@@ -124,6 +129,54 @@ tp_file_get_state_cb (TpProxy *proxy,
}
static void
+tp_file_get_available_socket_types_cb (TpProxy *proxy,
+ const GValue *value,
+ const GError *error,
+ gpointer user_data,
+ GObject *weak_object)
+{
+ EmpathyTpFilePriv *priv = GET_PRIV (weak_object);
+ GHashTable *socket_types;
+ GArray *access_controls;
+
+ if (error != NULL ||
+ !G_VALUE_HOLDS (value, TP_HASH_TYPE_SUPPORTED_SOCKET_MAP))
+ {
+ /* set a default value */
+ priv->socket_address_type = TP_SOCKET_ADDRESS_TYPE_UNIX;
+ priv->socket_access_control = TP_SOCKET_ACCESS_CONTROL_LOCALHOST;
+ goto out;
+ }
+
+ socket_types = g_value_get_boxed (value);
+
+ /* here UNIX is preferred to IPV4 */
+ if ((access_controls = g_hash_table_lookup (socket_types,
+ GUINT_TO_POINTER (TP_SOCKET_ADDRESS_TYPE_UNIX))) != NULL)
+ {
+ priv->socket_address_type = TP_SOCKET_ADDRESS_TYPE_UNIX;
+ priv->socket_access_control = TP_SOCKET_ACCESS_CONTROL_LOCALHOST;
+ goto out;
+ }
+
+ if ((access_controls = g_hash_table_lookup (socket_types,
+ GUINT_TO_POINTER (TP_SOCKET_ADDRESS_TYPE_IPV4))) != NULL)
+ {
+ priv->socket_address_type = TP_SOCKET_ADDRESS_TYPE_IPV4;
+
+ /* TODO: we should prefer PORT over LOCALHOST when the CM will
+ * support it.
+ */
+
+ priv->socket_access_control = TP_SOCKET_ACCESS_CONTROL_LOCALHOST;
+ }
+
+out:
+ DEBUG ("Socket address type: %u, access control %u",
+ priv->socket_address_type, priv->socket_access_control);
+}
+
+static void
tp_file_invalidated_cb (TpProxy *proxy,
guint domain,
gint code,
@@ -206,12 +259,35 @@ splice_stream_ready_cb (GObject *source,
static void
tp_file_start_transfer (EmpathyTpFile *tp_file)
{
- gint fd;
- struct sockaddr_un addr;
+ gint fd, domain, res = 0;
GError *error = NULL;
+ struct sockaddr *my_addr = NULL;
+ size_t my_size = 0;
EmpathyTpFilePriv *priv = GET_PRIV (tp_file);
- fd = socket (PF_UNIX, SOCK_STREAM, 0);
+ if (priv->socket_address_type == TP_SOCKET_ADDRESS_TYPE_UNIX)
+ {
+ domain = AF_UNIX;
+ }
+ else if (priv->socket_address_type == TP_SOCKET_ADDRESS_TYPE_IPV4)
+ {
+ domain = AF_INET;
+ }
+ else
+ {
+ error = g_error_new_literal (EMPATHY_FT_ERROR_QUARK,
+ EMPATHY_FT_ERROR_NOT_SUPPORTED, _("Socket type not supported"));
+
+ DEBUG ("Socket not supported, closing channel");
+
+ ft_operation_close_with_error (tp_file, error);
+ g_clear_error (&error);
+
+ return;
+ }
+
+ fd = socket (domain, SOCK_STREAM, 0);
+
if (fd < 0)
{
int code = errno;
@@ -227,12 +303,34 @@ tp_file_start_transfer (EmpathyTpFile *tp_file)
return;
}
- memset (&addr, 0, sizeof (addr));
- addr.sun_family = AF_UNIX;
- strncpy (addr.sun_path, priv->unix_socket_path->data,
- priv->unix_socket_path->len);
+ if (priv->socket_address_type == TP_SOCKET_ADDRESS_TYPE_UNIX)
+ {
+ struct sockaddr_un addr;
+
+ memset (&addr, 0, sizeof (addr));
+ addr.sun_family = domain;
+ strncpy (addr.sun_path, priv->socket_address->data,
+ priv->socket_address->len);
+
+ my_addr = (struct sockaddr *) &addr;
+ my_size = sizeof (addr);
+ }
+ else if (priv->socket_address_type == TP_SOCKET_ADDRESS_TYPE_IPV4)
+ {
+ struct sockaddr_in addr;
+
+ memset (&addr, 0, sizeof (addr));
+ addr.sin_family = domain;
+ inet_pton (AF_INET, priv->socket_address->data, &addr.sin_addr);
+ addr.sin_port = htons (priv->port);
+
+ my_addr = (struct sockaddr *) &addr;
+ my_size = sizeof (addr);
+ }
+
+ res = connect (fd, my_addr, my_size);
- if (connect (fd, (struct sockaddr*) &addr, sizeof (addr)) < 0)
+ if (res < 0)
{
int code = errno;
@@ -354,7 +452,7 @@ tp_file_state_changed_cb (TpChannel *proxy,
* data transfer but are just an observer for the channel.
*/
if (state == TP_FILE_TRANSFER_STATE_OPEN &&
- priv->unix_socket_path != NULL)
+ priv->socket_address != NULL)
tp_file_start_transfer (EMPATHY_TP_FILE (weak_object));
if (state == TP_FILE_TRANSFER_STATE_COMPLETED)
@@ -407,13 +505,14 @@ ft_operation_provide_or_accept_file_cb (TpChannel *proxy,
* report the method error.
*/
g_clear_error (&myerr);
- myerr = g_error_copy (error);
}
+
+ myerr = g_error_copy (error);
}
if (myerr != NULL)
{
- DEBUG ("Error: %s", error->message);
+ DEBUG ("Error: %s", myerr->message);
ft_operation_close_with_error (tp_file, myerr);
g_clear_error (&myerr);
return;
@@ -421,7 +520,7 @@ ft_operation_provide_or_accept_file_cb (TpChannel *proxy,
if (G_VALUE_TYPE (address) == DBUS_TYPE_G_UCHAR_ARRAY)
{
- priv->unix_socket_path = g_value_dup_boxed (address);
+ priv->socket_address = g_value_dup_boxed (address);
}
else if (G_VALUE_TYPE (address) == G_TYPE_STRING)
{
@@ -430,12 +529,32 @@ ft_operation_provide_or_accept_file_cb (TpChannel *proxy,
const gchar *path;
path = g_value_get_string (address);
- priv->unix_socket_path = g_array_sized_new (TRUE, FALSE, sizeof (gchar),
- strlen (path));
- g_array_insert_vals (priv->unix_socket_path, 0, path, strlen (path));
+ priv->socket_address = g_array_sized_new (TRUE, FALSE, sizeof (gchar),
+ strlen (path));
+ g_array_insert_vals (priv->socket_address, 0, path, strlen (path));
+ }
+ else if (G_VALUE_TYPE (address) == TP_STRUCT_TYPE_SOCKET_ADDRESS_IPV4)
+ {
+ GValueArray *val_array;
+ GValue *v;
+ const char *addr;
+
+ val_array = g_value_get_boxed (address);
+
+ /* IPV4 address */
+ v = g_value_array_get_nth (val_array, 0);
+ addr = g_value_get_string (v);
+ priv->socket_address = g_array_sized_new (TRUE, FALSE, sizeof (gchar),
+ strlen (addr));
+ g_array_insert_vals (priv->socket_address, 0, addr, strlen (addr));
+
+ /* port number */
+ v = g_value_array_get_nth (val_array, 1);
+ priv->port = g_value_get_uint (v);
}
- DEBUG ("Got unix socket path: %s", priv->unix_socket_path->data);
+ DEBUG ("Got socket address: %s, port (not zero if IPV4): %d",
+ priv->socket_address->data, priv->port);
/* if the channel is already open, start the transfer now, otherwise,
* wait for the state change signal.
@@ -445,6 +564,18 @@ ft_operation_provide_or_accept_file_cb (TpChannel *proxy,
}
static void
+initialize_empty_ac_variant (TpSocketAccessControl ac,
+ GValue *val)
+{
+ /* TODO: we will add more types here once we support PORT access control. */
+ if (ac == TP_SOCKET_ACCESS_CONTROL_LOCALHOST)
+ {
+ g_value_init (val, G_TYPE_STRING);
+ g_value_set_static_string (val, "");
+ }
+}
+
+static void
file_read_async_cb (GObject *source,
GAsyncResult *res,
gpointer user_data)
@@ -468,12 +599,14 @@ file_read_async_cb (GObject *source,
priv->in_stream = G_INPUT_STREAM (in_stream);
- g_value_init (&nothing, G_TYPE_STRING);
- g_value_set_static_string (&nothing, "");
+ /* we don't impose specific interface/port requirements even
+ * if we're not using UNIX sockets.
+ */
+ initialize_empty_ac_variant (priv->socket_access_control, &nothing);
tp_cli_channel_type_file_transfer_call_provide_file (
priv->channel, -1,
- TP_SOCKET_ADDRESS_TYPE_UNIX, TP_SOCKET_ACCESS_CONTROL_LOCALHOST,
+ priv->socket_address_type, priv->socket_access_control,
&nothing, ft_operation_provide_or_accept_file_cb,
NULL, NULL, G_OBJECT (tp_file));
}
@@ -503,11 +636,13 @@ file_replace_async_cb (GObject *source,
priv->out_stream = G_OUTPUT_STREAM (out_stream);
- g_value_init (&nothing, G_TYPE_STRING);
- g_value_set_static_string (&nothing, "");
+ /* we don't impose specific interface/port requirements even
+ * if we're not using UNIX sockets.
+ */
+ initialize_empty_ac_variant (priv->socket_access_control, &nothing);
tp_cli_channel_type_file_transfer_call_accept_file (priv->channel,
- -1, TP_SOCKET_ADDRESS_TYPE_UNIX, TP_SOCKET_ACCESS_CONTROL_LOCALHOST,
+ -1, priv->socket_address_type, priv->socket_access_control,
&nothing, priv->offset,
ft_operation_provide_or_accept_file_cb, NULL, NULL, G_OBJECT (tp_file));
}
@@ -592,10 +727,10 @@ do_finalize (GObject *object)
DEBUG ("%p", object);
- if (priv->unix_socket_path != NULL)
+ if (priv->socket_address != NULL)
{
- g_array_free (priv->unix_socket_path, TRUE);
- priv->unix_socket_path = NULL;
+ g_array_free (priv->socket_address, TRUE);
+ priv->socket_address = NULL;
}
G_OBJECT_CLASS (empathy_tp_file_parent_class)->finalize (object);
@@ -667,6 +802,10 @@ do_constructed (GObject *object)
-1, TP_IFACE_CHANNEL_TYPE_FILE_TRANSFER, "State", tp_file_get_state_cb,
NULL, NULL, object);
+ tp_cli_dbus_properties_call_get (priv->channel,
+ -1, TP_IFACE_CHANNEL_TYPE_FILE_TRANSFER, "AvailableSocketTypes",
+ tp_file_get_available_socket_types_cb, NULL, NULL, object);
+
priv->state_change_reason =
TP_FILE_TRANSFER_STATE_CHANGE_REASON_NONE;
}
diff --git a/libempathy/empathy-tp-file.h b/libempathy/empathy-tp-file.h
index 0d7d8efc0..b40b8c364 100644
--- a/libempathy/empathy-tp-file.h
+++ b/libempathy/empathy-tp-file.h
@@ -50,7 +50,9 @@ typedef enum {
EMPATHY_FT_ERROR_HASH_MISMATCH,
EMPATHY_FT_ERROR_TP_ERROR,
EMPATHY_FT_ERROR_SOCKET,
- EMPATHY_FT_ERROR_NOT_SUPPORTED
+ EMPATHY_FT_ERROR_NOT_SUPPORTED,
+ EMPATHY_FT_ERROR_INVALID_SOURCE_FILE,
+ EMPATHY_FT_ERROR_EMPTY_SOURCE_FILE
} EmpathyFTErrorEnum;
typedef struct _EmpathyTpFile EmpathyTpFile;
diff --git a/libempathy/empathy-tp-tube.c b/libempathy/empathy-tp-tube.c
deleted file mode 100644
index 7b9b1889e..000000000
--- a/libempathy/empathy-tp-tube.c
+++ /dev/null
@@ -1,669 +0,0 @@
-/*
- * Copyright (C) 2008 Collabora Ltd.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Authors: Guillaume Desmottes <guillaume.desmottes@collabora.co.uk>
- * Elliot Fairweather <elliot.fairweather@collabora.co.uk>
- */
-
-#include <config.h>
-
-#include <telepathy-glib/connection.h>
-#include <telepathy-glib/proxy.h>
-#include <telepathy-glib/util.h>
-#include <extensions/extensions.h>
-
-#include "empathy-enum-types.h"
-#include "empathy-tp-tube.h"
-#include "empathy-utils.h"
-
-#define DEBUG_FLAG EMPATHY_DEBUG_TP
-#include "empathy-debug.h"
-
-typedef struct {
- TpSocketAddressType type;
- EmpathyTpTubeAcceptStreamTubeCb *callback;
- gpointer user_data;
-} EmpathyTpTubeAcceptData;
-
-static EmpathyTpTubeAcceptData *
-new_empathy_tp_tube_accept_data (TpSocketAddressType type,
- EmpathyTpTubeAcceptStreamTubeCb *callback,
- gpointer user_data)
-{
- EmpathyTpTubeAcceptData *r;
-
- r = g_slice_new0 (EmpathyTpTubeAcceptData);
- r->type = type;
- r->callback = callback;
- r->user_data = user_data;
-
- return r;
-}
-
-static void
-free_empathy_tp_tube_accept_data (gpointer data)
-{
- g_slice_free (EmpathyTpTubeAcceptData, data);
-}
-
-
-typedef struct {
- EmpathyTpTubeReadyCb *callback;
- gpointer user_data;
- GDestroyNotify destroy;
- GObject *weak_object;
-} ReadyCbData;
-
-/**
- * SECTION:empathy-tp-tube
- * @title:EmpathyTpTube
- * @short_description: A wrapper around a Telepathy tube channel
- * @include: libempathy/empathy-tp-tube.h
- *
- * #EmpathyTpTube is a convenient object wrapping a Telepathy tube channel.
- */
-
-/**
- * EmpathyTpTube:
- * @parent: parent object
- *
- * An object wrapping a Telepathy tube channel.
- */
-
-#define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyTpTube)
-typedef struct
-{
- TpChannel *channel;
- TpTubeChannelState state;
- gboolean ready;
- GSList *ready_callbacks;
-} EmpathyTpTubePriv;
-
-enum
-{
- PROP_0,
- PROP_CHANNEL,
- PROP_STATE,
-};
-
-enum
-{
- DESTROY,
- LAST_SIGNAL
-};
-
-static guint signals[LAST_SIGNAL];
-
-G_DEFINE_TYPE (EmpathyTpTube, empathy_tp_tube, G_TYPE_OBJECT)
-
-static void
-tp_tube_state_changed_cb (TpChannel *channel,
- TpTubeChannelState state,
- gpointer user_data,
- GObject *tube)
-{
- EmpathyTpTubePriv *priv = GET_PRIV (tube);
-
- if (!priv->ready)
- /* We didn't get the state yet */
- return;
-
- DEBUG ("Tube state changed");
-
- priv->state = state;
- g_object_notify (tube, "state");
-}
-
-static void
-tp_tube_invalidated_cb (TpChannel *channel,
- GQuark domain,
- gint code,
- gchar *message,
- EmpathyTpTube *tube)
-{
- DEBUG ("Channel invalidated: %s", message);
- g_signal_emit (tube, signals[DESTROY], 0);
-}
-
-static void
-tp_tube_async_cb (TpChannel *channel,
- const GError *error,
- gpointer user_data,
- GObject *tube)
-{
- if (error)
- DEBUG ("Error %s: %s", (gchar *) user_data, error->message);
-}
-
-static void
-tp_tube_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- EmpathyTpTubePriv *priv = GET_PRIV (object);
-
- switch (prop_id)
- {
- case PROP_CHANNEL:
- priv->channel = g_value_dup_object (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-tp_tube_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- EmpathyTpTubePriv *priv = GET_PRIV (object);
-
- switch (prop_id)
- {
- case PROP_CHANNEL:
- g_value_set_object (value, priv->channel);
- break;
- case PROP_STATE:
- g_value_set_uint (value, priv->state);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void weak_object_notify (gpointer data,
- GObject *old_object);
-
-static ReadyCbData *
-ready_cb_data_new (EmpathyTpTube *self,
- EmpathyTpTubeReadyCb *callback,
- gpointer user_data,
- GDestroyNotify destroy,
- GObject *weak_object)
-{
- ReadyCbData *d = g_slice_new0 (ReadyCbData);
- d->callback = callback;
- d->user_data = user_data;
- d->destroy = destroy;
- d->weak_object = weak_object;
-
- if (weak_object != NULL)
- g_object_weak_ref (weak_object, weak_object_notify, self);
-
- return d;
-}
-
-static void
-ready_cb_data_free (ReadyCbData *data,
- EmpathyTpTube *self)
-{
- if (data->destroy != NULL)
- data->destroy (data->user_data);
-
- if (data->weak_object != NULL)
- g_object_weak_unref (data->weak_object,
- weak_object_notify, self);
-
- g_slice_free (ReadyCbData, data);
-}
-
-static void
-weak_object_notify (gpointer data,
- GObject *old_object)
-{
- EmpathyTpTube *self = EMPATHY_TP_TUBE (data);
- EmpathyTpTubePriv *priv = GET_PRIV (self);
- GSList *l, *ln;
-
- for (l = priv->ready_callbacks ; l != NULL ; l = ln )
- {
- ReadyCbData *d = (ReadyCbData *) l->data;
- ln = g_slist_next (l);
-
- if (d->weak_object == old_object)
- {
- ready_cb_data_free (d, self);
- priv->ready_callbacks = g_slist_delete_link (priv->ready_callbacks,
- l);
- }
- }
-}
-
-
-static void
-tube_is_ready (EmpathyTpTube *self,
- const GError *error)
-{
- EmpathyTpTubePriv *priv = GET_PRIV (self);
- GSList *l;
-
- priv->ready = TRUE;
-
- /* tube has to stay alive while we call the callbacks */
- g_object_ref (self);
- for (l = priv->ready_callbacks ; l != NULL ; l = g_slist_next (l))
- {
- ReadyCbData *data = (ReadyCbData *) l->data;
-
- data->callback (self, error, data->user_data, data->weak_object);
- ready_cb_data_free (data, self);
- }
- g_object_unref (self);
-
- g_slist_free (priv->ready_callbacks);
- priv->ready_callbacks = NULL;
-}
-
-static void
-got_tube_state_cb (TpProxy *proxy,
- const GValue *out_value,
- const GError *error,
- gpointer user_data,
- GObject *weak_object)
-{
- EmpathyTpTube *self = EMPATHY_TP_TUBE (user_data);
- EmpathyTpTubePriv *priv = GET_PRIV (self);
-
- if (error != NULL)
- {
- DEBUG ("Error getting State property: %s", error->message);
- }
- else
- {
- priv->state = g_value_get_uint (out_value);
- g_object_notify (G_OBJECT (self), "state");
- }
-
- tube_is_ready (self, error);
-}
-
-static GObject *
-tp_tube_constructor (GType type,
- guint n_props,
- GObjectConstructParam *props)
-{
- GObject *self;
- EmpathyTpTubePriv *priv;
-
- self = G_OBJECT_CLASS (empathy_tp_tube_parent_class)->constructor (
- type, n_props, props);
- priv = GET_PRIV (self);
-
- g_signal_connect (priv->channel, "invalidated",
- G_CALLBACK (tp_tube_invalidated_cb), self);
-
- priv->ready = FALSE;
-
- tp_cli_channel_interface_tube_connect_to_tube_channel_state_changed (
- priv->channel, tp_tube_state_changed_cb, NULL, NULL,
- self, NULL);
-
- tp_cli_dbus_properties_call_get (priv->channel, -1,
- TP_IFACE_CHANNEL_INTERFACE_TUBE, "State", got_tube_state_cb,
- self, NULL, G_OBJECT (self));
-
- return self;
-}
-
-static void
-tp_tube_finalize (GObject *object)
-{
- EmpathyTpTube *self = EMPATHY_TP_TUBE (object);
- EmpathyTpTubePriv *priv = GET_PRIV (object);
- GSList *l;
-
- DEBUG ("Finalizing: %p", object);
-
- if (priv->channel)
- {
- g_signal_handlers_disconnect_by_func (priv->channel,
- tp_tube_invalidated_cb, object);
- tp_cli_channel_call_close (priv->channel, -1, tp_tube_async_cb,
- "closing tube", NULL, NULL);
- g_object_unref (priv->channel);
- }
-
- for (l = priv->ready_callbacks; l != NULL; l = g_slist_next (l))
- {
- ReadyCbData *d = (ReadyCbData *) l->data;
-
- ready_cb_data_free (d, self);
- }
-
- g_slist_free (priv->ready_callbacks);
- priv->ready_callbacks = NULL;
-
- G_OBJECT_CLASS (empathy_tp_tube_parent_class)->finalize (object);
-}
-
-static void
-empathy_tp_tube_class_init (EmpathyTpTubeClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- object_class->constructor = tp_tube_constructor;
- object_class->finalize = tp_tube_finalize;
- object_class->set_property = tp_tube_set_property;
- object_class->get_property = tp_tube_get_property;
-
- /**
- * EmpathyTpTube:channel:
- *
- * The #TpChannel wrapped by the tube object.
- */
- g_object_class_install_property (object_class, PROP_CHANNEL,
- g_param_spec_object ("channel", "channel", "channel", TP_TYPE_CHANNEL,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
-
- /**
- * EmpathyTpTube:state:
- *
- * The state of the tube.
- */
- g_object_class_install_property (object_class, PROP_STATE,
- g_param_spec_uint ("state", "state", "state",
- 0, NUM_TP_TUBE_CHANNEL_STATES, 0,
- G_PARAM_READABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_STRINGS));
- /**
- * EmpathyTpTube::destroy:
- * @self: the tube object
- *
- * Emitted when then tube has been invalidated.
- */
- signals[DESTROY] = g_signal_new ("destroy",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- 0, NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
-
- g_type_class_add_private (klass, sizeof (EmpathyTpTubePriv));
-}
-
-static void
-empathy_tp_tube_init (EmpathyTpTube *tube)
-{
- EmpathyTpTubePriv *priv = G_TYPE_INSTANCE_GET_PRIVATE (tube,
- EMPATHY_TYPE_TP_TUBE, EmpathyTpTubePriv);
-
- tube->priv = priv;
-}
-
-/**
- * empathy_tp_tube_new:
- * @channel: a #TpChannel
- *
- * Creates a new #EmpathyTpTube.
- *
- * Return value: a new #EmpathyTpTube
- */
-EmpathyTpTube *
-empathy_tp_tube_new (TpChannel *channel)
-{
- g_return_val_if_fail (TP_IS_CHANNEL (channel), NULL);
-
- return g_object_new (EMPATHY_TYPE_TP_TUBE, "channel", channel, NULL);
-}
-
-/**
- * empathy_tp_tube_new_stream_tube:
- * @contact: the #EmpathyContact to which the tube is offered
- * @type: the type of the listening address of the local service. Either
- * %TP_SOCKET_ADDRESS_TYPE_IPV4 or %TP_SOCKET_ADDRESS_TYPE_IPV6.
- * @hostname: the address of the local service
- * @port: the port of the local service
- * @service: the service name of the tube
- * @parameters: the parameters of the tube
- *
- * Creates and offers a new #EmpathyTpTube of ChannelType StreamTube.
- *
- * Return value: a new #EmpathyTpTube
- */
-EmpathyTpTube *
-empathy_tp_tube_new_stream_tube (EmpathyContact *contact,
- TpSocketAddressType type,
- const gchar *hostname,
- guint port,
- const gchar *service,
- GHashTable *parameters)
-{
- TpConnection *connection;
- TpChannel *channel;
- gchar *object_path;
- GHashTable *params;
- GValue *address;
- GValue *control_param;
- EmpathyTpTube *tube = NULL;
- GError *error = NULL;
- GHashTable *request;
- GHashTable *channel_properties;
- GValue *value;
-
- g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), NULL);
- g_return_val_if_fail (hostname != NULL, NULL);
- g_return_val_if_fail (service != NULL, NULL);
-
- connection = empathy_contact_get_connection (contact);
-
- request = g_hash_table_new_full (g_str_hash, g_str_equal, NULL,
- (GDestroyNotify) tp_g_value_slice_free);
-
- /* org.freedesktop.Telepathy.Channel.ChannelType */
- value = tp_g_value_slice_new (G_TYPE_STRING);
- g_value_set_string (value, TP_IFACE_CHANNEL_TYPE_STREAM_TUBE);
- g_hash_table_insert (request, TP_IFACE_CHANNEL ".ChannelType", value);
-
- /* org.freedesktop.Telepathy.Channel.TargetHandleType */
- value = tp_g_value_slice_new (G_TYPE_UINT);
- g_value_set_uint (value, TP_HANDLE_TYPE_CONTACT);
- g_hash_table_insert (request, TP_IFACE_CHANNEL ".TargetHandleType", value);
-
- /* org.freedesktop.Telepathy.Channel.TargetHandleType */
- value = tp_g_value_slice_new (G_TYPE_UINT);
- g_value_set_uint (value, empathy_contact_get_handle (contact));
- g_hash_table_insert (request, TP_IFACE_CHANNEL ".TargetHandle", value);
-
- /* org.freedesktop.Telepathy.Channel.Type.StreamTube.Service */
- value = tp_g_value_slice_new (G_TYPE_STRING);
- g_value_set_string (value, service);
- g_hash_table_insert (request,
- TP_IFACE_CHANNEL_TYPE_STREAM_TUBE ".Service", value);
-
- if (!tp_cli_connection_interface_requests_run_create_channel (connection, -1,
- request, &object_path, &channel_properties, &error, NULL))
- {
- DEBUG ("Error requesting channel: %s", error->message);
- g_clear_error (&error);
- g_object_unref (connection);
- return NULL;
- }
-
- DEBUG ("Offering a new stream tube");
-
- channel = tp_channel_new_from_properties (connection, object_path,
- channel_properties, NULL);
-
- tp_channel_run_until_ready (channel, NULL, NULL);
-
- #define ADDRESS_TYPE dbus_g_type_get_struct ("GValueArray",\
- G_TYPE_STRING, G_TYPE_UINT, G_TYPE_INVALID)
- params = g_hash_table_new (g_str_hash, g_str_equal);
- address = tp_g_value_slice_new (ADDRESS_TYPE);
- g_value_take_boxed (address, dbus_g_type_specialized_construct (ADDRESS_TYPE));
- dbus_g_type_struct_set (address, 0, hostname, 1, port, G_MAXUINT);
- control_param = tp_g_value_slice_new (G_TYPE_STRING);
-
- if (parameters == NULL)
- /* Pass an empty dict as parameters */
- parameters = g_hash_table_new (g_str_hash, g_str_equal);
- else
- g_hash_table_ref (parameters);
-
- if (!tp_cli_channel_type_stream_tube_run_offer (channel, -1, type, address,
- TP_SOCKET_ACCESS_CONTROL_LOCALHOST, parameters,
- &error, NULL))
- {
- DEBUG ("Couldn't offer tube: %s", error->message);
- g_clear_error (&error);
- goto OUT;
- }
-
- DEBUG ("Stream tube offered");
-
- tube = empathy_tp_tube_new (channel);
-
-OUT:
- g_object_unref (channel);
- g_free (object_path);
- g_hash_table_destroy (request);
- g_hash_table_destroy (channel_properties);
- tp_g_value_slice_free (address);
- tp_g_value_slice_free (control_param);
- g_object_unref (connection);
- g_hash_table_unref (parameters);
-
- return tube;
-}
-
-static void
-tp_tube_accept_stream_cb (TpChannel *channel,
- const GValue *address,
- const GError *error,
- gpointer user_data,
- GObject *weak_object)
-{
- EmpathyTpTube *tube = EMPATHY_TP_TUBE (weak_object);
- EmpathyTpTubeAcceptData *data = (EmpathyTpTubeAcceptData *) user_data;
- EmpathyTpTubeAddress eaddress;
-
- eaddress.type = data->type;
-
- if (error)
- {
- DEBUG ("Error accepting tube: %s", error->message);
- data->callback (tube, NULL, error, data->user_data);
- return;
- }
-
- switch (eaddress.type)
- {
- case TP_SOCKET_ADDRESS_TYPE_UNIX:
- case TP_SOCKET_ADDRESS_TYPE_ABSTRACT_UNIX:
- eaddress.a.socket.path = g_value_get_boxed (address);
- break;
- case TP_SOCKET_ADDRESS_TYPE_IPV4:
- case TP_SOCKET_ADDRESS_TYPE_IPV6:
- dbus_g_type_struct_get (address,
- 0, &eaddress.a.inet.hostname,
- 1, &eaddress.a.inet.port, G_MAXUINT);
- break;
- }
-
- data->callback (tube, &eaddress, NULL, data->user_data);
-}
-
-/**
- * empathy_tp_tube_accept_stream_tube:
- * @tube: an #EmpathyTpTube
- * @type: the type of address the connection manager should listen on
- * @callback: called when the tube has been accepted
- * @user_data: arbitrary user-supplied data passed to the callback
- *
- * Accepts @tube of ChannelType StreamTube and call @callback once it's done.
- */
-void
-empathy_tp_tube_accept_stream_tube (EmpathyTpTube *tube,
- TpSocketAddressType type,
- EmpathyTpTubeAcceptStreamTubeCb *callback,
- gpointer user_data)
-{
- EmpathyTpTubePriv *priv = GET_PRIV (tube);
- GValue *control_param;
- EmpathyTpTubeAcceptData *data;
-
- g_return_if_fail (EMPATHY_IS_TP_TUBE (tube));
-
- DEBUG ("Accepting stream tube");
- /* FIXME allow other acls */
- control_param = tp_g_value_slice_new (G_TYPE_STRING);
-
- data = new_empathy_tp_tube_accept_data (type, callback, user_data);
-
- tp_cli_channel_type_stream_tube_call_accept (
- priv->channel, -1, type, TP_SOCKET_ACCESS_CONTROL_LOCALHOST,
- control_param, tp_tube_accept_stream_cb, data,
- free_empathy_tp_tube_accept_data, G_OBJECT (tube));
-
- tp_g_value_slice_free (control_param);
-}
-
-/**
- * EmpathyTpTubeReadyCb:
- * @tube: an #EmpathyTpTube
- * @error: %NULL on success, or the reason why the tube can't be ready
- * @user_data: the @user_data passed to empathy_tp_tube_call_when_ready()
- * @weak_object: the @weak_object passed to
- * empathy_tp_tube_call_when_ready()
- *
- * Called as the result of empathy_tp_tube_call_when_ready(). If the
- * tube's properties could be retrieved,
- * @error is %NULL and @tube is considered to be ready. Otherwise, @error is
- * non-%NULL and @tube is not ready.
- */
-
-/**
- * empathy_tp_tube_call_when_ready:
- * @tube: an #EmpathyTpTube
- * @callback: called when the tube becomes ready
- * @user_data: arbitrary user-supplied data passed to the callback
- * @destroy: called to destroy @user_data
- * @weak_object: object to reference weakly; if it is destroyed, @callback
- * will not be called, but @destroy will still be called
- *
- * If @tube is ready for use, call @callback immediately, then return.
- * Otherwise, arrange for @callback to be called when @tube becomes
- * ready for use.
- */
-void
-empathy_tp_tube_call_when_ready (EmpathyTpTube *self,
- EmpathyTpTubeReadyCb *callback,
- gpointer user_data,
- GDestroyNotify destroy,
- GObject *weak_object)
-{
- EmpathyTpTubePriv *priv = GET_PRIV (self);
-
- g_return_if_fail (self != NULL);
- g_return_if_fail (callback != NULL);
-
- if (priv->ready)
- {
- callback (self, NULL, user_data, weak_object);
- if (destroy != NULL)
- destroy (user_data);
- }
- else
- {
- priv->ready_callbacks = g_slist_prepend (priv->ready_callbacks,
- ready_cb_data_new (self, callback, user_data, destroy, weak_object));
- }
-}
diff --git a/libempathy/empathy-tp-tube.h b/libempathy/empathy-tp-tube.h
deleted file mode 100644
index 79cffa1a2..000000000
--- a/libempathy/empathy-tp-tube.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright (C) 2008 Collabora Ltd.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Authors: Guillaume Desmottes <guillaume.desmottes@collabora.co.uk>
- * Elliot Fairweather <elliot.fairweather@collabora.co.uk>
- */
-
-#ifndef __EMPATHY_TP_TUBE_H__
-#define __EMPATHY_TP_TUBE_H__
-
-#include <glib-object.h>
-
-#include <telepathy-glib/channel.h>
-
-#include "empathy-contact.h"
-
-G_BEGIN_DECLS
-
-#define EMPATHY_TYPE_TP_TUBE (empathy_tp_tube_get_type ())
-#define EMPATHY_TP_TUBE(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), \
- EMPATHY_TYPE_TP_TUBE, EmpathyTpTube))
-#define EMPATHY_TP_TUBE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), \
- EMPATHY_TYPE_TP_TUBE, EmpathyTpTubeClass))
-#define EMPATHY_IS_TP_TUBE(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), \
- EMPATHY_TYPE_TP_TUBE))
-#define EMPATHY_IS_TP_TUBE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), \
- EMPATHY_TYPE_TP_TUBE))
-#define EMPATHY_TP_TUBE_GET_CLASS(object) (G_TYPE_INSTANCE_GET_CLASS ((object), \
- EMPATHY_TYPE_TP_TUBE, EmpathyTpTubeClass))
-
-typedef struct _EmpathyTpTube EmpathyTpTube;
-typedef struct _EmpathyTpTubeClass EmpathyTpTubeClass;
-
-typedef struct {
- TpSocketAddressType type;
- union {
- struct socket_address_t {
- GArray *path;
- } socket;
- struct inet_address_t {
- gchar *hostname;
- guint port;
- } inet;
- } a;
-} EmpathyTpTubeAddress;
-
-struct _EmpathyTpTube {
- GObject parent;
- gpointer priv;
-};
-
-struct _EmpathyTpTubeClass {
- GObjectClass parent_class;
-};
-
-GType empathy_tp_tube_get_type (void) G_GNUC_CONST;
-EmpathyTpTube *empathy_tp_tube_new (TpChannel *channel);
-EmpathyTpTube *empathy_tp_tube_new_stream_tube (EmpathyContact *contact,
- TpSocketAddressType type,
- const gchar *hostname,
- guint port,
- const gchar *service,
- GHashTable *parameters);
-
-typedef void (EmpathyTpTubeAcceptStreamTubeCb) (EmpathyTpTube *tube,
- const EmpathyTpTubeAddress *address,
- const GError *error,
- gpointer user_data);
-
-void empathy_tp_tube_accept_stream_tube (EmpathyTpTube *tube,
- TpSocketAddressType type,
- EmpathyTpTubeAcceptStreamTubeCb *callback,
- gpointer user_data);
-
-typedef void (EmpathyTpTubeReadyCb)
- (EmpathyTpTube *tube,
- const GError *error,
- gpointer user_data,
- GObject *weak_object);
-
-void empathy_tp_tube_call_when_ready (EmpathyTpTube *tube,
- EmpathyTpTubeReadyCb *callback,
- gpointer user_data,
- GDestroyNotify destroy,
- GObject *weak_object);
-
-G_END_DECLS
-
-#endif /* __EMPATHY_TP_TUBE_H__ */
diff --git a/libempathy/empathy-tube-handler.c b/libempathy/empathy-tube-handler.c
index bbb7e11a6..2b50ec852 100644
--- a/libempathy/empathy-tube-handler.c
+++ b/libempathy/empathy-tube-handler.c
@@ -31,7 +31,6 @@
#include <extensions/extensions.h>
-#include "empathy-tp-tube.h"
#include "empathy-tube-handler.h"
#define DEBUG_FLAG EMPATHY_DEBUG_OTHER
@@ -59,21 +58,10 @@ typedef struct
gchar *channel;
guint handle_type;
guint handle;
- EmpathyTpTube *tube;
+ TpChannel *tube;
} IdleData;
static void
-tube_ready_cb (EmpathyTpTube *tube,
- const GError *error,
- gpointer user_data,
- GObject *weak_object)
-{
- IdleData *idle_data = user_data;
-
- g_signal_emit (idle_data->thandler, signals[NEW_TUBE], 0, tube);
-}
-
-static void
tube_ready_destroy_notify (gpointer data)
{
IdleData *idle_data = data;
@@ -100,9 +88,7 @@ channel_ready_cb (TpChannel *channel,
return;
}
- idle_data->tube = empathy_tp_tube_new (channel);
- empathy_tp_tube_call_when_ready (idle_data->tube, tube_ready_cb, idle_data,
- tube_ready_destroy_notify, NULL);
+ g_signal_emit (idle_data->thandler, signals[NEW_TUBE], 0, idle_data->tube);
g_object_unref (channel);
}
@@ -183,7 +169,7 @@ empathy_tube_handler_class_init (EmpathyTubeHandlerClass *klass)
signals[NEW_TUBE] =
g_signal_new ("new-tube", G_OBJECT_CLASS_TYPE (klass),
G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__OBJECT,
- G_TYPE_NONE, 1, EMPATHY_TYPE_TP_TUBE);
+ G_TYPE_NONE, 1, TP_TYPE_CHANNEL);
}
static void
diff --git a/libempathy/empathy-utils.c b/libempathy/empathy-utils.c
index 47746f536..fca7fcb5f 100644
--- a/libempathy/empathy-utils.c
+++ b/libempathy/empathy-utils.c
@@ -193,7 +193,7 @@ empathy_xml_node_get_child_content (xmlNodePtr node,
if (l) {
return xmlNodeGetContent (l);
}
-
+
return NULL;
}
@@ -220,10 +220,10 @@ empathy_xml_node_find_child_prop_value (xmlNodePtr node,
if (prop && strcmp (prop, prop_value) == 0) {
found = l;
}
-
+
xmlFree (prop);
}
-
+
return found;
}