From 62eada2ee0785a4f0182e13d40dd3273302024d7 Mon Sep 17 00:00:00 2001 From: Marco Pesenti Gritti Date: Fri, 5 Jan 2007 03:21:55 +0100 Subject: [PATCH] Implement audio controls --- configure.ac | 2 +- lib/src/Makefile.am | 4 +- lib/src/sugar-audio-manager.c | 138 +++++++++++++++++++++++++++++++++- lib/src/sugar-audio-manager.h | 3 + shell/view/Shell.py | 12 +++ 5 files changed, 153 insertions(+), 6 deletions(-) diff --git a/configure.ac b/configure.ac index 333a3872..a6e254bb 100644 --- a/configure.ac +++ b/configure.ac @@ -24,7 +24,7 @@ AM_CHECK_PYTHON_HEADERS(,[AC_MSG_ERROR(could not find Python headers)]) AC_PATH_PROG(PYGTK_CODEGEN, pygtk-codegen-2.0, no) PKG_CHECK_MODULES(PYGTK, pygtk-2.0) -PKG_CHECK_MODULES(LIB, gtk+-2.0 xulrunner-gtkmozembed) +PKG_CHECK_MODULES(LIB, gtk+-2.0 xulrunner-gtkmozembed gstreamer-0.10 gstreamer-plugins-base-0.10) MOZILLA_HOME="`$PKG_CONFIG --variable=libdir xulrunner-gtkmozembed`" AC_SUBST(MOZILLA_HOME) diff --git a/lib/src/Makefile.am b/lib/src/Makefile.am index ce4ec783..50ee2e2e 100644 --- a/lib/src/Makefile.am +++ b/lib/src/Makefile.am @@ -9,7 +9,9 @@ libsugarprivate_la_CPPFLAGS = \ noinst_LTLIBRARIES = libsugarprivate.la -libsugarprivate_la_LIBADD = $(GECKO_LIBS) +libsugarprivate_la_LIBADD = $(LIB_LIBS) \ + -lgstinterfaces-0.10 \ + -lgstaudio-0.10 libsugarprivate_la_SOURCES = \ $(BUILT_SOURCES) \ diff --git a/lib/src/sugar-audio-manager.c b/lib/src/sugar-audio-manager.c index 6444f116..6f73cbc4 100644 --- a/lib/src/sugar-audio-manager.c +++ b/lib/src/sugar-audio-manager.c @@ -16,23 +16,153 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */ +#include +#include +#include +#include + #include "sugar-audio-manager.h" +struct _SugarAudioManagerPrivate +{ + GstMixer *mixer; + GstMixerTrack *track; + guint timer_id; +}; + G_DEFINE_TYPE(SugarAudioManager, sugar_audio_manager, G_TYPE_OBJECT) -static void -sugar_audio_manager_class_init(SugarAudioManagerClass *grabber_class) +#define SUGAR_AUDIO_MANAGER_GET_PRIVATE(object) (G_TYPE_INSTANCE_GET_PRIVATE ((object), SUGAR_TYPE_AUDIO_MANAGER, SugarAudioManagerPrivate)) + +/* This is a modified version of code from gnome-control-center */ + +static gboolean +mixer_close_real(SugarAudioManager *manager) { - GObjectClass *g_object_class = G_OBJECT_CLASS (grabber_class); + if (manager->priv->mixer != NULL) + { + gst_element_set_state(GST_ELEMENT(manager->priv->mixer), GST_STATE_NULL); + gst_object_unref(GST_OBJECT(manager->priv->mixer)); + g_object_unref(G_OBJECT(manager->priv->track)); + manager->priv->mixer = NULL; + manager->priv->track = NULL; + } + + manager->priv->timer_id = 0; + + return FALSE; +} + +static gboolean +set_mixer_helper(GstMixer *mixer, gpointer user_data) +{ + const GList *tracks; + + tracks = gst_mixer_list_tracks(mixer); + + while (tracks != NULL) { + GstMixerTrack *track = GST_MIXER_TRACK(tracks->data); + + if (GST_MIXER_TRACK_HAS_FLAG(track, GST_MIXER_TRACK_MASTER)) { + SugarAudioManager *manager; + + manager = SUGAR_AUDIO_MANAGER(user_data); + + manager->priv->mixer = mixer; + manager->priv->track = track; + + /* no need to ref the mixer element */ + g_object_ref(manager->priv->track); + return TRUE; + } + + tracks = tracks->next; + } + + return FALSE; +} + +static gboolean +mixer_open(SugarAudioManager *manager) +{ + GList *mixer_list; + + if (manager->priv->timer_id != 0) { + g_source_remove (manager->priv->timer_id); + manager->priv->timer_id = 0; + return TRUE; + } + + mixer_list = gst_audio_default_registry_mixer_filter + (set_mixer_helper, TRUE, manager); + + if (mixer_list == NULL) + return FALSE; + + /* do not unref the mixer as we keep the ref for manager->priv->mixer */ + g_list_free (mixer_list); + + return TRUE; } static void -sugar_audio_manager_init(SugarAudioManager *grabber) +mixer_close(SugarAudioManager *manager) { + manager->priv->timer_id = g_timeout_add (4000, (GSourceFunc)mixer_close_real, manager); } void sugar_audio_manager_set_volume (SugarAudioManager *manager, int level) { + gint i, *volumes, volume; + GstMixerTrack *track; + + if (mixer_open(manager) == FALSE) + return; + + track = manager->priv->track; + volume = CLAMP(level, 0, 100); + + /* Rescale the volume from [0, 100] to [track min, track max]. */ + volume = (volume / 100.0) * (track->max_volume - track->min_volume) + + track->min_volume; + + volumes = g_new(gint, track->num_channels); + for (i = 0; i < track->num_channels; ++i) + volumes[i] = (gint)volume; + gst_mixer_set_volume(manager->priv->mixer, track, volumes); + g_free (volumes); + + mixer_close(manager); } + +static void +sugar_audio_manager_finalize (GObject *object) +{ + SugarAudioManager *manager = SUGAR_AUDIO_MANAGER(object); + + mixer_close_real(manager); + + G_OBJECT_CLASS(sugar_audio_manager_parent_class)->finalize(object); +} + +static void +sugar_audio_manager_class_init(SugarAudioManagerClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS(klass); + + gst_init (NULL, NULL); + + object_class->finalize = sugar_audio_manager_finalize; + + g_type_class_add_private(klass, sizeof(SugarAudioManagerPrivate)); +} + +static void +sugar_audio_manager_init(SugarAudioManager *manager) +{ + manager->priv = SUGAR_AUDIO_MANAGER_GET_PRIVATE(manager); +} + + diff --git a/lib/src/sugar-audio-manager.h b/lib/src/sugar-audio-manager.h index 3df8cef7..ba72fa02 100644 --- a/lib/src/sugar-audio-manager.h +++ b/lib/src/sugar-audio-manager.h @@ -36,6 +36,9 @@ typedef struct _SugarAudioManagerPrivate SugarAudioManagerPrivate; struct _SugarAudioManager { GObject base_instance; + + /*< private >*/ + SugarAudioManagerPrivate *priv; }; struct _SugarAudioManagerClass { diff --git a/shell/view/Shell.py b/shell/view/Shell.py index bace0f91..5ed8389a 100644 --- a/shell/view/Shell.py +++ b/shell/view/Shell.py @@ -86,6 +86,18 @@ class Shell(gobject.GObject): self._key_grabber.grab('F6') self._key_grabber.grab('F7') self._key_grabber.grab('F8') + self._key_grabber.grab('F9') + self._key_grabber.grab('F10') + self._key_grabber.grab('F11') + self._key_grabber.grab('F12') + self._key_grabber.grab('F13') + self._key_grabber.grab('F14') + self._key_grabber.grab('F15') + self._key_grabber.grab('F16') + self._key_grabber.grab('F17') + self._key_grabber.grab('F18') + self._key_grabber.grab('F19') + self._key_grabber.grab('F20') self._key_grabber.grab('0xDC') # Camera key self._key_grabber.grab('0xE0') # Overlay key self._key_grabber.grab('0x93') # Frame key