empathy r1108 - in trunk: libempathy libempathy-gtk python/pyempathy src



Author: xclaesse
Date: Sun May 18 14:27:44 2008
New Revision: 1108
URL: http://svn.gnome.org/viewvc/empathy?rev=1108&view=rev

Log:
Improve dispatcher. Fixes bug #465928.


Modified:
   trunk/libempathy-gtk/empathy-contact-list-view.c
   trunk/libempathy-gtk/empathy-contact-menu.c
   trunk/libempathy-gtk/empathy-new-message-dialog.c
   trunk/libempathy/empathy-dispatcher.c
   trunk/libempathy/empathy-dispatcher.h
   trunk/libempathy/empathy-utils.c
   trunk/libempathy/empathy-utils.h
   trunk/python/pyempathy/pyempathy.defs
   trunk/src/empathy-call-window.c
   trunk/src/empathy-call-window.h
   trunk/src/empathy-chat-window.c
   trunk/src/empathy-status-icon.c
   trunk/src/empathy.c

Modified: trunk/libempathy-gtk/empathy-contact-list-view.c
==============================================================================
--- trunk/libempathy-gtk/empathy-contact-list-view.c	(original)
+++ trunk/libempathy-gtk/empathy-contact-list-view.c	Sun May 18 14:27:44 2008
@@ -36,6 +36,7 @@
 #include <libempathy/empathy-contact-factory.h>
 #include <libempathy/empathy-contact-list.h>
 #include <libempathy/empathy-contact-groups.h>
+#include <libempathy/empathy-dispatcher.h>
 #include <libempathy/empathy-utils.h>
 
 #include "empathy-contact-list-view.h"
@@ -462,7 +463,7 @@
 			    -1);
 
 	if (contact) {
-		empathy_chat_with_contact (contact);
+		empathy_dispatcher_chat_with_contact (contact);
 		g_object_unref (contact);
 	}
 }
@@ -491,7 +492,7 @@
 			    -1);
 
 	if (contact) {
-		empathy_call_with_contact (contact);
+		empathy_dispatcher_call_with_contact (contact);
 		g_object_unref (contact);
 	}
 }

Modified: trunk/libempathy-gtk/empathy-contact-menu.c
==============================================================================
--- trunk/libempathy-gtk/empathy-contact-menu.c	(original)
+++ trunk/libempathy-gtk/empathy-contact-menu.c	Sun May 18 14:27:44 2008
@@ -26,8 +26,9 @@
 #include <glib/gi18n.h>
 #include <gtk/gtk.h>
 
-#include <libempathy/empathy-utils.h>
 #include <libempathy/empathy-log-manager.h>
+#include <libempathy/empathy-dispatcher.h>
+#include <libempathy/empathy-utils.h>
 
 #include "empathy-contact-menu.h"
 #include "empathy-images.h"
@@ -112,7 +113,7 @@
 	gtk_widget_show (image);
 
 	g_signal_connect_swapped (item, "activate",
-				  G_CALLBACK (empathy_chat_with_contact),
+				  G_CALLBACK (empathy_dispatcher_chat_with_contact),
 				  contact);
 	
 	return item;
@@ -134,7 +135,7 @@
 	gtk_widget_show (image);
 
 	g_signal_connect_swapped (item, "activate",
-				  G_CALLBACK (empathy_call_with_contact),
+				  G_CALLBACK (empathy_dispatcher_call_with_contact),
 				  contact);
 	
 	return item;

Modified: trunk/libempathy-gtk/empathy-new-message-dialog.c
==============================================================================
--- trunk/libempathy-gtk/empathy-new-message-dialog.c	(original)
+++ trunk/libempathy-gtk/empathy-new-message-dialog.c	Sun May 18 14:27:44 2008
@@ -32,6 +32,7 @@
 #include <libmissioncontrol/mission-control.h>
 
 #include <libempathy/empathy-contact-factory.h>
+#include <libempathy/empathy-dispatcher.h>
 #include <libempathy/empathy-utils.h>
 
 #include <libempathy-gtk/empathy-ui-utils.h>
@@ -67,10 +68,10 @@
 	}
 
 	if (response == 1) {
-		empathy_call_with_contact_id (account, id);
+		empathy_dispatcher_call_with_contact_id (account, id);
 	}	
 	else if (response == 2) {
-		empathy_chat_with_contact_id (account, id);
+		empathy_dispatcher_chat_with_contact_id (account, id);
 	}
 
 	g_object_unref (account);

Modified: trunk/libempathy/empathy-dispatcher.c
==============================================================================
--- trunk/libempathy/empathy-dispatcher.c	(original)
+++ trunk/libempathy/empathy-dispatcher.c	Sun May 18 14:27:44 2008
@@ -40,6 +40,7 @@
 #include "empathy-utils.h"
 #include "empathy-tube-handler.h"
 #include "empathy-contact-factory.h"
+#include "empathy-tp-group.h"
 
 #define DEBUG_FLAG EMPATHY_DEBUG_DISPATCHER
 #include <libempathy/empathy-debug.h>
@@ -49,7 +50,7 @@
 	GHashTable     *connections;
 	gpointer        token;
 	MissionControl *mc;
-	GHashTable     *tubes;
+	GSList         *tubes;
 } EmpathyDispatcherPriv;
 
 G_DEFINE_TYPE (EmpathyDispatcher, empathy_dispatcher, G_TYPE_OBJECT);
@@ -203,7 +204,6 @@
 			      gpointer     user_data,
 			      GObject     *dispatcher)
 {
-	EmpathyDispatcherPriv *priv = GET_PRIV (dispatcher);
 	static TpDBusDaemon   *daemon = NULL;
 	DispatcherTube        *tube;
 	McAccount             *account;
@@ -213,9 +213,8 @@
 	GError                *error = NULL;
 
 	/* Increase tube count */
-	number = GPOINTER_TO_UINT (g_hash_table_lookup (priv->tubes, channel));
-	g_hash_table_replace (priv->tubes, g_object_ref (channel),
-			      GUINT_TO_POINTER (++number));
+	number = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (channel), "tube-count"));
+	g_object_set_data (G_OBJECT (channel), "tube-count", GUINT_TO_POINTER (++number));
 	DEBUG ("Increased tube count for channel %p: %d", channel, number);
 
 	/* We dispatch only local pending tubes */
@@ -308,17 +307,18 @@
 }
 
 static void
-dispatcher_tubes_channel_invalidated_cb (TpProxy       *proxy,
-					 guint          domain,
-					 gint           code,
-					 gchar         *message,
+dispatcher_tubes_channel_invalidated_cb (TpProxy           *proxy,
+					 guint              domain,
+					 gint               code,
+					 gchar             *message,
 					 EmpathyDispatcher *dispatcher)
 {
 	EmpathyDispatcherPriv *priv = GET_PRIV (dispatcher);
 
-	DEBUG ("Error: %s", message);
+	DEBUG ("%s", message);
 
-	g_hash_table_remove (priv->tubes, proxy);
+	priv->tubes = g_slist_remove (priv->tubes, proxy);
+	g_object_unref (proxy);
 }
 
 static void
@@ -327,18 +327,16 @@
 				 gpointer   user_data,
 				 GObject   *dispatcher)
 {
-	EmpathyDispatcherPriv *priv = GET_PRIV (dispatcher);
-	guint                  number;
+	guint number;
 
-	number = GPOINTER_TO_UINT (g_hash_table_lookup (priv->tubes, channel));
+	number = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (channel), "tube-count"));
 	if (number == 1) {
 		DEBUG ("No more tube, closing channel");
 		tp_cli_channel_call_close (channel, -1, NULL, NULL, NULL, NULL);
 	}
 	else if (number > 1) {
 		DEBUG ("Decrease tube count: %d", number);
-		g_hash_table_replace (priv->tubes, g_object_ref (channel),
-				      GUINT_TO_POINTER (--number));
+		g_object_set_data (G_OBJECT (channel), "tube-count", GUINT_TO_POINTER (--number));
 	}
 }
 
@@ -348,15 +346,9 @@
 {
 	EmpathyDispatcherPriv *priv = GET_PRIV (dispatcher);
 
-	if (g_hash_table_lookup (priv->tubes, channel)) {
-		return;
-	}
-
-	DEBUG ("Handling new channel");
-
-	g_hash_table_insert (priv->tubes, g_object_ref (channel),
-			     GUINT_TO_POINTER (0));
+	DEBUG ("Called");
 
+	priv->tubes = g_slist_prepend (priv->tubes, g_object_ref (channel));
 	g_signal_connect (channel, "invalidated",
 			  G_CALLBACK (dispatcher_tubes_channel_invalidated_cb),
 			  dispatcher);
@@ -569,34 +561,24 @@
 	g_object_unref (account);
 }
 
-static guint
-dispatcher_channel_hash (gconstpointer key)
-{
-	TpProxy *channel = TP_PROXY (key);
-
-	return g_str_hash (channel->object_path);
-}
-
-static gboolean
-dispatcher_channel_equal (gconstpointer a,
-		      gconstpointer b)
-{
-	TpProxy *channel_a = TP_PROXY (a);
-	TpProxy *channel_b = TP_PROXY (b);
-
-	return g_str_equal (channel_a->object_path, channel_b->object_path);
-}
-
 static void
 dispatcher_finalize (GObject *object)
 {
 	EmpathyDispatcherPriv *priv = GET_PRIV (object);
+	GSList                *l;
 
 	empathy_disconnect_account_status_changed (priv->token);
 	g_object_unref (priv->mc);
 
+	for (l = priv->tubes; l; l = l->next) {
+		g_signal_handlers_disconnect_by_func (l->data,
+						      dispatcher_tubes_channel_invalidated_cb,
+						      object);
+		g_object_unref (l->data);
+	}
+	g_slist_free (priv->tubes);
+
 	g_hash_table_destroy (priv->connections);
-	g_hash_table_destroy (priv->tubes);
 }
 
 static void
@@ -645,10 +627,6 @@
 		EMPATHY_TYPE_DISPATCHER, EmpathyDispatcherPriv);
 
 	dispatcher->priv = priv;
-	priv->tubes = g_hash_table_new_full (dispatcher_channel_hash,
-					     dispatcher_channel_equal,
-					     g_object_unref, NULL);
-
 	priv->mc = empathy_mission_control_new ();
 	priv->token = empathy_connect_to_account_status_changed (priv->mc,
 		G_CALLBACK (dispatcher_status_changed_cb),
@@ -679,3 +657,162 @@
 	return dispatcher;
 }
 
+typedef struct {
+	const gchar *channel_type;
+	guint        handle_type;
+	guint        handle;
+} DispatcherRequestData;
+
+static void
+dispatcher_request_channel_cb (TpConnection *connection,
+			       const gchar  *object_path,
+			       const GError *error,
+			       gpointer      user_data,
+			       GObject      *weak_object)
+{
+	DispatcherRequestData *data = (DispatcherRequestData*) user_data;
+
+	if (error) {
+		DEBUG ("Error: %s", error->message);
+		return;
+	}
+
+	if (dispatcher) {
+		TpChannel *channel;
+
+		channel = tp_channel_new (connection, object_path,
+					  data->channel_type,
+					  data->handle_type,
+					  data->handle, NULL);
+
+		g_signal_emit (dispatcher, signals[DISPATCH_CHANNEL], 0, channel);
+	}
+}
+
+void
+empathy_dispatcher_call_with_contact (EmpathyContact *contact)
+{
+	MissionControl        *mc;
+	McAccount             *account;
+	TpConnection          *connection;
+	gchar                 *object_path;
+	TpChannel             *channel;
+	EmpathyContactFactory *factory;
+	EmpathyTpGroup        *group;
+	EmpathyContact        *self_contact;
+	GError                *error = NULL;
+
+	g_return_if_fail (EMPATHY_IS_CONTACT (contact));
+
+	mc = empathy_mission_control_new ();
+	account = empathy_contact_get_account (contact);
+	connection = mission_control_get_tpconnection (mc, account, NULL);
+	tp_connection_run_until_ready (connection, FALSE, NULL, NULL);
+	g_object_unref (mc);
+
+	/* We abuse of suppress_handler, TRUE means OUTGOING. The channel
+	 * will be catched in EmpathyFilter */
+	if (!tp_cli_connection_run_request_channel (connection, -1,
+						    TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA,
+						    TP_HANDLE_TYPE_NONE,
+						    0,
+						    TRUE,
+						    &object_path,
+						    &error,
+						    NULL)) {
+		DEBUG ("Couldn't request channel: %s",
+			error ? error->message : "No error given");
+		g_clear_error (&error);
+		g_object_unref (connection);
+		return;
+	}
+
+	channel = tp_channel_new (connection,
+				  object_path, TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA,
+				  TP_HANDLE_TYPE_NONE, 0, NULL);
+
+	group = empathy_tp_group_new (channel);
+	empathy_run_until_ready (group);
+
+	factory = empathy_contact_factory_new ();
+	self_contact = empathy_contact_factory_get_user (factory, account);
+	empathy_contact_run_until_ready (self_contact,
+					 EMPATHY_CONTACT_READY_HANDLE,
+					 NULL);
+
+	empathy_tp_group_add_member (group, contact, "");
+	empathy_tp_group_add_member (group, self_contact, "");	
+
+	g_object_unref (factory);
+	g_object_unref (self_contact);
+	g_object_unref (group);
+	g_object_unref (connection);
+	g_object_unref (channel);
+	g_free (object_path);
+}
+
+void
+empathy_dispatcher_call_with_contact_id (McAccount *account, const gchar *contact_id)
+{
+	EmpathyContactFactory *factory;
+	EmpathyContact        *contact;
+
+	factory = empathy_contact_factory_new ();
+	contact = empathy_contact_factory_get_from_id (factory, account, contact_id);
+	empathy_contact_run_until_ready (contact, EMPATHY_CONTACT_READY_HANDLE, NULL);
+
+	empathy_dispatcher_call_with_contact (contact);
+
+	g_object_unref (contact);
+	g_object_unref (factory);
+}
+
+void
+empathy_dispatcher_chat_with_contact (EmpathyContact  *contact)
+{
+	MissionControl        *mc;
+	McAccount             *account;
+	TpConnection          *connection;
+	DispatcherRequestData *data;
+
+	g_return_if_fail (EMPATHY_IS_CONTACT (contact));
+
+	mc = empathy_mission_control_new ();
+	account = empathy_contact_get_account (contact);
+	connection = mission_control_get_tpconnection (mc, account, NULL);
+	tp_connection_run_until_ready (connection, FALSE, NULL, NULL);
+	g_object_unref (mc);
+
+	/* We abuse of suppress_handler, TRUE means OUTGOING. */
+	data = g_new (DispatcherRequestData, 1);
+	data->channel_type = TP_IFACE_CHANNEL_TYPE_TEXT;
+	data->handle_type = TP_HANDLE_TYPE_CONTACT;
+	data->handle = empathy_contact_get_handle (contact);
+	tp_cli_connection_call_request_channel (connection, -1,
+						data->channel_type,
+						data->handle_type,
+						data->handle,
+						TRUE,
+						dispatcher_request_channel_cb,
+						data, g_free,
+						NULL);
+	g_object_unref (connection);
+}
+
+void
+empathy_dispatcher_chat_with_contact_id (McAccount   *account,
+					 const gchar *contact_id)
+{
+	EmpathyContactFactory *factory;
+	EmpathyContact        *contact;
+
+	factory = empathy_contact_factory_new ();
+	contact = empathy_contact_factory_get_from_id (factory, account, contact_id);
+	empathy_contact_run_until_ready (contact, EMPATHY_CONTACT_READY_HANDLE, NULL);
+
+	empathy_dispatcher_chat_with_contact (contact);
+
+	g_object_unref (contact);
+	g_object_unref (factory);
+}
+

Modified: trunk/libempathy/empathy-dispatcher.h
==============================================================================
--- trunk/libempathy/empathy-dispatcher.h	(original)
+++ trunk/libempathy/empathy-dispatcher.h	Sun May 18 14:27:44 2008
@@ -57,15 +57,21 @@
 	gboolean        activatable;
 } EmpathyDispatcherTube;
 
-GType                  empathy_dispatcher_get_type       (void) G_GNUC_CONST;
-EmpathyDispatcher *    empathy_dispatcher_new            (void);
-void                   empathy_dispatcher_channel_process(EmpathyDispatcher     *dispatcher,
-							  TpChannel             *channel);
-GType                  empathy_dispatcher_tube_get_type  (void);
-EmpathyDispatcherTube *empathy_dispatcher_tube_ref       (EmpathyDispatcherTube *tube);
-void                   empathy_dispatcher_tube_unref     (EmpathyDispatcherTube *tube);
-void                   empathy_dispatcher_tube_process   (EmpathyDispatcher     *dispatcher,
-							  EmpathyDispatcherTube *tube);
+GType                  empathy_dispatcher_get_type             (void) G_GNUC_CONST;
+EmpathyDispatcher *    empathy_dispatcher_new                  (void);
+void                   empathy_dispatcher_channel_process      (EmpathyDispatcher     *dispatcher,
+								TpChannel             *channel);
+GType                  empathy_dispatcher_tube_get_type        (void);
+EmpathyDispatcherTube *empathy_dispatcher_tube_ref             (EmpathyDispatcherTube *tube);
+void                   empathy_dispatcher_tube_unref           (EmpathyDispatcherTube *tube);
+void                   empathy_dispatcher_tube_process         (EmpathyDispatcher     *dispatcher,
+								EmpathyDispatcherTube *tube);
+void                   empathy_dispatcher_call_with_contact    (EmpathyContact        *contact);
+void                   empathy_dispatcher_call_with_contact_id (McAccount             *account,
+								const gchar           *contact_id);
+void                   empathy_dispatcher_chat_with_contact_id (McAccount             *account,
+								const gchar           *contact_id);
+void                   empathy_dispatcher_chat_with_contact    (EmpathyContact        *contact);
 
 G_END_DECLS
 

Modified: trunk/libempathy/empathy-utils.c
==============================================================================
--- trunk/libempathy/empathy-utils.c	(original)
+++ trunk/libempathy/empathy-utils.c	Sun May 18 14:27:44 2008
@@ -338,126 +338,6 @@
 	return mc;
 }
 
-void
-empathy_call_with_contact (EmpathyContact *contact)
-{
-	MissionControl        *mc;
-	McAccount             *account;
-	TpConnection          *connection;
-	gchar                 *object_path;
-	TpChannel             *channel;
-	EmpathyContactFactory *factory;
-	EmpathyTpGroup        *group;
-	EmpathyContact        *self_contact;
-	GError                *error = NULL;
-
-	g_return_if_fail (EMPATHY_IS_CONTACT (contact));
-
-	mc = empathy_mission_control_new ();
-	account = empathy_contact_get_account (contact);
-	connection = mission_control_get_tpconnection (mc, account, NULL);
-	tp_connection_run_until_ready (connection, FALSE, NULL, NULL);
-	g_object_unref (mc);
-
-	/* We abuse of suppress_handler, TRUE means OUTGOING. The channel
-	 * will be catched in EmpathyFilter */
-	if (!tp_cli_connection_run_request_channel (connection, -1,
-						    TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA,
-						    TP_HANDLE_TYPE_NONE,
-						    0,
-						    TRUE,
-						    &object_path,
-						    &error,
-						    NULL)) {
-		DEBUG ("Couldn't request channel: %s",
-			error ? error->message : "No error given");
-		g_clear_error (&error);
-		g_object_unref (connection);
-		return;
-	}
-
-	channel = tp_channel_new (connection,
-				  object_path, TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA,
-				  TP_HANDLE_TYPE_NONE, 0, NULL);
-
-	group = empathy_tp_group_new (channel);
-	empathy_run_until_ready (group);
-
-	factory = empathy_contact_factory_new ();
-	self_contact = empathy_contact_factory_get_user (factory, account);
-	empathy_contact_run_until_ready (self_contact,
-					 EMPATHY_CONTACT_READY_HANDLE,
-					 NULL);
-
-	empathy_tp_group_add_member (group, contact, "");
-	empathy_tp_group_add_member (group, self_contact, "");	
-
-	g_object_unref (factory);
-	g_object_unref (self_contact);
-	g_object_unref (group);
-	g_object_unref (connection);
-	g_object_unref (channel);
-	g_free (object_path);
-}
-
-void
-empathy_call_with_contact_id (McAccount *account, const gchar *contact_id)
-{
-	EmpathyContactFactory *factory;
-	EmpathyContact        *contact;
-
-	factory = empathy_contact_factory_new ();
-	contact = empathy_contact_factory_get_from_id (factory, account, contact_id);
-	empathy_contact_run_until_ready (contact, EMPATHY_CONTACT_READY_HANDLE, NULL);
-
-	empathy_call_with_contact (contact);
-
-	g_object_unref (contact);
-	g_object_unref (factory);
-}
-
-void
-empathy_chat_with_contact (EmpathyContact  *contact)
-{
-	MissionControl        *mc;
-	McAccount             *account;
-	TpConnection          *connection;
-
-	g_return_if_fail (EMPATHY_IS_CONTACT (contact));
-
-	mc = empathy_mission_control_new ();
-	account = empathy_contact_get_account (contact);
-	connection = mission_control_get_tpconnection (mc, account, NULL);
-	tp_connection_run_until_ready (connection, FALSE, NULL, NULL);
-	g_object_unref (mc);
-
-	/* We abuse of suppress_handler, TRUE means OUTGOING. The channel
-	 * will be catched in EmpathyFilter */
-	tp_cli_connection_call_request_channel (connection, -1,
-						TP_IFACE_CHANNEL_TYPE_TEXT,
-						TP_HANDLE_TYPE_CONTACT,
-						empathy_contact_get_handle (contact),
-						TRUE,
-						NULL, NULL, NULL, NULL);
-	g_object_unref (connection);
-}
-
-void
-empathy_chat_with_contact_id (McAccount *account, const gchar *contact_id)
-{
-	EmpathyContactFactory *factory;
-	EmpathyContact        *contact;
-
-	factory = empathy_contact_factory_new ();
-	contact = empathy_contact_factory_get_from_id (factory, account, contact_id);
-	empathy_contact_run_until_ready (contact, EMPATHY_CONTACT_READY_HANDLE, NULL);
-
-	empathy_chat_with_contact (contact);
-
-	g_object_unref (contact);
-	g_object_unref (factory);
-}
-
 const gchar *
 empathy_presence_get_default_message (McPresence presence)
 {
@@ -747,3 +627,28 @@
 					data);
 }
 
+guint
+empathy_proxy_hash (gconstpointer key)
+{
+	TpProxy *proxy = TP_PROXY (key);
+
+	g_return_val_if_fail (TP_IS_PROXY (proxy), 0);
+
+	return g_str_hash (proxy->object_path) +
+	       g_str_hash (proxy->bus_name);
+}
+
+gboolean
+empathy_proxy_equal (gconstpointer a,
+		     gconstpointer b)
+{
+	TpProxy *proxy_a = TP_PROXY (a);
+	TpProxy *proxy_b = TP_PROXY (b);
+
+	g_return_val_if_fail (TP_IS_PROXY (proxy_a), FALSE);
+	g_return_val_if_fail (TP_IS_PROXY (proxy_b), FALSE);
+
+	return g_str_equal (proxy_a->object_path, proxy_b->object_path) &&
+	       g_str_equal (proxy_a->bus_name, proxy_b->bus_name);
+}
+

Modified: trunk/libempathy/empathy-utils.h
==============================================================================
--- trunk/libempathy/empathy-utils.h	(original)
+++ trunk/libempathy/empathy-utils.h	Sun May 18 14:27:44 2008
@@ -83,12 +83,6 @@
 gboolean     empathy_account_equal                  (gconstpointer    a,
 						    gconstpointer    b);
 MissionControl *empathy_mission_control_new         (void);
-void         empathy_call_with_contact              (EmpathyContact  *contact);
-void         empathy_call_with_contact_id           (McAccount       *account,
-						     const gchar     *contact_id);
-void         empathy_chat_with_contact              (EmpathyContact  *contact);
-void         empathy_chat_with_contact_id           (McAccount       *account,
-						     const gchar     *contact_id);
 const gchar * empathy_presence_get_default_message  (McPresence       presence);
 const gchar * empathy_presence_to_str               (McPresence       presence);
 McPresence    empathy_presence_from_str             (const gchar     *str);
@@ -104,11 +98,16 @@
 						     gpointer         user_data,
 						     GMainLoop      **loop);
 McAccount *  empathy_channel_get_account            (TpChannel       *channel);
-gpointer      empathy_connect_to_account_status_changed (MissionControl *mc,
+gpointer     empathy_connect_to_account_status_changed (MissionControl *mc,
 							 GCallback       handler,
 							 gpointer        user_data,
 							 GClosureNotify  free_func);
-void          empathy_disconnect_account_status_changed (gpointer        token);
+void         empathy_disconnect_account_status_changed (gpointer      token);
+gboolean     empathy_proxy_equal                    (gconstpointer    a,
+						     gconstpointer    b);
+guint        empathy_proxy_hash                     (gconstpointer    key);
+
+
 
 G_END_DECLS
 

Modified: trunk/python/pyempathy/pyempathy.defs
==============================================================================
--- trunk/python/pyempathy/pyempathy.defs	(original)
+++ trunk/python/pyempathy/pyempathy.defs	Sun May 18 14:27:44 2008
@@ -498,40 +498,6 @@
   (return-type "MissionControl*")
 )
 
-(define-function empathy_call_with_contact
-  (c-name "empathy_call_with_contact")
-  (return-type "none")
-  (parameters
-    '("EmpathyContact*" "contact")
-  )
-)
-
-(define-function empathy_call_with_contact_id
-  (c-name "empathy_call_with_contact_id")
-  (return-type "none")
-  (parameters
-    '("McAccount*" "account")
-    '("const-gchar*" "contact_id")
-  )
-)
-
-(define-function empathy_chat_with_contact
-  (c-name "empathy_chat_with_contact")
-  (return-type "none")
-  (parameters
-    '("EmpathyContact*" "contact")
-  )
-)
-
-(define-function empathy_chat_with_contact_id
-  (c-name "empathy_chat_with_contact_id")
-  (return-type "none")
-  (parameters
-    '("McAccount*" "account")
-    '("const-gchar*" "contact_id")
-  )
-)
-
 (define-function empathy_presence_get_default_message
   (c-name "empathy_presence_get_default_message")
   (return-type "const-gchar*")
@@ -612,6 +578,23 @@
   )
 )
 
+(define-function empathy_proxy_equal
+  (c-name "empathy_proxy_equal")
+  (return-type "gboolean")
+  (parameters
+    '("gconstpointer" "a")
+    '("gconstpointer" "b")
+  )
+)
+
+(define-function empathy_proxy_hash
+  (c-name "empathy_proxy_hash")
+  (return-type "guint")
+  (parameters
+    '("gconstpointer" "key")
+  )
+)
+
 
 
 ;; From empathy-message.h
@@ -2302,4 +2285,38 @@
   )
 )
 
+(define-function empathy_dispatcher_call_with_contact
+  (c-name "empathy_dispatcher_call_with_contact")
+  (return-type "none")
+  (parameters
+    '("EmpathyContact*" "contact")
+  )
+)
+
+(define-function empathy_dispatcher_call_with_contact_id
+  (c-name "empathy_dispatcher_call_with_contact_id")
+  (return-type "none")
+  (parameters
+    '("McAccount*" "account")
+    '("const-gchar*" "contact_id")
+  )
+)
+
+(define-function empathy_dispatcher_chat_with_contact_id
+  (c-name "empathy_dispatcher_chat_with_contact_id")
+  (return-type "none")
+  (parameters
+    '("McAccount*" "account")
+    '("const-gchar*" "contact_id")
+  )
+)
+
+(define-function empathy_dispatcher_chat_with_contact
+  (c-name "empathy_dispatcher_chat_with_contact")
+  (return-type "none")
+  (parameters
+    '("EmpathyContact*" "contact")
+  )
+)
+
 

Modified: trunk/src/empathy-call-window.c
==============================================================================
--- trunk/src/empathy-call-window.c	(original)
+++ trunk/src/empathy-call-window.c	Sun May 18 14:27:44 2008
@@ -38,7 +38,7 @@
 #define DEBUG_FLAG EMPATHY_DEBUG_OTHER
 #include <libempathy/empathy-debug.h>
 
-typedef struct 
+typedef struct
 {
   EmpathyTpCall *call;
   GTimeVal start_time;
@@ -61,6 +61,8 @@
   GtkWidget *keypad_expander;
 } EmpathyCallWindow;
 
+static GSList *windows = NULL;
+
 static gboolean
 call_window_update_timer (gpointer data)
 {
@@ -269,8 +271,11 @@
                         EmpathyCallWindow *window)
 {
   call_window_finalize (window);
+
   g_object_unref (window->output_video_socket);
   g_object_unref (window->preview_video_socket);
+
+  windows = g_slist_remove (windows, window);
   g_slice_free (EmpathyCallWindow, window);
 }
 
@@ -461,17 +466,18 @@
 }
 
 GtkWidget *
-empathy_call_window_new (EmpathyTpCall *call)
+empathy_call_window_new (TpChannel *channel)
 {
   EmpathyCallWindow *window;
   GladeXML *glade;
   gchar *filename;
   const gchar *icons[] = {"audio-input-microphone", NULL};
 
-  g_return_val_if_fail (EMPATHY_IS_TP_CALL (call), NULL);
+  g_return_val_if_fail (TP_IS_CHANNEL (channel), NULL);
 
   window = g_slice_new0 (EmpathyCallWindow);
-  window->call = g_object_ref (call);
+  windows = g_slist_prepend (windows, window);
+  window->call = empathy_tp_call_new (channel);
 
   filename = empathy_file_lookup ("empathy-call-window.glade", "src");
   glade = empathy_glade_get_file (filename,
@@ -562,3 +568,52 @@
   return window->window;
 }
 
+GtkWidget *
+empathy_call_window_find (TpChannel *channel)
+{
+  GSList *l;
+
+  g_return_val_if_fail (TP_IS_CHANNEL (channel), NULL);
+
+  for (l = windows; l; l = l->next)
+    {
+      EmpathyCallWindow *window = l->data;
+      TpChannel *this_channel = NULL;
+
+      if (window->call)
+          g_object_get (window->call, "channel", &this_channel, NULL);
+      if (this_channel)
+        {
+          g_object_unref (this_channel);
+          if (empathy_proxy_equal (channel, this_channel))
+              return window->window;
+        }
+    }
+
+  return NULL;
+}
+
+void
+empathy_call_window_set_channel (GtkWidget *window, TpChannel *channel)
+{
+  GSList *l;
+
+  g_return_if_fail (GTK_IS_WIDGET (window));
+  g_return_if_fail (TP_IS_CHANNEL (channel));
+
+  for (l = windows; l; l = l->next)
+    {
+      EmpathyCallWindow *call_window = l->data;
+
+      if (call_window->window == window)
+        {
+          if (!call_window->call)
+            {
+              call_window->call = empathy_tp_call_new (channel);
+              call_window_update (call_window);
+            }
+          break;
+        }
+    }
+}
+

Modified: trunk/src/empathy-call-window.h
==============================================================================
--- trunk/src/empathy-call-window.h	(original)
+++ trunk/src/empathy-call-window.h	Sun May 18 14:27:44 2008
@@ -26,11 +26,14 @@
 
 #include <gtk/gtk.h>
 
-#include <libempathy/empathy-tp-call.h>
+#include <telepathy-glib/channel.h>
 
 G_BEGIN_DECLS
 
-GtkWidget *empathy_call_window_new (EmpathyTpCall *call);
+GtkWidget *empathy_call_window_new (TpChannel *channel);
+GtkWidget *empathy_call_window_find (TpChannel *channel);
+void empathy_call_window_set_channel (GtkWidget *window,
+    TpChannel *channel);
 
 G_END_DECLS
 

Modified: trunk/src/empathy-chat-window.c
==============================================================================
--- trunk/src/empathy-chat-window.c	(original)
+++ trunk/src/empathy-chat-window.c	Sun May 18 14:27:44 2008
@@ -40,6 +40,7 @@
 #include <libempathy/empathy-contact-factory.h>
 #include <libempathy/empathy-contact.h>
 #include <libempathy/empathy-message.h>
+#include <libempathy/empathy-dispatcher.h>
 #include <libempathy/empathy-utils.h>
 
 #include <libempathy-gtk/empathy-images.h>
@@ -977,7 +978,7 @@
 		chat = empathy_chat_window_find_chat (account, strv[1]);
 
 		if (!chat) {
-			empathy_chat_with_contact_id (account, strv[2]);
+			empathy_dispatcher_chat_with_contact_id (account, strv[2]);
 			g_object_unref (account);
 			g_strfreev (strv);
 			return;

Modified: trunk/src/empathy-status-icon.c
==============================================================================
--- trunk/src/empathy-status-icon.c	(original)
+++ trunk/src/empathy-status-icon.c	Sun May 18 14:27:44 2008
@@ -82,19 +82,181 @@
 	gchar               *message;
 	StatusIconEventFunc  func;
 	gpointer             user_data;
+	TpChannel           *channel;
+	EmpathyStatusIcon   *icon;
 };
 
 G_DEFINE_TYPE (EmpathyStatusIcon, empathy_status_icon, G_TYPE_OBJECT);
 
 static void
+status_icon_update_tooltip (EmpathyStatusIcon *icon)
+{
+	EmpathyStatusIconPriv *priv = GET_PRIV (icon);
+	const gchar           *tooltip = NULL;
+
+	if (priv->events) {
+		tooltip = ((StatusIconEvent*)priv->events->data)->message;
+	}
+
+	if (!tooltip) {
+		tooltip = empathy_idle_get_status (priv->idle);
+	}
+
+	gtk_status_icon_set_tooltip (priv->icon, tooltip);	
+}
+
+static void
+status_icon_update_icon (EmpathyStatusIcon *icon)
+{
+	EmpathyStatusIconPriv *priv = GET_PRIV (icon);
+	const gchar           *icon_name;
+
+	if (priv->events && priv->showing_event_icon) {
+		icon_name = ((StatusIconEvent*)priv->events->data)->icon_name;
+	} else {
+		McPresence state;
+
+		state = empathy_idle_get_state (priv->idle);
+		icon_name = empathy_icon_name_for_presence (state);
+	}
+
+	gtk_status_icon_set_from_icon_name (priv->icon, icon_name);
+}
+
+static gboolean
+status_icon_blink_timeout_cb (EmpathyStatusIcon *icon)
+{
+	EmpathyStatusIconPriv *priv = GET_PRIV (icon);
+
+	priv->showing_event_icon = !priv->showing_event_icon;
+	status_icon_update_icon (icon);
+
+	return TRUE;
+}
+
+static void status_icon_channel_invalidated_cb (TpProxy *channel, guint domain,
+						gint code, gchar *message,
+						EmpathyStatusIcon *icon);
+
+static void
 status_icon_event_free (StatusIconEvent *event)
 {
 	g_free (event->icon_name);
 	g_free (event->message);
+	if (event->channel) {
+		g_signal_handlers_disconnect_by_func (event->channel,
+						      status_icon_channel_invalidated_cb,
+						      event->icon);
+		g_object_unref (event->channel);
+	}
 	g_slice_free (StatusIconEvent, event);
 }
 
 static void
+status_icon_event_remove (EmpathyStatusIcon *icon,
+			  StatusIconEvent   *event)
+{
+	EmpathyStatusIconPriv *priv = GET_PRIV (icon);
+	GSList                *l;
+
+	if (!(l = g_slist_find (priv->events, event))) {
+		return;
+	}
+
+	priv->events = g_slist_delete_link (priv->events, l);		
+	status_icon_event_free (event);
+	status_icon_update_tooltip (icon);
+	status_icon_update_icon (icon);
+
+	if (!priv->events && priv->blink_timeout) {
+		g_source_remove (priv->blink_timeout);
+		priv->blink_timeout = 0;
+	}
+}
+
+static void
+status_icon_event_remove_by_channel (EmpathyStatusIcon *icon,
+				     TpChannel         *channel)
+{
+	EmpathyStatusIconPriv *priv = GET_PRIV (icon);
+	GSList                *l;
+
+	for (l = priv->events; l; l = l->next) {
+		StatusIconEvent *event = l->data;
+
+		if (empathy_proxy_equal (event->channel, channel)) {
+			DEBUG ("Found event '%s'", event->message);
+			status_icon_event_remove (icon, event);
+			break;
+		}
+	}
+}
+
+static void
+status_icon_event_activate (EmpathyStatusIcon *icon,
+			    StatusIconEvent   *event)
+{
+	if (event->func) {
+		event->func (icon, event->user_data);
+	}
+	status_icon_event_remove (icon, event);
+}
+
+static void
+status_icon_event_add (EmpathyStatusIcon   *icon,
+		       const gchar         *icon_name,
+		       const gchar         *message,
+		       StatusIconEventFunc  func,
+		       gpointer             user_data,
+		       TpChannel           *channel)
+{
+	EmpathyStatusIconPriv *priv = GET_PRIV (icon);
+	StatusIconEvent       *event;
+	gboolean               had_events;
+
+	DEBUG ("Adding event: %s", message);
+
+	event = g_slice_new0 (StatusIconEvent);
+	event->icon_name = g_strdup (icon_name);
+	event->message = g_strdup (message);
+	event->func = func;
+	event->user_data = user_data;
+	event->icon = icon;
+
+	if (channel) {
+		event->channel = g_object_ref (channel);
+		g_signal_connect (channel, "invalidated",
+				  G_CALLBACK (status_icon_channel_invalidated_cb),
+				  icon);
+	}
+
+	had_events = (priv->events != NULL);
+	priv->events = g_slist_append (priv->events, event);
+	if (!had_events) {
+		priv->showing_event_icon = TRUE;
+		status_icon_update_icon (icon);
+		status_icon_update_tooltip (icon);
+
+		if (!priv->blink_timeout) {
+			priv->blink_timeout = g_timeout_add (BLINK_TIMEOUT,
+							     (GSourceFunc) status_icon_blink_timeout_cb,
+							     icon);
+		}
+	}
+}
+
+static void
+status_icon_channel_invalidated_cb (TpProxy           *channel,
+				    guint              domain,
+				    gint               code,
+				    gchar             *message,
+				    EmpathyStatusIcon *icon)
+{
+	DEBUG ("%s", message);
+	status_icon_event_remove_by_channel (icon, TP_CHANNEL (channel));
+}
+
+static void
 status_icon_set_visibility (EmpathyStatusIcon *icon,
 			    gboolean           visible,
 			    gboolean           store)
@@ -148,41 +310,6 @@
 }
 
 static void
-status_icon_update_tooltip (EmpathyStatusIcon *icon)
-{
-	EmpathyStatusIconPriv *priv = GET_PRIV (icon);
-	const gchar           *tooltip = NULL;
-
-	if (priv->events) {
-		tooltip = ((StatusIconEvent*)priv->events->data)->message;
-	}
-
-	if (!tooltip) {
-		tooltip = empathy_idle_get_status (priv->idle);
-	}
-
-	gtk_status_icon_set_tooltip (priv->icon, tooltip);	
-}
-
-static void
-status_icon_update_icon (EmpathyStatusIcon *icon)
-{
-	EmpathyStatusIconPriv *priv = GET_PRIV (icon);
-	const gchar           *icon_name;
-
-	if (priv->events && priv->showing_event_icon) {
-		icon_name = ((StatusIconEvent*)priv->events->data)->icon_name;
-	} else {
-		McPresence state;
-
-		state = empathy_idle_get_state (priv->idle);
-		icon_name = empathy_icon_name_for_presence (state);
-	}
-
-	gtk_status_icon_set_from_icon_name (priv->icon, icon_name);
-}
-
-static void
 status_icon_idle_notify_cb (EmpathyStatusIcon *icon)
 {
 	status_icon_update_icon (icon);
@@ -199,27 +326,6 @@
 }
 
 static void
-status_icon_event_activate (EmpathyStatusIcon *icon,
-			    StatusIconEvent   *event)
-{
-	EmpathyStatusIconPriv *priv = GET_PRIV (icon);
-
-	if (event->func) {
-		event->func (icon, event->user_data);
-	}
-
-	priv->events = g_slist_remove (priv->events, event);
-	status_icon_event_free (event);
-	status_icon_update_tooltip (icon);
-	status_icon_update_icon (icon);
-
-	if (!priv->events && priv->blink_timeout) {
-		g_source_remove (priv->blink_timeout);
-		priv->blink_timeout = 0;
-	}
-}
-
-static void
 status_icon_activate_cb (GtkStatusIcon     *status_icon,
 			 EmpathyStatusIcon *icon)
 {
@@ -319,51 +425,6 @@
 	g_object_unref (glade);
 }
 
-static gboolean
-status_icon_blink_timeout_cb (EmpathyStatusIcon *icon)
-{
-	EmpathyStatusIconPriv *priv = GET_PRIV (icon);
-
-	priv->showing_event_icon = !priv->showing_event_icon;
-	status_icon_update_icon (icon);
-
-	return TRUE;
-}
-
-static void
-status_icon_event_add (EmpathyStatusIcon   *icon,
-		       const gchar         *icon_name,
-		       const gchar         *message,
-		       StatusIconEventFunc  func,
-		       gpointer             user_data)
-{
-	EmpathyStatusIconPriv *priv = GET_PRIV (icon);
-	StatusIconEvent       *event;
-	gboolean               had_events;
-
-	DEBUG ("Adding event: %s", message);
-
-	event = g_slice_new (StatusIconEvent);
-	event->icon_name = g_strdup (icon_name);
-	event->message = g_strdup (message);
-	event->func = func;
-	event->user_data = user_data;
-
-	had_events = (priv->events != NULL);
-	priv->events = g_slist_append (priv->events, event);
-	if (!had_events) {
-		priv->showing_event_icon = TRUE;
-		status_icon_update_icon (icon);
-		status_icon_update_tooltip (icon);
-
-		if (!priv->blink_timeout) {
-			priv->blink_timeout = g_timeout_add (BLINK_TIMEOUT,
-							     (GSourceFunc) status_icon_blink_timeout_cb,
-							     icon);
-		}
-	}
-}
-
 static void
 status_icon_channel_process (EmpathyStatusIcon *icon,
 			     gpointer           user_data)
@@ -372,7 +433,6 @@
 	TpChannel             *channel = TP_CHANNEL (user_data);
 
 	empathy_dispatcher_channel_process (priv->dispatcher, channel);
-	g_object_unref (channel);
 }
 
 static gboolean
@@ -404,7 +464,7 @@
 	channel = empathy_tp_chat_get_channel (tp_chat);
 	status_icon_event_add (icon, EMPATHY_IMAGE_NEW_MESSAGE, msg,
 			       status_icon_channel_process,
-			       g_object_ref (channel));
+			       channel, channel);
 
 	g_free (msg);
 }
@@ -442,7 +502,7 @@
 
 		status_icon_event_add (icon, EMPATHY_IMAGE_VOIP, msg,
 				       status_icon_channel_process,
-				       g_object_ref (channel));
+				       channel, channel);
 
 		g_free (msg);
 		g_object_unref (contact);
@@ -453,6 +513,14 @@
 }
 
 static void
+status_icon_dispatch_channel_cb (EmpathyDispatcher *dispatcher,
+				 TpChannel         *channel,
+				 EmpathyStatusIcon *icon)
+{
+	status_icon_event_remove_by_channel (icon, channel);
+}
+
+static void
 status_icon_tube_process (EmpathyStatusIcon *icon,
 			  gpointer           user_data)
 {
@@ -512,7 +580,8 @@
 	}
 
 	status_icon_event_add (icon, icon_name, msg, status_icon_tube_process,
-			       empathy_dispatcher_tube_ref (tube));
+			       empathy_dispatcher_tube_ref (tube),
+			       tube->channel);
 
 	g_free (msg);
 }
@@ -558,7 +627,8 @@
 
 	status_icon_event_add (icon, GTK_STOCK_DIALOG_QUESTION, str->str,
 			       status_icon_pending_subscribe,
-			       g_object_ref (contact));
+			       g_object_ref (contact),
+			       NULL);
 
 	g_string_free (str, TRUE);
 }
@@ -650,6 +720,9 @@
 	g_signal_connect (priv->dispatcher, "filter-channel",
 			  G_CALLBACK (status_icon_filter_channel_cb),
 			  icon);
+	g_signal_connect (priv->dispatcher, "dispatch-channel",
+			  G_CALLBACK (status_icon_dispatch_channel_cb),
+			  icon);
 	g_signal_connect (priv->dispatcher, "filter-tube",
 			  G_CALLBACK (status_icon_filter_tube_cb),
 			  icon);

Modified: trunk/src/empathy.c
==============================================================================
--- trunk/src/empathy.c	(original)
+++ trunk/src/empathy.c	Sun May 18 14:27:44 2008
@@ -40,7 +40,7 @@
 #include <libempathy/empathy-utils.h>
 #include <libempathy/empathy-dispatcher.h>
 #include <libempathy/empathy-tp-chat.h>
-#include <libempathy/empathy-tp-call.h>
+#include <libempathy/empathy-tp-group.h>
 
 #include <libempathy-gtk/empathy-conf.h>
 
@@ -98,11 +98,14 @@
 		g_object_unref (tp_chat);
 	}
 	else if (!tp_strdiff (channel_type, TP_IFACE_CHANNEL_TYPE_STREAMED_MEDIA)) {
-		EmpathyTpCall *tp_call;
+		GtkWidget *window;
 
-		tp_call = empathy_tp_call_new (channel);
-		empathy_call_window_new (tp_call);
-		g_object_unref (tp_call);
+		window = empathy_call_window_find (channel);
+		if (window) {
+			gtk_window_present (GTK_WINDOW (window));
+		} else {
+			empathy_call_window_new (channel);
+		}
 	}
 }
 



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