diff --git a/src/empathy-call-window.c b/src/empathy-call-window.c
index 520a928..7349fd3 100644
--- a/src/empathy-call-window.c
+++ b/src/empathy-call-window.c
@@ -44,6 +44,7 @@
 
 #include "empathy-call-window.h"
 #include "empathy-call-window-fullscreen.h"
+#include "empathy-event-manager.h"
 #include "empathy-sidebar.h"
 
 #define BUTTON_ID "empathy-call-dtmf-button-id"
@@ -83,6 +84,7 @@ enum {
 };
 
 typedef enum {
+  RINGING,
   CONNECTING,
   CONNECTED,
   DISCONNECTED,
@@ -102,6 +104,7 @@ struct _EmpathyCallWindowPriv
   gboolean outgoing;
 
   GtkUIManager *ui_manager;
+  GtkWidget *answer_button;
   GtkWidget *video_output;
   GtkWidget *video_preview;
   GtkWidget *remote_user_avatar_widget;
@@ -115,6 +118,7 @@ struct _EmpathyCallWindowPriv
   GtkWidget *camera_button;
   GtkWidget *toolbar;
   GtkWidget *pane;
+  GtkAction *menu_answer;
   GtkAction *show_preview;
   GtkAction *send_video;
   GtkAction *redial;
@@ -136,6 +140,16 @@ struct _EmpathyCallWindowPriv
      it needs to be repacked. We keep a reference on it for easier access. */
   GtkWidget *vbox;
 
+  /* If the call is disconnected but this EmpathyCallWindow is still opened,
+     we interract directly with the event manager in order to receive the
+     call request and to respond to it */
+  EmpathyEventManager *event_manager;
+
+  /* If the call window is "Ringing", this contains the call event. When the
+     user accepts or declines the call, this event is passed to the
+     event_manager which creates or discards the call. */
+  EmpathyEvent *incoming_call_event;
+
   gulong video_output_motion_handler_id;
 
   gdouble volume;
@@ -176,67 +190,89 @@ struct _EmpathyCallWindowPriv
   gint original_height_before_fs;
 };
 
+/* An hash table containing the created call windows. The format is the
+   following:
+   Key: The contact with whom the call takes place.
+   Value : The EmpathyCallWindow used for the call. */
+static GHashTable *call_windows;
+
 #define GET_PRIV(o) \
   (G_TYPE_INSTANCE_GET_PRIVATE ((o), EMPATHY_TYPE_CALL_WINDOW, \
-    EmpathyCallWindowPriv))
+  EmpathyCallWindowPriv))
 
-static void empathy_call_window_realized_cb (GtkWidget *widget,
+
+static void empathy_call_window_answer_cb (gpointer object,
+  EmpathyCallWindow *window);
+
+static gboolean empathy_call_window_bus_message (GstBus *bus,
+  GstMessage *message, gpointer user_data);
+
+static void empathy_call_window_camera_toggled_cb (GtkToggleToolButton *toggle,
   EmpathyCallWindow *window);
 
+static void empathy_call_window_channel_closed_cb (TfChannel *channel,
+  gpointer user_data);
+
+static void empathy_call_window_conference_added_cb (
+  EmpathyCallHandler *handler, GstElement *conference, gpointer user_data);
+
 static gboolean empathy_call_window_delete_cb (GtkWidget *widget,
   GdkEvent *event, EmpathyCallWindow *window);
 
-static gboolean empathy_call_window_state_event_cb (GtkWidget *widget,
-  GdkEventWindowState *event, EmpathyCallWindow *window);
-
-static void empathy_call_window_sidebar_toggled_cb (GtkToggleButton *toggle,
-  EmpathyCallWindow *window);
+static gboolean empathy_call_window_disconnected (EmpathyCallWindow *self);
 
-static void empathy_call_window_camera_toggled_cb (GtkToggleToolButton *toggle,
+static void empathy_call_window_fullscreen_cb (gpointer object,
   EmpathyCallWindow *window);
 
-static void empathy_call_window_set_send_video (EmpathyCallWindow *window,
-  gboolean send);
+static void empathy_call_window_fullscreen_toggle (EmpathyCallWindow *window);
 
-static void empathy_call_window_send_video_toggled_cb (GtkToggleAction *toggle,
+static void empathy_call_window_hangup_cb (gpointer object,
   EmpathyCallWindow *window);
 
-static void empathy_call_window_show_preview_toggled_cb (GtkToggleAction *toggle,
-  EmpathyCallWindow *window);
+static gboolean empathy_call_window_key_press_cb (GtkWidget *video_output,
+  GdkEventKey *event, EmpathyCallWindow *window);
 
 static void empathy_call_window_mic_toggled_cb (
   GtkToggleToolButton *toggle, EmpathyCallWindow *window);
 
-static void empathy_call_window_sidebar_hidden_cb (EmpathySidebar *sidebar,
+static void empathy_call_window_realized_cb (GtkWidget *widget,
   EmpathyCallWindow *window);
 
-static void empathy_call_window_sidebar_shown_cb (EmpathySidebar *sidebar,
+static void empathy_call_window_redial_cb (gpointer object,
   EmpathyCallWindow *window);
 
-static void empathy_call_window_hangup_cb (gpointer object,
-  EmpathyCallWindow *window);
+static gboolean empathy_call_window_request_resource_cb (
+  EmpathyCallHandler *handler, FsMediaType type, FsStreamDirection direction,
+  gpointer user_data);
 
-static void empathy_call_window_fullscreen_cb (gpointer object,
-  EmpathyCallWindow *window);
+static void empathy_call_window_restart_call (EmpathyCallWindow *window);
 
-static void empathy_call_window_fullscreen_toggle (EmpathyCallWindow *window);
+static gboolean empathy_call_window_state_event_cb (GtkWidget *widget,
+  GdkEventWindowState *event, EmpathyCallWindow *window);
 
-static gboolean empathy_call_window_video_button_press_cb (GtkWidget *video_output,
-  GdkEventButton *event, EmpathyCallWindow *window);
+static void empathy_call_window_send_video_toggled_cb (GtkToggleAction *toggle,
+  EmpathyCallWindow *window);
 
-static gboolean empathy_call_window_key_press_cb (GtkWidget *video_output,
-  GdkEventKey *event, EmpathyCallWindow *window);
+static void empathy_call_window_set_send_video (EmpathyCallWindow *window,
+  gboolean send);
 
-static gboolean empathy_call_window_video_output_motion_notify (GtkWidget *widget,
-  GdkEventMotion *event, EmpathyCallWindow *window);
+static void empathy_call_window_show_preview_toggled_cb (GtkToggleAction *toggle,
+  EmpathyCallWindow *window);
 
-static void empathy_call_window_video_menu_popup (EmpathyCallWindow *window,
-  guint button);
+static void empathy_call_window_sidebar_hidden_cb (EmpathySidebar *sidebar,
+  EmpathyCallWindow *window);
 
-static void empathy_call_window_redial_cb (gpointer object,
+static void empathy_call_window_sidebar_shown_cb (EmpathySidebar *sidebar,
   EmpathyCallWindow *window);
 
-static void empathy_call_window_restart_call (EmpathyCallWindow *window);
+static void empathy_call_window_sidebar_toggled_cb (GtkToggleButton *toggle,
+  EmpathyCallWindow *window);
+
+static void empathy_call_window_sink_added_cb (EmpathyCallHandler *handler,
+  GstPad *sink, guint media_type, gpointer user_data);
+
+static void empathy_call_window_src_added_cb (EmpathyCallHandler *handler,
+  GstPad *src, guint media_type, gpointer user_data);
 
 static void empathy_call_window_status_message (EmpathyCallWindow *window,
   gchar *message);
@@ -244,13 +280,19 @@ static void empathy_call_window_status_message (EmpathyCallWindow *window,
 static void empathy_call_window_update_avatars_visibility (EmpathyTpCall *call,
   EmpathyCallWindow *window);
 
-static gboolean empathy_call_window_bus_message (GstBus *bus,
-  GstMessage *message, gpointer user_data);
+static gboolean empathy_call_window_video_button_press_cb (GtkWidget *video_output,
+  GdkEventButton *event, EmpathyCallWindow *window);
 
-static void
-empathy_call_window_volume_changed_cb (GtkScaleButton *button,
+static void empathy_call_window_video_menu_popup (EmpathyCallWindow *window,
+  guint button);
+
+static gboolean empathy_call_window_video_output_motion_notify (GtkWidget *widget,
+  GdkEventMotion *event, EmpathyCallWindow *window);
+
+static void empathy_call_window_volume_changed_cb (GtkScaleButton *button,
   gdouble value, EmpathyCallWindow *window);
 
+
 static void
 empathy_call_window_setup_toolbar (EmpathyCallWindow *self)
 {
@@ -668,6 +710,44 @@ empathy_call_window_set_state_connecting (EmpathyCallWindow *window)
 }
 
 static void
+empathy_call_window_set_state_ringing (EmpathyCallWindow *window)
+{
+  EmpathyCallWindowPriv *priv = GET_PRIV (window);
+  empathy_call_window_status_message (window, _("Ringing"));
+  priv->call_state = RINGING;
+
+  gtk_action_set_sensitive (priv->menu_answer, TRUE);
+  gtk_widget_set_sensitive (priv->answer_button, TRUE);
+}
+
+static void
+empathy_call_window_event_added_cb (EmpathyEventManager *manager,
+    EmpathyEvent *event, EmpathyCallWindow *self)
+{
+  EmpathyCallWindowPriv *priv = GET_PRIV (self);
+  gchar *header_if_current_contact = g_strdup_printf (
+      _("Incoming call from %s"), empathy_contact_get_name (priv->contact));
+
+  if (g_strcmp0 (event->header, header_if_current_contact) == 0)
+    {
+      empathy_call_window_set_state_ringing (self);
+      priv->incoming_call_event = event;
+    }
+
+  g_free (header_if_current_contact);
+}
+
+static void
+empathy_call_window_event_removed_cb (EmpathyEventManager *manager,
+    EmpathyEvent *event, EmpathyCallWindow *self)
+{
+  EmpathyCallWindowPriv *priv = GET_PRIV (self);
+
+  if (event == priv->incoming_call_event)
+    empathy_call_window_disconnected (self);
+}
+
+static void
 empathy_call_window_init (EmpathyCallWindow *self)
 {
   EmpathyCallWindowPriv *priv = GET_PRIV (self);
@@ -679,11 +759,20 @@ empathy_call_window_init (EmpathyCallWindow *self)
   GstBus *bus;
   gchar *filename;
 
+  priv->event_manager = empathy_event_manager_dup_singleton ();
+
+  g_signal_connect (priv->event_manager, "event-added",
+    G_CALLBACK (empathy_call_window_event_added_cb), self);
+  g_signal_connect (priv->event_manager, "event-removed",
+    G_CALLBACK (empathy_call_window_event_removed_cb), self);
+
   filename = empathy_file_lookup ("empathy-call-window.ui", "src");
   gui = empathy_builder_get_file (filename,
     "call_window_vbox", &top_vbox,
     "pane", &priv->pane,
     "statusbar", &priv->statusbar,
+    "menuanswer", &priv->menu_answer,
+    "answer", &priv->answer_button,
     "redial", &priv->redial_button,
     "microphone", &priv->mic_button,
     "camera", &priv->camera_button,
@@ -696,6 +785,8 @@ empathy_call_window_init (EmpathyCallWindow *self)
     NULL);
 
   empathy_builder_connect (gui, self,
+    "menuanswer", "activate", empathy_call_window_answer_cb,
+    "answer", "clicked", empathy_call_window_answer_cb,
     "menuhangup", "activate", empathy_call_window_hangup_cb,
     "hangup", "clicked", empathy_call_window_hangup_cb,
     "menuredial", "activate", empathy_call_window_redial_cb,
@@ -1020,7 +1111,6 @@ empathy_call_window_video_stream_changed_cb (EmpathyTpCall *call,
 void
 empathy_call_window_dispose (GObject *object)
 {
-  EmpathyTpCall *call;
   EmpathyCallWindow *self = EMPATHY_CALL_WINDOW (object);
   EmpathyCallWindowPriv *priv = GET_PRIV (self);
 
@@ -1029,18 +1119,27 @@ empathy_call_window_dispose (GObject *object)
 
   priv->dispose_has_run = TRUE;
 
-  g_object_get (priv->handler, "tp-call", &call, NULL);
-
-  if (call != NULL)
+  if (priv->handler != NULL)
     {
-      g_signal_handlers_disconnect_by_func (call,
-        empathy_call_window_video_stream_changed_cb, object);
-    }
+      EmpathyTpCall *call;
+      EmpathyContact *contact;
 
-  g_object_unref (call);
+      g_object_get (priv->handler, "tp-call", &call, NULL);
+      g_object_get (priv->handler, "contact", &contact, NULL);
 
-  if (priv->handler != NULL)
-    g_object_unref (priv->handler);
+      g_object_unref (call);
+
+      if (call_windows != NULL)
+        g_hash_table_remove (call_windows, contact);
+
+      if (call != NULL)
+        {
+          g_signal_handlers_disconnect_by_func (call,
+              empathy_call_window_video_stream_changed_cb, object);
+        }
+
+      g_object_unref (priv->handler);
+    }
 
   priv->handler = NULL;
 
@@ -1098,6 +1197,12 @@ empathy_call_window_finalize (GObject *object)
       priv->video_output_motion_handler_id = 0;
     }
 
+  g_signal_handlers_disconnect_by_func (priv->event_manager,
+    empathy_call_window_event_added_cb, self);
+
+  g_signal_handlers_disconnect_by_func (priv->event_manager,
+    empathy_call_window_event_removed_cb, self);
+
   /* free any data held directly by the object here */
   g_mutex_free (priv->lock);
 
@@ -1115,6 +1220,58 @@ empathy_call_window_new (EmpathyCallHandler *handler)
 }
 
 static void
+empathy_call_window_connect_handler (EmpathyCallWindow *window)
+{
+  EmpathyCallWindowPriv *priv = GET_PRIV (window);
+
+  g_signal_connect (priv->handler, "conference-added",
+      G_CALLBACK (empathy_call_window_conference_added_cb), window);
+  g_signal_connect (priv->handler, "request-resource",
+      G_CALLBACK (empathy_call_window_request_resource_cb), window);
+  g_signal_connect (priv->handler, "closed",
+      G_CALLBACK (empathy_call_window_channel_closed_cb), window);
+  g_signal_connect (priv->handler, "src-pad-added",
+      G_CALLBACK (empathy_call_window_src_added_cb), window);
+  g_signal_connect (priv->handler, "sink-pad-added",
+      G_CALLBACK (empathy_call_window_sink_added_cb), window);
+}
+
+void
+empathy_call_window_present_window (EmpathyCallHandler *handler)
+{
+  EmpathyCallWindow *window;
+  EmpathyContact *contact;
+
+  g_return_if_fail (handler != NULL);
+
+  g_object_get (handler, "contact", &contact, NULL);
+
+  if (call_windows == NULL)
+    call_windows = g_hash_table_new (NULL, NULL);
+
+  if ((window = g_hash_table_lookup (call_windows, contact)) == NULL)
+    {
+      /* There is no existing window for this contact. We create a new one */
+      window = empathy_call_window_new (handler);
+
+      g_hash_table_insert (call_windows, contact, window);
+
+      gtk_widget_show (GTK_WIDGET (window));
+    }
+  else
+    {
+      EmpathyCallWindowPriv *priv = GET_PRIV (window);
+
+      g_object_ref (handler);
+      priv->handler = handler;
+      empathy_call_window_connect_handler (window);
+
+      empathy_window_present (GTK_WINDOW (window), TRUE);
+      empathy_call_window_restart_call (window);
+    }
+}
+
+static void
 empathy_call_window_conference_added_cb (EmpathyCallHandler *handler,
   GstElement *conference, gpointer user_data)
 {
@@ -1202,6 +1359,8 @@ empathy_call_window_disconnected (EmpathyCallWindow *self)
   EmpathyCallWindowPriv *priv = GET_PRIV (self);
   gboolean could_reset_pipeline = empathy_call_window_reset_pipeline (self);
 
+  priv->incoming_call_event = NULL;
+
   if (priv->call_state == CONNECTING)
       empathy_sound_stop (EMPATHY_SOUND_PHONE_OUTGOING);
 
@@ -1243,6 +1402,9 @@ empathy_call_window_disconnected (EmpathyCallWindow *self)
           FALSE);
       gtk_action_set_sensitive (priv->show_preview, FALSE);
 
+      gtk_action_set_sensitive (priv->menu_answer, FALSE);
+      gtk_widget_set_sensitive (priv->answer_button, FALSE);
+
       gtk_widget_hide (priv->video_output);
       gtk_widget_show (priv->remote_user_avatar_widget);
 
@@ -1349,6 +1511,8 @@ empathy_call_window_connected (gpointer user_data)
   gboolean can_send_video = priv->video_input != NULL && priv->contact != NULL
     && empathy_contact_can_voip_video (priv->contact);
 
+  priv->incoming_call_event = NULL;
+
   g_object_get (priv->handler, "tp-call", &call, NULL);
 
   g_signal_connect (call, "notify::video-stream",
@@ -1375,6 +1539,8 @@ empathy_call_window_connected (gpointer user_data)
   gtk_widget_set_sensitive (priv->camera_button, can_send_video);
   gtk_action_set_sensitive (priv->send_video, can_send_video);
 
+  gtk_action_set_sensitive (priv->menu_answer, FALSE);
+  gtk_widget_set_sensitive (priv->answer_button, FALSE);
   gtk_action_set_sensitive (priv->redial, FALSE);
   gtk_widget_set_sensitive (priv->redial_button, FALSE);
 
@@ -1633,17 +1799,7 @@ empathy_call_window_realized_cb (GtkWidget *widget, EmpathyCallWindow *window)
 {
   EmpathyCallWindowPriv *priv = GET_PRIV (window);
 
-  g_signal_connect (priv->handler, "conference-added",
-    G_CALLBACK (empathy_call_window_conference_added_cb), window);
-  g_signal_connect (priv->handler, "request-resource",
-    G_CALLBACK (empathy_call_window_request_resource_cb), window);
-  g_signal_connect (priv->handler, "closed",
-    G_CALLBACK (empathy_call_window_channel_closed_cb), window);
-  g_signal_connect (priv->handler, "src-pad-added",
-    G_CALLBACK (empathy_call_window_src_added_cb), window);
-  g_signal_connect (priv->handler, "sink-pad-added",
-    G_CALLBACK (empathy_call_window_sink_added_cb), window);
-
+  empathy_call_window_connect_handler (window);
   gst_element_set_state (priv->pipeline, GST_STATE_PAUSED);
 }
 
@@ -1931,10 +2087,27 @@ empathy_call_window_sidebar_shown_cb (EmpathySidebar *sidebar,
 }
 
 static void
+empathy_call_window_answer_cb (gpointer object,
+    EmpathyCallWindow *window)
+{
+  EmpathyCallWindowPriv *priv = GET_PRIV (window);
+
+  empathy_event_manager_accept_incoming_call_event (priv->incoming_call_event,
+    priv->event_manager);
+}
+
+static void
 empathy_call_window_hangup_cb (gpointer object,
                                EmpathyCallWindow *window)
 {
-  if (empathy_call_window_disconnected (window))
+  EmpathyCallWindowPriv *priv = GET_PRIV (window);
+  gboolean ringing = priv->call_state == RINGING;
+
+  if (ringing)
+    empathy_event_manager_reject_incoming_call_event (priv->incoming_call_event,
+      priv->event_manager);
+
+  if (empathy_call_window_disconnected (window) && !ringing)
     gtk_widget_destroy (GTK_WIDGET (window));
 }
 
diff --git a/src/empathy-call-window.h b/src/empathy-call-window.h
index 01ea5de..ebf0468 100644
--- a/src/empathy-call-window.h
+++ b/src/empathy-call-window.h
@@ -58,6 +58,7 @@ GType empathy_call_window_get_type (void);
     EmpathyCallWindowClass))
 
 EmpathyCallWindow *empathy_call_window_new (EmpathyCallHandler *handler);
+void empathy_call_window_present_window (EmpathyCallHandler *handler);
 
 G_END_DECLS
 
diff --git a/src/empathy-call-window.ui b/src/empathy-call-window.ui
index 9e7c096..34c4b8f 100644
--- a/src/empathy-call-window.ui
+++ b/src/empathy-call-window.ui
@@ -18,6 +18,14 @@
           </object>
         </child>
         <child>
+          <object class="GtkAction" id="menuanswer">
+            <property name="icon_name">call-start</property>
+            <property name="name">menuanswer</property>
+            <property name="label" translatable="yes">Answer</property>
+            <property name="sensitive">False</property>
+          </object>
+        </child>
+        <child>
           <object class="GtkAction" id="menuhangup">
             <property name="icon_name">call-stop</property>
             <property name="name">menuhangup</property>
@@ -58,6 +66,7 @@
       <menubar name="menubar1">
         <menu action="call">
           <menuitem action="send_video"/>
+          <menuitem action="menuanswer"/>
           <menuitem action="menuhangup"/>
           <menuitem action="menuredial"/>
         </menu>
@@ -85,6 +94,18 @@
           <object class="GtkToolbar" id="toolbar">
             <property name="visible">True</property>
             <child>
+              <object class="GtkToolButton" id="answer">
+                <property name="visible">True</property>
+                <property name="is_important">True</property>
+                <property name="label" translatable="yes">Answer</property>
+                <property name="icon_name">call-start</property>
+                <property name="sensitive">False</property>
+              </object>
+              <packing>
+                <property name="homogeneous">True</property>
+              </packing>
+            </child>
+            <child>
               <object class="GtkToolButton" id="hangup">
                 <property name="visible">True</property>
                 <property name="is_important">True</property>
diff --git a/src/empathy-event-manager.c b/src/empathy-event-manager.c
index 1a7ec09..e42b445 100644
--- a/src/empathy-event-manager.c
+++ b/src/empathy-event-manager.c
@@ -276,6 +276,28 @@ event_update (EmpathyEventManager *manager, EventPriv *event,
 }
 
 static void
+event_manager_accept_incoming_call (EventManagerApproval *approval)
+{
+  EmpathyCallFactory *factory = empathy_call_factory_get ();
+  empathy_call_factory_claim_channel (factory, approval->operation);
+}
+
+static void
+event_manager_reject_incoming_call (EventManagerApproval *approval)
+{
+  EmpathyTpCall *call =
+    EMPATHY_TP_CALL (
+      empathy_dispatch_operation_get_channel_wrapper (approval->operation));
+
+  g_object_ref (call);
+
+  if (empathy_dispatch_operation_claim (approval->operation))
+    empathy_tp_call_close (call);
+
+  g_object_unref (call);
+}
+
+static void
 event_manager_call_window_confirmation_dialog_response_cb (GtkDialog *dialog,
   gint response, gpointer user_data)
 {
@@ -285,23 +307,9 @@ event_manager_call_window_confirmation_dialog_response_cb (GtkDialog *dialog,
   approval->dialog = NULL;
 
   if (response != GTK_RESPONSE_ACCEPT)
-    {
-      EmpathyTpCall *call =
-        EMPATHY_TP_CALL (
-          empathy_dispatch_operation_get_channel_wrapper (
-            approval->operation));
-
-      g_object_ref (call);
-      if (empathy_dispatch_operation_claim (approval->operation))
-        empathy_tp_call_close (call);
-      g_object_unref (call);
-
-    }
+    event_manager_reject_incoming_call (approval);
   else
-    {
-      EmpathyCallFactory *factory = empathy_call_factory_get ();
-      empathy_call_factory_claim_channel (factory, approval->operation);
-    }
+    event_manager_accept_incoming_call (approval);
 }
 
 static void
@@ -385,6 +393,56 @@ event_manager_chat_message_received_cb (EmpathyTpChat *tp_chat,
     EMPATHY_SOUND_CONVERSATION_NEW);
 }
 
+static EventPriv *
+empathy_event_manager_get_existing_event_from_public (EmpathyEvent *event,
+  EmpathyEventManager *manager)
+{
+  /* Returns the EventPriv that is in the EmpathyEventManager's event list
+     whose public part corresponds to the EmpathyEvent passed by parameter. */
+
+  EmpathyEventManagerPriv *priv = GET_PRIV (manager);
+  EventPriv *e;
+  EventPriv *event_priv = NULL;
+  GSList *event_list = priv->events;
+  gboolean event_found = FALSE;
+
+  for (event_list = priv->events; event_list && !event_found;
+        event_list = event_list->next)
+    {
+      e = event_list->data;
+      event_found = empathy_events_are_equals (&e->public, event);
+
+      if (event_found)
+        event_priv = e;
+    }
+
+  return event_priv;
+}
+
+void
+empathy_event_manager_accept_incoming_call_event (EmpathyEvent *event,
+    EmpathyEventManager *manager)
+{
+  EventPriv *event_priv =
+    empathy_event_manager_get_existing_event_from_public (event, manager);
+
+  g_return_if_fail (event_priv != NULL);
+
+  event_manager_accept_incoming_call (event_priv->approval);
+}
+
+void
+empathy_event_manager_reject_incoming_call_event (EmpathyEvent *event,
+    EmpathyEventManager *manager)
+{
+  EventPriv *event_priv =
+    empathy_event_manager_get_existing_event_from_public (event, manager);
+
+  g_return_if_fail (event_priv != NULL);
+
+  event_manager_reject_incoming_call (event_priv->approval);
+}
+
 static void
 event_manager_approval_done (EventManagerApproval *approval)
 {
@@ -1085,6 +1143,16 @@ empathy_event_manager_get_top_event (EmpathyEventManager *manager)
   return priv->events ? priv->events->data : NULL;
 }
 
+gboolean
+empathy_events_are_equals (EmpathyEvent *event1, EmpathyEvent *event2)
+{
+  return (event1->contact == event2->contact &&
+           g_strcmp0 (event1->icon_name, event2->icon_name) == 0 &&
+           g_strcmp0 (event1->header, event2->header) == 0 &&
+           g_strcmp0 (event1->message, event2->message) == 0 &&
+           event1->must_ack == event2->must_ack);
+}
+
 void
 empathy_event_activate (EmpathyEvent *event_public)
 {
diff --git a/src/empathy-event-manager.h b/src/empathy-event-manager.h
index af73c8e..8125428 100644
--- a/src/empathy-event-manager.h
+++ b/src/empathy-event-manager.h
@@ -62,6 +62,12 @@ EmpathyEvent *       empathy_event_manager_get_top_event (EmpathyEventManager *m
 GSList *             empathy_event_manager_get_events    (EmpathyEventManager *manager);
 void                 empathy_event_activate              (EmpathyEvent        *event);
 void                 empathy_event_inhibit_updates       (EmpathyEvent        *event);
+gboolean empathy_events_are_equals (EmpathyEvent *event1, EmpathyEvent *event2);
+
+void empathy_event_manager_accept_incoming_call_event (EmpathyEvent *event,
+    EmpathyEventManager *manager);
+void empathy_event_manager_reject_incoming_call_event (EmpathyEvent *event,
+    EmpathyEventManager *manager);
 
 G_END_DECLS
 
diff --git a/src/empathy.c b/src/empathy.c
index aef3610..dd02020 100644
--- a/src/empathy.c
+++ b/src/empathy.c
@@ -447,10 +447,7 @@ static void
 new_call_handler_cb (EmpathyCallFactory *factory, EmpathyCallHandler *handler,
 	gboolean outgoing, gpointer user_data)
 {
-	EmpathyCallWindow *window;
-
-	window = empathy_call_window_new (handler);
-	gtk_widget_show (GTK_WIDGET (window));
+	empathy_call_window_present_window (handler);
 }
 
 #ifdef ENABLE_DEBUG
