summaryrefslogtreecommitdiff
path: root/plugins/media-keys
diff options
context:
space:
mode:
authorStefano Karapetsas <[email protected]>2012-01-22 22:59:41 +0100
committerStefano Karapetsas <[email protected]>2012-01-22 22:59:41 +0100
commit8f91d9b2cefd226c60234a6122b624ba65e7b424 (patch)
tree7b9422f117477da0aa0145a1f14a02ae47493969 /plugins/media-keys
parent5c00322b3ea38a54d06e6390711dd49c31b77040 (diff)
downloadmate-settings-daemon-8f91d9b2cefd226c60234a6122b624ba65e7b424.tar.bz2
mate-settings-daemon-8f91d9b2cefd226c60234a6122b624ba65e7b424.tar.xz
add support for gstreamer/alsa/oss instead of pulse for media-keys
https://bugzilla.gnome.org/show_bug.cgi?id=571145 patch stolen from debian: http://patch-tracker.debian.org/patch/series/view/gnome-settings-daemon/2.30.2-2+squeeze1/20_gstreamer.patch
Diffstat (limited to 'plugins/media-keys')
-rw-r--r--plugins/media-keys/Makefile.am9
-rw-r--r--plugins/media-keys/cut-n-paste/Makefile.am34
-rw-r--r--plugins/media-keys/cut-n-paste/gvc-gstreamer-acme-vol.c402
-rw-r--r--plugins/media-keys/cut-n-paste/gvc-gstreamer-acme-vol.h56
-rw-r--r--plugins/media-keys/gsd-media-keys-manager.c75
5 files changed, 557 insertions, 19 deletions
diff --git a/plugins/media-keys/Makefile.am b/plugins/media-keys/Makefile.am
index d8bff08..43f2156 100644
--- a/plugins/media-keys/Makefile.am
+++ b/plugins/media-keys/Makefile.am
@@ -3,13 +3,8 @@ context = actions
NULL =
-SUBDIRS =
-plugin_LTLIBRARIES =
-
-if HAVE_PULSE
SUBDIRS += cut-n-paste
plugin_LTLIBRARIES += libmedia-keys.la
-endif
BUILT_SOURCES = \
gsd-media-keys-manager-glue.h \
@@ -108,9 +103,7 @@ libmedia_keys_la_LIBADD = \
plugin_in_files = \
media-keys.mate-settings-plugin.in
-if HAVE_PULSE
plugin_DATA = $(plugin_in_files:.mate-settings-plugin.in=.mate-settings-plugin)
-endif
noinst_PROGRAMS = \
test-media-keys \
@@ -176,9 +169,7 @@ test_media_keys_LDADD = \
$(GST_LIBS) \
-lm
-if HAVE_PULSE
test_media_keys_LDADD += $(top_builddir)/plugins/media-keys/cut-n-paste/libgvc.la
-endif
gtkbuilderdir = $(pkgdatadir)
gtkbuilder_DATA = \
diff --git a/plugins/media-keys/cut-n-paste/Makefile.am b/plugins/media-keys/cut-n-paste/Makefile.am
index bc59a10..5d8dc4b 100644
--- a/plugins/media-keys/cut-n-paste/Makefile.am
+++ b/plugins/media-keys/cut-n-paste/Makefile.am
@@ -4,16 +4,24 @@ noinst_LTLIBRARIES = libgvc.la
INCLUDES = \
$(WARN_CFLAGS) \
- $(VOLUME_CONTROL_CFLAGS) \
- $(PULSE_CFLAGS) \
$(NULL)
libgvc_la_LIBADD = \
- $(VOLUME_CONTROL_LIBS) \
- $(PULSE_LIBS) \
$(NULL)
libgvc_la_SOURCES = \
+ $(NULL)
+
+if HAVE_PULSE
+INCLUDES += \
+ $(VOLUME_CONTROL_CFLAGS) \
+ $(PULSE_CFLAGS)
+
+libgvc_la_LIBADD += \
+ $(VOLUME_CONTROL_LIBS) \
+ $(PULSE_LIBS)
+
+libgvc_la_SOURCES +=
gvc-mixer-stream.h \
gvc-mixer-stream.c \
gvc-channel-map.h \
@@ -31,8 +39,22 @@ libgvc_la_SOURCES = \
gvc-mixer-event-role.h \
gvc-mixer-event-role.c \
gvc-mixer-control.h \
- gvc-mixer-control.c \
- $(NULL)
+ gvc-mixer-control.c
+endif
+
+if HAVE_GSTREAMER
+INCLUDES += \
+ $(SETTINGS_PLUGIN_CFLAGS) \
+ $(AM_CFLAGS) \
+ $(GST_CFLAGS)
+
+libgvc_la_LIBADD += \
+ $(GST_LIBS)
+
+libgvc_la_SOURCES += \
+ gvc-gstreamer-acme-vol.c \
+ gvc-gstreamer-acme-vol.h
+endif
MAINTAINERCLEANFILES = \
*~ \
diff --git a/plugins/media-keys/cut-n-paste/gvc-gstreamer-acme-vol.c b/plugins/media-keys/cut-n-paste/gvc-gstreamer-acme-vol.c
new file mode 100644
index 0000000..d0ef380
--- /dev/null
+++ b/plugins/media-keys/cut-n-paste/gvc-gstreamer-acme-vol.c
@@ -0,0 +1,402 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/* acme-volume.c
+
+ Copyright (C) 2002, 2003 Bastien Nocera
+ Copyright (C) 2004 Novell, Inc.
+ Copyright (C) 2009 PERIER Romain <[email protected]>
+ Copyright (C) 2011 Stefano Karapetsas <[email protected]>
+
+ The Mate Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The Mate Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the Mate Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ Author: Bastien Nocera <[email protected]>
+ Jon Trowbridge <[email protected]>
+*/
+
+#include "config.h"
+#include "gvc-gstreamer-acme-vol.h"
+
+#include <gst/gst.h>
+#include <gst/audio/mixerutils.h>
+#include <gst/interfaces/mixer.h>
+#include <gst/interfaces/propertyprobe.h>
+
+#include <mateconf/mateconf-client.h>
+
+#include <string.h>
+
+#define TIMEOUT 4
+
+#define DEFAULT_MIXER_DEVICE_KEY "/desktop/mate/sound/default_mixer_device"
+#define DEFAULT_MIXER_TRACKS_KEY "/desktop/mate/sound/default_mixer_tracks"
+
+#define ACME_VOLUME_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), ACME_TYPE_VOLUME, AcmeVolumePrivate))
+
+struct AcmeVolumePrivate {
+ GstMixer *mixer;
+ GList *mixer_tracks;
+ guint timer_id;
+ gdouble volume;
+ gboolean mute;
+ MateConfClient *mateconf_client;
+};
+
+G_DEFINE_TYPE (AcmeVolume, acme_volume, G_TYPE_OBJECT)
+
+static gboolean acme_volume_open (AcmeVolume *acme);
+static void acme_volume_close (AcmeVolume *acme);
+static gboolean acme_volume_close_real (AcmeVolume *self);
+
+static gpointer acme_volume_object = NULL;
+
+static void
+acme_volume_finalize (GObject *object)
+{
+ AcmeVolume *self;
+
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (ACME_IS_VOLUME (object));
+
+ self = ACME_VOLUME (object);
+
+ if (self->_priv->timer_id != 0)
+ g_source_remove (self->_priv->timer_id);
+ acme_volume_close_real (self);
+
+ if (self->_priv->mateconf_client != NULL) {
+ g_object_unref (self->_priv->mateconf_client);
+ self->_priv->mateconf_client = NULL;
+ }
+
+ G_OBJECT_CLASS (acme_volume_parent_class)->finalize (object);
+}
+
+void
+acme_volume_set_mute (AcmeVolume *self, gboolean val)
+{
+ GList *t;
+
+ g_return_if_fail(ACME_IS_VOLUME(self));
+ g_return_if_fail(acme_volume_open(self));
+
+ for (t = self->_priv->mixer_tracks; t != NULL; t = t->next) {
+ GstMixerTrack *track = GST_MIXER_TRACK (t->data);
+ gst_mixer_set_mute (self->_priv->mixer, track, val);
+ }
+ self->_priv->mute = val;
+ acme_volume_close (self);
+}
+
+static void
+update_state (AcmeVolume * self)
+{
+ gint *volumes, n;
+ gdouble vol = 0;
+ GstMixerTrack *track = GST_MIXER_TRACK (self->_priv->mixer_tracks->data);
+
+ /* update mixer by getting volume */
+ volumes = g_new0 (gint, track->num_channels);
+ gst_mixer_get_volume (self->_priv->mixer, track, volumes);
+ for (n = 0; n < track->num_channels; n++)
+ vol += volumes[n];
+ g_free (volumes);
+ vol /= track->num_channels;
+ vol = 100 * vol / (track->max_volume - track->min_volume);
+
+ /* update mute flag, and volume if not muted */
+ if (GST_MIXER_TRACK_HAS_FLAG (track, GST_MIXER_TRACK_MUTE))
+ self->_priv->mute = TRUE;
+ self->_priv->volume = vol;
+}
+
+gboolean
+acme_volume_get_mute (AcmeVolume *self)
+{
+ g_return_val_if_fail(acme_volume_open(self), FALSE);
+
+ update_state (self);
+ acme_volume_close (self);
+
+ return self->_priv->mute;
+}
+
+gint
+acme_volume_get_volume (AcmeVolume *self)
+{
+
+ g_return_val_if_fail(acme_volume_open(self), 0);
+
+ update_state (self);
+
+ acme_volume_close (self);
+
+ return (gint) (self->_priv->volume + 0.5);
+}
+
+void
+acme_volume_set_volume (AcmeVolume *self, gint val)
+{
+ GList *t;
+
+ g_return_if_fail(acme_volume_open(self));
+
+ val = CLAMP (val, 0, 100);
+
+ for (t = self->_priv->mixer_tracks; t != NULL; t = t->next) {
+ GstMixerTrack *track = GST_MIXER_TRACK (t->data);
+ gint *volumes, n;
+ gdouble scale = (track->max_volume - track->min_volume) / 100.0;
+ gint vol = (gint) (val * scale + track->min_volume + 0.5);
+
+ volumes = g_new (gint, track->num_channels);
+ for (n = 0; n < track->num_channels; n++)
+ volumes[n] = vol;
+ gst_mixer_set_volume (self->_priv->mixer, track, volumes);
+ g_free (volumes);
+ }
+
+ /* update state */
+ self->_priv->volume = val;
+
+ acme_volume_close (self);
+}
+
+void
+acme_volume_mute_toggle (AcmeVolume *self)
+{
+ gboolean muted;
+
+ g_return_if_fail (self != NULL);
+ g_return_if_fail (ACME_IS_VOLUME(self));
+
+ muted = acme_volume_get_mute(self);
+ acme_volume_set_mute(self, !muted);
+}
+
+gint
+acme_volume_get_threshold (AcmeVolume *self)
+{
+ GList *t;
+ gint steps = 101;
+
+ g_return_val_if_fail(acme_volume_open(self), 1);
+
+ for (t = self->_priv->mixer_tracks; t != NULL; t = t->next) {
+ GstMixerTrack *track = GST_MIXER_TRACK (t->data);
+ gint track_steps = track->max_volume - track->min_volume;
+ if (track_steps > 0 && track_steps < steps)
+ steps = track_steps;
+ }
+
+ acme_volume_close (self);
+
+ return 100 / steps + 1;
+}
+
+static gboolean
+acme_volume_close_real (AcmeVolume *self)
+{
+ if (self->_priv->mixer != NULL)
+ {
+ gst_element_set_state (GST_ELEMENT (self->_priv->mixer), GST_STATE_NULL);
+ gst_object_unref (GST_OBJECT (self->_priv->mixer));
+ g_list_foreach (self->_priv->mixer_tracks, (GFunc) g_object_unref, NULL);
+ g_list_free (self->_priv->mixer_tracks);
+ self->_priv->mixer = NULL;
+ self->_priv->mixer_tracks = NULL;
+ }
+
+ self->_priv->timer_id = 0;
+ return FALSE;
+}
+
+/*
+ * _acme_set_mixer
+ * @mixer A pointer to mixer element
+ * @data A pointer to user data (AcmeVolume instance to be modified)
+ * @return A gboolean indicating success if Master track was found, failed otherwises.
+ */
+static gboolean
+_acme_set_mixer(GstMixer *mixer, gpointer user_data)
+{
+ const GList *tracks;
+
+ for (tracks = gst_mixer_list_tracks (mixer); tracks != NULL; tracks = tracks->next) {
+ GstMixerTrack *track = GST_MIXER_TRACK (tracks->data);
+
+ if (GST_MIXER_TRACK_HAS_FLAG (track, GST_MIXER_TRACK_MASTER)) {
+ AcmeVolume *self;
+
+ self = ACME_VOLUME (user_data);
+
+ self->_priv->mixer = mixer;
+ self->_priv->mixer_tracks = g_list_append (self->_priv->mixer_tracks, g_object_ref (track));
+ return TRUE;
+ }
+
+ continue;
+ }
+
+ return FALSE;
+}
+
+/* This is a modified version of code from gnome-media's gst-mixer */
+static gboolean
+acme_volume_open (AcmeVolume *self)
+{
+ gchar *mixer_device, **factory_and_device = NULL;
+ GList *mixer_list;
+
+ if (self->_priv->timer_id != 0) {
+ g_source_remove (self->_priv->timer_id);
+ self->_priv->timer_id = 0;
+ return TRUE;
+ }
+
+ mixer_device = mateconf_client_get_string (self->_priv->mateconf_client, DEFAULT_MIXER_DEVICE_KEY, NULL);
+ if (mixer_device != NULL)
+ factory_and_device = g_strsplit (mixer_device, ":", 2);
+
+ if (factory_and_device != NULL && factory_and_device[0] != NULL) {
+ GstElement *element;
+
+ element = gst_element_factory_make (factory_and_device[0], NULL);
+
+ if (element != NULL) {
+ if (factory_and_device[1] != NULL &&
+ g_object_class_find_property (G_OBJECT_GET_CLASS (element), "device"))
+ g_object_set (G_OBJECT (element), "device", factory_and_device[1], NULL);
+ gst_element_set_state (element, GST_STATE_READY);
+
+ if (GST_IS_MIXER (element))
+ self->_priv->mixer = GST_MIXER (element);
+ else {
+ gst_element_set_state (element, GST_STATE_NULL);
+ gst_object_unref (element);
+ }
+ }
+ }
+
+ g_free (mixer_device);
+ g_strfreev (factory_and_device);
+
+ if (self->_priv->mixer != NULL) {
+ const GList *m;
+ GSList *tracks, *t;
+ GError *error = NULL;
+
+ /* Try to use tracks saved in MateConf
+ Note: errors need to be treated , for example if the user set a non type list for this key
+ or if the elements type_list are not "matched" */
+ tracks = mateconf_client_get_list (self->_priv->mateconf_client, DEFAULT_MIXER_TRACKS_KEY,
+ MATECONF_VALUE_STRING, &error);
+
+ if (error) {
+ g_warning("ERROR: %s\n", error->message);
+ g_error_free(error);
+ }
+
+ /* We use these tracks ONLY if they are supported on the system with the following mixer */
+ for (m = gst_mixer_list_tracks (self->_priv->mixer); m != NULL; m = m->next) {
+ GstMixerTrack *track = GST_MIXER_TRACK (m->data);
+
+ for (t = tracks; t != NULL; t = t->next)
+ if (!strcmp (t->data, track->label))
+ self->_priv->mixer_tracks = g_list_append (self->_priv->mixer_tracks, g_object_ref (track));
+
+ }
+
+ g_slist_foreach (tracks, (GFunc)g_free, NULL);
+ g_slist_free (tracks);
+
+ /* If no track stored in MateConf is avaiable try to use Master track */
+ if (self->_priv->mixer_tracks == NULL) {
+ for (m = gst_mixer_list_tracks (self->_priv->mixer); m != NULL; m = m->next) {
+ GstMixerTrack *track = GST_MIXER_TRACK (m->data);
+
+ if (GST_MIXER_TRACK_HAS_FLAG (track, GST_MIXER_TRACK_MASTER)) {
+ self->_priv->mixer_tracks = g_list_append (self->_priv->mixer_tracks, g_object_ref (track));
+ break;
+ }
+ }
+ }
+
+ if (self->_priv->mixer_tracks != NULL)
+ return TRUE;
+ else {
+ gst_element_set_state (GST_ELEMENT (self->_priv->mixer), GST_STATE_NULL);
+ gst_object_unref (self->_priv->mixer);
+ }
+ }
+
+ /* Go through all elements of a certain class and check whether
+ * they implement a mixer. If so, walk through the tracks and look
+ * for first one named "volume".
+ *
+ * We should probably do something intelligent if we don't find an
+ * appropriate mixer/track. But now we do something stupid...
+ * everything just becomes a no-op.
+ */
+ mixer_list = gst_audio_default_registry_mixer_filter (_acme_set_mixer,
+ TRUE,
+ self);
+
+ if (mixer_list == NULL)
+ return FALSE;
+
+ /* do not unref the mixer as we keep the ref for self->priv->mixer */
+ g_list_free (mixer_list);
+
+ return TRUE;
+}
+
+static void
+acme_volume_close (AcmeVolume *self)
+{
+ self->_priv->timer_id = g_timeout_add_seconds (TIMEOUT,
+ (GSourceFunc) acme_volume_close_real, self);
+}
+
+static void
+acme_volume_init (AcmeVolume *self)
+{
+ self->_priv = ACME_VOLUME_GET_PRIVATE (self);
+ self->_priv->mateconf_client = mateconf_client_get_default ();
+}
+
+static void
+acme_volume_class_init (AcmeVolumeClass *klass)
+{
+ G_OBJECT_CLASS (klass)->finalize = acme_volume_finalize;
+
+ gst_init (NULL, NULL);
+
+ g_type_class_add_private (klass, sizeof (AcmeVolumePrivate));
+}
+
+/* acme_volume_new
+ * @return A singleton instance of type AcmeVolume
+ */
+AcmeVolume *
+acme_volume_new (void)
+{
+ if (acme_volume_object == NULL) {
+ acme_volume_object = g_object_new (ACME_TYPE_VOLUME, NULL);
+ return ACME_VOLUME(acme_volume_object);
+ }
+ g_object_ref(acme_volume_object);
+ return ACME_VOLUME(acme_volume_object);
+}
diff --git a/plugins/media-keys/cut-n-paste/gvc-gstreamer-acme-vol.h b/plugins/media-keys/cut-n-paste/gvc-gstreamer-acme-vol.h
new file mode 100644
index 0000000..82c1b18
--- /dev/null
+++ b/plugins/media-keys/cut-n-paste/gvc-gstreamer-acme-vol.h
@@ -0,0 +1,56 @@
+/* acme-volume.h
+
+ Copyright (C) 2002, 2003 Bastien Nocera
+ Copyright (C) 2004 Novell, Inc.
+ Copyright (C) 2009 PERIER Romain <[email protected]>
+ Copyright (C) 2011 Stefano Karapetsas <[email protected]>
+
+ The Mate Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The Mate Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the Mate Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ Author: Bastien Nocera <[email protected]>
+ Jon Trowbridge <[email protected]>
+ */
+
+#include <glib-object.h>
+
+#define ACME_TYPE_VOLUME (acme_volume_get_type ())
+#define ACME_VOLUME(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), ACME_TYPE_VOLUME, AcmeVolume))
+#define ACME_VOLUME_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), ACME_TYPE_VOLUME, AcmeVolumeClass))
+#define ACME_IS_VOLUME(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), ACME_TYPE_VOLUME))
+#define ACME_VOLUME_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), ACME_TYPE_VOLUME, AcmeVolumeClass))
+
+typedef struct AcmeVolume AcmeVolume;
+typedef struct AcmeVolumeClass AcmeVolumeClass;
+typedef struct AcmeVolumePrivate AcmeVolumePrivate;
+
+struct AcmeVolume {
+ GObject parent;
+ AcmeVolumePrivate *_priv;
+};
+
+struct AcmeVolumeClass {
+ GObjectClass parent;
+};
+
+GType acme_volume_get_type (void);
+AcmeVolume *acme_volume_new (void);
+void acme_volume_set_mute (AcmeVolume *self, gboolean val);
+void acme_volume_mute_toggle (AcmeVolume *self);
+gboolean acme_volume_get_mute (AcmeVolume *self);
+void acme_volume_set_volume (AcmeVolume *self, gint val);
+gint acme_volume_get_volume (AcmeVolume *self);
+gint acme_volume_get_threshold (AcmeVolume *self);
+
diff --git a/plugins/media-keys/gsd-media-keys-manager.c b/plugins/media-keys/gsd-media-keys-manager.c
index ae7d3e2..9e8bcde 100644
--- a/plugins/media-keys/gsd-media-keys-manager.c
+++ b/plugins/media-keys/gsd-media-keys-manager.c
@@ -53,6 +53,8 @@
#ifdef HAVE_PULSE
#include <canberra-gtk.h>
#include "gvc-mixer-control.h"
+#elif defined(HAVE_GSTREAMER)
+#include "gvc-gstreamer-acme-vol.h"
#endif /* HAVE_PULSE */
#define GSD_DBUS_PATH "/org/mate/SettingsDaemon"
@@ -78,6 +80,8 @@ struct GsdMediaKeysManagerPrivate
/* Volume bits */
GvcMixerControl *volume;
GvcMixerStream *stream;
+#elif defined(HAVE_GSTREAMER)
+ AcmeVolume *volume;
#endif /* HAVE_PULSE */
GtkWidget *dialog;
MateConfClient *conf_client;
@@ -682,7 +686,9 @@ update_dialog (GsdMediaKeysManager *manager,
CA_PROP_APPLICATION_ID, "org.mate.VolumeControl",
NULL);
}
-
+#endif /* HAVE_PULSE */
+
+#if defined(HAVE_PULSE) || defined(HAVE_GSTREAMER)
static void
do_sound_action (GsdMediaKeysManager *manager,
int type)
@@ -692,8 +698,13 @@ do_sound_action (GsdMediaKeysManager *manager,
int vol_step;
gboolean sound_changed;
+#ifdef HAVE_PULSE
if (manager->priv->stream == NULL)
return;
+#elif defined(HAVE_GSTREAMER)
+ if (manager->priv->volume == NULL)
+ return;
+#endif
vol_step = mateconf_client_get_int (manager->priv->conf_client,
MATECONF_MISC_DIR "/volume_step",
@@ -702,20 +713,36 @@ do_sound_action (GsdMediaKeysManager *manager,
if (vol_step <= 0 || vol_step > 100)
vol_step = VOLUME_STEP;
+#ifdef HAVE_PULSE
norm_vol_step = PA_VOLUME_NORM * vol_step / 100;
/* FIXME: this is racy */
vol = gvc_mixer_stream_get_volume (manager->priv->stream);
muted = gvc_mixer_stream_get_is_muted (manager->priv->stream);
+#else
+ if (vol_step > 0) {
+ gint threshold = acme_volume_get_threshold (manager->priv->volume);
+ if (vol_step < threshold)
+ vol_step = threshold;
+ g_debug ("Using volume step of %d", vol_step);
+ }
+ vol = acme_volume_get_volume (manager->priv->volume);
+ muted = acme_volume_get_mute (manager->priv->volume);
+#endif
sound_changed = FALSE;
switch (type) {
case MUTE_KEY:
+#ifdef HAVE_PULSE
muted = !muted;
gvc_mixer_stream_change_is_muted (manager->priv->stream, muted);
sound_changed = TRUE;
+#else
+ acme_volume_mute_toggle (manager->priv->volume);
+#endif
break;
case VOLUME_DOWN_KEY:
+#ifdef HAVE_PULSE
if (!muted && (vol <= norm_vol_step)) {
muted = !muted;
vol = 0;
@@ -731,11 +758,17 @@ do_sound_action (GsdMediaKeysManager *manager,
sound_changed = TRUE;
}
}
+#else
+ if (!muted && (vol <= vol_step))
+ acme_volume_mute_toggle (manager->priv->volume);
+ acme_volume_set_volume (manager->priv->volume, vol - vol_step);
+#endif
break;
case VOLUME_UP_KEY:
if (muted) {
muted = !muted;
if (vol == 0) {
+#ifdef HAVE_PULSE
vol = vol + norm_vol_step;
gvc_mixer_stream_change_is_muted (manager->priv->stream, muted);
if (gvc_mixer_stream_set_volume (manager->priv->stream, vol) != FALSE) {
@@ -746,7 +779,14 @@ do_sound_action (GsdMediaKeysManager *manager,
gvc_mixer_stream_change_is_muted (manager->priv->stream, muted);
sound_changed = TRUE;
}
+else
+ /* We need to unmute otherwise vol is blocked (and muted) */
+ acme_volume_set_mute (manager->priv->volume, FALSE);
+ }
+ acme_volume_set_volume (manager->priv->volume, vol + vol_step);
+#endif
} else {
+#ifdef HAVE_PULSE
if (vol < MAX_VOLUME) {
if (vol + norm_vol_step >= MAX_VOLUME) {
vol = MAX_VOLUME;
@@ -758,13 +798,34 @@ do_sound_action (GsdMediaKeysManager *manager,
sound_changed = TRUE;
}
}
+#else
+ acme_volume_set_volume (manager->priv->volume, vol + vol_step);
+#endif
}
break;
}
+#ifdef HAVE_PULSE
update_dialog (manager, vol, muted, sound_changed);
+#else
+ muted = acme_volume_get_mute (manager->priv->volume);
+ vol = acme_volume_get_volume (manager->priv->volume);
+
+ /* FIXME: AcmeVolume should probably emit signals
+ instead of doing it like this */
+ dialog_init (manager);
+ gsd_media_keys_window_set_volume_muted (GSD_MEDIA_KEYS_WINDOW (manager->priv->dialog),
+ muted);
+ gsd_media_keys_window_set_volume_level (GSD_MEDIA_KEYS_WINDOW (manager->priv->dialog),
+ vol);
+ gsd_media_keys_window_set_action (GSD_MEDIA_KEYS_WINDOW (manager->priv->dialog),
+ GSD_MEDIA_KEYS_WINDOW_ACTION_VOLUME);
+ dialog_show (manager);
+#endif /* HAVE_PULSE */
}
+#endif /* defined(HAVE_PULSE) || defined(HAVE_GSTREAMER) */
+#ifdef HAVE_PULSE
static void
update_default_sink (GsdMediaKeysManager *manager)
{
@@ -926,9 +987,9 @@ do_action (GsdMediaKeysManager *manager,
case MUTE_KEY:
case VOLUME_DOWN_KEY:
case VOLUME_UP_KEY:
-#ifdef HAVE_PULSE
+#if defined(HAVE_PULSE) || defined(HAVE_GSTREAMER)
do_sound_action (manager, type);
-#endif /* HAVE_PULSE */
+#endif /* HAVE_PULSE || HAVE_GSTREAMER */
break;
case POWER_KEY:
do_exit_action (manager);
@@ -1129,6 +1190,10 @@ gsd_media_keys_manager_start (GsdMediaKeysManager *manager,
gvc_mixer_control_open (manager->priv->volume);
mate_settings_profile_end ("gvc_mixer_control_new");
+#elif defined(HAVE_GSTREAMER)
+ mate_settings_profile_start ("acme_volume_new");
+ manager->priv->volume = acme_volume_new ();
+ mate_settings_profile_end ("acme_volume_new");
#endif /* HAVE_PULSE */
g_idle_add ((GSourceFunc) start_media_keys_idle_cb, manager);
@@ -1206,12 +1271,14 @@ gsd_media_keys_manager_stop (GsdMediaKeysManager *manager)
g_object_unref (priv->stream);
priv->stream = NULL;
}
+#endif /* HAVE_PULSE */
+#if defined(HAVE_PULSE) || defined(HAVE_GSTREAMER)
if (priv->volume) {
g_object_unref (priv->volume);
priv->volume = NULL;
}
-#endif /* HAVE_PULSE */
+#endif /* defined(HAVE_PULSE) || defined(HAVE_GSTREAMER) */
if (priv->dialog != NULL) {
gtk_widget_destroy (priv->dialog);