[ekiga] Notifications: Added Audio*Device detection.



commit a78848d36b46da06534062e6ec053205923e1dd7
Author: Damien Sandras <dsandras beip be>
Date:   Sat May 12 18:02:20 2012 +0200

    Notifications: Added Audio*Device detection.
    
    Changing the audio device when a new device is added or a
    device removal happens is now done through Notifications.
    
    Handle the case where the added/removed device is
    the prefered one or not.
    
    This allows the main window to get rid of those signals.
    
    We do not support changing the 'Ringer' device anymore. However, it did
    not really made sense as it is supposed to be the soundcard (which is
    hardwired in the laptop) in most cases.

 lib/engine/audioinput/audioinput-core.cpp   |   37 ++++-
 lib/engine/audioinput/audioinput-core.h     |    8 +-
 lib/engine/audiooutput/audiooutput-core.cpp |   39 ++++-
 lib/engine/audiooutput/audiooutput-core.h   |   11 +-
 lib/engine/engine.cpp                       |    4 +-
 src/gui/main_window.cpp                     |  212 ---------------------------
 6 files changed, 79 insertions(+), 232 deletions(-)
---
diff --git a/lib/engine/audioinput/audioinput-core.cpp b/lib/engine/audioinput/audioinput-core.cpp
index aab8c0d..46c2576 100644
--- a/lib/engine/audioinput/audioinput-core.cpp
+++ b/lib/engine/audioinput/audioinput-core.cpp
@@ -38,11 +38,17 @@
 #include <sstream>
 #include <math.h>
 
+#include <glib/gi18n.h>
+
+#include "config.h"
+
 #include "audioinput-core.h"
 
 using namespace Ekiga;
 
-AudioInputCore::AudioInputCore ()
+#define AUDIO_DEVICES_KEY "/apps/" PACKAGE_NAME "/devices/audio/"
+
+AudioInputCore::AudioInputCore (Ekiga::ServiceCore & _core) : core(_core)
 {
   PWaitAndSignal m_var(core_mutex);
   PWaitAndSignal m_vol(volume_mutex);
@@ -69,6 +75,8 @@ AudioInputCore::AudioInputCore ()
   average_level = 0;
   calculate_average = false;
   yield = false;
+
+  notification_core = core.get<Ekiga::NotificationCore> ("notification-core");
 }
 
 AudioInputCore::~AudioInputCore ()
@@ -186,13 +194,21 @@ void AudioInputCore::add_device (const std::string & source, const std::string &
   for (std::set<AudioInputManager *>::iterator iter = managers.begin ();
        iter != managers.end ();
        iter++) {
-     if ((*iter)->has_device (source, device_name, device)) {
+    if ((*iter)->has_device (source, device_name, device)) {
 
-       if ( desired_device == device)
-         internal_set_device(desired_device);
+      if ( desired_device == device) {
+        internal_set_device(desired_device);
+        boost::shared_ptr<Ekiga::Notification> notif (new Ekiga::Notification (Ekiga::Notification::Info, _("New device detected"), device.GetString ()));
+        notification_core->push_notification (notif);
+      }
+      else {
 
-       device_added (device, desired_device == device);
-     }
+        boost::shared_ptr<Ekiga::Notification> notif (new Ekiga::Notification (Ekiga::Notification::Info, _("New device detected"), device.GetString (), _("Use it"), boost::bind (&AudioInputCore::on_set_device, (AudioInputCore*) this, device)));
+        notification_core->push_notification (notif);
+      }
+
+      device_added(device, desired_device == device);
+    }
   }
 }
 
@@ -216,6 +232,10 @@ void AudioInputCore::remove_device (const std::string & source, const std::strin
             new_device.name = AUDIO_INPUT_FALLBACK_DEVICE_NAME;
             internal_set_device( new_device);
        }
+
+       boost::shared_ptr<Ekiga::Notification> notif (new Ekiga::Notification (Ekiga::Notification::Info, _("Device removed"), device.GetString ()));
+       notification_core->push_notification (notif);
+
        device_removed (device,  current_device == device);
      }
   }
@@ -357,6 +377,11 @@ void AudioInputCore::set_volume (unsigned volume)
   desired_volume = volume;
 }
 
+void AudioInputCore::on_set_device (const AudioInputDevice & device)
+{
+  gm_conf_set_string (AUDIO_DEVICES_KEY "input_device", device.GetString ().c_str ());
+}
+
 void AudioInputCore::on_device_opened (AudioInputDevice device,
                                        AudioInputSettings settings,
                                        AudioInputManager *manager)
diff --git a/lib/engine/audioinput/audioinput-core.h b/lib/engine/audioinput/audioinput-core.h
index 0ead1d0..70737a6 100644
--- a/lib/engine/audioinput/audioinput-core.h
+++ b/lib/engine/audioinput/audioinput-core.h
@@ -41,6 +41,7 @@
 #include "runtime.h"
 
 #include "audioinput-manager.h"
+#include "notification-core.h"
 #include "hal-core.h"
 #include "audioinput-gmconf-bridge.h"
 
@@ -94,9 +95,8 @@ namespace Ekiga
   public:
 
       /** The constructor
-       * @param _videooutput_core reference ot the audio output core.
        */
-      AudioInputCore ();
+      AudioInputCore (Ekiga::ServiceCore & core);
 
       /** The destructor
       */
@@ -273,6 +273,7 @@ namespace Ekiga
       boost::signal2<void, AudioInputDevice, bool> device_removed;
 
   private:
+      void on_set_device (const AudioInputDevice & device);
       void on_device_opened (AudioInputDevice device,
                              AudioInputSettings settings,
                              AudioInputManager *manager);
@@ -320,6 +321,9 @@ namespace Ekiga
       float average_level;
       bool calculate_average;
       bool yield;
+
+      Ekiga::ServiceCore & core;
+      boost::shared_ptr<Ekiga::NotificationCore> notification_core;
     };
 /**
  * @}
diff --git a/lib/engine/audiooutput/audiooutput-core.cpp b/lib/engine/audiooutput/audiooutput-core.cpp
index 3199135..f0e3c53 100644
--- a/lib/engine/audiooutput/audiooutput-core.cpp
+++ b/lib/engine/audiooutput/audiooutput-core.cpp
@@ -33,15 +33,23 @@
  *                          An audiooutput core manages AudioOutputManagers.
  *
  */
-#include "audiooutput-core.h"
-#include "audiooutput-manager.h"
+
 #include <algorithm>
 #include <math.h>
 
+#include <glib/gi18n.h>
+
+#include "config.h"
+
+#include "audiooutput-core.h"
+#include "audiooutput-manager.h"
+
 using namespace Ekiga;
 
-AudioOutputCore::AudioOutputCore ()
-:  audio_event_scheduler(*this)
+#define AUDIO_DEVICES_KEY "/apps/" PACKAGE_NAME "/devices/audio/"
+
+AudioOutputCore::AudioOutputCore (Ekiga::ServiceCore & _core)
+: audio_event_scheduler(*this), core(_core)
 {
   PWaitAndSignal m_pri(core_mutex[primary]);
   PWaitAndSignal m_sec(core_mutex[secondary]);
@@ -56,13 +64,15 @@ AudioOutputCore::AudioOutputCore ()
 
   current_primary_volume = 0;
   desired_primary_volume = 0;
-  
+
   current_manager[primary] = NULL;
   current_manager[secondary] = NULL;
   audiooutput_core_conf_bridge = NULL;
   average_level = 0;
   calculate_average = false;
   yield = false;
+
+  notification_core = core.get<Ekiga::NotificationCore> ("notification-core");
 }
 
 AudioOutputCore::~AudioOutputCore ()
@@ -203,8 +213,15 @@ void AudioOutputCore::add_device (const std::string & sink, const std::string &
        iter++) {
      if ((*iter)->has_device (sink, device_name, device)) {
 
-       if ( desired_primary_device == device ) {
+       if ( desired_primary_device == device) {
          internal_set_primary_device(desired_primary_device);
+         boost::shared_ptr<Ekiga::Notification> notif (new Ekiga::Notification (Ekiga::Notification::Info, _("New device detected"), device.GetString ()));
+         notification_core->push_notification (notif);
+       }
+       else {
+
+         boost::shared_ptr<Ekiga::Notification> notif (new Ekiga::Notification (Ekiga::Notification::Info, _("New device detected"), device.GetString (), _("Use it"), boost::bind (&AudioOutputCore::on_set_device, (AudioOutputCore*) this, device)));
+         notification_core->push_notification (notif);
        }
 
        device_added(device, desired_primary_device == device);
@@ -232,6 +249,9 @@ void AudioOutputCore::remove_device (const std::string & sink, const std::string
          internal_set_primary_device(new_device);
        }
 
+       boost::shared_ptr<Ekiga::Notification> notif (new Ekiga::Notification (Ekiga::Notification::Info, _("Device removed"), device.GetString ()));
+       notification_core->push_notification (notif);
+
        device_removed(device, device == current_device[primary]);
      }
   }
@@ -360,9 +380,14 @@ void AudioOutputCore::play_buffer(AudioOutputPS ps, const char* buffer, unsigned
   }
 }
 
+void AudioOutputCore::on_set_device (const AudioOutputDevice & device)
+{
+  gm_conf_set_string (AUDIO_DEVICES_KEY "output_device", device.GetString ().c_str ());
+}
+
 void AudioOutputCore::on_device_opened (AudioOutputPS ps,
                                         AudioOutputDevice device,
-                                        AudioOutputSettings settings, 
+                                        AudioOutputSettings settings,
                                         AudioOutputManager *manager)
 {
   device_opened (*manager, ps, device, settings);
diff --git a/lib/engine/audiooutput/audiooutput-core.h b/lib/engine/audiooutput/audiooutput-core.h
index 91b10f8..7aff46b 100644
--- a/lib/engine/audiooutput/audiooutput-core.h
+++ b/lib/engine/audiooutput/audiooutput-core.h
@@ -39,6 +39,7 @@
 #include "services.h"
 #include "runtime.h"
 #include "hal-core.h"
+#include "notification-core.h"
 
 #include "audiooutput-manager.h"
 #include "audiooutput-gmconf-bridge.h"
@@ -89,7 +90,7 @@ namespace Ekiga
 
       /** The constructor
        */
-      AudioOutputCore ();
+      AudioOutputCore (Ekiga::ServiceCore & core);
 
       /** The destructor
       */
@@ -317,9 +318,10 @@ namespace Ekiga
       boost::signal2<void, AudioOutputDevice, bool> device_removed;
 
   private:
-      void on_device_opened (AudioOutputPS ps, 
+      void on_set_device (const AudioOutputDevice & device);
+      void on_device_opened (AudioOutputPS ps,
                              AudioOutputDevice device,
-                             AudioOutputSettings settings, 
+                             AudioOutputSettings settings,
                              AudioOutputManager *manager);
       void on_device_closed (AudioOutputPS ps, AudioOutputDevice device, AudioOutputManager *manager);
       void on_device_error  (AudioOutputPS ps, AudioOutputDevice device, AudioOutputErrorCodes error_code, AudioOutputManager *manager);
@@ -363,6 +365,9 @@ namespace Ekiga
       float average_level;
       bool calculate_average;
       bool yield;
+
+      Ekiga::ServiceCore & core;
+      boost::shared_ptr<Ekiga::NotificationCore> notification_core;
     };
 /**
  * @}
diff --git a/lib/engine/engine.cpp b/lib/engine/engine.cpp
index 2a76662..35aadb9 100644
--- a/lib/engine/engine.cpp
+++ b/lib/engine/engine.cpp
@@ -114,8 +114,8 @@ engine_init (Ekiga::ServiceCorePtr service_core,
   boost::shared_ptr<Ekiga::ChatCore> chat_core (new Ekiga::ChatCore);
   boost::shared_ptr<Ekiga::VideoOutputCore> videooutput_core (new Ekiga::VideoOutputCore);
   boost::shared_ptr<Ekiga::VideoInputCore> videoinput_core (new Ekiga::VideoInputCore ((*service_core.get ()), videooutput_core));
-  boost::shared_ptr<Ekiga::AudioOutputCore> audiooutput_core (new Ekiga::AudioOutputCore);
-  boost::shared_ptr<Ekiga::AudioInputCore> audioinput_core (new Ekiga::AudioInputCore);
+  boost::shared_ptr<Ekiga::AudioOutputCore> audiooutput_core (new Ekiga::AudioOutputCore ((*service_core.get ())));
+  boost::shared_ptr<Ekiga::AudioInputCore> audioinput_core (new Ekiga::AudioInputCore ((*service_core.get ())));
   boost::shared_ptr<Ekiga::HalCore> hal_core (new Ekiga::HalCore);
   boost::shared_ptr<Ekiga::FriendOrFoe> friend_or_foe (new Ekiga::FriendOrFoe);
 
diff --git a/src/gui/main_window.cpp b/src/gui/main_window.cpp
index d4a9d96..b6e83a2 100644
--- a/src/gui/main_window.cpp
+++ b/src/gui/main_window.cpp
@@ -333,10 +333,6 @@ static void ekiga_main_window_init_uri_toolbar (EkigaMainWindow *mw);
  */
 static void ekiga_main_window_init_actions_toolbar (EkigaMainWindow *mw);
 
-static void ekiga_main_window_add_device_dialog_show (EkigaMainWindow *main_window,
-                                                      const Ekiga::Device & device,
-                                                      DeviceType device_type);
-
 
 /* DESCRIPTION   :  /
  * BEHAVIOR      : Flashes a message on the statusbar during a few seconds.
@@ -762,108 +758,6 @@ static bool on_handle_errors (std::string error,
 }
 
 
-/*
- * Display Engine Callbacks
- */
-void
-on_audioinput_device_added_cb (const Ekiga::AudioInputDevice & device,
-                               bool is_desired,
-                               gpointer self)
-{
-  EkigaMainWindow *mw = EKIGA_MAIN_WINDOW (self);
-  gchar* message = NULL;
-
-  /* Translators: This is a hotplug status */
-  message = g_strdup_printf (_("Added audio input device %s"),
-			     device.GetString().c_str ());
-  ekiga_main_window_flash_message (mw, "%s", message);
-  g_free (message);
-  if (!is_desired  && mw->priv->calling_state == Standby)
-    ekiga_main_window_add_device_dialog_show (mw, device, AudioInput);
-}
-
-void
-on_audioinput_device_removed_cb (const Ekiga::AudioInputDevice & device,
-                                 bool,
-                                 gpointer self)
-{
-  gchar* message = NULL;
-
-  /* Translators: This is a hotplug status */
-  message = g_strdup_printf (_("Removed audio input device %s"),
-			     device.GetString().c_str ());
-  ekiga_main_window_flash_message (EKIGA_MAIN_WINDOW (self), "%s", message);
-  g_free (message);
-}
-
-void
-on_audiooutput_device_added_cb (const Ekiga::AudioOutputDevice & device,
-                                bool is_desired,
-                                gpointer self)
-{
-  EkigaMainWindow *mw;
-  gchar *message;
-
-  g_return_if_fail (EKIGA_IS_MAIN_WINDOW (self));
-
-  mw = EKIGA_MAIN_WINDOW (self);
-
-  message = g_strdup_printf (_("Added audio output device %s"), device.GetString().c_str ());
-  ekiga_main_window_flash_message (mw, "%s", message);
-  g_free (message);
-  if (!is_desired && mw->priv->calling_state == Standby && !mw->priv->current_call) {
-    ekiga_main_window_add_device_dialog_show (mw, device, AudioOutput);
-    ekiga_main_window_add_device_dialog_show (mw, device, Ringer);
-  }
-}
-
-void
-on_audiooutput_device_removed_cb (const Ekiga::AudioOutputDevice & device,
-                                  bool,
-                                  gpointer self)
-{
-  gchar *message;
-
-  g_return_if_fail (EKIGA_IS_MAIN_WINDOW (self));
-
-  message = g_strdup_printf (_("Removed audio output device %s"),
-			     device.GetString().c_str ());
-  ekiga_main_window_flash_message (EKIGA_MAIN_WINDOW (self), "%s", message);
-  g_free (message);
-}
-
-/* Implementation */
-static void
-add_device_response_cb (GtkDialog *add_device_popup,
-                           gint response,
-                           gpointer data)
-{
-  deviceStruct *device_struct = (deviceStruct*) data;
-
-  gtk_widget_hide (GTK_WIDGET (add_device_popup));
-
-  if (response == 2) {
-
-    switch (device_struct->deviceType)
-    {
-     case AudioInput:
-       gm_conf_set_string (AUDIO_DEVICES_KEY "input_device", device_struct->name);
-       break;
-     case AudioOutput:
-       gm_conf_set_string (AUDIO_DEVICES_KEY "output_device", device_struct->name);
-       break;
-     case Ringer:
-       gm_conf_set_string (SOUND_EVENTS_KEY "output_device", device_struct->name);
-       break;
-     case VideoInput:
-       gm_conf_set_string (VIDEO_DEVICES_KEY "input_device", device_struct->name);
-       break;
-     default:;
-    }
-  }
-}
-
-
 /* GTK callbacks */
 static gboolean
 on_delayed_hide_call_window_cb (gpointer data)
@@ -1211,96 +1105,6 @@ ekiga_main_window_get_call_url (EkigaMainWindow *mw)
 }
 
 static void
-ekiga_main_window_add_device_dialog_show (EkigaMainWindow *mw,
-                                          const Ekiga::Device & device,
-                                          DeviceType device_type)
-{
-  GtkWidget *label = NULL;
-  GtkWidget *vbox = NULL;
-  GtkWidget *add_device_popup = NULL;
-
-  g_return_if_fail (EKIGA_IS_MAIN_WINDOW (mw));
-
-  add_device_popup = gtk_dialog_new ();
-  gtk_dialog_add_button (GTK_DIALOG (add_device_popup),
-			 _("No"), 0);
-  gtk_dialog_add_button (GTK_DIALOG (add_device_popup),
-			 _("Yes"), 2);
-
-  gtk_dialog_set_default_response (GTK_DIALOG (add_device_popup), 2);
-
-  vbox = GTK_DIALOG (add_device_popup)->vbox;
-
-  std::string msg;
-  std::string title;
-
-  switch (device_type) {
-    case AudioInput:
-      msg = _("Detected new audio input device:");
-      title = _("Audio Devices");
-      break;
-    case AudioOutput:
-      msg = _("Detected new audio output device:");
-      title = _("Audio Devices");
-      break;
-    case Ringer:
-      msg = _("Detected new ringer device:");
-      title = _("Audio Devices");
-      break;
-    case VideoInput:
-      msg = _("Detected new video input device:");
-      title = _("Video Devices");
-      break;
-    default:
-      break;
-  }
-  label = gtk_label_new (NULL);
-  gtk_label_set_markup (GTK_LABEL (label), msg.c_str());
-  gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 2);
-  gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.0);
-  gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
-
-  msg  = "<b>" + device.GetString() + "</b>";
-  label = gtk_label_new (NULL);
-  gtk_label_set_markup (GTK_LABEL (label), msg.c_str());
-  gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 2);
-  gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.0);
-  gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
-
-  msg  = _("Do you want to use it as default device?");
-  label = gtk_label_new (NULL);
-  gtk_label_set_markup (GTK_LABEL (label), msg.c_str());
-  gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 2);
-  gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.0);
-  gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
-
-  gtk_window_set_title (GTK_WINDOW (add_device_popup), title.c_str ());
-  gtk_window_set_modal (GTK_WINDOW (add_device_popup), TRUE);
-  gtk_window_set_keep_above (GTK_WINDOW (add_device_popup), TRUE);
-  gtk_window_set_urgency_hint (GTK_WINDOW (mw), TRUE);
-  gtk_window_set_transient_for (GTK_WINDOW (add_device_popup),
-				GTK_WINDOW (mw));
-
-  gtk_widget_show_all (add_device_popup);
-
-  deviceStruct* device_struct = g_new(deviceStruct, 1);
-  snprintf (device_struct->name, sizeof (device_struct->name), "%s", (device.GetString()).c_str());
-  device_struct->deviceType = device_type;
-
-  g_signal_connect_data (add_device_popup, "delete_event",
-                         G_CALLBACK (gtk_widget_hide_on_delete),
-                         (gpointer) device_struct,
-                         (GClosureNotify) g_free,
-                         (GConnectFlags) 0);
-
-  g_signal_connect_data (add_device_popup, "response",
-                         G_CALLBACK (add_device_response_cb),
-                         (gpointer) device_struct,
-                         (GClosureNotify) g_free,
-                         (GConnectFlags) 0);
-}
-
-static void
 ekiga_main_window_init_uri_toolbar (EkigaMainWindow *mw)
 {
   GtkWidget *call_button = NULL;
@@ -1895,22 +1699,6 @@ ekiga_main_window_connect_engine_signals (EkigaMainWindow *mw)
 
   g_return_if_fail (EKIGA_IS_MAIN_WINDOW (mw));
 
-  /* New AudioInput Engine signals */
-  boost::shared_ptr<Ekiga::AudioInputCore> audioinput_core = mw->priv->core->get<Ekiga::AudioInputCore> ("audioinput-core");
-  conn = audioinput_core->device_added.connect (boost::bind (&on_audioinput_device_added_cb, _1, _2, (gpointer) mw));
-  mw->priv->connections.push_back (conn);
-
-  conn = audioinput_core->device_removed.connect (boost::bind (&on_audioinput_device_removed_cb, _1, _2, (gpointer) mw));
-  mw->priv->connections.push_back (conn);
-
-  /* New AudioOutput Engine signals */
-  boost::shared_ptr<Ekiga::AudioOutputCore> audiooutput_core = mw->priv->core->get<Ekiga::AudioOutputCore> ("audiooutput-core");
-  conn = audiooutput_core->device_added.connect (boost::bind (&on_audiooutput_device_added_cb, _1, _2, (gpointer) mw));
-  mw->priv->connections.push_back (conn);
-
-  conn = audiooutput_core->device_removed.connect (boost::bind (&on_audiooutput_device_removed_cb, _1, _2, (gpointer) mw));
-  mw->priv->connections.push_back (conn);
-
   /* New Call Engine signals */
   boost::shared_ptr<Ekiga::CallCore> call_core = mw->priv->core->get<Ekiga::CallCore> ("call-core");
   boost::shared_ptr<Ekiga::AccountCore> account_core = mw->priv->core->get<Ekiga::AccountCore> ("account-core");



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