]> git.0d.be Git - empathy.git/blobdiff - src/empathy-call-window.c
Add en_GB in gitignore
[empathy.git] / src / empathy-call-window.c
index 7ad016f849bbe42e83c50f2941fd2f7dfefb8be0..cd9ec4d6031ba0ad3e2d3e5a7b55d2c02853a5d1 100644 (file)
@@ -22,6 +22,8 @@
 #include <stdio.h>
 #include <stdlib.h>
 
+#include <math.h>
+
 #include <gst/gst.h>
 #include <gtk/gtk.h>
 #include <glib/gi18n.h>
@@ -92,6 +94,10 @@ struct _EmpathyCallWindowPriv
   GTimer *timer;
   guint timer_id;
 
+  GtkWidget *video_contrast;
+  GtkWidget *video_brightness;
+  GtkWidget *video_gamma;
+
   GMutex *lock;
 };
 
@@ -119,6 +125,9 @@ static void empathy_call_window_hangup (EmpathyCallWindow *window);
 static void empathy_call_window_status_message (EmpathyCallWindow *window,
   gchar *message);
 
+static gboolean empathy_call_window_bus_message (GstBus *bus,
+  GstMessage *message, gpointer user_data);
+
 static void
 empathy_call_window_volume_changed_cb (GtkScaleButton *button,
   gdouble value, EmpathyCallWindow *window);
@@ -260,53 +269,183 @@ empathy_call_window_create_dtmf (EmpathyCallWindow *self)
   return table;
 }
 
+static GtkWidget *
+empathy_call_window_create_video_input_add_slider (EmpathyCallWindow *self,
+  gchar *label_text, GtkWidget *bin)
+{
+   GtkWidget *vbox = gtk_vbox_new (FALSE, 2);
+   GtkWidget *scale = gtk_vscale_new_with_range (0, 100, 10);
+   GtkWidget *label = gtk_label_new (label_text);
+
+   gtk_widget_set_sensitive (scale, FALSE);
+
+   gtk_container_add (GTK_CONTAINER (bin), vbox);
+
+   gtk_range_set_inverted (GTK_RANGE (scale), TRUE);
+   gtk_box_pack_start (GTK_BOX (vbox), scale, TRUE, TRUE, 0);
+   gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
+
+   return scale;
+}
+
+static void
+empathy_call_window_video_contrast_changed_cb (GtkAdjustment *adj,
+  EmpathyCallWindow *self)
+
+{
+  EmpathyCallWindowPriv *priv = GET_PRIV (self);
+
+  empathy_video_src_set_channel (priv->video_input,
+    EMPATHY_GST_VIDEO_SRC_CHANNEL_CONTRAST, gtk_adjustment_get_value (adj));
+}
+
+static void
+empathy_call_window_video_brightness_changed_cb (GtkAdjustment *adj,
+  EmpathyCallWindow *self)
+
+{
+  EmpathyCallWindowPriv *priv = GET_PRIV (self);
+
+  empathy_video_src_set_channel (priv->video_input,
+    EMPATHY_GST_VIDEO_SRC_CHANNEL_BRIGHTNESS, gtk_adjustment_get_value (adj));
+}
+
+static void
+empathy_call_window_video_gamma_changed_cb (GtkAdjustment *adj,
+  EmpathyCallWindow *self)
+
+{
+  EmpathyCallWindowPriv *priv = GET_PRIV (self);
+
+  empathy_video_src_set_channel (priv->video_input,
+    EMPATHY_GST_VIDEO_SRC_CHANNEL_GAMMA, gtk_adjustment_get_value (adj));
+}
+
+
 static GtkWidget *
 empathy_call_window_create_video_input (EmpathyCallWindow *self)
 {
+  EmpathyCallWindowPriv *priv = GET_PRIV (self);
   GtkWidget *hbox;
-  int i;
-  gchar *controls[] = { _("Contrast"), _("Brightness"), _("Gamma"), NULL };
 
   hbox = gtk_hbox_new (TRUE, 3);
 
-  for (i = 0; controls[i] != NULL; i++)
+  priv->video_contrast = empathy_call_window_create_video_input_add_slider (
+    self,  _("Contrast"), hbox);
+
+  priv->video_brightness = empathy_call_window_create_video_input_add_slider (
+    self,  _("Brightness"), hbox);
+
+  priv->video_gamma = empathy_call_window_create_video_input_add_slider (
+    self,  _("Gamma"), hbox);
+
+  return hbox;
+}
+
+static void
+empathy_call_window_setup_video_input (EmpathyCallWindow *self)
+{
+  EmpathyCallWindowPriv *priv = GET_PRIV (self);
+  guint supported;
+  GtkAdjustment *adj;
+
+  supported = empathy_video_src_get_supported_channels (priv->video_input);
+
+  if (supported & EMPATHY_GST_VIDEO_SRC_SUPPORTS_CONTRAST)
     {
-      GtkWidget *vbox = gtk_vbox_new (FALSE, 2);
-      GtkWidget *scale = gtk_vscale_new_with_range (0, 100, 10);
-      GtkWidget *label = gtk_label_new (controls[i]);
+      adj = gtk_range_get_adjustment (GTK_RANGE (priv->video_contrast));
+
+      gtk_adjustment_set_value (adj,
+        empathy_video_src_get_channel (priv->video_input,
+          EMPATHY_GST_VIDEO_SRC_CHANNEL_CONTRAST));
 
-      gtk_container_add (GTK_CONTAINER (hbox), vbox);
+      g_signal_connect (G_OBJECT (adj), "value-changed",
+        G_CALLBACK (empathy_call_window_video_contrast_changed_cb), self);
 
-      gtk_range_set_inverted (GTK_RANGE (scale), TRUE);
-      gtk_box_pack_start (GTK_BOX (vbox), scale, TRUE, TRUE, 0);
-      gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
+      gtk_widget_set_sensitive (priv->video_contrast, TRUE);
     }
 
-  return hbox;
+  if (supported & EMPATHY_GST_VIDEO_SRC_SUPPORTS_BRIGHTNESS)
+    {
+      adj = gtk_range_get_adjustment (GTK_RANGE (priv->video_brightness));
+
+      gtk_adjustment_set_value (adj,
+        empathy_video_src_get_channel (priv->video_input,
+          EMPATHY_GST_VIDEO_SRC_CHANNEL_BRIGHTNESS));
+
+      g_signal_connect (G_OBJECT (adj), "value-changed",
+        G_CALLBACK (empathy_call_window_video_brightness_changed_cb), self);
+      gtk_widget_set_sensitive (priv->video_brightness, TRUE);
+    }
+
+  if (supported & EMPATHY_GST_VIDEO_SRC_SUPPORTS_GAMMA)
+    {
+      adj = gtk_range_get_adjustment (GTK_RANGE (priv->video_gamma));
+
+      gtk_adjustment_set_value (adj,
+        empathy_video_src_get_channel (priv->video_input,
+          EMPATHY_GST_VIDEO_SRC_CHANNEL_GAMMA));
+
+      g_signal_connect (G_OBJECT (adj), "value-changed",
+        G_CALLBACK (empathy_call_window_video_gamma_changed_cb), self);
+      gtk_widget_set_sensitive (priv->video_gamma, TRUE);
+    }
+}
+
+static void
+empathy_call_window_mic_volume_changed_cb (GtkAdjustment *adj,
+  EmpathyCallWindow *self)
+{
+  EmpathyCallWindowPriv *priv = GET_PRIV (self);
+
+  empathy_audio_src_set_volume (EMPATHY_GST_AUDIO_SRC (priv->audio_input),
+    gtk_adjustment_get_value (adj)/100);
+}
+
+static void
+empathy_call_window_audio_input_level_changed_cb (EmpathyGstAudioSrc *src,
+  gdouble level, GtkProgressBar *bar)
+{
+  gdouble value;
+
+  value = CLAMP (pow (10, level / 20), 0.0, 1.0);
+  gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (bar), value);
 }
 
 static GtkWidget *
 empathy_call_window_create_audio_input (EmpathyCallWindow *self)
 {
+  EmpathyCallWindowPriv *priv = GET_PRIV (self);
   GtkWidget *hbox, *vbox, *scale, *progress, *label;
+  GtkAdjustment *adj;
 
   hbox = gtk_hbox_new (TRUE, 3);
 
   vbox = gtk_vbox_new (FALSE, 3);
   gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 3);
 
-  scale = gtk_vscale_new_with_range (0, 100, 10);
+  scale = gtk_vscale_new_with_range (0, 150, 100);
   gtk_range_set_inverted (GTK_RANGE (scale), TRUE);
   label = gtk_label_new (_("Volume"));
 
+  adj = gtk_range_get_adjustment (GTK_RANGE (scale));
+  gtk_adjustment_set_value (adj,
+    empathy_audio_src_get_volume (
+      EMPATHY_GST_AUDIO_SRC (priv->audio_input)) * 100);
+
+  g_signal_connect (G_OBJECT (adj), "value-changed",
+    G_CALLBACK (empathy_call_window_mic_volume_changed_cb), self);
+
   gtk_box_pack_start (GTK_BOX (vbox), scale, TRUE, TRUE, 3);
   gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 3);
 
-
   progress = gtk_progress_bar_new ();
   gtk_progress_bar_set_orientation (GTK_PROGRESS_BAR (progress),
     GTK_PROGRESS_BOTTOM_TO_TOP);
-  gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (progress), 0.5);
+  gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (progress), 0);
+
+  g_signal_connect (priv->audio_input, "peak-level-changed",
+    G_CALLBACK (empathy_call_window_audio_input_level_changed_cb), progress);
 
   gtk_box_pack_start (GTK_BOX (hbox), progress, FALSE, FALSE, 3);
 
@@ -348,6 +487,8 @@ empathy_call_window_init (EmpathyCallWindow *self)
 
   bus = gst_pipeline_get_bus (GST_PIPELINE (priv->pipeline));
 
+  gst_bus_add_watch (bus, empathy_call_window_bus_message, self);
+
   priv->video_output = empathy_video_widget_new (bus);
   gtk_box_pack_start (GTK_BOX (hbox), priv->video_output, TRUE, TRUE, 3);
 
@@ -567,9 +708,16 @@ empathy_call_window_channel_closed_cb (TfChannel *channel, gpointer user_data)
   EmpathyCallWindow *self = EMPATHY_CALL_WINDOW (user_data);
   EmpathyCallWindowPriv *priv = GET_PRIV (self);
 
+  g_mutex_lock (priv->lock);
+
   g_timer_stop (priv->timer);
-  g_source_remove (priv->timer_id);
+
+  if (priv->timer_id != 0)
+    g_source_remove (priv->timer_id);
   priv->timer_id = 0;
+
+  g_mutex_unlock (priv->lock);
+
   empathy_call_window_status_message (self, _("Disconnected"));
 
   gtk_widget_set_sensitive (priv->camera_button, FALSE);
@@ -663,11 +811,14 @@ empathy_call_window_connected (gpointer user_data)
 
   g_object_unref (call);
 
+  g_mutex_lock (priv->lock);
+
   priv->timer_id = g_timeout_add_seconds (1,
     empathy_call_window_update_timer, self);
 
+  g_mutex_unlock (priv->lock);
+
   empathy_call_window_update_timer (self);
-  gdk_threads_leave ();
 
   return FALSE;
 }
@@ -738,12 +889,39 @@ empathy_call_window_sink_added_cb (EmpathyCallHandler *handler,
 
 }
 
+static gboolean
+empathy_call_window_bus_message (GstBus *bus, GstMessage *message,
+  gpointer user_data)
+{
+  EmpathyCallWindow *self = EMPATHY_CALL_WINDOW (user_data);
+  EmpathyCallWindowPriv *priv = GET_PRIV (self);
+
+  empathy_call_handler_bus_message (priv->handler, bus, message);
+
+  switch (GST_MESSAGE_TYPE (message))
+    {
+      case GST_MESSAGE_STATE_CHANGED:
+        if (GST_MESSAGE_SRC (message) == GST_OBJECT (priv->video_input))
+          {
+            GstState newstate;
+
+            gst_message_parse_state_changed (message, NULL, &newstate, NULL);
+            if (newstate == GST_STATE_PAUSED)
+              empathy_call_window_setup_video_input (self);
+          }
+        break;
+      default:
+        break;
+    }
+
+  return TRUE;
+}
+
 static void
 empathy_call_window_realized_cb (GtkWidget *widget, EmpathyCallWindow *window)
 {
   EmpathyCallWindowPriv *priv = GET_PRIV (window);
   GstElement *preview;
-  GstBus *bus;
 
   g_signal_connect (priv->handler, "conference-added",
     G_CALLBACK (empathy_call_window_conference_added_cb), window);
@@ -754,8 +932,6 @@ empathy_call_window_realized_cb (GtkWidget *widget, EmpathyCallWindow *window)
   g_signal_connect (priv->handler, "sink-pad-added",
     G_CALLBACK (empathy_call_window_sink_added_cb), window);
 
-  bus = gst_pipeline_get_bus (GST_PIPELINE (priv->pipeline));
-  empathy_call_handler_set_bus (priv->handler, bus);
   empathy_call_handler_start_call (priv->handler);
 
   preview = empathy_video_widget_get_element (
@@ -767,8 +943,6 @@ empathy_call_window_realized_cb (GtkWidget *widget, EmpathyCallWindow *window)
     preview, NULL);
 
   gst_element_set_state (priv->pipeline, GST_STATE_PLAYING);
-
-  g_object_unref (bus);
 }
 
 static gboolean