From ee02c5c89132db72e5cd987cd443cd09202b6f5b Mon Sep 17 00:00:00 2001 From: Emilio Pozuelo Monfort Date: Wed, 7 Sep 2011 15:54:29 +0100 Subject: Let the existing call window know about new incoming calls https://bugzilla.gnome.org/show_bug.cgi?id=580794 --- src/empathy-call-window.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++ src/empathy-call.c | 38 +++++++++++++++++++++++++++++ 2 files changed, 100 insertions(+) diff --git a/src/empathy-call-window.c b/src/empathy-call-window.c index af06b6251..81bee0596 100644 --- a/src/empathy-call-window.c +++ b/src/empathy-call-window.c @@ -43,6 +43,7 @@ #include #include #include +#include #include #include @@ -103,6 +104,7 @@ enum { }; typedef enum { + RINGING, CONNECTING, CONNECTED, HELD, @@ -184,6 +186,12 @@ struct _EmpathyCallWindowPriv easilly repack everything when toggling fullscreen */ GtkWidget *content_hbox; + /* These are used to accept or reject an incoming call when the status + is RINGING. */ + TpyCallChannel *pending_channel; + TpChannelDispatchOperation *pending_cdo; + TpAddDispatchOperationContext *pending_context; + gulong video_output_motion_handler_id; guint bus_message_source_id; @@ -1359,6 +1367,60 @@ empathy_call_window_stage_allocation_changed_cb (ClutterActor *stage, FLOATING_TOOLBAR_SPACING - FLOATING_TOOLBAR_HEIGHT); } +static void +empathy_call_window_set_state_ringing (EmpathyCallWindow *self) +{ + g_assert (self->priv->call_state != CONNECTED); + + empathy_call_window_status_message (self, _("Incoming call")); + self->priv->call_state = RINGING; +} + +static void +empathy_call_window_stop_ringing (EmpathyCallWindow *self) +{ + empathy_call_window_status_message (self, _("Disconnected")); + self->priv->call_state = DISCONNECTED; +} + +static void +empathy_call_window_incoming_channel_invalidated_cb (TpProxy *channel, + guint domain, + gint code, + gchar *message, + EmpathyCallWindow *self) +{ + tp_channel_dispatch_operation_destroy_channels_async ( + self->priv->pending_cdo, NULL, NULL); + empathy_call_window_stop_ringing (self); + + tp_clear_object (&self->priv->pending_cdo); + tp_clear_object (&self->priv->pending_channel); + tp_clear_object (&self->priv->pending_context); +} + +void +empathy_call_window_start_ringing (EmpathyCallWindow *self, + TpyCallChannel *channel, + TpChannelDispatchOperation *dispatch_operation, + TpAddDispatchOperationContext *context) +{ + g_assert (self->priv->pending_channel == NULL); + g_assert (self->priv->pending_context == NULL); + g_assert (self->priv->pending_cdo == NULL); + + /* Start ringing and delay until the user answers or hangs. */ + self->priv->pending_channel = g_object_ref (channel); + self->priv->pending_context = g_object_ref (context); + self->priv->pending_cdo = g_object_ref (dispatch_operation); + + g_signal_connect (self->priv->pending_channel, "invalidated", + G_CALLBACK (empathy_call_window_incoming_channel_invalidated_cb), self); + + empathy_call_window_set_state_ringing (self); + tp_add_dispatch_operation_context_accept (context); +} + static void empathy_call_window_init (EmpathyCallWindow *self) { diff --git a/src/empathy-call.c b/src/empathy-call.c index a5e463ba3..1b643dec1 100644 --- a/src/empathy-call.c +++ b/src/empathy-call.c @@ -70,6 +70,42 @@ call_window_destroyed_cb (GtkWidget *window, g_application_release (G_APPLICATION (app)); } +static gboolean +find_window_for_handle (gpointer key, + gpointer value, + gpointer user_data) +{ + EmpathyContact *contact = key; + guint handle = GPOINTER_TO_UINT (user_data); + + if (handle == empathy_contact_get_handle (contact)) + return TRUE; + + return FALSE; +} + +static gboolean +incoming_call_cb (EmpathyCallFactory *factory, + guint handle, + TpyCallChannel *channel, + TpChannelDispatchOperation *dispatch_operation, + TpAddDispatchOperationContext *context, + gpointer user_data) +{ + EmpathyCallWindow *window = g_hash_table_find (call_windows, + find_window_for_handle, GUINT_TO_POINTER (handle)); + + if (window != NULL) + { + /* The window takes care of accepting or rejecting the context. */ + empathy_call_window_start_ringing (window, + channel, dispatch_operation, context); + return TRUE; + } + + return FALSE; +} + static void new_call_handler_cb (EmpathyCallFactory *factory, EmpathyCallHandler *handler, @@ -123,6 +159,8 @@ activate_cb (GApplication *application) g_signal_connect (G_OBJECT (call_factory), "new-call-handler", G_CALLBACK (new_call_handler_cb), NULL); + g_signal_connect (G_OBJECT (call_factory), "incoming-call", + G_CALLBACK (incoming_call_cb), NULL); if (!empathy_call_factory_register (call_factory, &error)) { -- cgit v1.2.3