diff options
author | yokirinjin | 2024-03-11 10:41:01 -0400 |
---|---|---|
committer | yokirinjin | 2024-03-11 10:41:01 -0400 |
commit | 439e8fc1cf14f49ebcc5c55dd6ba8d6af23822c0 (patch) | |
tree | d618629fa189c3d3169eb9ec520b5e6b64680ac5 | |
parent | 7dab7610295524dfeab52dce4683a99af5024803 (diff) | |
download | aur-439e8fc1cf14f49ebcc5c55dd6ba8d6af23822c0.tar.gz |
Update to 4.18.1, new maintainer
-rw-r--r-- | .SRCINFO | 25 | ||||
-rw-r--r-- | PKGBUILD | 47 | ||||
-rw-r--r-- | no-full-debug-default-for-git.patch | 16 | ||||
-rw-r--r-- | xfce4-mixer-alsa-git.patch | 1603 |
4 files changed, 30 insertions, 1661 deletions
@@ -1,22 +1,15 @@ pkgbase = xfce4-mixer - pkgdesc = A volume control application based on ALSA (stable git) - pkgver = 4.11.0 - pkgrel = 2 - url = https://git.xfce.org/apps/xfce4-mixer/ - arch = i686 + pkgdesc = A volume control application based on GStreamer + pkgver = 4.18.1 + pkgrel = 1 + url = https://docs.xfce.org/apps/xfce4-mixer arch = x86_64 - arch = mips64el - arch = armv6h - arch = armv7h - arch = arm - arch = aarch64 license = GPL2 - makedepends = xfce4-dev-tools + makedepends = intltool depends = xfce4-panel - depends = alsa-lib - depends = libunique>=1.1 - source = git+https://git.xfce.org/apps/xfce4-mixer#commit=ce642ac52e0bed7495261694fd630748bf71157f - sha256sums = SKIP + depends = alsa-lib>=1.2.1 + depends = gstreamer + source = https://archive.xfce.org/src/apps/xfce4-mixer/4.18/xfce4-mixer-4.18.1.tar.bz2 + sha256sums = b27f67dccc9dd67d989b405dab02be1299436dd71b58edb88a1d5f82571ead95 pkgname = xfce4-mixer - @@ -1,35 +1,30 @@ -# Contributor: qaz <fkxxyz@163.com> +# Maintainer: yokirinjin <aur.country952@passmail.com> +# Contributor: yokirinjin <aur.country952@passmail.com> + pkgname=xfce4-mixer -pkgver=4.11.0 -pkgrel=2 -pkgdesc="A volume control application based on GStreamer" -arch=('i686' 'x86_64' 'mips64el' 'armv6h' 'armv7h' 'arm' 'aarch64') -url="https://git.xfce.org/apps/xfce4-mixer/" +pkgver=4.18.1 +pkgrel=1 +pkgdesc='A volume control application based on GStreamer' +arch=('x86_64') +url='https://docs.xfce.org/apps/xfce4-mixer' license=('GPL2') -depends=('xfce4-panel' 'alsa-lib>=1.2.1') -makedepends=('xfce4-dev-tools') -source=('git+https://git.xfce.org/apps/xfce4-mixer#commit=ce642ac52e0bed7495261694fd630748bf71157f' - xfce4-mixer-alsa-git.patch - no-full-debug-default-for-git.patch) - -sha256sums=('SKIP' - 'd044469a259a86e44dfa107f2b8051774848ef43bc72d0d91220dd40641efeb6' - '85d5226a930aae0fa43e6ab8b8dab4f28f3555f40b05f0f8f315d7d4cd60d408') - -prepare() { - cd "$srcdir/$pkgname" - patch -Np1 -i "${srcdir}/xfce4-mixer-alsa-git.patch" - patch -Np1 -i "${srcdir}/no-full-debug-default-for-git.patch" -} +depends=('xfce4-panel' 'alsa-lib>=1.2.1' 'gstreamer') +makedepends=('intltool') +source=("https://archive.xfce.org/src/apps/$pkgname/${pkgver%.*}/$pkgname-$pkgver.tar.bz2") +sha256sums=('b27f67dccc9dd67d989b405dab02be1299436dd71b58edb88a1d5f82571ead95') build() { - cd "$srcdir/$pkgname" - ./autogen.sh --localstatedir=/var --prefix=/usr --sysconfdir=/etc + cd $pkgname-$pkgver + + ./configure \ + --prefix=/usr \ + --sysconfdir=/etc \ + --localstatedir=/var \ + --disable-debug make } -package () -{ - cd "$srcdir/$pkgname" +package () { + cd $pkgname-$pkgver make DESTDIR="$pkgdir" install } diff --git a/no-full-debug-default-for-git.patch b/no-full-debug-default-for-git.patch deleted file mode 100644 index e37557cb6c54..000000000000 --- a/no-full-debug-default-for-git.patch +++ /dev/null @@ -1,16 +0,0 @@ ---- - configure.ac.in | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/configure.ac.in -+++ b/configure.ac.in -@@ -32,7 +32,7 @@ m4_define([xfce4_mixer_version], [xfce4_ - dnl ******************************************* - dnl *** Debugging support for git snapshots *** - dnl ******************************************* --m4_define([mixer_debug_default], [ifelse(xfce4_mixer_version_tag(), [git], [full], [minimum])]) -+m4_define([mixer_debug_default], [minimum]) - - dnl *************************** - dnl *** Initialize autoconf *** - diff --git a/xfce4-mixer-alsa-git.patch b/xfce4-mixer-alsa-git.patch deleted file mode 100644 index 96c1d70a746e..000000000000 --- a/xfce4-mixer-alsa-git.patch +++ /dev/null @@ -1,1603 +0,0 @@ ---- - configure.ac.in | 18 - libxfce4mixer/Makefile.am | 25 - libxfce4mixer/audio.h | 8 - libxfce4mixer/libxfce4mixer.c | 40 + - libxfce4mixer/libxfce4mixer.h | 2 - libxfce4mixer/xfce-mixer-preferences.h | 3 - libxfce4mixer/xfce-mixer-track-combo.c | 3 - libxfce4mixer/xfce-mixer-track-combo.h | 3 - libxfce4mixer/xfce-mixer-track-type.h | 2 - libxfce4mixer/xfce4-mixer-alsa.c | 974 +++++++++++++++++++++++++++++++ - libxfce4mixer/xfce4-mixer-alsa.h | 192 ++++++ - panel-plugin/Makefile.am | 15 - panel-plugin/xfce-plugin-dialog.c | 3 - panel-plugin/xfce-plugin-dialog.h | 3 - xfce4-mixer/Makefile.am | 11 - xfce4-mixer/xfce-mixer-container.c | 3 - xfce4-mixer/xfce-mixer-controls-dialog.c | 3 - xfce4-mixer/xfce-mixer-option.c | 3 - xfce4-mixer/xfce-mixer-switch.c | 3 - xfce4-mixer/xfce-mixer-track.c | 3 - xfce4-mixer/xfce-mixer-window.c | 4 - 21 files changed, 1278 insertions(+), 43 deletions(-) - ---- a/libxfce4mixer/libxfce4mixer.c -+++ b/libxfce4mixer/libxfce4mixer.c -@@ -31,8 +31,7 @@ - - #include <dbus/dbus-glib.h> - --#include <gst/audio/mixerutils.h> --#include <gst/interfaces/mixer.h> -+#include "audio.h" - - #include <libxfce4util/libxfce4util.h> - -@@ -40,8 +39,10 @@ - - - -+#ifndef XFCE4_MIXER_ALSA - static gboolean _xfce_mixer_filter_mixer (GstMixer *mixer, - gpointer user_data); -+#endif - static void _xfce_mixer_add_track_labels (gpointer data, - gpointer user_data); - static void _xfce_mixer_init_mixer (gpointer data, -@@ -88,7 +89,11 @@ xfce_mixer_init (void) - gtk_icon_theme_append_search_path (icon_theme, MIXER_DATADIR G_DIR_SEPARATOR_S "icons"); - - /* Get list of all available mixer devices */ -+#ifdef XFCE4_MIXER_ALSA -+ mixers = gst_mixer_probe_devices (); -+#else - mixers = gst_audio_default_registry_mixer_filter (_xfce_mixer_filter_mixer, FALSE, &counter); -+#endif - - /* Create a GstBus for notifications */ - bus = gst_bus_new (); -@@ -396,6 +401,9 @@ xfce_mixer_get_max_volume (gint *volumes - - - -+static void set_mixer_name (GstMixer *mixer, const gchar *name); -+ -+#ifndef XFCE4_MIXER_ALSA - static gboolean - _xfce_mixer_filter_mixer (GstMixer *mixer, - gpointer user_data) -@@ -427,8 +435,24 @@ _xfce_mixer_filter_mixer (GstMixer *mixe - /* Free device name */ - g_free (device_name); - -+ set_mixer_name (mixer, name); -+ g_free (name); -+ -+ /* Keep the mixer (we want all devices to be visible) */ -+ return TRUE; -+} -+#endif /* !XFCE4_MIXER_ALSA */ -+ -+static void -+set_mixer_name (GstMixer *mixer, const gchar *name) -+{ -+ gint length; -+ const gchar *p; -+ gchar *internal_name; -+ - /* Set name to be used by xfce4-mixer */ -- g_object_set_data_full (G_OBJECT (mixer), "xfce-mixer-name", name, (GDestroyNotify) g_free); -+ g_object_set_data_full (G_OBJECT (mixer), "xfce-mixer-name", -+ g_strdup (name), (GDestroyNotify) g_free); - - /* Count alpha-numeric characters in the name */ - for (length = 0, p = name; *p != '\0'; ++p) -@@ -442,15 +466,11 @@ _xfce_mixer_filter_mixer (GstMixer *mixe - internal_name[length++] = *p; - internal_name[length] = '\0'; - -- /* Remember name for use by xfce4-mixer */ -+ /* Set name to be used by xfce4-mixer */ - g_object_set_data_full (G_OBJECT (mixer), "xfce-mixer-internal-name", internal_name, (GDestroyNotify) g_free); -- -- /* Keep the mixer (we want all devices to be visible) */ -- return TRUE; - } - - -- - static void - _xfce_mixer_add_track_labels (gpointer data, - gpointer user_data) -@@ -492,6 +512,10 @@ _xfce_mixer_init_mixer (gpointer data, - { - GstMixer *card = GST_MIXER (data); - -+#ifdef XFCE4_MIXER_ALSA -+ set_mixer_name (card, gst_mixer_get_card_name (card)); -+#endif -+ - /* Add custom labels to all tracks */ - _xfce_mixer_add_track_labels (card, NULL); - ---- a/libxfce4mixer/libxfce4mixer.h -+++ b/libxfce4mixer/libxfce4mixer.h -@@ -26,7 +26,7 @@ - - #include <dbus/dbus-glib.h> - --#include <gst/interfaces/mixer.h> -+#include "audio.h" - - #include "xfce-mixer-preferences.h" - #include "xfce-mixer-card-combo.h" ---- /dev/null -+++ b/libxfce4mixer/xfce4-mixer-alsa.h -@@ -0,0 +1,192 @@ -+/* -+ * Simple alternative GstMixer implementation with ALSA-native API -+ */ -+ -+#ifndef __XFCE4_MIXER_ALSA_H -+#define __XFCE4_MIXER_ALSA_H -+ -+G_BEGIN_DECLS -+ -+/* -+ * GstMixer -+ */ -+ -+GType gst_mixer_get_type (void); -+ -+#define GST_TYPE_MIXER \ -+ (gst_mixer_get_type ()) -+#define GST_MIXER(obj) \ -+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_MIXER, GstMixer)) -+#define GST_MIXER_CLASS(klass) \ -+ (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_MIXER, GstMixerClass)) -+#define GST_IS_MIXER(obj) \ -+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_MIXER)) -+#define GST_IS_MIXER_CLASS(klass) \ -+ (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_MIXER)) -+#define GST_MIXER_GET_CLASS(inst) \ -+ (G_TYPE_INSTANCE_GET_INTERFACE ((inst), GST_TYPE_MIXER, GstMixerClass)) -+ -+typedef struct _GstMixer GstMixer; -+typedef struct _GstMixerClass GstMixerClass; -+ -+typedef enum { -+ GST_MIXER_FLAG_NONE = 0, -+ GST_MIXER_FLAG_AUTO_NOTIFICATIONS = (1<<0), -+ GST_MIXER_FLAG_HAS_WHITELIST = (1<<1), -+ GST_MIXER_FLAG_GROUPING = (1<<2), -+} GstMixerFlags; -+ -+typedef enum { -+ GST_MIXER_MESSAGE_INVALID, -+ GST_MIXER_MESSAGE_MUTE_TOGGLED, -+ GST_MIXER_MESSAGE_RECORD_TOGGLED, -+ GST_MIXER_MESSAGE_VOLUME_CHANGED, -+ GST_MIXER_MESSAGE_OPTION_CHANGED, -+ GST_MIXER_MESSAGE_OPTIONS_LIST_CHANGED, -+ GST_MIXER_MESSAGE_MIXER_CHANGED -+} GstMixerMessageType; -+ -+struct _GstMixer { -+ GstElement element; -+ GList *tracklist; -+ void *handle; /* snd_mixer_t */ -+ const char *name; -+ const gchar *card_name; -+ GSource *src; -+}; -+ -+struct _GstMixerClass { -+ GstElementClass parent_class; -+}; -+ -+const GList *gst_mixer_list_tracks (GstMixer *mixer); -+ -+static inline GstMixerFlags -+gst_mixer_get_mixer_flags (GstMixer * mixer) -+{ -+ return GST_MIXER_FLAG_AUTO_NOTIFICATIONS; -+} -+ -+GstMixerMessageType gst_mixer_message_get_type (GstMessage *message); -+ -+int gst_mixer_new (const char *name, GstMixer **mixer_ret); -+GList *gst_mixer_probe_devices (void); -+const gchar *gst_mixer_get_card_name (GstMixer *mixer); -+ -+/* -+ * GstMixerTrack -+ */ -+ -+GType gst_mixer_track_get_type (void); -+ -+#define GST_TYPE_MIXER_TRACK \ -+ (gst_mixer_track_get_type ()) -+#define GST_MIXER_TRACK(obj) \ -+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_MIXER_TRACK, \ -+ GstMixerTrack)) -+#define GST_MIXER_TRACK_CLASS(klass) \ -+ (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_MIXER_TRACK, \ -+ GstMixerTrackClass)) -+#define GST_IS_MIXER_TRACK(obj) \ -+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_MIXER_TRACK)) -+#define GST_IS_MIXER_TRACK_CLASS(klass) \ -+ (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_MIXER_TRACK)) -+ -+typedef struct _GstMixerTrack GstMixerTrack; -+typedef struct _GstMixerTrackClass GstMixerTrackClass; -+ -+typedef enum { -+ GST_MIXER_TRACK_INPUT = (1<<0), -+ GST_MIXER_TRACK_OUTPUT = (1<<1), -+ GST_MIXER_TRACK_MUTE = (1<<2), -+ GST_MIXER_TRACK_RECORD = (1<<3), -+ GST_MIXER_TRACK_MASTER = (1<<4), -+ GST_MIXER_TRACK_SOFTWARE = (1<<5), -+ GST_MIXER_TRACK_NO_RECORD = (1<<6), -+ GST_MIXER_TRACK_NO_MUTE = (1<<7), -+ GST_MIXER_TRACK_WHITELIST = (1<<8), -+ GST_MIXER_TRACK_READONLY = (1<<9), -+ GST_MIXER_TRACK_WRITEONLY = (1<<10) -+} GstMixerTrackFlags; -+ -+struct _GstMixerTrack { -+ GObject parent; -+ void *element; -+ gchar *label; -+ gchar *untranslated_label; -+ guint index; -+ GstMixerTrackFlags flags; -+ gint num_channels; -+ gint *volumes; -+ gint min_volume; -+ gint max_volume; -+ GstMixerTrack *shared_mute; -+ gboolean has_volume; -+ gboolean has_switch; -+}; -+ -+struct _GstMixerTrackClass { -+ GObjectClass parent; -+}; -+ -+#define GST_MIXER_TRACK_HAS_FLAG(track, flag) ((track)->flags & (flag)) -+ -+void gst_mixer_get_volume (GstMixer *mixer, GstMixerTrack *track, gint *volumes); -+void gst_mixer_set_volume (GstMixer *mixer, GstMixerTrack *track, gint *volumes); -+void gst_mixer_set_mute (GstMixer *mixer, GstMixerTrack *track, gboolean mute); -+void gst_mixer_set_record (GstMixer *mixer, GstMixerTrack *track, gboolean record); -+ -+void gst_mixer_message_parse_mute_toggled (GstMessage *message, -+ GstMixerTrack **track, -+ gboolean *mute); -+void gst_mixer_message_parse_record_toggled (GstMessage *message, -+ GstMixerTrack **track, -+ gboolean *record); -+void gst_mixer_message_parse_volume_changed (GstMessage *message, -+ GstMixerTrack **track, -+ gint **volumes, -+ gint *num_channels); -+ -+/* -+ * GstMixerOptions -+ */ -+ -+GType gst_mixer_options_get_type (void); -+ -+#define GST_TYPE_MIXER_OPTIONS \ -+ (gst_mixer_options_get_type ()) -+#define GST_MIXER_OPTIONS(obj) \ -+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_MIXER_OPTIONS, GstMixerOptions)) -+#define GST_MIXER_OPTIONS_CLASS(klass) \ -+ (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_MIXER_OPTIONS, GstMixerOptionsClass)) -+#define GST_IS_MIXER_OPTIONS(obj) \ -+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_MIXER_OPTIONS)) -+#define GST_IS_MIXER_OPTIONS_CLASS(klass) \ -+ (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_MIXER_OPTIONS)) -+#define GST_MIXER_OPTIONS_GET_CLASS(inst) \ -+ (G_TYPE_INSTANCE_GET_INTERFACE ((inst), GST_TYPE_MIXER_OPTIONS, GstMixerOptionsClass)) -+ -+typedef struct _GstMixerOptions GstMixerOptions; -+typedef struct _GstMixerOptionsClass GstMixerOptionsClass; -+ -+struct _GstMixerOptions { -+ GstMixerTrack parent; -+ GList *values; -+}; -+ -+struct _GstMixerOptionsClass { -+ GstMixerTrackClass parent; -+}; -+ -+void gst_mixer_set_option (GstMixer * mixer, GstMixerOptions * opts, gchar * value); -+const gchar * gst_mixer_get_option (GstMixer * mixer, GstMixerOptions * opts); -+GList * gst_mixer_options_get_values (GstMixerOptions *mixer_options); -+void gst_mixer_message_parse_option_changed (GstMessage *message, -+ GstMixerOptions ** options, -+ const gchar **value); -+void gst_mixer_message_parse_options_list_changed (GstMessage *message, -+ GstMixerOptions **options); -+ -+G_END_DECLS -+ -+#endif /* __XFCE4_MIXER_ALSA_H */ ---- a/libxfce4mixer/xfce-mixer-preferences.h -+++ b/libxfce4mixer/xfce-mixer-preferences.h -@@ -24,8 +24,7 @@ - - #include <glib-object.h> - --#include <gst/gst.h> --#include <gst/interfaces/mixer.h> -+#include "audio.h" - - G_BEGIN_DECLS - ---- a/libxfce4mixer/xfce-mixer-track-combo.c -+++ b/libxfce4mixer/xfce-mixer-track-combo.c -@@ -27,8 +27,7 @@ - - #include <gtk/gtk.h> - --#include <gst/gst.h> --#include <gst/interfaces/mixer.h> -+#include "audio.h" - - #include "libxfce4mixer.h" - #include "xfce-mixer-track-type.h" ---- a/libxfce4mixer/xfce-mixer-track-combo.h -+++ b/libxfce4mixer/xfce-mixer-track-combo.h -@@ -24,8 +24,7 @@ - - #include <gtk/gtk.h> - --#include <gst/gst.h> --#include <gst/interfaces/mixer.h> -+#include "audio.h" - - G_BEGIN_DECLS - ---- a/libxfce4mixer/xfce-mixer-track-type.h -+++ b/libxfce4mixer/xfce-mixer-track-type.h -@@ -22,7 +22,7 @@ - #define __XFCE_TRACK_TYPE_H__ - - #include <glib-object.h> --#include <gst/interfaces/mixer.h> -+#include "audio.h" - - G_BEGIN_DECLS - ---- /dev/null -+++ b/libxfce4mixer/xfce4-mixer-alsa.c -@@ -0,0 +1,974 @@ -+/* -+ * Simple alternative GstMixer implementation with ALSA-native API -+ */ -+ -+#include "config.h" -+#include "audio.h" -+ -+#include <alsa/asoundlib.h> -+ -+#define GST_MIXER_MESSAGE_NAME "gst-mixer-message" -+ -+/* -+ * GstMixer -+ */ -+ -+G_DEFINE_TYPE (GstMixer, gst_mixer, GST_TYPE_ELEMENT); -+ -+static void gst_mixer_init (GstMixer *mixer) -+{ -+} -+ -+static void gst_mixer_dispose (GObject * object) -+{ -+ GstMixer *mixer = GST_MIXER (object); -+ -+ if (mixer->src) { -+ g_source_destroy (mixer->src); -+ mixer->src = NULL; -+ } -+ -+ if (mixer->handle) { -+ snd_mixer_close (mixer->handle); -+ mixer->handle = NULL; -+ } -+ -+ g_list_free_full (mixer->tracklist, g_object_unref); -+ mixer->tracklist = NULL; -+ -+ g_free ((gpointer *) mixer->name); -+ mixer->name = NULL; -+ -+ g_free ((gpointer *) mixer->card_name); -+ mixer->card_name = NULL; -+ -+ G_OBJECT_CLASS (gst_mixer_parent_class)->dispose (object); -+} -+ -+static void gst_mixer_class_init (GstMixerClass *klass) -+{ -+ GstElementClass *element_klass = GST_ELEMENT_CLASS (klass); -+ GObjectClass *object_klass = G_OBJECT_CLASS (klass); -+ -+ gst_element_class_set_static_metadata (element_klass, -+ "ALSA mixer", "Generic/Audio", -+ "Control audio mixer via ALSA API", -+ "Takashi Iwai <tiwai@suse.de>"); -+ -+ object_klass->dispose = gst_mixer_dispose; -+} -+ -+/* -+ * GstMixerTrack -+ */ -+ -+G_DEFINE_TYPE (GstMixerTrack, gst_mixer_track, G_TYPE_OBJECT); -+ -+static void gst_mixer_track_init (GstMixerTrack *track) -+{ -+} -+ -+static void notify_mute_change (GstMixer *mixer, GstMixerTrack *track, -+ gboolean mute) -+{ -+ GstStructure *s; -+ GstMessage *m; -+ -+ s = gst_structure_new (GST_MIXER_MESSAGE_NAME, -+ "type", G_TYPE_STRING, "mute-toggled", -+ "track", GST_TYPE_MIXER_TRACK, track, -+ "mute", G_TYPE_BOOLEAN, mute, -+ NULL); -+ m = gst_message_new_element (GST_OBJECT (mixer), s); -+ gst_element_post_message (GST_ELEMENT (mixer), m); -+} -+ -+static void update_mute (GstMixer *mixer, GstMixerTrack *track, gboolean mute) -+{ -+ int old_flag = track->flags & GST_MIXER_TRACK_MUTE; -+ -+ if (mute) { -+ track->flags |= GST_MIXER_TRACK_MUTE; -+ if (track->shared_mute) -+ track->shared_mute->flags |= GST_MIXER_TRACK_MUTE; -+ } else { -+ track->flags &= ~GST_MIXER_TRACK_MUTE; -+ if (track->shared_mute) -+ track->shared_mute->flags &= ~GST_MIXER_TRACK_MUTE; -+ } -+ -+ if ((track->flags & GST_MIXER_TRACK_MUTE) != old_flag) -+ notify_mute_change (mixer, track, mute); -+} -+ -+static void notify_recording_change (GstMixer *mixer, GstMixerTrack *track, -+ gboolean recording) -+{ -+ GstStructure *s; -+ GstMessage *m; -+ -+ s = gst_structure_new (GST_MIXER_MESSAGE_NAME, -+ "type", G_TYPE_STRING, "record-toggled", -+ "track", GST_TYPE_MIXER_TRACK, track, -+ "record", G_TYPE_BOOLEAN, recording, -+ NULL); -+ m = gst_message_new_element (GST_OBJECT (mixer), s); -+ gst_element_post_message (GST_ELEMENT (mixer), m); -+} -+ -+static void update_recording (GstMixer *mixer, GstMixerTrack *track, -+ gboolean recording) -+{ -+ int old_flag = track->flags & GST_MIXER_TRACK_RECORD; -+ -+ if (recording) -+ track->flags |= GST_MIXER_TRACK_RECORD; -+ else -+ track->flags &= ~GST_MIXER_TRACK_RECORD; -+ -+ if ((track->flags & GST_MIXER_TRACK_RECORD) != old_flag) -+ notify_recording_change (mixer, track, recording); -+} -+ -+static void notify_volume_change (GstMixer *mixer, GstMixerTrack *track) -+{ -+ GstStructure *s; -+ GstMessage *m; -+ GValue l = { 0, }; -+ GValue v = { 0, }; -+ int i; -+ -+ s = gst_structure_new (GST_MIXER_MESSAGE_NAME, -+ "type", G_TYPE_STRING, "volume-changed", -+ "track", GST_TYPE_MIXER_TRACK, track, -+ NULL); -+ g_value_init (&l, GST_TYPE_ARRAY); -+ g_value_init (&v, G_TYPE_INT); -+ -+ for (i = 0; i < track->num_channels; i++) { -+ g_value_set_int (&v, track->volumes[i]); -+ gst_value_array_append_value (&l, &v); -+ } -+ -+ gst_structure_set_value (s, "volumes", &l); -+ g_value_unset (&v); -+ g_value_unset (&l); -+ -+ m = gst_message_new_element (GST_OBJECT (mixer), s); -+ gst_element_post_message (GST_ELEMENT (mixer), m); -+} -+ -+static void track_update (GstMixer *mixer, GstMixerTrack *track) -+{ -+ gboolean vol_changed = FALSE; -+ int i; -+ -+ if (track->flags & GST_MIXER_TRACK_OUTPUT) { -+ int audible = 0; -+ if (track->has_switch) { -+ for (i = 0; i < track->num_channels; i++) { -+ int v = 0; -+ snd_mixer_selem_get_playback_switch (track->element, i, &v); -+ if (v) -+ audible = 1; -+ } -+ } -+ -+ if (track->has_volume) { -+ for (i = 0; i < track->num_channels; i++) { -+ long vol = 0; -+ snd_mixer_selem_get_playback_volume (track->element, i, &vol); -+ if (track->volumes[i] != vol) -+ vol_changed = TRUE; -+ track->volumes[i] = vol; -+ if (!track->has_switch && -+ vol > track->min_volume) -+ audible = 1; -+ } -+ } -+ -+ update_mute (mixer, track, !audible); -+ } -+ -+ if (track->flags & GST_MIXER_TRACK_INPUT) { -+ int recording = 0; -+ if (track->has_switch) { -+ for (i = 0; i < track->num_channels; i++) { -+ int v = 0; -+ snd_mixer_selem_get_capture_switch (track->element, i, &v); -+ if (v) -+ recording = 1; -+ } -+ } -+ -+ if (track->has_volume) { -+ for (i = 0; i < track->num_channels; i++) { -+ long vol = 0; -+ snd_mixer_selem_get_capture_volume (track->element, i, &vol); -+ if (track->volumes[i] != vol) -+ vol_changed = TRUE; -+ track->volumes[i] = vol; -+ if (!track->has_switch && -+ vol > track->min_volume) -+ recording = 1; -+ } -+ } -+ -+ update_recording (mixer, track, recording); -+ } -+ -+ if (vol_changed) -+ notify_volume_change (mixer, track); -+} -+ -+static GstMixerTrack *track_new (snd_mixer_elem_t *element, int num, -+ int flags, gboolean append_capture) -+{ -+ GstMixerTrack *track; -+ const char *name; -+ -+ track = (GstMixerTrack *) g_object_new (GST_TYPE_MIXER_TRACK, NULL); -+ track->index = snd_mixer_selem_get_index (element); -+ track->element = element; -+ track->flags = flags; -+ -+ if (flags & GST_MIXER_TRACK_OUTPUT) { -+ while (snd_mixer_selem_has_playback_channel (element, -+ track->num_channels)) -+ track->num_channels++; -+ } else if (flags & GST_MIXER_TRACK_INPUT) { -+ while (snd_mixer_selem_has_capture_channel (element, -+ track->num_channels)) -+ track->num_channels++; -+ } -+ -+ track->volumes = g_new (gint, track->num_channels); -+ -+ name = snd_mixer_selem_get_name (element); -+ track->untranslated_label = g_strdup (name); -+ -+ if (!num) -+ track->label = g_strdup_printf ("%s%s", name, -+ append_capture ? " Capture" : ""); -+ else -+ track->label = g_strdup_printf ("%s%s %d", name, -+ append_capture ? " Capture" : "", -+ num); -+ -+ return track; -+} -+ -+enum { -+ ARG_0, -+ ARG_LABEL, -+ ARG_UNTRANSLATED_LABEL, -+ ARG_INDEX, -+}; -+ -+static void gst_mixer_track_get_property (GObject *object, guint prop_id, -+ GValue *value, GParamSpec *pspec) -+{ -+ GstMixerTrack *track = GST_MIXER_TRACK (object); -+ -+ switch (prop_id) { -+ case ARG_LABEL: -+ g_value_set_string (value, track->label); -+ break; -+ case ARG_UNTRANSLATED_LABEL: -+ g_value_set_string (value, track->untranslated_label); -+ break; -+ case ARG_INDEX: -+ g_value_set_uint (value, track->index); -+ break; -+ default: -+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); -+ break; -+ } -+} -+ -+static void gst_mixer_track_set_property (GObject *object, -+ guint prop_id, -+ const GValue *value, -+ GParamSpec * pspec) -+{ -+ GstMixerTrack *track; -+ -+ track = GST_MIXER_TRACK (object); -+ -+ switch (prop_id) { -+ case ARG_LABEL: -+ g_free (track->label); -+ track->label = g_value_dup_string (value); -+ break; -+ case ARG_UNTRANSLATED_LABEL: -+ g_free (track->untranslated_label); -+ track->untranslated_label = g_value_dup_string (value); -+ break; -+ case ARG_INDEX: -+ track->index = g_value_get_uint (value); -+ break; -+ default: -+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); -+ break; -+ } -+} -+ -+static void gst_mixer_track_dispose (GObject * object) -+{ -+ GstMixerTrack *track = GST_MIXER_TRACK (object); -+ -+ if (track->label) { -+ g_free (track->label); -+ track->label = NULL; -+ } -+ -+ if (track->untranslated_label) { -+ g_free (track->untranslated_label); -+ track->untranslated_label = NULL; -+ } -+ -+ G_OBJECT_CLASS (gst_mixer_track_parent_class)->dispose (object); -+} -+ -+static void gst_mixer_track_class_init (GstMixerTrackClass * klass) -+{ -+ GObjectClass *object_klass = G_OBJECT_CLASS (klass); -+ -+ object_klass->get_property = gst_mixer_track_get_property; -+ object_klass->set_property = gst_mixer_track_set_property; -+ -+ g_object_class_install_property (object_klass, ARG_UNTRANSLATED_LABEL, -+ g_param_spec_string ("untranslated-label", -+ "Untranslated track label", -+ "The untranslated label assigned to the track (since 0.10.13)", -+ NULL, -+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); -+ -+ g_object_class_install_property (object_klass, ARG_LABEL, -+ g_param_spec_string ("label", "Track label", -+ "The label assigned to the track (may be translated)", -+ NULL, -+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS | G_PARAM_STATIC_STRINGS)); -+ -+ g_object_class_install_property (object_klass, ARG_INDEX, -+ g_param_spec_uint ("index", "Index", -+ "Track index", -+ 0, G_MAXUINT, 0, -+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); -+ -+ object_klass->dispose = gst_mixer_track_dispose; -+} -+ -+static void get_playback_min_max (GstMixerTrack *track) -+{ -+ if (track->has_volume) { -+ long min = 0, max = 0; -+ snd_mixer_selem_get_playback_volume_range (track->element, &min, &max); -+ track->min_volume = min; -+ track->max_volume = max; -+ } -+} -+ -+static void get_capture_min_max (GstMixerTrack *track) -+{ -+ if (track->has_volume) { -+ long min = 0, max = 0; -+ snd_mixer_selem_get_capture_volume_range (track->element, &min, &max); -+ track->min_volume = min; -+ track->max_volume = max; -+ } -+} -+ -+static GstMixerTrack *get_named_playback_track (GstMixer *mixer, -+ const char *name) -+{ -+ GList *item; -+ GstMixerTrack *track; -+ -+ for (item = mixer->tracklist; item; item = item->next) { -+ track = GST_MIXER_TRACK (item->data); -+ if (! (track->flags & GST_MIXER_TRACK_OUTPUT)) -+ continue; -+ if (!strcmp (track->label, name)) -+ return track; -+ } -+ return NULL; -+} -+ -+static void mark_master_track (GstMixer *mixer) -+{ -+ GList *item; -+ GstMixerTrack *track; -+ -+ if ((track = get_named_playback_track (mixer, "Master")) || -+ (track = get_named_playback_track (mixer, "Front")) || -+ (track = get_named_playback_track (mixer, "PCM")) || -+ (track = get_named_playback_track (mixer, "Speaker"))) -+ goto found; -+ -+ /* If not found, take a mono track with both volume and switch */ -+ for (item = mixer->tracklist; item; item = item->next) { -+ track = GST_MIXER_TRACK (item->data); -+ if (! (track->flags & GST_MIXER_TRACK_OUTPUT)) -+ continue; -+ if (track->has_volume && track->has_switch && -+ track->num_channels == 1) -+ goto found; -+ } -+ -+ /* If not found, take any track with both volume and switch */ -+ for (item = mixer->tracklist; item; item = item->next) { -+ track = GST_MIXER_TRACK (item->data); -+ if (! (track->flags & GST_MIXER_TRACK_OUTPUT)) -+ continue; -+ if (track->has_volume && track->has_switch) -+ goto found; -+ } -+ -+ /* If not found, take any track with volume */ -+ for (item = mixer->tracklist; item; item = item->next) { -+ track = GST_MIXER_TRACK (item->data); -+ if (! (track->flags & GST_MIXER_TRACK_OUTPUT)) -+ continue; -+ if (track->has_volume) -+ goto found; -+ } -+ -+ return; -+ -+ found: -+ track->flags |= GST_MIXER_TRACK_MASTER; -+ return; -+} -+ -+static int mixer_elem_callback (snd_mixer_elem_t *elem, unsigned int mask) -+{ -+ GstMixer *mixer = snd_mixer_elem_get_callback_private (elem); -+ GList *item; -+ -+ for (item = mixer->tracklist; item; item = item->next) { -+ GstMixerTrack *track = GST_MIXER_TRACK (item->data); -+ if (track->element == elem) -+ track_update (mixer, track); -+ } -+ -+ return 0; -+} -+ -+static int mixer_callback (snd_mixer_t *ctl, unsigned int mask, -+ snd_mixer_elem_t *elem) -+{ -+ GstMixer *mixer = snd_mixer_get_callback_private (ctl); -+ -+ snd_mixer_handle_events (mixer->handle); -+ return 0; -+} -+ -+const GList *gst_mixer_list_tracks (GstMixer *mixer) -+{ -+ return mixer->tracklist; -+} -+ -+static gboolean same_volumes (gint num_channels, const gint *volumes) -+{ -+ gint i; -+ -+ for (i = 1; i < num_channels; i++) { -+ if (volumes[0] != volumes[i]) -+ return FALSE; -+ } -+ -+ return TRUE; -+} -+ -+void gst_mixer_set_volume (GstMixer *mixer, GstMixerTrack *track, gint *volumes) -+{ -+ gint i; -+ -+ track_update (mixer, track); -+ -+ if (!track->has_volume) -+ return; -+ -+ for (i = 0; i < track->num_channels; i++) -+ track->volumes[i] = volumes[i]; -+ -+ if (track->flags & GST_MIXER_TRACK_OUTPUT) { -+ if (!track->has_switch && (track->flags & GST_MIXER_TRACK_MUTE)) -+ return; -+ if (same_volumes (track->num_channels, volumes)) { -+ snd_mixer_selem_set_playback_volume_all (track->element, -+ volumes[0]); -+ } else { -+ for (i = 0; i < track->num_channels; i++) -+ snd_mixer_selem_set_playback_volume (track->element, i, -+ volumes[i]); -+ } -+ } else { -+ if (!track->has_switch && ! (track->flags & GST_MIXER_TRACK_RECORD)) -+ return; -+ if (same_volumes (track->num_channels, volumes)) { -+ snd_mixer_selem_set_capture_volume_all (track->element, -+ volumes[0]); -+ } else { -+ for (i = 0; i < track->num_channels; i++) -+ snd_mixer_selem_set_capture_volume (track->element, i, -+ volumes[i]); -+ } -+ } -+} -+ -+void gst_mixer_get_volume (GstMixer *mixer, GstMixerTrack *track, gint *volumes) -+{ -+ int i; -+ -+ if (!track->has_volume) -+ return; -+ -+ track_update (mixer, track); -+ for (i = 0; i < track->num_channels; i++) -+ volumes[i] = track->volumes[i]; -+} -+ -+void gst_mixer_set_mute (GstMixer *mixer, GstMixerTrack *track, gboolean mute) -+{ -+ int i; -+ -+ if (track->flags & GST_MIXER_TRACK_INPUT) { -+ if (track->shared_mute) -+ track = track->shared_mute; -+ else -+ return; -+ } -+ -+ track_update (mixer, track); -+ -+ mute = !!mute; -+ if (mute == !! (track->flags & GST_MIXER_TRACK_MUTE)) -+ return; -+ -+ update_mute (mixer, track, mute); -+ -+ if (track->has_switch) { -+ snd_mixer_selem_set_playback_switch_all (track->element, !mute); -+ } else { -+ for (i = 0; i < track->num_channels; i++) { -+ long vol = mute ? track->min_volume : track->volumes[i]; -+ snd_mixer_selem_set_playback_volume (track->element, i, vol); -+ } -+ } -+} -+ -+void gst_mixer_set_record (GstMixer * mixer, GstMixerTrack *track, gboolean record) -+{ -+ int i; -+ -+ if (! (track->flags & GST_MIXER_TRACK_INPUT)) -+ return; -+ -+ track_update (mixer, track); -+ -+ record = !!record; -+ if (record == !! (track->flags & GST_MIXER_TRACK_RECORD)) -+ return; -+ -+ if (record) -+ track->flags |= GST_MIXER_TRACK_RECORD; -+ else -+ track->flags &= ~GST_MIXER_TRACK_RECORD; -+ -+ if (track->has_switch) { -+ snd_mixer_selem_set_capture_switch_all (track->element, record); -+ } else { -+ for (i = 0; i < track->num_channels; i++) { -+ long vol = record ? track->volumes[i] : track->min_volume; -+ snd_mixer_selem_set_capture_volume (track->element, i, vol); -+ } -+ } -+} -+ -+GstMixerMessageType -+gst_mixer_message_get_type (GstMessage * message) -+{ -+ const GstStructure *s; -+ const gchar *m_type; -+ -+ s = gst_message_get_structure (message); -+ m_type = gst_structure_get_string (s, "type"); -+ if (!m_type) -+ return GST_MIXER_MESSAGE_INVALID; -+ -+ if (g_str_equal (m_type, "mute-toggled")) -+ return GST_MIXER_MESSAGE_MUTE_TOGGLED; -+ else if (g_str_equal (m_type, "record-toggled")) -+ return GST_MIXER_MESSAGE_RECORD_TOGGLED; -+ else if (g_str_equal (m_type, "volume-changed")) -+ return GST_MIXER_MESSAGE_VOLUME_CHANGED; -+ else if (g_str_equal (m_type, "option-changed")) -+ return GST_MIXER_MESSAGE_OPTION_CHANGED; -+ else if (g_str_equal (m_type, "options-list-changed")) -+ return GST_MIXER_MESSAGE_OPTIONS_LIST_CHANGED; -+ else if (g_str_equal (m_type, "mixer-changed")) -+ return GST_MIXER_MESSAGE_MIXER_CHANGED; -+ -+ return GST_MIXER_MESSAGE_INVALID; -+} -+ -+static void message_parse_track (const GstStructure *s, GstMixerTrack **track) -+{ -+ if (track) { -+ const GValue *v = gst_structure_get_value (s, "track"); -+ *track = (GstMixerTrack *)g_value_get_object (v); -+ } -+} -+ -+void gst_mixer_message_parse_mute_toggled (GstMessage *message, -+ GstMixerTrack **track, -+ gboolean *mute) -+{ -+ const GstStructure *s = gst_message_get_structure (message); -+ -+ message_parse_track (s, track); -+ if (mute) -+ gst_structure_get_boolean (s, "mute", mute); -+} -+ -+void gst_mixer_message_parse_record_toggled (GstMessage *message, -+ GstMixerTrack **track, -+ gboolean *record) -+{ -+ const GstStructure *s = gst_message_get_structure (message); -+ -+ message_parse_track (s, track); -+ if (record) -+ gst_structure_get_boolean (s, "record", record); -+} -+ -+void gst_mixer_message_parse_volume_changed (GstMessage *message, -+ GstMixerTrack **track, -+ gint **volumes, -+ gint *num_channels) -+{ -+ const GstStructure *s = gst_message_get_structure (message); -+ -+ message_parse_track (s, track); -+ if (volumes || num_channels) { -+ gint n_chans, i; -+ const GValue *v = gst_structure_get_value (s, "volumes"); -+ -+ n_chans = gst_value_array_get_size (v); -+ if (num_channels) -+ *num_channels = n_chans; -+ -+ if (volumes) { -+ *volumes = g_new (gint, n_chans); -+ for (i = 0; i < n_chans; i++) { -+ const GValue *e = gst_value_array_get_value (v, i); -+ -+ (*volumes)[i] = g_value_get_int (e); -+ } -+ } -+ } -+} -+ -+/* -+ * GstMixerOptions -+ */ -+ -+G_DEFINE_TYPE (GstMixerOptions, gst_mixer_options, GST_TYPE_MIXER_TRACK); -+ -+static GstMixerOptions * -+mixer_options_new (snd_mixer_elem_t *element, int num) -+{ -+ GstMixerOptions *opt; -+ GstMixerTrack *track; -+ const char *label; -+ int i; -+ -+ label = snd_mixer_selem_get_name (element); -+ opt = g_object_new (GST_TYPE_MIXER_OPTIONS, -+ "untranslated-label", label, -+ "index", snd_mixer_selem_get_index (element), -+ NULL); -+ track = GST_MIXER_TRACK (opt); -+ track->element = element; -+ if (!num) -+ track->label = g_strdup (label); -+ else -+ track->label = g_strdup_printf ("%s %d", label, num); -+ -+ num = snd_mixer_selem_get_enum_items (element); -+ for (i = 0; i < num; i++) { -+ char str[256]; -+ if (snd_mixer_selem_get_enum_item_name (element, i, sizeof(str), str) < 0) -+ break; -+ opt->values = g_list_append (opt->values, g_strdup (str)); -+ } -+ -+ return opt; -+} -+ -+static void gst_mixer_options_dispose (GObject * object) -+{ -+ GstMixerOptions *opt = GST_MIXER_OPTIONS (object); -+ -+ g_list_free_full (opt->values, g_free); -+ opt->values = NULL; -+ -+ G_OBJECT_CLASS (gst_mixer_options_parent_class)->dispose (object); -+} -+ -+static void gst_mixer_options_init (GstMixerOptions *opt) -+{ -+} -+ -+static void gst_mixer_options_class_init (GstMixerOptionsClass * klass) -+{ -+ GObjectClass *object_klass = G_OBJECT_CLASS (klass); -+ -+ object_klass->dispose = gst_mixer_options_dispose; -+} -+ -+const gchar *gst_mixer_get_option (GstMixer *mixer, GstMixerOptions *opt) -+{ -+ unsigned int idx; -+ -+ if (snd_mixer_selem_get_enum_item (opt->parent.element, 0, &idx) < 0) -+ return "error"; -+ return g_list_nth_data (opt->values, idx); -+} -+ -+void gst_mixer_set_option (GstMixer *mixer, GstMixerOptions *opt, -+ gchar *value) -+{ -+ int n = 0; -+ GList *item; -+ -+ for (item = opt->values; item; item = item->next, n++) { -+ if (!strcmp (item->data, value)) { -+ snd_mixer_selem_set_enum_item (opt->parent.element, 0, n); -+ break; -+ } -+ } -+} -+ -+GList *gst_mixer_options_get_values (GstMixerOptions *opt) -+{ -+ return opt->values; -+} -+ -+static void message_parse_options (const GstStructure *s, -+ GstMixerOptions ** options) -+{ -+ if (options) { -+ const GValue *v = gst_structure_get_value (s, "options"); -+ *options = (GstMixerOptions *) g_value_get_object (v); -+ } -+} -+ -+void gst_mixer_message_parse_option_changed (GstMessage *message, -+ GstMixerOptions ** options, -+ const gchar **value) -+{ -+ const GstStructure *s = gst_message_get_structure (message); -+ -+ message_parse_options (s, options); -+ if (value) -+ *value = gst_structure_get_string (s, "value"); -+} -+ -+void gst_mixer_message_parse_options_list_changed (GstMessage *message, -+ GstMixerOptions **options) -+{ -+ const GstStructure *s = gst_message_get_structure (message); -+ -+ message_parse_options (s, options); -+} -+ -+/* -+ */ -+ -+static void create_track_list (GstMixer *mixer) -+{ -+ snd_mixer_elem_t *element, *temp; -+ GList *item; -+ -+ if (mixer->tracklist) -+ return; -+ -+ for (element = snd_mixer_first_elem (mixer->handle); element; -+ element = snd_mixer_elem_next (element)) { -+ GstMixerTrack *play_track = NULL; -+ GstMixerTrack *cap_track = NULL; -+ const gchar *name = snd_mixer_selem_get_name (element); -+ int index = 0; -+ int has_volume, has_switch; -+ -+ for (item = mixer->tracklist; item; item = item->next) { -+ temp = GST_MIXER_TRACK (item->data)->element; -+ if (strcmp (name, snd_mixer_selem_get_name (temp)) == 0) -+ index++; -+ } -+ -+ has_volume = snd_mixer_selem_has_playback_volume (element); -+ has_switch = snd_mixer_selem_has_playback_switch (element); -+ if (has_volume || has_switch) { -+ play_track = track_new (element, index, -+ GST_MIXER_TRACK_OUTPUT, FALSE); -+ play_track->has_volume = has_volume; -+ play_track->has_switch = has_switch; -+ get_playback_min_max (play_track); -+ } -+ -+ has_volume = snd_mixer_selem_has_capture_volume (element); -+ has_switch = snd_mixer_selem_has_capture_switch (element); -+ if (play_track && snd_mixer_selem_has_common_volume (element)) -+ has_volume = 0; -+ if (play_track && snd_mixer_selem_has_common_switch (element)) -+ has_switch = 0; -+ if (has_volume || has_switch) { -+ cap_track = track_new (element, index, -+ GST_MIXER_TRACK_INPUT, -+ play_track != NULL); -+ cap_track->has_volume = has_volume; -+ cap_track->has_switch = has_switch; -+ get_capture_min_max (cap_track); -+ } -+ -+ if (play_track && cap_track) { -+ play_track->shared_mute = cap_track; -+ cap_track->shared_mute = play_track; -+ } -+ -+ if (play_track) { -+ track_update (mixer, play_track); -+ mixer->tracklist = g_list_append (mixer->tracklist, play_track); -+ } -+ -+ if (cap_track) { -+ track_update (mixer, cap_track); -+ mixer->tracklist = g_list_append (mixer->tracklist, cap_track); -+ } -+ -+ if (snd_mixer_selem_is_enumerated (element)) { -+ mixer->tracklist = g_list_append (mixer->tracklist, -+ mixer_options_new (element, index)); -+ } -+ -+ snd_mixer_elem_set_callback_private (element, mixer); -+ snd_mixer_elem_set_callback (element, mixer_elem_callback); -+ } -+ -+ mark_master_track (mixer); -+} -+ -+static gboolean mixer_src_callback (gpointer user_data) -+{ -+ GstMixer *mixer = (GstMixer *)user_data; -+ -+ snd_mixer_handle_events (mixer->handle); -+ return TRUE; -+} -+ -+static gboolean mixer_src_dispatch (GSource *source, -+ GSourceFunc callback, -+ gpointer user_data) -+{ -+ return callback (user_data); -+} -+ -+static void mixer_src_attach (GstMixer *mixer) -+{ -+ static GSourceFuncs func = { -+ .dispatch = mixer_src_dispatch, -+ }; -+ struct pollfd pfd; -+ -+ if (snd_mixer_poll_descriptors (mixer->handle, &pfd, 1) != 1) -+ return; -+ -+ mixer->src = g_source_new (&func, sizeof (*mixer->src)); -+ g_source_add_unix_fd (mixer->src, pfd.fd, G_IO_IN | G_IO_ERR); -+ g_source_set_callback (mixer->src, mixer_src_callback, mixer, NULL); -+ g_source_attach (mixer->src, g_main_context_default ()); -+} -+ -+/* -+ * These are new functions that didn't exist in the original gstreamer API; -+ * instead of lengthy probing using factory, just provide a simpler method -+ */ -+ -+int gst_mixer_new (const char *name, GstMixer **mixer_ret) -+{ -+ GstMixer *mixer; -+ snd_hctl_t *hctl; -+ int err; -+ -+ mixer = (GstMixer *) g_object_new (GST_TYPE_MIXER, NULL); -+ mixer->name = g_strdup (name); -+ -+ err = snd_mixer_open ((snd_mixer_t **) &mixer->handle, 0); -+ if (err < 0) -+ return err; -+ -+ err = snd_mixer_attach (mixer->handle, name); -+ if (err < 0) -+ goto error; -+ -+ err = snd_mixer_selem_register (mixer->handle, NULL, NULL); -+ if (err < 0) -+ goto error; -+ -+ err = snd_mixer_load (mixer->handle); -+ if (err < 0) -+ goto error; -+ -+ snd_mixer_get_hctl (mixer->handle, name, &hctl); -+ { -+ snd_ctl_card_info_t *info; -+ -+ snd_ctl_card_info_alloca (&info); -+ snd_ctl_card_info (snd_hctl_ctl (hctl), info); -+ mixer->card_name = g_strdup_printf ("%s (Alsa mixer)", -+ snd_ctl_card_info_get_name (info)); -+ } -+ -+ snd_mixer_set_callback_private (mixer->handle, mixer); -+ snd_mixer_set_callback (mixer->handle, mixer_callback); -+ -+ create_track_list (mixer); -+ -+ mixer_src_attach (mixer); -+ -+ *mixer_ret = mixer; -+ return 0; -+ -+ error: -+ gst_object_unref (mixer); -+ return err; -+} -+ -+GList *gst_mixer_probe_devices (void) -+{ -+ int card = -1; -+ GList *card_list = NULL; -+ -+ while (snd_card_next(&card) >= 0 && card >= 0) { -+ GstMixer *mixer; -+ char name [16]; -+ int err; -+ -+ sprintf (name, "hw:%d", card); -+ err = gst_mixer_new (name, &mixer); -+ if (err < 0) -+ continue; -+ card_list = g_list_append (card_list, mixer); -+ } -+ -+ return card_list; -+} -+ -+const gchar *gst_mixer_get_card_name (GstMixer *mixer) -+{ -+ return mixer->card_name; -+} ---- a/panel-plugin/xfce-plugin-dialog.c -+++ b/panel-plugin/xfce-plugin-dialog.c -@@ -25,8 +25,7 @@ - - #include <gtk/gtk.h> - --#include <gst/gst.h> --#include <gst/interfaces/mixer.h> -+#include "../libxfce4mixer/audio.h" - - #include <libxfce4ui/libxfce4ui.h> - #include <libxfce4panel/libxfce4panel.h> ---- a/panel-plugin/xfce-plugin-dialog.h -+++ b/panel-plugin/xfce-plugin-dialog.h -@@ -24,8 +24,7 @@ - - #include <gtk/gtk.h> - --#include <gst/gst.h> --#include <gst/interfaces/mixer.h> -+#include "../libxfce4mixer/audio.h" - - G_BEGIN_DECLS - ---- a/xfce4-mixer/xfce-mixer-container.c -+++ b/xfce4-mixer/xfce-mixer-container.c -@@ -23,8 +23,7 @@ - #include <config.h> - #endif - --#include <gst/gst.h> --#include <gst/interfaces/mixer.h> -+#include "../libxfce4mixer/audio.h" - - #include <libxfce4util/libxfce4util.h> - #include <libxfce4ui/libxfce4ui.h> ---- a/xfce4-mixer/xfce-mixer-controls-dialog.c -+++ b/xfce4-mixer/xfce-mixer-controls-dialog.c -@@ -23,8 +23,7 @@ - #include <config.h> - #endif - --#include <gst/gst.h> --#include <gst/interfaces/mixer.h> -+#include "../libxfce4mixer/audio.h" - - #include <libxfce4util/libxfce4util.h> - #include <libxfce4ui/libxfce4ui.h> ---- a/xfce4-mixer/xfce-mixer-option.c -+++ b/xfce4-mixer/xfce-mixer-option.c -@@ -23,8 +23,7 @@ - #include <config.h> - #endif - --#include <gst/gst.h> --#include <gst/interfaces/mixer.h> -+#include "../libxfce4mixer/audio.h" - - #include <libxfce4util/libxfce4util.h> - #include <libxfce4ui/libxfce4ui.h> ---- a/xfce4-mixer/xfce-mixer-switch.c -+++ b/xfce4-mixer/xfce-mixer-switch.c -@@ -23,8 +23,7 @@ - #include <config.h> - #endif - --#include <gst/gst.h> --#include <gst/interfaces/mixer.h> -+#include "../libxfce4mixer/audio.h" - - #include <libxfce4util/libxfce4util.h> - #include <libxfce4ui/libxfce4ui.h> ---- a/xfce4-mixer/xfce-mixer-track.c -+++ b/xfce4-mixer/xfce-mixer-track.c -@@ -27,8 +27,7 @@ - #include <math.h> - #endif - --#include <gst/gst.h> --#include <gst/interfaces/mixer.h> -+#include "../libxfce4mixer/audio.h" - - #include <libxfce4util/libxfce4util.h> - #include <libxfce4ui/libxfce4ui.h> ---- a/xfce4-mixer/xfce-mixer-window.c -+++ b/xfce4-mixer/xfce-mixer-window.c -@@ -23,9 +23,7 @@ - #include <config.h> - #endif - --#include <gst/gst.h> --#include <gst/audio/mixerutils.h> --#include <gst/interfaces/mixer.h> -+#include "../libxfce4mixer/audio.h" - - #include <libxfce4util/libxfce4util.h> - #include <libxfce4ui/libxfce4ui.h> ---- a/libxfce4mixer/Makefile.am -+++ b/libxfce4mixer/Makefile.am -@@ -17,7 +17,14 @@ libxfce4mixer_la_SOURCES = \ - xfce-mixer-preferences.h \ - xfce-mixer-preferences.c \ - xfce-mixer-debug.h \ -- xfce-mixer-debug.c -+ xfce-mixer-debug.c \ -+ audio.h -+ -+if XFCE4_MIXER_ALSA -+libxfce4mixer_la_SOURCES += \ -+ xfce4-mixer-alsa.h \ -+ xfce4-mixer-alsa.c -+endif - - libxfce4mixer_la_CPPFLAGS = \ - -I$(top_builddir) \ -@@ -35,7 +42,12 @@ libxfce4mixer_la_CFLAGS = \ - $(LIBXFCE4UI_CFLAGS) \ - $(XFCONF_CFLAGS) \ - $(DBUS_GLIB_CFLAGS) \ -- $(GST_PLUGINS_BASE_CFLAGS) -+ $(GST_CFLAGS) -+ -+if XFCE4_MIXER_ALSA -+libxfce4mixer_la_CFLAGS += \ -+ $(ALSA_CFLAGS) -+endif - - libxfce4mixer_la_LDFLAGS = \ - -no-undefined -@@ -48,6 +60,13 @@ libxfce4mixer_la_LIBADD = \ - $(LIBXFCE4UI_LIBS) \ - $(XFCONF_LIBS) \ - $(DBUS_GLIB_LIBS) \ -- $(GST_PLUGINS_BASE_LIBS) \ -+ $(GST_LIBS) -+ -+if XFCE4_MIXER_ALSA -+libxfce4mixer_la_LIBADD += \ -+ $(ALSA_LIBS) -+else -+libxfce4mixer_la_LIBADD += \ - -lgstaudio-0.10 \ - -lgstinterfaces-0.10 -+endif ---- a/panel-plugin/Makefile.am -+++ b/panel-plugin/Makefile.am -@@ -27,7 +27,7 @@ libmixer_la_CFLAGS = \ - $(LIBXFCE4UI_CFLAGS) \ - $(LIBXFCE4PANEL_CFLAGS) \ - $(XFCONF_CFLAGS) \ -- $(GST_PLUGINS_BASE_CFLAGS) \ -+ $(GST_CFLAGS) \ - $(KEYBINDER_CFLAGS) - - libmixer_la_DEPENDENCIES = \ -@@ -48,11 +48,18 @@ libmixer_la_LIBADD = \ - $(LIBXFCE4UI_LIBS) \ - $(LIBXFCE4PANEL_LIBS) \ - $(XFCONF_LIBS) \ -- $(GST_PLUGINS_BASE_LIBS) \ -- -lgstaudio-0.10 \ -- -lgstinterfaces-0.10 \ -+ $(GST_LIBS) \ - $(KEYBINDER_LIBS) - -+if XFCE4_MIXER_ALSA -+libmixer_la_LIBADD += \ -+ $(ALSA_LIBS) -+else -+libmixer_la_LIBADD += \ -+ -lgstaudio-0.10 \ -+ -lgstinterfaces-0.10 -+endif -+ - desktopdir = $(datadir)/xfce4/panel/plugins - - desktop_in_files = mixer.desktop.in ---- a/xfce4-mixer/Makefile.am -+++ b/xfce4-mixer/Makefile.am -@@ -34,7 +34,7 @@ xfce4_mixer_CFLAGS = \ - $(LIBXFCE4UTIL_CFLAGS) \ - $(LIBXFCE4UI_CFLAGS) \ - $(XFCONF_CFLAGS) \ -- $(GST_PLUGINS_BASE_CFLAGS) -+ $(GST_CFLAGS) - - xfce4_mixer_DEPENDENCIES = \ - $(top_builddir)/libxfce4mixer/libxfce4mixer.la -@@ -47,9 +47,16 @@ xfce4_mixer_LDFLAGS = \ - $(LIBXFCE4UTIL_LIBS) \ - $(LIBXFCE4UI_LIBS) \ - $(XFCONF_LIBS) \ -- $(GST_PLUGINS_BASE_LIBS) \ -+ $(GST_LIBS) -+ -+if XFCE4_MIXER_ALSA -+xfce4_mixer_LDFLAGS += \ -+ $(ALSA_LIBS) -+else -+xfce4_mixer_LDFLAGS += \ - -lgstaudio-0.10 \ - -lgstinterfaces-0.10 -+endif - - dist_man_MANS = xfce4-mixer.1 - ---- /dev/null -+++ b/libxfce4mixer/audio.h -@@ -0,0 +1,8 @@ -+#ifdef XFCE4_MIXER_ALSA -+#include <gst/gst.h> -+#include "xfce4-mixer-alsa.h" -+#else -+#include <gst/gst.h> -+#include <gst/interfaces/mixer.h> -+#include <gst/audio/mixerutils.h> -+#endif ---- a/configure.ac.in -+++ b/configure.ac.in -@@ -96,13 +96,29 @@ dnl *********************************** - XDT_CHECK_PACKAGE([GLIB], [glib-2.0], [2.42.0]) - XDT_CHECK_PACKAGE([GTHREAD], [gthread-2.0], [2.42.0]) - XDT_CHECK_PACKAGE([DBUS_GLIB], [dbus-glib-1], [0.84]) --XDT_CHECK_PACKAGE([GST_PLUGINS_BASE], [gstreamer-plugins-base-0.10], [0.10.25]) - XDT_CHECK_PACKAGE([GTK], [gtk+-3.0], [3.14.0]) - XDT_CHECK_PACKAGE([LIBXFCE4UTIL], [libxfce4util-1.0], [4.12.0]) - XDT_CHECK_PACKAGE([LIBXFCE4UI], [libxfce4ui-2], [4.12.0]) - XDT_CHECK_PACKAGE([LIBXFCE4PANEL], [libxfce4panel-2.0], [4.12.0]) - XDT_CHECK_PACKAGE([XFCONF], [libxfconf-0], [4.12.0]) - -+AC_MSG_CHECKING(for audio engine) -+AC_ARG_WITH(audio, -+ AS_HELP_STRING([--with-audio], -+ [audio engine, either gstmixer or alsa (default)]), -+ audio="$withval", audio="alsa") -+ -+if test "$audio" = "gstmixer"; then -+ AC_MSG_RESULT(gstreamer-0.10 native mixer) -+ XDT_CHECK_PACKAGE([GST], [gstreamer-plugins-base-0.10], [0.10.25]) -+else -+ AC_MSG_RESULT(gstreamer-1.0 ALSA mixer) -+ XDT_CHECK_PACKAGE([GST], [gstreamer-1.0], [1.0]) -+ XDT_CHECK_PACKAGE([ALSA], [alsa], [0.9]) -+ AC_DEFINE([XFCE4_MIXER_ALSA], 1, [Built-in ALSA-based gstreamer mixer i/f]) -+fi -+AM_CONDITIONAL([XFCE4_MIXER_ALSA], [test x"$audio" != x"gstmixer"]) -+ - dnl *********************************** - dnl *** Check for optional packages *** - dnl |