]> git.0d.be Git - empathy.git/blobdiff - src/empathy-call-window.c
roster-window: fix crash if empathy_chatroom_manager_find() failed
[empathy.git] / src / empathy-call-window.c
index e8c3912d7570046e7d4705f176e5744ac6ed65d6..a54346c6de9d87b451a7c26ef0354dfab267ad2b 100644 (file)
  */
 
 #include "config.h"
+#include "empathy-call-window.h"
 
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <math.h>
-
-#include <gdk/gdkkeysyms.h>
-#include <gst/gst.h>
-#include <gtk/gtk.h>
 #include <glib/gi18n.h>
-
-#include <clutter/clutter.h>
-#include <clutter-gtk/clutter-gtk.h>
-#include <clutter-gst/clutter-gst.h>
-
-#include <telepathy-glib/util.h>
 #include <telepathy-farstream/telepathy-farstream.h>
-#include <telepathy-glib/util.h>
-
 #include <farstream/fs-element-added-notifier.h>
 #include <farstream/fs-utils.h>
+#include <tp-account-widgets/tpaw-builder.h>
+#include <tp-account-widgets/tpaw-camera-monitor.h>
+#include <tp-account-widgets/tpaw-images.h>
+#include <tp-account-widgets/tpaw-pixbuf-utils.h>
+#include <tp-account-widgets/tpaw-utils.h>
+#include <telepathy-glib/telepathy-glib-dbus.h>
 
-#include <libempathy/empathy-camera-monitor.h>
-#include <libempathy/empathy-gsettings.h>
-#include <libempathy/empathy-request-util.h>
-#include <libempathy/empathy-utils.h>
-
-#include <libempathy-gtk/empathy-avatar-image.h>
-#include <libempathy-gtk/empathy-dialpad-widget.h>
-#include <libempathy-gtk/empathy-ui-utils.h>
-#include <libempathy-gtk/empathy-sound-manager.h>
-#include <libempathy-gtk/empathy-geometry.h>
-#include <libempathy-gtk/empathy-images.h>
-#include <libempathy-gtk/empathy-call-utils.h>
-
-#define DEBUG_FLAG EMPATHY_DEBUG_VOIP
-#include <libempathy/empathy-debug.h>
-
-#include "empathy-call-window.h"
-#include "empathy-call-window-fullscreen.h"
-#include "empathy-call-factory.h"
 #include "empathy-about-dialog.h"
-#include "empathy-audio-src.h"
 #include "empathy-audio-sink.h"
-#include "empathy-video-src.h"
+#include "empathy-call-utils.h"
+#include "empathy-call-window-fullscreen.h"
+#include "empathy-camera-menu.h"
+#include "empathy-dialpad-widget.h"
+#include "empathy-geometry.h"
+#include "empathy-gsettings.h"
+#include "empathy-images.h"
 #include "empathy-mic-menu.h"
 #include "empathy-preferences.h"
+#include "empathy-request-util.h"
 #include "empathy-rounded-actor.h"
 #include "empathy-rounded-rectangle.h"
 #include "empathy-rounded-texture.h"
-#include "empathy-camera-menu.h"
+#include "empathy-sound-manager.h"
+#include "empathy-ui-utils.h"
+#include "empathy-utils.h"
+
+#define DEBUG_FLAG EMPATHY_DEBUG_VOIP
+#include "empathy-debug.h"
 
 #define CONTENT_HBOX_SPACING 3
 #define CONTENT_HBOX_CHILDREN_PACKING_PADDING 0
 /* The roundedness of preview box and placeholders */
 #define PREVIEW_ROUND_FACTOR 16
 
+#define PREVIEW_BUTTON_OPACITY 180
+
 G_DEFINE_TYPE(EmpathyCallWindow, empathy_call_window, GTK_TYPE_WINDOW)
 
 enum {
   PROP_CALL_HANDLER = 1,
 };
 
+enum {
+  SIG_INHIBIT,
+  LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL];
+
 typedef enum {
   RINGING,       /* Incoming call */
   CONNECTING,    /* Outgoing call */
@@ -134,9 +126,9 @@ struct _EmpathyCallWindowPriv
 
   EmpathyContact *contact;
 
-  EmpathyCameraMonitor *camera_monitor;
+  TpawCameraMonitor *camera_monitor;
 
-  guint call_state;
+  CallState call_state;
   gboolean outgoing;
 
   GtkUIManager *ui_manager;
@@ -574,17 +566,17 @@ empathy_call_window_swap_camera_cb (GtkAction *action,
 
   DEBUG ("Swapping the camera");
 
-  cameras = empathy_camera_monitor_get_cameras (self->priv->camera_monitor);
+  cameras = tpaw_camera_monitor_get_cameras (self->priv->camera_monitor);
   current_cam = empathy_video_src_dup_device (
       EMPATHY_GST_VIDEO_SRC (self->priv->video_input));
 
   for (l = cameras; l != NULL; l = l->next)
     {
-      EmpathyCamera *camera = l->data;
+      TpawCamera *camera = l->data;
 
       if (!tp_strdiff (camera->device, current_cam))
         {
-          EmpathyCamera *next;
+          TpawCamera *next;
 
           if (l->next != NULL)
             next = l->next->data;
@@ -605,29 +597,34 @@ empathy_call_window_swap_camera_cb (GtkAction *action,
 }
 
 static void
-empathy_call_window_camera_added_cb (EmpathyCameraMonitor *monitor,
-    EmpathyCamera *camera,
-    EmpathyCallWindow *self)
+empathy_call_window_update_swap_camera (EmpathyCallWindow *self)
 {
-  const GList *cameras = empathy_camera_monitor_get_cameras (monitor);
+  const GList *cameras = tpaw_camera_monitor_get_cameras (
+      self->priv->camera_monitor);
 
   gtk_action_set_visible (self->priv->menu_swap_camera,
       g_list_length ((GList *) cameras) >= 2);
 }
 
 static void
-empathy_call_window_camera_removed_cb (EmpathyCameraMonitor *monitor,
-    EmpathyCamera *camera,
+empathy_call_window_camera_added_cb (TpawCameraMonitor *monitor,
+    TpawCamera *camera,
     EmpathyCallWindow *self)
 {
-  const GList *cameras = empathy_camera_monitor_get_cameras (monitor);
+  empathy_call_window_update_swap_camera (self);
+}
 
-  gtk_action_set_visible (self->priv->menu_swap_camera,
-      g_list_length ((GList *) cameras) >= 2);
+static void
+empathy_call_window_camera_removed_cb (TpawCameraMonitor *monitor,
+    TpawCamera *camera,
+    EmpathyCallWindow *self)
+{
+  empathy_call_window_update_swap_camera (self);
 }
 
 static void
-empathy_call_window_preview_button_clicked_cb (GtkButton *button,
+empathy_call_window_preview_button_clicked_cb (ClutterClickAction *action,
+    ClutterActor *actor,
     EmpathyCallWindow *self)
 {
   GtkWidget *menu;
@@ -640,7 +637,9 @@ empathy_call_window_preview_button_clicked_cb (GtkButton *button,
 }
 
 static void
-empathy_call_window_preview_hidden_button_clicked_cb (GtkButton *button,
+empathy_call_window_preview_hidden_button_clicked_cb (
+    ClutterClickAction *action,
+    ClutterActor *actor,
     EmpathyCallWindow *self)
 {
   GtkWidget *menu;
@@ -1068,7 +1067,6 @@ create_video_preview (EmpathyCallWindow *self)
   ClutterActor *preview;
   ClutterActor *b;
   ClutterAction *action;
-  GtkWidget *button;
   PreviewPosition pos;
 
   g_assert (priv->video_preview == NULL);
@@ -1120,27 +1118,27 @@ create_video_preview (EmpathyCallWindow *self)
       "async", FALSE,
       NULL);
 
-  /* Translators: this is an "Info" label. It should be as short
-   * as possible. */
-  button = gtk_button_new_with_label (_("i"));
-  priv->preview_shown_button = b = gtk_clutter_actor_new_with_contents (button);
-  clutter_actor_set_size (b, 24, 24);
+  /* Preview show */
+  priv->preview_shown_button = b = gtk_clutter_actor_new_with_contents (
+      gtk_image_new_from_icon_name ("emblem-system-symbolic",
+        GTK_ICON_SIZE_MENU));
   clutter_actor_set_margin_right (b, 4);
   clutter_actor_set_margin_bottom (b, 2);
+  clutter_actor_set_opacity (b, PREVIEW_BUTTON_OPACITY);
   make_background_transparent (GTK_CLUTTER_ACTOR (b));
 
   clutter_bin_layout_add (CLUTTER_BIN_LAYOUT (layout), b,
       CLUTTER_BIN_ALIGNMENT_END, CLUTTER_BIN_ALIGNMENT_END);
 
-  g_signal_connect (button, "clicked",
-      G_CALLBACK (empathy_call_window_preview_button_clicked_cb),
-      self);
+  action = clutter_click_action_new ();
+  clutter_actor_add_action (b, action);
+  g_signal_connect (action, "clicked",
+      G_CALLBACK (empathy_call_window_preview_button_clicked_cb), self);
 
-  /* Translators: this is an "Info" label. It should be as short
-   * as possible. */
-  button = gtk_button_new_with_label (_("i"));
-  priv->preview_hidden_button = b = gtk_clutter_actor_new_with_contents (button);
-  clutter_actor_set_size (b, 24, 24);
+  /* Preview hidden */
+  priv->preview_hidden_button = b = gtk_clutter_actor_new_with_contents (
+      gtk_image_new_from_icon_name ("emblem-system-symbolic",
+        GTK_ICON_SIZE_MENU));
   make_background_transparent (GTK_CLUTTER_ACTOR (b));
 
   clutter_bin_layout_add (CLUTTER_BIN_LAYOUT (priv->preview_layout),
@@ -1152,9 +1150,10 @@ create_video_preview (EmpathyCallWindow *self)
 
   clutter_actor_hide (priv->preview_hidden_button);
 
-  g_signal_connect (button, "clicked",
-      G_CALLBACK (empathy_call_window_preview_hidden_button_clicked_cb),
-      self);
+  action = clutter_click_action_new ();
+  clutter_actor_add_action (b, action);
+  g_signal_connect (action, "clicked",
+      G_CALLBACK (empathy_call_window_preview_hidden_button_clicked_cb), self);
 
   clutter_bin_layout_add (CLUTTER_BIN_LAYOUT (priv->preview_layout),
       priv->video_preview,
@@ -1313,10 +1312,10 @@ enable_camera (EmpathyCallWindow *self)
 }
 
 static void
-empathy_call_window_camera_toggled_cb (GtkToggleToolButton *toggle,
+empathy_call_window_camera_toggled_cb (GtkToggleButton *toggle,
   EmpathyCallWindow *self)
 {
-  if (gtk_toggle_tool_button_get_active (toggle))
+  if (gtk_toggle_button_get_active (toggle))
     enable_camera (self);
   else
     disable_camera (self);
@@ -1365,7 +1364,65 @@ empathy_call_window_contents_cb (GtkAction *action,
 }
 
 static void
-empathy_call_window_debug_cb (GtkAction *action,
+show_png (GPid pid, gint status, gpointer user_data)
+{
+  gtk_show_uri (NULL, (gchar *) user_data, GDK_CURRENT_TIME, NULL);
+  g_spawn_close_pid (pid);
+  g_free (user_data);
+}
+
+static void
+empathy_call_window_debug_gst_cb (GtkAction *action,
+    EmpathyCallWindow *self)
+{
+  EmpathyCallWindowPriv *priv = GET_PRIV (self);
+  GDateTime *date_time;
+  GPid dot_pid;
+  const gchar *dot_dir;
+  const gchar *prgname;
+  gchar *dot_cmd;
+  gchar *filename;
+  gchar **argv;
+  gint argc;
+
+  if (priv->pipeline == NULL)
+    DEBUG ("No pipeline");
+
+  date_time = g_date_time_new_now_utc ();
+  prgname = g_get_prgname ();
+  filename = g_strdup_printf ("%s-%" G_GINT64_FORMAT, prgname,
+      g_date_time_to_unix (date_time));
+
+  GST_DEBUG_BIN_TO_DOT_FILE (GST_BIN (priv->pipeline),
+      GST_DEBUG_GRAPH_SHOW_ALL, filename);
+
+  dot_dir = g_getenv ("GST_DEBUG_DUMP_DOT_DIR");
+  dot_cmd = g_strdup_printf ("dot -Tpng -o %s.png %s.dot",
+      filename,
+      filename);
+  g_shell_parse_argv (dot_cmd, &argc, &argv, NULL);
+
+  if (g_spawn_async (dot_dir,
+          argv,
+          NULL,
+          G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_SEARCH_PATH,
+          NULL,
+          NULL,
+          &dot_pid,
+          NULL))
+    {
+      gchar *uri = g_strdup_printf ("file://%s/%s.png", dot_dir, filename);
+      g_child_watch_add (dot_pid, show_png, uri);
+    }
+
+  g_strfreev (argv);
+  g_free (dot_cmd);
+  g_free (filename);
+  g_date_time_unref (date_time);
+}
+
+static void
+empathy_call_window_debug_tp_cb (GtkAction *action,
     EmpathyCallWindow *self)
 {
   empathy_launch_program (BIN_DIR, "empathy-debugger", "-s Empathy.Call");
@@ -1453,8 +1510,9 @@ empathy_call_window_incoming_call_response_cb (GtkDialog *dialog,
   switch (response_id)
     {
       case GTK_RESPONSE_ACCEPT:
-        tp_channel_dispatch_operation_handle_with_async (
-            self->priv->pending_cdo, EMPATHY_CALL_BUS_NAME, NULL, NULL);
+        tp_channel_dispatch_operation_handle_with_time_async (
+            self->priv->pending_cdo, EMPATHY_CALL_TP_BUS_NAME,
+            empathy_get_current_action_time (), NULL, NULL);
 
         tp_clear_object (&self->priv->pending_cdo);
         tp_clear_object (&self->priv->pending_channel);
@@ -1574,7 +1632,7 @@ empathy_call_window_init (EmpathyCallWindow *self)
   priv->timer = g_timer_new ();
 
   filename = empathy_file_lookup ("empathy-call-window.ui", "src");
-  gui = empathy_builder_get_file (filename,
+  gui = tpaw_builder_get_file (filename,
     "call_window_vbox", &top_vbox,
     "errors_vbox", &priv->errors_vbox,
     "pane", &priv->pane,
@@ -1611,7 +1669,7 @@ empathy_call_window_init (EmpathyCallWindow *self)
     NULL);
   g_free (filename);
 
-  empathy_builder_connect (gui, self,
+  tpaw_builder_connect (gui, self,
     "hangup", "clicked", empathy_call_window_hangup_cb,
     "audiocall", "clicked", empathy_call_window_audio_call_cb,
     "videocall", "clicked", empathy_call_window_video_call_cb,
@@ -1620,7 +1678,8 @@ empathy_call_window_init (EmpathyCallWindow *self)
     "menufullscreen", "activate", empathy_call_window_fullscreen_cb,
     "menusettings", "activate", empathy_call_window_settings_cb,
     "menucontents", "activate", empathy_call_window_contents_cb,
-    "menudebug", "activate", empathy_call_window_debug_cb,
+    "menudebuggst", "activate", empathy_call_window_debug_gst_cb,
+    "menudebugtp", "activate", empathy_call_window_debug_tp_cb,
     "menuabout", "activate", empathy_call_window_about_cb,
     "menupreviewdisable", "activate", empathy_call_window_disable_camera_cb,
     "menupreviewminimise", "activate", empathy_call_window_minimise_camera_cb,
@@ -1631,7 +1690,8 @@ empathy_call_window_init (EmpathyCallWindow *self)
   empathy_set_css_provider (GTK_WIDGET (self));
   gtk_action_set_sensitive (priv->menu_fullscreen, FALSE);
 
-  priv->camera_monitor = empathy_camera_monitor_dup_singleton ();
+  priv->camera_monitor = tpaw_camera_monitor_dup_singleton ();
+  empathy_call_window_update_swap_camera (self);
 
   g_object_bind_property (priv->camera_monitor, "available",
       priv->camera_button, "sensitive",
@@ -1807,6 +1867,8 @@ empathy_call_window_init (EmpathyCallWindow *self)
 
   empathy_call_window_show_hangup_button (self, TRUE);
 
+  gtk_window_set_default_size (GTK_WINDOW (self), 580, 480);
+
   empathy_geometry_bind (GTK_WINDOW (self), "call-window");
   /* These signals are used to track the window position and save it
    * when the window is destroyed. We need to do this as we don't want
@@ -1839,8 +1901,8 @@ init_contact_avatar_with_size (EmpathyContact *contact,
 
   if (pixbuf_avatar == NULL)
     {
-      pixbuf_avatar = empathy_pixbuf_from_icon_name_sized (
-          EMPATHY_IMAGE_AVATAR_DEFAULT, size);
+      pixbuf_avatar = tpaw_pixbuf_from_icon_name_sized (
+          TPAW_IMAGE_AVATAR_DEFAULT, size);
     }
 
   gtk_image_set_from_pixbuf (GTK_IMAGE (image_widget), pixbuf_avatar);
@@ -2297,6 +2359,13 @@ empathy_call_window_class_init (
     G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
   g_object_class_install_property (object_class,
     PROP_CALL_HANDLER, param_spec);
+
+  signals[SIG_INHIBIT] = g_signal_new ("inhibit",
+      G_OBJECT_CLASS_TYPE (empathy_call_window_class),
+      G_SIGNAL_RUN_LAST,
+      0, NULL, NULL, NULL,
+      G_TYPE_NONE,
+      1, G_TYPE_BOOLEAN);
 }
 
 void
@@ -2396,12 +2465,15 @@ empathy_call_window_new (EmpathyCallHandler *handler)
 }
 
 void
-empathy_call_window_present (EmpathyCallWindow *self,
-    EmpathyCallHandler *handler)
+empathy_call_window_new_handler (EmpathyCallWindow *self,
+    EmpathyCallHandler *handler,
+    gboolean present,
+    guint32 x11_time)
 {
   g_return_if_fail (EMPATHY_IS_CALL_HANDLER (handler));
 
-  empathy_window_present (GTK_WINDOW (self));
+  if (present)
+    tpaw_window_present_with_time (GTK_WINDOW (self), x11_time);
 
   if (self->priv->call_state == DISCONNECTED)
     {
@@ -2447,6 +2519,9 @@ empathy_call_window_conference_removed_cb (EmpathyCallHandler *handler,
   EmpathyCallWindow *self = EMPATHY_CALL_WINDOW (user_data);
   EmpathyCallWindowPriv *priv = GET_PRIV (self);
 
+  g_list_free_full (priv->notifiers, g_object_unref);
+  priv->notifiers = NULL;
+
   gst_bin_remove (GST_BIN (priv->pipeline), conference);
   gst_element_set_state (conference, GST_STATE_NULL);
 }
@@ -2537,9 +2612,18 @@ empathy_call_window_disconnected (EmpathyCallWindow *self,
   /* Leave full screen mode if needed */
   gtk_window_unfullscreen (GTK_WINDOW (self));
 
+  g_signal_emit (self, signals[SIG_INHIBIT], 0, FALSE);
+
   gtk_action_set_sensitive (priv->menu_fullscreen, FALSE);
   gtk_widget_set_sensitive (priv->dtmf_panel, FALSE);
 
+  /* Create the video input and then turn on the camera
+   * menu, so that the active camera gets marked as such.
+   */
+  if (priv->video_input == NULL)
+    create_video_input (self);
+  empathy_camera_menu_set_sensitive (priv->camera_menu, TRUE);
+
   could_reset_pipeline = empathy_call_window_reset_pipeline (self);
 
   if (priv->call_state == CONNECTING)
@@ -2578,7 +2662,7 @@ empathy_call_window_disconnected (EmpathyCallWindow *self,
 
       /* Be sure that the mic button is enabled */
       empathy_audio_src_set_mute (
-          EMPATHY_GST_AUDIO_SRC (self->priv->audio_input), TRUE);
+          EMPATHY_GST_AUDIO_SRC (self->priv->audio_input), FALSE);
 
       if (priv->camera_state == CAMERA_STATE_ON)
         {
@@ -2735,12 +2819,11 @@ empathy_call_window_get_video_sink_pad (EmpathyCallWindow *self)
   if (priv->funnel == NULL)
     {
       output = priv->video_output_sink;
-
-      priv->funnel = gst_element_factory_make ("fsfunnel", NULL);
+      priv->funnel = gst_element_factory_make ("funnel", NULL);
 
       if (!priv->funnel)
         {
-          g_warning ("Could not create fsfunnel");
+          g_warning ("Could not create video funnel");
           return NULL;
         }
 
@@ -2776,8 +2859,7 @@ empathy_call_window_get_video_sink_pad (EmpathyCallWindow *self)
           goto error_output_added;
         }
     }
-
-  pad = gst_element_get_request_pad (priv->funnel, "sink%d");
+  pad = gst_element_get_request_pad (priv->funnel, "sink_%u");
 
   if (!pad)
     g_warning ("Could not get request pad from funnel");
@@ -2827,6 +2909,7 @@ empathy_call_window_get_audio_sink_pad (EmpathyCallWindow *self,
           g_warning ("Could not start audio sink");
           goto error;
         }
+      priv->audio_output_added = TRUE;
     }
 
   template = gst_element_class_get_pad_template (
@@ -2867,6 +2950,8 @@ empathy_call_window_update_timer (gpointer user_data)
 
   if (priv->call_state == HELD)
     status = _("On hold");
+  else if (priv->call_state == DISCONNECTED)
+    status = _("Disconnected");
   else if (priv->muted)
     status = _("Mute");
   else
@@ -3037,7 +3122,7 @@ media_stream_error_to_txt (EmpathyCallWindow *self,
 
       case TP_MEDIA_STREAM_ERROR_INVALID_CM_BEHAVIOR:
         tp_connection_parse_object_path (
-            tp_channel_borrow_connection (TP_CHANNEL (call)),
+            tp_channel_get_connection (TP_CHANNEL (call)),
             NULL, &cm);
 
         url = g_strdup_printf ("http://bugs.freedesktop.org/enter_bug.cgi?"
@@ -3124,7 +3209,7 @@ show_balance_error (EmpathyCallWindow *self)
       "call-channel", &call,
       NULL);
 
-  conn = tp_channel_borrow_connection (call);
+  conn = tp_channel_get_connection (call);
   g_object_unref (call);
 
   uri = tp_connection_get_balance_uri (conn);
@@ -3189,7 +3274,7 @@ empathy_call_window_state_changed_cb (EmpathyCallHandler *handler,
 
   can_send_video = priv->video_input != NULL &&
     empathy_contact_can_voip_video (priv->contact) &&
-    empathy_camera_monitor_get_available (priv->camera_monitor);
+    tpaw_camera_monitor_get_available (priv->camera_monitor);
 
   g_object_get (priv->handler, "call-channel", &call, NULL);
 
@@ -3255,14 +3340,12 @@ empathy_call_window_check_video_cb (gpointer data)
 }
 
 /* Called from the streaming thread */
-static gboolean
+static GstPadProbeReturn
 empathy_call_window_video_probe_cb (GstPad *pad,
-    GstMiniObject *mini_obj,
-    EmpathyCallWindow *self)
+    GstPadProbeInfo *info,
+    gpointer user_data)
 {
-  /* Ignore events */
-  if (GST_IS_EVENT (mini_obj))
-    return TRUE;
+    EmpathyCallWindow *self = user_data;
 
   if (G_UNLIKELY (!self->priv->got_video))
     {
@@ -3274,7 +3357,7 @@ empathy_call_window_video_probe_cb (GstPad *pad,
       self->priv->got_video = TRUE;
     }
 
-  return TRUE;
+  return GST_PAD_PROBE_OK;
 }
 
 /* Called from the streaming thread */
@@ -3302,8 +3385,10 @@ empathy_call_window_src_added_cb (EmpathyCallHandler *handler,
         g_idle_add (empathy_call_window_show_video_output_cb, self);
         pad = empathy_call_window_get_video_sink_pad (self);
 
-        gst_pad_add_data_probe (src,
-            G_CALLBACK (empathy_call_window_video_probe_cb), self);
+        gst_pad_add_probe (src,
+            GST_PAD_PROBE_TYPE_BUFFER | GST_PAD_PROBE_TYPE_BUFFER_LIST,
+            empathy_call_window_video_probe_cb, self, NULL);
+
         if (priv->got_video_src > 0)
           g_source_remove (priv->got_video_src);
         priv->got_video_src = g_timeout_add_seconds (1,
@@ -3482,7 +3567,7 @@ empathy_call_window_content_added_cb (EmpathyCallHandler *handler,
       case FS_MEDIA_TYPE_VIDEO:
         if (priv->video_tee != NULL)
           {
-            pad = gst_element_get_request_pad (priv->video_tee, "src%d");
+            pad = gst_element_get_request_pad (priv->video_tee, "src_%u");
             if (GST_PAD_LINK_FAILED (gst_pad_link (pad, sink)))
               {
                 g_warning ("Could not link video source input pipeline");
@@ -3527,6 +3612,7 @@ empathy_call_window_remove_video_input (EmpathyCallWindow *self)
   priv->video_preview = NULL;
 
   gtk_widget_set_sensitive (priv->camera_button, FALSE);
+  empathy_camera_menu_set_sensitive (priv->camera_menu, FALSE);
 }
 
 static void
@@ -3534,6 +3620,8 @@ start_call (EmpathyCallWindow *self)
 {
   EmpathyCallWindowPriv *priv = GET_PRIV (self);
 
+  g_signal_emit (self, signals[SIG_INHIBIT], 0, TRUE);
+
   priv->call_started = TRUE;
   empathy_call_handler_start_call (priv->handler,
       gtk_get_current_event_time ());
@@ -3901,7 +3989,7 @@ empathy_call_window_state_event_cb (GtkWidget *widget,
       show_controls (window, set_fullscreen);
       show_borders (window, set_fullscreen);
       gtk_action_set_stock_id (priv->menu_fullscreen,
-          (set_fullscreen ? "gtk-leave-fullscreen" : "gtk-fullscreen"));
+          (set_fullscreen ? "view-restore" : "view-fullscreen"));
       priv->is_fullscreen = set_fullscreen;
   }