summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.am4
-rw-r--r--backends/null/Makefile.am6
-rw-r--r--backends/null/null.c32
-rw-r--r--backends/null/null.h6
-rw-r--r--backends/pulse/Makefile.am14
-rw-r--r--backends/pulse/pulse-connection.c764
-rw-r--r--backends/pulse/pulse-connection.h102
-rw-r--r--backends/pulse/pulse-device.c251
-rw-r--r--backends/pulse/pulse-device.h27
-rw-r--r--backends/pulse/pulse-sink-input.c (renamed from backends/pulse/pulse-track.c)0
-rw-r--r--backends/pulse/pulse-sink-input.h (renamed from backends/pulse/pulse-track.h)0
-rw-r--r--backends/pulse/pulse-sink.c130
-rw-r--r--backends/pulse/pulse-sink.h69
-rw-r--r--backends/pulse/pulse-source-output.c0
-rw-r--r--backends/pulse/pulse-source-output.h0
-rw-r--r--backends/pulse/pulse-source.c0
-rw-r--r--backends/pulse/pulse-source.h0
-rw-r--r--backends/pulse/pulse-stream.c259
-rw-r--r--backends/pulse/pulse-stream.h86
-rw-r--r--backends/pulse/pulse.c383
-rw-r--r--backends/pulse/pulse.h2
-rw-r--r--configure.ac2
-rw-r--r--docs/Makefile.am (renamed from doc/Makefile.am)0
-rw-r--r--libmatemixer/Makefile.am16
-rw-r--r--libmatemixer/matemixer-backend-module.c85
-rw-r--r--libmatemixer/matemixer-backend-module.h23
-rw-r--r--libmatemixer/matemixer-backend.c45
-rw-r--r--libmatemixer/matemixer-backend.h22
-rw-r--r--libmatemixer/matemixer-control.c117
-rw-r--r--libmatemixer/matemixer-control.h20
-rw-r--r--libmatemixer/matemixer-device-port.c270
-rw-r--r--libmatemixer/matemixer-device-port.h80
-rw-r--r--libmatemixer/matemixer-device-profile.c189
-rw-r--r--libmatemixer/matemixer-device-profile.h67
-rw-r--r--libmatemixer/matemixer-device.c147
-rw-r--r--libmatemixer/matemixer-device.h36
-rw-r--r--libmatemixer/matemixer-enum-types.c88
-rw-r--r--libmatemixer/matemixer-enum-types.h15
-rw-r--r--libmatemixer/matemixer-enums.h56
-rw-r--r--libmatemixer/matemixer-port.c256
-rw-r--r--libmatemixer/matemixer-port.h73
-rw-r--r--libmatemixer/matemixer-private.h4
-rw-r--r--libmatemixer/matemixer-profile.c196
-rw-r--r--libmatemixer/matemixer-profile.h67
-rw-r--r--libmatemixer/matemixer-stream.c531
-rw-r--r--libmatemixer/matemixer-stream.h165
-rw-r--r--libmatemixer/matemixer-track.c29
-rw-r--r--libmatemixer/matemixer-track.h47
-rw-r--r--libmatemixer/matemixer.c21
-rw-r--r--libmatemixer/matemixer.h2
50 files changed, 3570 insertions, 1234 deletions
diff --git a/Makefile.am b/Makefile.am
index 57aa03e..0eb7591 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -4,9 +4,9 @@ SUBDIRS = \
libmatemixer \
backends \
data \
- doc
+ docs
-EXTRA_DIR = autogen.sh
+EXTRA_DIST = autogen.sh
MAINTAINERCLEANFILES = \
$(srcdir)/aclocal.m4 \
diff --git a/backends/null/Makefile.am b/backends/null/Makefile.am
index b6d92c7..f28bc06 100644
--- a/backends/null/Makefile.am
+++ b/backends/null/Makefile.am
@@ -6,15 +6,13 @@ AM_CPPFLAGS = \
-I$(top_srcdir) \
-DG_LOG_DOMAIN=\"libmatemixer-null\"
-libmatemixer_null_la_CFLAGS = \
- $(GLIB_CFLAGS)
+libmatemixer_null_la_CFLAGS = $(GLIB_CFLAGS)
libmatemixer_null_la_SOURCES = \
null.c \
null.h
-libmatemixer_null_la_LIBADD = \
- $(GLIB_LIBS)
+libmatemixer_null_la_LIBADD = $(GLIB_LIBS)
libmatemixer_null_la_LDFLAGS = \
-avoid-version \
diff --git a/backends/null/null.c b/backends/null/null.c
index b96c9b0..1e8085d 100644
--- a/backends/null/null.c
+++ b/backends/null/null.c
@@ -26,19 +26,17 @@
#define BACKEND_NAME "Null"
#define BACKEND_PRIORITY 999
-/* Support function for dynamic loading of the backend module */
-void backend_module_init (GTypeModule *module);
-
-const MateMixerBackendModuleInfo *backend_module_get_info (void);
-
static void mate_mixer_backend_interface_init (MateMixerBackendInterface *iface);
+static void mate_mixer_null_class_init (MateMixerNullClass *klass);
+static void mate_mixer_null_class_finalize (MateMixerNullClass *klass);
+static void mate_mixer_null_init (MateMixerNull *null);
G_DEFINE_DYNAMIC_TYPE_EXTENDED (MateMixerNull, mate_mixer_null,
G_TYPE_OBJECT, 0,
G_IMPLEMENT_INTERFACE_DYNAMIC (MATE_MIXER_TYPE_BACKEND,
mate_mixer_backend_interface_init))
-static MateMixerBackendModuleInfo info;
+static MateMixerBackendInfo info;
void
backend_module_init (GTypeModule *module)
@@ -48,10 +46,10 @@ backend_module_init (GTypeModule *module)
info.name = BACKEND_NAME;
info.priority = BACKEND_PRIORITY;
info.g_type = MATE_MIXER_TYPE_NULL;
- info.backend_type = MATE_MIXER_BACKEND_TYPE_NULL;
+ info.backend_type = MATE_MIXER_BACKEND_NULL;
}
-const MateMixerBackendModuleInfo *
+const MateMixerBackendInfo *
backend_module_get_info (void)
{
return &info;
@@ -64,28 +62,18 @@ mate_mixer_backend_interface_init (MateMixerBackendInterface *iface)
}
static void
-mate_mixer_null_init (MateMixerNull *null)
-{
-}
-
-static void
-mate_mixer_null_finalize (GObject *object)
+mate_mixer_null_class_init (MateMixerNullClass *klass)
{
- G_OBJECT_CLASS (mate_mixer_null_parent_class)->finalize (object);
}
+/* Called in the code generated by G_DEFINE_DYNAMIC_TYPE_EXTENDED() */
static void
-mate_mixer_null_class_init (MateMixerNullClass *klass)
+mate_mixer_null_class_finalize (MateMixerNullClass *klass)
{
- GObjectClass *object_class;
-
- object_class = G_OBJECT_CLASS (klass);
- object_class->finalize = mate_mixer_null_finalize;
}
-/* Called in the code generated by G_DEFINE_DYNAMIC_TYPE_EXTENDED() */
static void
-mate_mixer_null_class_finalize (MateMixerNullClass *klass)
+mate_mixer_null_init (MateMixerNull *null)
{
}
diff --git a/backends/null/null.h b/backends/null/null.h
index d73794e..c9dd501 100644
--- a/backends/null/null.h
+++ b/backends/null/null.h
@@ -51,6 +51,10 @@ struct _MateMixerNullClass
GType mate_mixer_null_get_type (void) G_GNUC_CONST;
-gboolean mate_mixer_null_open (MateMixerBackend *backend);
+/* Support function for dynamic loading of the backend module */
+void backend_module_init (GTypeModule *module);
+const MateMixerBackendInfo *backend_module_get_info (void);
+
+gboolean mate_mixer_null_open (MateMixerBackend *backend);
#endif /* MATEMIXER_NULL_H */
diff --git a/backends/pulse/Makefile.am b/backends/pulse/Makefile.am
index 2f7cd6f..2cc7b5e 100644
--- a/backends/pulse/Makefile.am
+++ b/backends/pulse/Makefile.am
@@ -13,10 +13,20 @@ libmatemixer_pulse_la_CFLAGS = \
libmatemixer_pulse_la_SOURCES = \
pulse.c \
pulse.h \
+ pulse-connection.c \
+ pulse-connection.h \
pulse-device.c \
pulse-device.h \
- pulse-track.c \
- pulse-track.h
+ pulse-stream.c \
+ pulse-stream.h \
+ pulse-sink.c \
+ pulse-sink.h \
+ pulse-sink-input.c \
+ pulse-sink-input.h \
+ pulse-source.c \
+ pulse-source.h \
+ pulse-source-output.c \
+ pulse-source-output.h
libmatemixer_pulse_la_LIBADD = \
$(GLIB_LIBS) \
diff --git a/backends/pulse/pulse-connection.c b/backends/pulse/pulse-connection.c
new file mode 100644
index 0000000..6c70490
--- /dev/null
+++ b/backends/pulse/pulse-connection.c
@@ -0,0 +1,764 @@
+/*
+ * Copyright (C) 2014 Michal Ratajsky <[email protected]>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the licence, or (at your option) any later version.
+ *
+ * This 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <glib.h>
+#include <glib-object.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <pulse/pulseaudio.h>
+
+#include "pulse-connection.h"
+
+struct _MateMixerPulseConnectionPrivate
+{
+ gchar *server;
+ gboolean reconnect;
+ gboolean connected;
+ pa_context *context;
+ pa_threaded_mainloop *mainloop;
+};
+
+enum {
+ PROP_0,
+ PROP_SERVER,
+ PROP_RECONNECT,
+ PROP_CONNECTED,
+ N_PROPERTIES
+};
+
+enum {
+ LIST_ITEM_CARD,
+ LIST_ITEM_SINK,
+ LIST_ITEM_SOURCE,
+ LIST_ITEM_SINK_INPUT,
+ LIST_ITEM_SOURCE_OUTPUT,
+ CARD_ADDED,
+ CARD_REMOVED,
+ CARD_CHANGED,
+ SINK_ADDED,
+ SINK_REMOVED,
+ SINK_CHANGED,
+ SOURCE_ADDED,
+ SOURCE_REMOVED,
+ SOURCE_CHANGED,
+ N_SIGNALS
+};
+
+static GParamSpec *properties[N_PROPERTIES] = { NULL, };
+
+static guint signals[N_SIGNALS] = { 0, };
+
+G_DEFINE_TYPE (MateMixerPulseConnection, mate_mixer_pulse_connection, G_TYPE_OBJECT);
+
+static gchar *pulse_connection_get_name (void);
+
+static gboolean pulse_connection_process_operation (MateMixerPulseConnection *connection,
+ pa_operation *o);
+
+static void pulse_connection_state_cb (pa_context *c, void *userdata);
+
+static void pulse_connection_subscribe_cb (pa_context *c,
+ pa_subscription_event_type_t t,
+ uint32_t idx,
+ void *userdata);
+
+static void pulse_connection_card_info_cb (pa_context *c,
+ const pa_card_info *info,
+ int eol,
+ void *userdata);
+
+static void pulse_connection_sink_info_cb (pa_context *c,
+ const pa_sink_info *info,
+ int eol,
+ void *userdata);
+
+static void pulse_connection_source_info_cb (pa_context *c,
+ const pa_source_info *info,
+ int eol,
+ void *userdata);
+
+static void pulse_connection_sink_input_info_cb (pa_context *c,
+ const pa_sink_input_info *info,
+ int eol,
+ void *userdata);
+
+static void pulse_connection_source_output_info_cb (pa_context *c,
+ const pa_source_output_info *info,
+ int eol,
+ void *userdata);
+
+static void
+mate_mixer_pulse_connection_init (MateMixerPulseConnection *connection)
+{
+ connection->priv = G_TYPE_INSTANCE_GET_PRIVATE (
+ connection,
+ MATE_MIXER_TYPE_PULSE_CONNECTION,
+ MateMixerPulseConnectionPrivate);
+}
+
+static void
+mate_mixer_pulse_connection_get_property (GObject *object,
+ guint param_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ MateMixerPulseConnection *connection;
+
+ connection = MATE_MIXER_PULSE_CONNECTION (object);
+
+ switch (param_id) {
+ case PROP_SERVER:
+ g_value_set_string (value, connection->priv->server);
+ break;
+ case PROP_RECONNECT:
+ g_value_set_boolean (value, connection->priv->reconnect);
+ break;
+ case PROP_CONNECTED:
+ g_value_set_boolean (value, connection->priv->connected);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+ break;
+ }
+}
+
+static void
+mate_mixer_pulse_connection_set_property (GObject *object,
+ guint param_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ MateMixerPulseConnection *connection;
+
+ connection = MATE_MIXER_PULSE_CONNECTION (object);
+
+ switch (param_id) {
+ case PROP_SERVER:
+ connection->priv->server = g_strdup (g_value_get_string (value));
+ break;
+ case PROP_RECONNECT:
+ connection->priv->reconnect = g_value_get_boolean (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+ break;
+ }
+}
+
+static void
+mate_mixer_pulse_connection_finalize (GObject *object)
+{
+ MateMixerPulseConnection *connection;
+
+ connection = MATE_MIXER_PULSE_CONNECTION (object);
+
+ g_free (connection->priv->server);
+
+ G_OBJECT_CLASS (mate_mixer_pulse_connection_parent_class)->finalize (object);
+}
+
+static void
+mate_mixer_pulse_connection_class_init (MateMixerPulseConnectionClass *klass)
+{
+ GObjectClass *object_class;
+
+ object_class = G_OBJECT_CLASS (klass);
+ object_class->finalize = mate_mixer_pulse_connection_finalize;
+ object_class->get_property = mate_mixer_pulse_connection_get_property;
+ object_class->set_property = mate_mixer_pulse_connection_set_property;
+
+ properties[PROP_SERVER] = g_param_spec_string (
+ "server",
+ "Server",
+ "PulseAudio server to connect to",
+ NULL,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
+ properties[PROP_RECONNECT] = g_param_spec_boolean (
+ "reconnect",
+ "Reconnect",
+ "Try to reconnect when connection to PulseAudio server is lost",
+ TRUE,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
+ properties[PROP_CONNECTED] = g_param_spec_boolean (
+ "connected",
+ "Connected",
+ "Connected to a PulseAudio server or not",
+ FALSE,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+
+ signals[LIST_ITEM_CARD] = g_signal_new (
+ "list-item-card",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (MateMixerPulseConnectionClass, list_item_card),
+ NULL,
+ NULL,
+ g_cclosure_marshal_VOID__POINTER,
+ G_TYPE_NONE,
+ 1,
+ G_TYPE_POINTER);
+
+ signals[LIST_ITEM_SINK] = g_signal_new (
+ "list-item-sink",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (MateMixerPulseConnectionClass, list_item_sink),
+ NULL,
+ NULL,
+ g_cclosure_marshal_VOID__POINTER,
+ G_TYPE_NONE,
+ 1,
+ G_TYPE_POINTER);
+
+ signals[LIST_ITEM_SINK_INPUT] = g_signal_new (
+ "list-item-sink-input",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (MateMixerPulseConnectionClass, list_item_sink_input),
+ NULL,
+ NULL,
+ g_cclosure_marshal_VOID__POINTER,
+ G_TYPE_NONE,
+ 1,
+ G_TYPE_POINTER);
+
+ signals[LIST_ITEM_SOURCE] = g_signal_new (
+ "list-item-source",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (MateMixerPulseConnectionClass, list_item_source),
+ NULL,
+ NULL,
+ g_cclosure_marshal_VOID__POINTER,
+ G_TYPE_NONE,
+ 1,
+ G_TYPE_POINTER);
+
+ signals[LIST_ITEM_SOURCE_OUTPUT] = g_signal_new (
+ "list-item-source-output",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (MateMixerPulseConnectionClass, list_item_source_output),
+ NULL,
+ NULL,
+ g_cclosure_marshal_VOID__POINTER,
+ G_TYPE_NONE,
+ 1,
+ G_TYPE_POINTER);
+
+ g_object_class_install_properties (object_class, N_PROPERTIES, properties);
+
+ g_type_class_add_private (object_class, sizeof (MateMixerPulseConnectionPrivate));
+}
+
+// XXX: pass more info about application, provide API
+
+MateMixerPulseConnection *
+mate_mixer_pulse_connection_new (const gchar *server, const gchar *app_name)
+{
+ pa_threaded_mainloop *mainloop;
+ pa_context *context;
+ MateMixerPulseConnection *connection;
+
+ mainloop = pa_threaded_mainloop_new ();
+ if (G_UNLIKELY (mainloop == NULL)) {
+ g_warning ("Failed to create PulseAudio main loop");
+ return NULL;
+ }
+
+ if (app_name != NULL) {
+ context = pa_context_new (
+ pa_threaded_mainloop_get_api (mainloop),
+ app_name);
+ } else {
+ gchar *name = pulse_connection_get_name ();
+
+ context = pa_context_new (
+ pa_threaded_mainloop_get_api (mainloop),
+ name);
+
+ g_free (name);
+ }
+
+ if (G_UNLIKELY (context == NULL)) {
+ g_warning ("Failed to create PulseAudio context");
+
+ pa_threaded_mainloop_free (mainloop);
+ return NULL;
+ }
+
+ connection = g_object_new (MATE_MIXER_TYPE_PULSE_CONNECTION,
+ "server", server,
+ "reconnect", TRUE,
+ NULL);
+
+ connection->priv->mainloop = mainloop;
+ connection->priv->context = context;
+
+ return connection;
+}
+
+gboolean
+mate_mixer_pulse_connection_connect (MateMixerPulseConnection *connection)
+{
+ int ret;
+ pa_operation *o;
+
+ g_return_val_if_fail (MATE_MIXER_IS_PULSE_CONNECTION (connection), FALSE);
+
+ if (connection->priv->connected)
+ return TRUE;
+
+ /* Initiate a connection, this call does not guarantee the connection
+ * to be established and usable */
+ ret = pa_context_connect (connection->priv->context, NULL, PA_CONTEXT_NOFLAGS, NULL);
+ if (ret < 0) {
+ g_warning ("Failed to connect to PulseAudio server: %s", pa_strerror (ret));
+ return FALSE;
+ }
+
+ pa_threaded_mainloop_lock (connection->priv->mainloop);
+
+ /* Set callback for connection status changes; the callback is not really
+ * used when connecting the first time, it is only needed to signal
+ * a status change */
+ pa_context_set_state_callback (connection->priv->context,
+ pulse_connection_state_cb,
+ connection);
+
+ ret = pa_threaded_mainloop_start (connection->priv->mainloop);
+ if (ret < 0) {
+ g_warning ("Failed to start PulseAudio main loop: %s", pa_strerror (ret));
+
+ pa_context_disconnect (connection->priv->context);
+ pa_threaded_mainloop_unlock (connection->priv->mainloop);
+ return FALSE;
+ }
+
+ while (TRUE) {
+ /* Wait for a connection state which tells us whether the connection
+ * has been established or has failed */
+ pa_context_state_t state =
+ pa_context_get_state (connection->priv->context);
+
+ if (state == PA_CONTEXT_READY)
+ break;
+
+ if (state == PA_CONTEXT_FAILED ||
+ state == PA_CONTEXT_TERMINATED) {
+ g_warning ("Failed to connect to PulseAudio server: %s",
+ pa_strerror (pa_context_errno (connection->priv->context)));
+
+ pa_context_disconnect (connection->priv->context);
+ pa_threaded_mainloop_unlock (connection->priv->mainloop);
+ return FALSE;
+ }
+ pa_threaded_mainloop_wait (connection->priv->mainloop);
+ }
+
+ pa_context_set_subscribe_callback (connection->priv->context,
+ pulse_connection_subscribe_cb,
+ connection);
+
+ // XXX don't want notifications before the initial lists are downloaded
+
+ o = pa_context_subscribe (connection->priv->context,
+ PA_SUBSCRIPTION_MASK_CARD |
+ PA_SUBSCRIPTION_MASK_SINK |
+ PA_SUBSCRIPTION_MASK_SOURCE |
+ PA_SUBSCRIPTION_MASK_SINK_INPUT |
+ PA_SUBSCRIPTION_MASK_SOURCE_OUTPUT,
+ NULL, NULL);
+ if (o == NULL)
+ g_warning ("Failed to subscribe to PulseAudio notifications: %s",
+ pa_strerror (pa_context_errno (connection->priv->context)));
+ else
+ pa_operation_unref (o);
+
+ pa_threaded_mainloop_unlock (connection->priv->mainloop);
+
+ connection->priv->connected = TRUE;
+
+ g_object_notify_by_pspec (G_OBJECT (connection), properties[PROP_CONNECTED]);
+ return TRUE;
+}
+
+void
+mate_mixer_pulse_connection_disconnect (MateMixerPulseConnection *connection)
+{
+ g_return_val_if_fail (MATE_MIXER_IS_PULSE_CONNECTION (connection), FALSE);
+
+ if (!connection->priv->connected)
+ return;
+
+ pa_context_disconnect (connection->priv->context);
+
+ connection->priv->connected = FALSE;
+
+ g_object_notify_by_pspec (G_OBJECT (connection), properties[PROP_CONNECTED]);
+}
+
+gboolean
+mate_mixer_pulse_connection_get_server_info (MateMixerPulseConnection *connection)
+{
+ // TODO
+ return TRUE;
+}
+
+gboolean
+mate_mixer_pulse_connection_get_card_list (MateMixerPulseConnection *connection)
+{
+ pa_operation *o;
+ gboolean ret;
+
+ g_return_val_if_fail (MATE_MIXER_IS_PULSE_CONNECTION (connection), FALSE);
+
+ pa_threaded_mainloop_lock (connection->priv->mainloop);
+
+ o = pa_context_get_card_info_list (
+ connection->priv->context,
+ pulse_connection_card_info_cb,
+ connection);
+
+ ret = pulse_connection_process_operation (connection, o);
+
+ pa_threaded_mainloop_unlock (connection->priv->mainloop);
+ return ret;
+}
+
+gboolean
+mate_mixer_pulse_connection_get_sink_list (MateMixerPulseConnection *connection)
+{
+ pa_operation *o;
+ gboolean ret;
+
+ g_return_val_if_fail (MATE_MIXER_IS_PULSE_CONNECTION (connection), FALSE);
+
+ pa_threaded_mainloop_lock (connection->priv->mainloop);
+
+ o = pa_context_get_sink_info_list (
+ connection->priv->context,
+ pulse_connection_sink_info_cb,
+ connection);
+
+ ret = pulse_connection_process_operation (connection, o);
+
+ pa_threaded_mainloop_unlock (connection->priv->mainloop);
+ return ret;
+}
+
+gboolean
+mate_mixer_pulse_connection_get_sink_input_list (MateMixerPulseConnection *connection)
+{
+ pa_operation *o;
+ gboolean ret;
+
+ g_return_val_if_fail (MATE_MIXER_IS_PULSE_CONNECTION (connection), FALSE);
+
+ pa_threaded_mainloop_lock (connection->priv->mainloop);
+
+ o = pa_context_get_sink_input_info_list (
+ connection->priv->context,
+ pulse_connection_sink_input_info_cb,
+ connection);
+
+ ret = pulse_connection_process_operation (connection, o);
+
+ pa_threaded_mainloop_unlock (connection->priv->mainloop);
+ return ret;
+}
+
+gboolean
+mate_mixer_pulse_connection_get_source_list (MateMixerPulseConnection *connection)
+{
+ pa_operation *o;
+ gboolean ret;
+
+ g_return_val_if_fail (MATE_MIXER_IS_PULSE_CONNECTION (connection), FALSE);
+
+ pa_threaded_mainloop_lock (connection->priv->mainloop);
+
+ o = pa_context_get_source_info_list (
+ connection->priv->context,
+ pulse_connection_source_info_cb,
+ connection);
+
+ ret = pulse_connection_process_operation (connection, o);
+
+ pa_threaded_mainloop_unlock (connection->priv->mainloop);
+ return ret;
+}
+
+gboolean
+mate_mixer_pulse_connection_get_source_output_list (MateMixerPulseConnection *connection)
+{
+ pa_operation *o;
+ gboolean ret;
+
+ g_return_val_if_fail (MATE_MIXER_IS_PULSE_CONNECTION (connection), FALSE);
+
+ pa_threaded_mainloop_lock (connection->priv->mainloop);
+
+ o = pa_context_get_source_output_info_list (
+ connection->priv->context,
+ pulse_connection_source_output_info_cb,
+ connection);
+
+ ret = pulse_connection_process_operation (connection, o);
+
+ pa_threaded_mainloop_unlock (connection->priv->mainloop);
+ return ret;
+}
+
+gboolean
+mate_mixer_pulse_connection_set_card_profile (MateMixerPulseConnection *connection,
+ const gchar *card,
+ const gchar *profile)
+{
+ pa_operation *o;
+ gboolean ret;
+
+ g_return_val_if_fail (MATE_MIXER_IS_PULSE_CONNECTION (connection), FALSE);
+
+ pa_threaded_mainloop_lock (connection->priv->mainloop);
+
+ o = pa_context_set_card_profile_by_name (
+ connection->priv->context,
+ card,
+ profile,
+ NULL, NULL);
+
+ // XXX maybe shouldn't wait for the completion
+
+ ret = pulse_connection_process_operation (connection, o);
+
+ pa_threaded_mainloop_unlock (connection->priv->mainloop);
+ return ret;
+}
+
+gboolean
+mate_mixer_pulse_connection_set_sink_mute (MateMixerPulseConnection *connection,
+ guint32 index,
+ gboolean mute)
+{
+ pa_operation *o;
+ gboolean ret;
+
+ g_return_val_if_fail (MATE_MIXER_IS_PULSE_CONNECTION (connection), FALSE);
+
+ pa_threaded_mainloop_lock (connection->priv->mainloop);
+
+ o = pa_context_set_sink_mute_by_index (
+ connection->priv->context,
+ index,
+ (int) mute,
+ NULL, NULL);
+
+ // XXX maybe shouldn't wait for the completion
+
+ ret = pulse_connection_process_operation (connection, o);
+
+ pa_threaded_mainloop_unlock (connection->priv->mainloop);
+ return ret;
+}
+
+static gboolean
+pulse_connection_process_operation (MateMixerPulseConnection *connection,
+ pa_operation *o)
+{
+ if (o == NULL) {
+ g_warning ("Failed to process PulseAudio operation: %s",
+ pa_strerror (pa_context_errno (connection->priv->context)));
+
+ return FALSE;
+ }
+
+ while (pa_operation_get_state (o) == PA_OPERATION_RUNNING)
+ pa_threaded_mainloop_wait (connection->priv->mainloop);
+
+ pa_operation_unref (o);
+ return TRUE;
+}
+
+static gchar *
+pulse_connection_get_name (void)
+{
+ const char *name_app;
+ char name_buf[256];
+
+ /* Inspired by GStreamer's pulse plugin */
+ name_app = g_get_application_name ();
+ if (name_app != NULL)
+ return g_strdup (name_app);
+
+ if (pa_get_binary_name (name_buf, sizeof (name_buf)) != NULL)
+ return g_strdup (name_buf);
+
+ return g_strdup_printf ("libmatemixer-%lu", (gulong) getpid ());
+}
+
+static void
+pulse_connection_state_cb (pa_context *c, void *userdata)
+{
+ MateMixerPulseConnection *connection;
+ pa_context_state_t state;
+
+ connection = MATE_MIXER_PULSE_CONNECTION (userdata);
+
+ state = pa_context_get_state (c);
+ switch (state) {
+ case PA_CONTEXT_READY:
+ /* The connection is established, the context is ready to
+ * execute operations. */
+ if (!connection->priv->connected) {
+ connection->priv->connected = TRUE;
+
+ g_object_notify_by_pspec (
+ G_OBJECT (connection),
+ properties[PROP_CONNECTED]);
+ }
+ break;
+
+ case PA_CONTEXT_TERMINATED:
+ /* The connection was terminated cleanly. */
+ if (connection->priv->connected) {
+ connection->priv->connected = FALSE;
+
+ g_object_notify_by_pspec (
+ G_OBJECT (connection),
+ properties[PROP_CONNECTED]);
+
+ pa_context_disconnect (connection->priv->context);
+ }
+ break;
+
+ case PA_CONTEXT_FAILED:
+ break;
+
+ default:
+ break;
+ }
+
+ pa_threaded_mainloop_signal (connection->priv->mainloop, 0);
+}
+
+static void
+pulse_connection_subscribe_cb (pa_context *c,
+ pa_subscription_event_type_t t,
+ uint32_t idx,
+ void *userdata)
+{
+ // TODO
+}
+
+static void
+pulse_connection_card_info_cb (pa_context *c,
+ const pa_card_info *info,
+ int eol,
+ void *userdata)
+{
+ MateMixerPulseConnection *connection;
+
+ connection = MATE_MIXER_PULSE_CONNECTION (userdata);
+
+ if (!eol)
+ g_signal_emit (G_OBJECT (connection),
+ signals[LIST_ITEM_CARD],
+ 0,
+ info);
+
+ pa_threaded_mainloop_signal (connection->priv->mainloop, 0);
+}
+
+static void
+pulse_connection_sink_info_cb (pa_context *c,
+ const pa_sink_info *info,
+ int eol,
+ void *userdata)
+{
+ MateMixerPulseConnection *connection;
+
+ connection = MATE_MIXER_PULSE_CONNECTION (userdata);
+
+ if (!eol)
+ g_signal_emit (G_OBJECT (connection),
+ signals[LIST_ITEM_SINK],
+ 0,
+ info);
+
+ pa_threaded_mainloop_signal (connection->priv->mainloop, 0);
+}
+
+static void
+pulse_connection_sink_input_info_cb (pa_context *c,
+ const pa_sink_input_info *info,
+ int eol,
+ void *userdata)
+{
+ MateMixerPulseConnection *connection;
+
+ connection = MATE_MIXER_PULSE_CONNECTION (userdata);
+
+ if (!eol)
+ g_signal_emit (G_OBJECT (connection),
+ signals[LIST_ITEM_SINK_INPUT],
+ 0,
+ info);
+
+ pa_threaded_mainloop_signal (connection->priv->mainloop, 0);
+}
+
+static void
+pulse_connection_source_info_cb (pa_context *c,
+ const pa_source_info *info,
+ int eol,
+ void *userdata)
+{
+ MateMixerPulseConnection *connection;
+
+ connection = MATE_MIXER_PULSE_CONNECTION (userdata);
+
+ if (!eol)
+ g_signal_emit (G_OBJECT (connection),
+ signals[LIST_ITEM_SOURCE],
+ 0,
+ info);
+
+ pa_threaded_mainloop_signal (connection->priv->mainloop, 0);
+}
+
+static void
+pulse_connection_source_output_info_cb (pa_context *c,
+ const pa_source_output_info *info,
+ int eol,
+ void *userdata)
+{
+ MateMixerPulseConnection *connection;
+
+ connection = MATE_MIXER_PULSE_CONNECTION (userdata);
+
+ if (!eol)
+ g_signal_emit (G_OBJECT (connection),
+ signals[LIST_ITEM_SOURCE_OUTPUT],
+ 0,
+ info);
+
+ pa_threaded_mainloop_signal (connection->priv->mainloop, 0);
+}
diff --git a/backends/pulse/pulse-connection.h b/backends/pulse/pulse-connection.h
new file mode 100644
index 0000000..85fd0b7
--- /dev/null
+++ b/backends/pulse/pulse-connection.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2014 Michal Ratajsky <[email protected]>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the licence, or (at your option) any later version.
+ *
+ * This 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef MATEMIXER_PULSE_CONNECTION_H
+#define MATEMIXER_PULSE_CONNECTION_H
+
+#include <glib.h>
+#include <glib-object.h>
+
+#include <pulse/pulseaudio.h>
+
+G_BEGIN_DECLS
+
+#define MATE_MIXER_TYPE_PULSE_CONNECTION \
+ (mate_mixer_pulse_connection_get_type ())
+#define MATE_MIXER_PULSE_CONNECTION(o) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((o), MATE_MIXER_TYPE_PULSE_CONNECTION, MateMixerPulseConnection))
+#define MATE_MIXER_IS_PULSE_CONNECTION(o) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((o), MATE_MIXER_TYPE_PULSE_CONNECTION))
+#define MATE_MIXER_PULSE_CONNECTION_CLASS(k) \
+ (G_TYPE_CHECK_CLASS_CAST ((k), MATE_MIXER_TYPE_PULSE_CONNECTION, MateMixerPulseConnectionClass))
+#define MATE_MIXER_IS_PULSE_CONNECTION_CLASS(k) \
+ (G_TYPE_CLASS_CHECK_CLASS_TYPE ((k), MATE_MIXER_TYPE_PULSE_CONNECTION))
+#define MATE_MIXER_PULSE_CONNECTION_GET_CLASS(o) \
+ (G_TYPE_INSTANCE_GET_CLASS ((o), MATE_MIXER_TYPE_PULSE_CONNECTION, MateMixerPulseConnectionClass))
+
+typedef struct _MateMixerPulseConnection MateMixerPulseConnection;
+typedef struct _MateMixerPulseConnectionClass MateMixerPulseConnectionClass;
+typedef struct _MateMixerPulseConnectionPrivate MateMixerPulseConnectionPrivate;
+
+struct _MateMixerPulseConnection
+{
+ GObject parent;
+
+ MateMixerPulseConnectionPrivate *priv;
+};
+
+struct _MateMixerPulseConnectionClass
+{
+ GObjectClass parent;
+
+ void (*disconnected) (MateMixerPulseConnection *connection);
+ void (*reconnected) (MateMixerPulseConnection *connection);
+
+ void (*list_item_card) (MateMixerPulseConnection *connection,
+ const pa_card_info *info);
+ void (*list_item_sink) (MateMixerPulseConnection *connection,
+ const pa_sink_info *info);
+ void (*list_item_sink_input) (MateMixerPulseConnection *connection,
+ const pa_sink_input_info *info);
+ void (*list_item_source) (MateMixerPulseConnection *connection,
+ const pa_source_info *info);
+ void (*list_item_source_output) (MateMixerPulseConnection *connection,
+ const pa_source_output_info *info);
+};
+
+GType mate_mixer_pulse_connection_get_type (void) G_GNUC_CONST;
+
+MateMixerPulseConnection *mate_mixer_pulse_connection_new (const gchar *server,
+ const gchar *app_name);
+
+gboolean mate_mixer_pulse_connection_connect (MateMixerPulseConnection *connection);
+
+void mate_mixer_pulse_connection_disconnect (MateMixerPulseConnection *connection);
+
+gboolean mate_mixer_pulse_connection_get_server_info (MateMixerPulseConnection *connection);
+
+gboolean mate_mixer_pulse_connection_get_card_list (MateMixerPulseConnection *connection);
+
+gboolean mate_mixer_pulse_connection_get_sink_list (MateMixerPulseConnection *connection);
+
+gboolean mate_mixer_pulse_connection_get_sink_input_list (MateMixerPulseConnection *connection);
+
+gboolean mate_mixer_pulse_connection_get_source_list (MateMixerPulseConnection *connection);
+
+gboolean mate_mixer_pulse_connection_get_source_output_list (MateMixerPulseConnection *connection);
+
+gboolean mate_mixer_pulse_connection_set_card_profile (MateMixerPulseConnection *connection,
+ const gchar *device,
+ const gchar *profile);
+
+gboolean mate_mixer_pulse_connection_set_sink_mute (MateMixerPulseConnection *connection,
+ guint32 index,
+ gboolean mute);
+
+G_END_DECLS
+
+#endif /* MATEMIXER_PULSE_CONNECTION_H */
diff --git a/backends/pulse/pulse-device.c b/backends/pulse/pulse-device.c
index dbc287c..a411d7f 100644
--- a/backends/pulse/pulse-device.c
+++ b/backends/pulse/pulse-device.c
@@ -19,30 +19,31 @@
#include <glib-object.h>
#include <libmatemixer/matemixer-device.h>
-#include <libmatemixer/matemixer-device-port.h>
-#include <libmatemixer/matemixer-device-profile.h>
+#include <libmatemixer/matemixer-port.h>
+#include <libmatemixer/matemixer-profile.h>
#include <pulse/pulseaudio.h>
+#include "pulse-connection.h"
#include "pulse-device.h"
struct _MateMixerPulseDevicePrivate
{
- guint32 index;
- GList *profiles;
- GList *ports;
- gchar *identifier;
- gchar *name;
- gchar *icon;
-
- MateMixerDeviceProfile *active_profile;
+ guint32 index;
+ gchar *name;
+ gchar *description;
+ GList *profiles;
+ GList *ports;
+ gchar *icon;
+ MateMixerProfile *profile;
+ MateMixerPulseConnection *connection;
};
enum
{
PROP_0,
- PROP_IDENTIFIER,
PROP_NAME,
+ PROP_DESCRIPTION,
PROP_ICON,
PROP_ACTIVE_PROFILE,
N_PROPERTIES
@@ -57,9 +58,12 @@ G_DEFINE_TYPE_WITH_CODE (MateMixerPulseDevice, mate_mixer_pulse_device, G_TYPE_O
static void
mate_mixer_device_interface_init (MateMixerDeviceInterface *iface)
{
- iface->list_tracks = mate_mixer_pulse_device_list_tracks;
- iface->get_ports = mate_mixer_pulse_device_get_ports;
- iface->get_profiles = mate_mixer_pulse_device_get_profiles;
+ iface->get_name = mate_mixer_pulse_device_get_name;
+ iface->get_description = mate_mixer_pulse_device_get_description;
+ iface->get_icon = mate_mixer_pulse_device_get_icon;
+ iface->list_streams = mate_mixer_pulse_device_list_streams;
+ iface->list_ports = mate_mixer_pulse_device_list_ports;
+ iface->list_profiles = mate_mixer_pulse_device_list_profiles;
iface->get_active_profile = mate_mixer_pulse_device_get_active_profile;
iface->set_active_profile = mate_mixer_pulse_device_set_active_profile;
}
@@ -67,10 +71,9 @@ mate_mixer_device_interface_init (MateMixerDeviceInterface *iface)
static void
mate_mixer_pulse_device_init (MateMixerPulseDevice *device)
{
- device->priv = G_TYPE_INSTANCE_GET_PRIVATE (
- device,
- MATE_MIXER_TYPE_PULSE_DEVICE,
- MateMixerPulseDevicePrivate);
+ device->priv = G_TYPE_INSTANCE_GET_PRIVATE (device,
+ MATE_MIXER_TYPE_PULSE_DEVICE,
+ MateMixerPulseDevicePrivate);
}
static void
@@ -84,17 +87,17 @@ mate_mixer_pulse_device_get_property (GObject *object,
device = MATE_MIXER_PULSE_DEVICE (object);
switch (param_id) {
- case PROP_IDENTIFIER:
- g_value_set_string (value, device->priv->identifier);
- break;
case PROP_NAME:
g_value_set_string (value, device->priv->name);
break;
+ case PROP_DESCRIPTION:
+ g_value_set_string (value, device->priv->description);
+ break;
case PROP_ICON:
g_value_set_string (value, device->priv->icon);
break;
case PROP_ACTIVE_PROFILE:
- g_value_set_object (value, device->priv->active_profile);
+ g_value_set_object (value, device->priv->profile);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
@@ -113,20 +116,15 @@ mate_mixer_pulse_device_set_property (GObject *object,
device = MATE_MIXER_PULSE_DEVICE (object);
switch (param_id) {
- case PROP_IDENTIFIER:
- device->priv->identifier = g_strdup (g_value_get_string (value));
- break;
case PROP_NAME:
device->priv->name = g_strdup (g_value_get_string (value));
break;
+ case PROP_DESCRIPTION:
+ device->priv->description = g_strdup (g_value_get_string (value));
+ break;
case PROP_ICON:
device->priv->icon = g_strdup (g_value_get_string (value));
break;
- case PROP_ACTIVE_PROFILE:
- mate_mixer_pulse_device_set_active_profile (
- MATE_MIXER_DEVICE (device),
- g_value_get_object (value));
- break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
break;
@@ -134,24 +132,38 @@ mate_mixer_pulse_device_set_property (GObject *object,
}
static void
-mate_mixer_pulse_device_finalize (GObject *object)
+mate_mixer_pulse_device_dispose (GObject *object)
{
MateMixerPulseDevice *device;
device = MATE_MIXER_PULSE_DEVICE (object);
- g_free (device->priv->identifier);
- g_free (device->priv->name);
- g_free (device->priv->icon);
-
- if (device->priv->profiles != NULL)
+ if (device->priv->profiles != NULL) {
g_list_free_full (device->priv->profiles, g_object_unref);
+ device->priv->profiles = NULL;
+ }
- if (device->priv->ports != NULL)
+ if (device->priv->ports != NULL) {
g_list_free_full (device->priv->ports, g_object_unref);
+ device->priv->ports = NULL;
+ }
+
+ g_clear_object (&device->priv->profile);
+ g_clear_object (&device->priv->connection);
+
+ G_OBJECT_CLASS (mate_mixer_pulse_device_parent_class)->dispose (object);
+}
+
+static void
+mate_mixer_pulse_device_finalize (GObject *object)
+{
+ MateMixerPulseDevice *device;
- if (device->priv->active_profile != NULL)
- g_object_unref (device->priv->active_profile);
+ device = MATE_MIXER_PULSE_DEVICE (object);
+
+ g_free (device->priv->name);
+ g_free (device->priv->description);
+ g_free (device->priv->icon);
G_OBJECT_CLASS (mate_mixer_pulse_device_parent_class)->finalize (object);
}
@@ -162,12 +174,13 @@ mate_mixer_pulse_device_class_init (MateMixerPulseDeviceClass *klass)
GObjectClass *object_class;
object_class = G_OBJECT_CLASS (klass);
+ object_class->dispose = mate_mixer_pulse_device_dispose;
object_class->finalize = mate_mixer_pulse_device_finalize;
object_class->get_property = mate_mixer_pulse_device_get_property;
object_class->set_property = mate_mixer_pulse_device_set_property;
- g_object_class_override_property (object_class, PROP_IDENTIFIER, "identifier");
g_object_class_override_property (object_class, PROP_NAME, "name");
+ g_object_class_override_property (object_class, PROP_DESCRIPTION, "description");
g_object_class_override_property (object_class, PROP_ICON, "icon");
g_object_class_override_property (object_class, PROP_ACTIVE_PROFILE, "active-profile");
@@ -175,19 +188,19 @@ mate_mixer_pulse_device_class_init (MateMixerPulseDeviceClass *klass)
}
MateMixerPulseDevice *
-mate_mixer_pulse_device_new (const pa_card_info *info)
+mate_mixer_pulse_device_new (MateMixerPulseConnection *connection, const pa_card_info *info)
{
- MateMixerPulseDevice *device;
- MateMixerDeviceProfile *active_profile = NULL;
- GList *profiles = NULL;
- GList *ports = NULL;
- guint32 i;
+ MateMixerPulseDevice *device;
+ MateMixerProfile *active_profile = NULL;
+ GList *profiles = NULL;
+ GList *ports = NULL;
+ guint32 i;
g_return_val_if_fail (info != NULL, NULL);
/* Create a list of card profiles */
for (i = 0; i < info->n_profiles; i++) {
- MateMixerDeviceProfile *profile;
+ MateMixerProfile *profile;
#if PA_CHECK_VERSION(5, 0, 0)
pa_card_profile_info2 *p_info = info->profiles2[i];
@@ -199,9 +212,9 @@ mate_mixer_pulse_device_new (const pa_card_info *info)
continue;
#else
/* The old profile list is an array of structs, not pointers */
- pa_card_profile_info *p_info = &info->profiles[i];
+ pa_card_profile_info *p_info = &info->profiles[i];
#endif
- profile = mate_mixer_device_profile_new (
+ profile = mate_mixer_profile_new (
p_info->name,
p_info->description,
p_info->priority);
@@ -222,28 +235,27 @@ mate_mixer_pulse_device_new (const pa_card_info *info)
/* Create a list of card ports */
for (i = 0; i < info->n_ports; i++) {
- MateMixerDevicePort *port;
- MateMixerDevicePortDirection direction = 0;
- MateMixerDevicePortStatus status = 0;
- pa_card_port_info *p_info = info->ports[i];
-
- if (p_info->direction & PA_DIRECTION_INPUT)
- direction |= MATE_MIXER_DEVICE_PORT_DIRECTION_INPUT;
-
- if (p_info->direction & PA_DIRECTION_OUTPUT)
- direction |= MATE_MIXER_DEVICE_PORT_DIRECTION_OUTPUT;
+ MateMixerPort *port;
+ MateMixerPortStatus status = MATE_MIXER_PORT_UNKNOWN_STATUS;
+ pa_card_port_info *p_info = info->ports[i];
#if PA_CHECK_VERSION(2, 0, 0)
- if (p_info->available == PA_PORT_AVAILABLE_YES)
- status |= MATE_MIXER_DEVICE_PORT_STATUS_AVAILABLE;
+ switch (p_info->available) {
+ case PA_PORT_AVAILABLE_YES:
+ status = MATE_MIXER_PORT_AVAILABLE;
+ break;
+ case PA_PORT_AVAILABLE_NO:
+ status = MATE_MIXER_PORT_UNAVAILABLE;
+ break;
+ default:
+ break;
+ }
#endif
- port = mate_mixer_device_port_new (
- p_info->name,
- p_info->description,
- pa_proplist_gets (p_info->proplist, "device.icon_name"),
- p_info->priority,
- direction,
- status);
+ port = mate_mixer_port_new (p_info->name,
+ p_info->description,
+ pa_proplist_gets (p_info->proplist, "device.icon_name"),
+ p_info->priority,
+ status);
ports = g_list_prepend (ports, port);
}
@@ -253,15 +265,21 @@ mate_mixer_pulse_device_new (const pa_card_info *info)
ports = g_list_reverse (ports);
device = g_object_new (MATE_MIXER_TYPE_PULSE_DEVICE,
- "identifier", info->name,
- "name", pa_proplist_gets (info->proplist, "device.description"),
- "icon", pa_proplist_gets (info->proplist, "device.icon_name"),
- "active-profile", active_profile,
- NULL);
+ "name", info->name,
+ "description", pa_proplist_gets (info->proplist, "device.description"),
+ "icon", pa_proplist_gets (info->proplist, "device.icon_name"),
+ NULL);
+
+ if (profiles) {
+ device->priv->profiles = profiles;
+
+ if (G_LIKELY (active_profile))
+ device->priv->profile = g_object_ref (active_profile);
+ }
device->priv->index = info->index;
- device->priv->profiles = profiles;
device->priv->ports = ports;
+ device->priv->connection = g_object_ref (connection);
return device;
}
@@ -276,45 +294,104 @@ mate_mixer_pulse_device_update (MateMixerPulseDevice *device, const pa_card_info
return TRUE;
}
+MateMixerPulseConnection *
+mate_mixer_pulse_device_get_connection (MateMixerPulseDevice *device)
+{
+ g_return_val_if_fail (MATE_MIXER_IS_PULSE_DEVICE (device), NULL);
+
+ return device->priv->connection;
+}
+
+guint32
+mate_mixer_pulse_device_get_index (MateMixerPulseDevice *device)
+{
+ g_return_val_if_fail (MATE_MIXER_IS_PULSE_DEVICE (device), 0);
+
+ return device->priv->index;
+}
+
+const gchar *
+mate_mixer_pulse_device_get_name (MateMixerDevice *device)
+{
+ g_return_val_if_fail (MATE_MIXER_IS_PULSE_DEVICE (device), NULL);
+
+ return MATE_MIXER_PULSE_DEVICE (device)->priv->name;
+}
+
+const gchar *
+mate_mixer_pulse_device_get_description (MateMixerDevice *device)
+{
+ g_return_val_if_fail (MATE_MIXER_IS_PULSE_DEVICE (device), NULL);
+
+ return MATE_MIXER_PULSE_DEVICE (device)->priv->description;
+}
+
+const gchar *
+mate_mixer_pulse_device_get_icon (MateMixerDevice *device)
+{
+ g_return_val_if_fail (MATE_MIXER_IS_PULSE_DEVICE (device), NULL);
+
+ return MATE_MIXER_PULSE_DEVICE (device)->priv->icon;
+}
+
const GList *
-mate_mixer_pulse_device_list_tracks (MateMixerDevice *device)
+mate_mixer_pulse_device_list_streams (MateMixerDevice *device)
{
// TODO
return NULL;
}
const GList *
-mate_mixer_pulse_device_get_ports (MateMixerDevice *device)
+mate_mixer_pulse_device_list_ports (MateMixerDevice *device)
{
g_return_val_if_fail (MATE_MIXER_IS_PULSE_DEVICE (device), NULL);
- return MATE_MIXER_PULSE_DEVICE (device)->priv->ports;
+ return (const GList *) MATE_MIXER_PULSE_DEVICE (device)->priv->ports;
}
const GList *
-mate_mixer_pulse_device_get_profiles (MateMixerDevice *device)
+mate_mixer_pulse_device_list_profiles (MateMixerDevice *device)
{
g_return_val_if_fail (MATE_MIXER_IS_PULSE_DEVICE (device), NULL);
- return MATE_MIXER_PULSE_DEVICE (device)->priv->profiles;
+ return (const GList *) MATE_MIXER_PULSE_DEVICE (device)->priv->profiles;
}
-MateMixerDeviceProfile *
+MateMixerProfile *
mate_mixer_pulse_device_get_active_profile (MateMixerDevice *device)
{
g_return_val_if_fail (MATE_MIXER_IS_PULSE_DEVICE (device), NULL);
- return MATE_MIXER_PULSE_DEVICE (device)->priv->active_profile;
+ return MATE_MIXER_PULSE_DEVICE (device)->priv->profile;
}
gboolean
-mate_mixer_pulse_device_set_active_profile (MateMixerDevice *device,
- MateMixerDeviceProfile *profile)
+mate_mixer_pulse_device_set_active_profile (MateMixerDevice *device, const gchar *name)
{
+ gboolean ret;
+ MateMixerPulseDevicePrivate *priv;
+
g_return_val_if_fail (MATE_MIXER_IS_PULSE_DEVICE (device), FALSE);
- g_return_val_if_fail (MATE_MIXER_IS_DEVICE_PROFILE (profile), FALSE);
+ g_return_val_if_fail (name != NULL, FALSE);
- // TODO
- // pa_context_set_card_profile_by_index ()
- return TRUE;
+ priv = MATE_MIXER_PULSE_DEVICE (device)->priv;
+ ret = mate_mixer_pulse_connection_set_card_profile (priv->connection,
+ priv->name,
+ name);
+
+ // XXX decide to either confirm the change during the connection call or
+ // wait for a notification from Pulse
+/*
+ if (ret) {
+ if (priv->profile)
+ g_object_unref (priv->profile);
+
+ priv->profile = g_object_ref (profile);
+
+ g_object_notify_by_pspec (
+ G_OBJECT (device),
+ properties[PROP_ACTIVE_PROFILE]);
+ }
+*/
+ return ret;
}
diff --git a/backends/pulse/pulse-device.h b/backends/pulse/pulse-device.h
index ab997fe..896b02b 100644
--- a/backends/pulse/pulse-device.h
+++ b/backends/pulse/pulse-device.h
@@ -22,10 +22,12 @@
#include <glib-object.h>
#include <libmatemixer/matemixer-device.h>
-#include <libmatemixer/matemixer-device-profile.h>
+#include <libmatemixer/matemixer-profile.h>
#include <pulse/pulseaudio.h>
+#include "pulse-connection.h"
+
G_BEGIN_DECLS
#define MATE_MIXER_TYPE_PULSE_DEVICE \
@@ -54,26 +56,35 @@ struct _MateMixerPulseDevice
struct _MateMixerPulseDeviceClass
{
- GObjectClass parent;
+ GObjectClass parent;
};
GType mate_mixer_pulse_device_get_type (void) G_GNUC_CONST;
-MateMixerPulseDevice *mate_mixer_pulse_device_new (const pa_card_info *info);
+MateMixerPulseDevice *mate_mixer_pulse_device_new (MateMixerPulseConnection *connection,
+ const pa_card_info *info);
gboolean mate_mixer_pulse_device_update (MateMixerPulseDevice *device,
const pa_card_info *info);
+MateMixerPulseConnection *mate_mixer_pulse_device_get_connection (MateMixerPulseDevice *device);
+
+guint32 mate_mixer_pulse_device_get_index (MateMixerPulseDevice *device);
+
/* Interface implementation */
-const GList *mate_mixer_pulse_device_list_tracks (MateMixerDevice *device);
+const gchar *mate_mixer_pulse_device_get_name (MateMixerDevice *device);
+const gchar *mate_mixer_pulse_device_get_description (MateMixerDevice *device);
+const gchar *mate_mixer_pulse_device_get_icon (MateMixerDevice *device);
+
+const GList *mate_mixer_pulse_device_list_streams (MateMixerDevice *device);
-const GList *mate_mixer_pulse_device_get_ports (MateMixerDevice *device);
-const GList *mate_mixer_pulse_device_get_profiles (MateMixerDevice *device);
+const GList *mate_mixer_pulse_device_list_ports (MateMixerDevice *device);
+const GList *mate_mixer_pulse_device_list_profiles (MateMixerDevice *device);
-MateMixerDeviceProfile *mate_mixer_pulse_device_get_active_profile (MateMixerDevice *device);
+MateMixerProfile *mate_mixer_pulse_device_get_active_profile (MateMixerDevice *device);
gboolean mate_mixer_pulse_device_set_active_profile (MateMixerDevice *device,
- MateMixerDeviceProfile *profile);
+ const gchar *name);
G_END_DECLS
diff --git a/backends/pulse/pulse-track.c b/backends/pulse/pulse-sink-input.c
index e69de29..e69de29 100644
--- a/backends/pulse/pulse-track.c
+++ b/backends/pulse/pulse-sink-input.c
diff --git a/backends/pulse/pulse-track.h b/backends/pulse/pulse-sink-input.h
index e69de29..e69de29 100644
--- a/backends/pulse/pulse-track.h
+++ b/backends/pulse/pulse-sink-input.h
diff --git a/backends/pulse/pulse-sink.c b/backends/pulse/pulse-sink.c
new file mode 100644
index 0000000..64eb4c1
--- /dev/null
+++ b/backends/pulse/pulse-sink.c
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2014 Michal Ratajsky <[email protected]>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the licence, or (at your option) any later version.
+ *
+ * This 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <glib.h>
+#include <glib-object.h>
+
+#include <libmatemixer/matemixer-stream.h>
+#include <libmatemixer/matemixer-port.h>
+
+#include <pulse/pulseaudio.h>
+
+#include "pulse-connection.h"
+#include "pulse-stream.h"
+#include "pulse-sink.h"
+
+struct _MateMixerPulseSinkPrivate
+{
+ guint32 index_monitor;
+};
+
+G_DEFINE_TYPE (MateMixerPulseSink, mate_mixer_pulse_sink, MATE_MIXER_TYPE_PULSE_STREAM);
+
+static void
+mate_mixer_pulse_sink_init (MateMixerPulseSink *sink)
+{
+ sink->priv = G_TYPE_INSTANCE_GET_PRIVATE (sink,
+ MATE_MIXER_TYPE_PULSE_SINK,
+ MateMixerPulseSinkPrivate);
+}
+
+static void
+mate_mixer_pulse_sink_class_init (MateMixerPulseSinkClass *klass)
+{
+ MateMixerPulseStreamClass *stream_class;
+
+ stream_class = MATE_MIXER_PULSE_STREAM_CLASS (klass);
+
+ stream_class->set_volume = mate_mixer_pulse_sink_set_volume;
+ stream_class->set_mute = mate_mixer_pulse_sink_set_mute;
+
+ g_type_class_add_private (G_OBJECT (klass), sizeof (MateMixerPulseSinkPrivate));
+}
+
+MateMixerPulseStream *
+mate_mixer_pulse_sink_new (MateMixerPulseConnection *connection, const pa_sink_info *info)
+{
+ MateMixerPulseStream *stream;
+ GList *ports = NULL;
+ int i;
+
+ for (i = 0; i < info->n_ports; i++) {
+ MateMixerPort *port;
+ MateMixerPortStatus status = MATE_MIXER_PORT_UNKNOWN_STATUS;
+ pa_sink_port_info *p_info = info->ports[i];
+
+#if PA_CHECK_VERSION(2, 0, 0)
+ switch (p_info->available) {
+ case PA_PORT_AVAILABLE_YES:
+ status = MATE_MIXER_PORT_AVAILABLE;
+ break;
+ case PA_PORT_AVAILABLE_NO:
+ status = MATE_MIXER_PORT_UNAVAILABLE;
+ break;
+ default:
+ break;
+ }
+#endif
+ port = mate_mixer_port_new (p_info->name,
+ p_info->description,
+ NULL,
+ p_info->priority,
+ status);
+
+ ports = g_list_prepend (ports, port);
+ }
+
+ if (ports)
+ ports = g_list_reverse (ports);
+
+ stream = g_object_new (MATE_MIXER_TYPE_PULSE_STREAM,
+ "connection", connection,
+ "index", info->index,
+ "name", info->name,
+ "description", info->description,
+ "channels", info->channel_map.channels,
+ "mute", info->mute ? TRUE : FALSE,
+ NULL);
+
+ return stream;
+}
+
+gboolean
+mate_mixer_pulse_sink_set_volume (MateMixerStream *stream, guint32 volume)
+{
+ g_return_val_if_fail (MATE_MIXER_IS_PULSE_STREAM (stream), FALSE);
+
+/*
+ return mate_mixer_pulse_connection_set_sink_volume (mate_mixer_pulse_stream_get_connection (MATE_MIXER_PULSE_STREAM (stream)),
+ volume);
+*/
+ return TRUE;
+}
+
+gboolean
+mate_mixer_pulse_sink_set_mute (MateMixerStream *stream, gboolean mute)
+{
+ MateMixerPulseStream *pulse_stream;
+
+ g_return_val_if_fail (MATE_MIXER_IS_PULSE_STREAM (stream), FALSE);
+
+ pulse_stream = MATE_MIXER_PULSE_STREAM (stream);
+
+ return mate_mixer_pulse_connection_set_sink_mute (mate_mixer_pulse_stream_get_connection (pulse_stream),
+ mate_mixer_pulse_stream_get_index (pulse_stream),
+ mute);
+}
diff --git a/backends/pulse/pulse-sink.h b/backends/pulse/pulse-sink.h
new file mode 100644
index 0000000..ef2608f
--- /dev/null
+++ b/backends/pulse/pulse-sink.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2014 Michal Ratajsky <[email protected]>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the licence, or (at your option) any later version.
+ *
+ * This 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef MATEMIXER_PULSE_SINK_H
+#define MATEMIXER_PULSE_SINK_H
+
+#include <glib.h>
+#include <glib-object.h>
+
+#include <libmatemixer/matemixer-stream.h>
+
+#include <pulse/pulseaudio.h>
+
+G_BEGIN_DECLS
+
+#define MATE_MIXER_TYPE_PULSE_SINK \
+ (mate_mixer_pulse_sink_get_type ())
+#define MATE_MIXER_PULSE_SINK(o) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((o), MATE_MIXER_TYPE_PULSE_SINK, MateMixerPulseSink))
+#define MATE_MIXER_IS_PULSE_SINK(o) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((o), MATE_MIXER_TYPE_PULSE_SINK))
+#define MATE_MIXER_PULSE_SINK_CLASS(k) \
+ (G_TYPE_CHECK_CLASS_CAST ((k), MATE_MIXER_TYPE_PULSE_SINK, MateMixerPulseSinkClass))
+#define MATE_MIXER_IS_PULSE_SINK_CLASS(k) \
+ (G_TYPE_CLASS_CHECK_CLASS_TYPE ((k), MATE_MIXER_TYPE_PULSE_SINK))
+#define MATE_MIXER_PULSE_SINK_GET_CLASS(o) \
+ (G_TYPE_INSTANCE_GET_CLASS ((o), MATE_MIXER_TYPE_PULSE_SINK, MateMixerPulseSinkClass))
+
+typedef struct _MateMixerPulseSink MateMixerPulseSink;
+typedef struct _MateMixerPulseSinkClass MateMixerPulseSinkClass;
+typedef struct _MateMixerPulseSinkPrivate MateMixerPulseSinkPrivate;
+
+struct _MateMixerPulseSink
+{
+ GObject parent;
+
+ MateMixerPulseSinkPrivate *priv;
+};
+
+struct _MateMixerPulseSinkClass
+{
+ GObjectClass parent;
+};
+
+GType mate_mixer_pulse_sink_get_type (void) G_GNUC_CONST;
+
+MateMixerPulseStream *mate_mixer_pulse_sink_new (MateMixerPulseConnection *connection,
+ const pa_sink_info *info);
+
+gboolean mate_mixer_pulse_sink_set_volume (MateMixerStream *stream, guint32 volume);
+gboolean mate_mixer_pulse_sink_set_mute (MateMixerStream *stream, gboolean mute);
+
+G_END_DECLS
+
+#endif /* MATEMIXER_PULSE_SINK_H */
diff --git a/backends/pulse/pulse-source-output.c b/backends/pulse/pulse-source-output.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/backends/pulse/pulse-source-output.c
diff --git a/backends/pulse/pulse-source-output.h b/backends/pulse/pulse-source-output.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/backends/pulse/pulse-source-output.h
diff --git a/backends/pulse/pulse-source.c b/backends/pulse/pulse-source.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/backends/pulse/pulse-source.c
diff --git a/backends/pulse/pulse-source.h b/backends/pulse/pulse-source.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/backends/pulse/pulse-source.h
diff --git a/backends/pulse/pulse-stream.c b/backends/pulse/pulse-stream.c
new file mode 100644
index 0000000..a9e01d1
--- /dev/null
+++ b/backends/pulse/pulse-stream.c
@@ -0,0 +1,259 @@
+/*
+ * Copyright (C) 2014 Michal Ratajsky <[email protected]>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the licence, or (at your option) any later version.
+ *
+ * This 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <glib.h>
+#include <glib-object.h>
+
+#include <libmatemixer/matemixer-stream.h>
+#include <libmatemixer/matemixer-port.h>
+
+#include <pulse/pulseaudio.h>
+
+#include "pulse-connection.h"
+#include "pulse-stream.h"
+
+struct _MateMixerPulseStreamPrivate
+{
+ guint32 index;
+ gchar *name;
+ gchar *description;
+ gchar *icon;
+ guint channels;
+ gboolean mute;
+ GList *ports;
+ MateMixerPort *port;
+ MateMixerPulseConnection *connection;
+};
+
+enum
+{
+ PROP_0,
+ PROP_INDEX,
+ PROP_NAME,
+ PROP_DESCRIPTION,
+ PROP_ICON,
+ PROP_CHANNELS,
+ PROP_VOLUME,
+ PROP_MUTE,
+ N_PROPERTIES
+};
+
+static void mate_mixer_stream_interface_init (MateMixerStreamInterface *iface);
+static void mate_mixer_pulse_stream_class_init (MateMixerPulseStreamClass *klass);
+static void mate_mixer_pulse_stream_init (MateMixerPulseStream *stream);
+static void mate_mixer_pulse_stream_dispose (GObject *object);
+static void mate_mixer_pulse_stream_finalize (GObject *object);
+
+G_DEFINE_ABSTRACT_TYPE_WITH_CODE (MateMixerPulseStream, mate_mixer_pulse_stream, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (MATE_MIXER_TYPE_STREAM,
+ mate_mixer_stream_interface_init))
+
+static void
+mate_mixer_stream_interface_init (MateMixerStreamInterface *iface)
+{
+ iface->get_name = mate_mixer_pulse_stream_get_name;
+ iface->get_description = mate_mixer_pulse_stream_get_description;
+ iface->get_icon = mate_mixer_pulse_stream_get_icon;
+ iface->list_ports = mate_mixer_pulse_stream_list_ports;
+}
+
+static void
+mate_mixer_pulse_stream_get_property (GObject *object,
+ guint param_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ MateMixerPulseStream *stream;
+
+ stream = MATE_MIXER_PULSE_STREAM (object);
+
+ switch (param_id) {
+ case PROP_NAME:
+ g_value_set_string (value, stream->priv->name);
+ break;
+ case PROP_DESCRIPTION:
+ g_value_set_string (value, stream->priv->description);
+ break;
+ case PROP_ICON:
+ g_value_set_string (value, stream->priv->icon);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+ break;
+ }
+}
+
+static void
+mate_mixer_pulse_stream_set_property (GObject *object,
+ guint param_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ MateMixerPulseStream *stream;
+
+ stream = MATE_MIXER_PULSE_STREAM (object);
+
+ switch (param_id) {
+ case PROP_NAME:
+ stream->priv->name = g_strdup (g_value_get_string (value));
+ break;
+ case PROP_DESCRIPTION:
+ stream->priv->description = g_strdup (g_value_get_string (value));
+ break;
+ case PROP_ICON:
+ stream->priv->icon = g_strdup (g_value_get_string (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+ break;
+ }
+}
+
+static void
+mate_mixer_pulse_stream_class_init (MateMixerPulseStreamClass *klass)
+{
+ GObjectClass *object_class;
+
+ object_class = G_OBJECT_CLASS (klass);
+ object_class->dispose = mate_mixer_pulse_stream_dispose;
+ object_class->finalize = mate_mixer_pulse_stream_finalize;
+ object_class->get_property = mate_mixer_pulse_stream_get_property;
+ object_class->set_property = mate_mixer_pulse_stream_set_property;
+
+ g_object_class_override_property (object_class, PROP_NAME, "name");
+ g_object_class_override_property (object_class, PROP_DESCRIPTION, "description");
+ g_object_class_override_property (object_class, PROP_ICON, "icon");
+
+ g_type_class_add_private (object_class, sizeof (MateMixerPulseStreamPrivate));
+}
+
+static void
+mate_mixer_pulse_stream_init (MateMixerPulseStream *stream)
+{
+ stream->priv = G_TYPE_INSTANCE_GET_PRIVATE (
+ stream,
+ MATE_MIXER_TYPE_PULSE_STREAM,
+ MateMixerPulseStreamPrivate);
+}
+
+static void
+mate_mixer_pulse_stream_dispose (GObject *object)
+{
+ MateMixerPulseStream *stream;
+
+ stream = MATE_MIXER_PULSE_STREAM (object);
+
+ if (stream->priv->ports) {
+ g_list_free_full (stream->priv->ports, g_object_unref);
+ stream->priv->ports = NULL;
+ }
+ g_clear_object (&stream->priv->connection);
+
+ G_OBJECT_CLASS (mate_mixer_pulse_stream_parent_class)->dispose (object);
+}
+
+static void
+mate_mixer_pulse_stream_finalize (GObject *object)
+{
+ MateMixerPulseStream *stream;
+
+ stream = MATE_MIXER_PULSE_STREAM (object);
+
+ g_free (stream->priv->name);
+ g_free (stream->priv->description);
+ g_free (stream->priv->icon);
+
+ G_OBJECT_CLASS (mate_mixer_pulse_stream_parent_class)->finalize (object);
+}
+
+MateMixerPulseConnection *
+mate_mixer_pulse_stream_get_connection (MateMixerPulseStream *stream)
+{
+ g_return_val_if_fail (MATE_MIXER_IS_PULSE_STREAM (stream), NULL);
+
+ return stream->priv->connection;
+}
+
+guint32
+mate_mixer_pulse_stream_get_index (MateMixerPulseStream *stream)
+{
+ g_return_val_if_fail (MATE_MIXER_IS_PULSE_STREAM (stream), FALSE);
+
+ return stream->priv->index;
+}
+
+const gchar *
+mate_mixer_pulse_stream_get_name (MateMixerStream *stream)
+{
+ g_return_val_if_fail (MATE_MIXER_IS_PULSE_STREAM (stream), FALSE);
+
+ return MATE_MIXER_PULSE_STREAM (stream)->priv->name;
+}
+
+const gchar *
+mate_mixer_pulse_stream_get_description (MateMixerStream *stream)
+{
+ g_return_val_if_fail (MATE_MIXER_IS_PULSE_STREAM (stream), FALSE);
+
+ return MATE_MIXER_PULSE_STREAM (stream)->priv->description;
+}
+
+const gchar *
+mate_mixer_pulse_stream_get_icon (MateMixerStream *stream)
+{
+ g_return_val_if_fail (MATE_MIXER_IS_PULSE_STREAM (stream), FALSE);
+
+ return MATE_MIXER_PULSE_STREAM (stream)->priv->icon;
+}
+
+MateMixerPort *
+mate_mixer_pulse_stream_get_active_port (MateMixerStream *stream)
+{
+ g_return_val_if_fail (MATE_MIXER_IS_PULSE_STREAM (stream), FALSE);
+
+ return MATE_MIXER_PULSE_STREAM (stream)->priv->port;
+}
+
+const GList *
+mate_mixer_pulse_stream_list_ports (MateMixerStream *stream)
+{
+ g_return_val_if_fail (MATE_MIXER_IS_PULSE_STREAM (stream), FALSE);
+
+ return MATE_MIXER_PULSE_STREAM (stream)->priv->ports;
+}
+
+gboolean
+mate_mixer_pulse_stream_set_volume (MateMixerStream *stream, guint32 volume)
+{
+ g_return_val_if_fail (MATE_MIXER_IS_PULSE_STREAM (stream), FALSE);
+
+ return MATE_MIXER_PULSE_STREAM_GET_CLASS (stream)->set_volume (stream, volume);
+}
+
+gboolean
+mate_mixer_pulse_stream_set_mute (MateMixerStream *stream, gboolean mute)
+{
+ g_return_val_if_fail (MATE_MIXER_IS_PULSE_STREAM (stream), FALSE);
+
+ return MATE_MIXER_PULSE_STREAM_GET_CLASS (stream)->set_mute (stream, mute);
+}
+
+gboolean
+mate_mixer_pulse_stream_set_active_port (MateMixerStream *stream, MateMixerPort *port)
+{
+ return TRUE;
+}
diff --git a/backends/pulse/pulse-stream.h b/backends/pulse/pulse-stream.h
new file mode 100644
index 0000000..3d3ee78
--- /dev/null
+++ b/backends/pulse/pulse-stream.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2014 Michal Ratajsky <[email protected]>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the licence, or (at your option) any later version.
+ *
+ * This 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef MATEMIXER_PULSE_STREAM_H
+#define MATEMIXER_PULSE_STREAM_H
+
+#include <glib.h>
+#include <glib-object.h>
+
+#include <libmatemixer/matemixer-stream.h>
+#include <libmatemixer/matemixer-port.h>
+
+#include <pulse/pulseaudio.h>
+
+#include "pulse-connection.h"
+
+G_BEGIN_DECLS
+
+#define MATE_MIXER_TYPE_PULSE_STREAM \
+ (mate_mixer_pulse_stream_get_type ())
+#define MATE_MIXER_PULSE_STREAM(o) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((o), MATE_MIXER_TYPE_PULSE_STREAM, MateMixerPulseStream))
+#define MATE_MIXER_IS_PULSE_STREAM(o) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((o), MATE_MIXER_TYPE_PULSE_STREAM))
+#define MATE_MIXER_PULSE_STREAM_CLASS(k) \
+ (G_TYPE_CHECK_CLASS_CAST ((k), MATE_MIXER_TYPE_PULSE_STREAM, MateMixerPulseStreamClass))
+#define MATE_MIXER_IS_PULSE_STREAM_CLASS(k) \
+ (G_TYPE_CLASS_CHECK_CLASS_TYPE ((k), MATE_MIXER_TYPE_PULSE_STREAM))
+#define MATE_MIXER_PULSE_STREAM_GET_CLASS(o) \
+ (G_TYPE_INSTANCE_GET_CLASS ((o), MATE_MIXER_TYPE_PULSE_STREAM, MateMixerPulseStreamClass))
+
+typedef struct _MateMixerPulseStream MateMixerPulseStream;
+typedef struct _MateMixerPulseStreamClass MateMixerPulseStreamClass;
+typedef struct _MateMixerPulseStreamPrivate MateMixerPulseStreamPrivate;
+
+struct _MateMixerPulseStream
+{
+ GObject parent;
+
+ MateMixerPulseStreamPrivate *priv;
+};
+
+struct _MateMixerPulseStreamClass
+{
+ GObjectClass parent;
+
+ gboolean (*set_volume) (MateMixerStream *stream, guint32 volume);
+ gboolean (*set_mute) (MateMixerStream *stream, gboolean mute);
+};
+
+GType mate_mixer_pulse_stream_get_type (void) G_GNUC_CONST;
+
+MateMixerPulseConnection * mate_mixer_pulse_stream_get_connection (MateMixerPulseStream *stream);
+guint32 mate_mixer_pulse_stream_get_index (MateMixerPulseStream *stream);
+
+/* Interface implementation */
+const gchar * mate_mixer_pulse_stream_get_name (MateMixerStream *stream);
+const gchar * mate_mixer_pulse_stream_get_description (MateMixerStream *stream);
+const gchar * mate_mixer_pulse_stream_get_icon (MateMixerStream *stream);
+
+MateMixerPort * mate_mixer_pulse_stream_get_active_port (MateMixerStream *stream);
+gboolean mate_mixer_pulse_stream_set_active_port (MateMixerStream *stream,
+ MateMixerPort *port);
+const GList * mate_mixer_pulse_stream_list_ports (MateMixerStream *stream);
+gboolean mate_mixer_pulse_stream_set_mute (MateMixerStream *stream,
+ gboolean mute);
+gboolean mate_mixer_pulse_stream_set_volume (MateMixerStream *stream,
+ guint32 volume);
+
+G_END_DECLS
+
+#endif /* MATEMIXER_PULSE_STREAM_H */
diff --git a/backends/pulse/pulse.c b/backends/pulse/pulse.c
index d306577..59c5935 100644
--- a/backends/pulse/pulse.c
+++ b/backends/pulse/pulse.c
@@ -17,8 +17,6 @@
#include <glib.h>
#include <glib-object.h>
-#include <sys/types.h>
-#include <unistd.h>
#include <libmatemixer/matemixer-backend.h>
#include <libmatemixer/matemixer-backend-module.h>
@@ -27,47 +25,59 @@
#include <pulse/thread-mainloop.h>
#include "pulse.h"
+#include "pulse-connection.h"
#include "pulse-device.h"
+#include "pulse-stream.h"
+#include "pulse-sink.h"
#define BACKEND_NAME "PulseAudio"
#define BACKEND_PRIORITY 0
struct _MateMixerPulsePrivate
{
- pa_threaded_mainloop *mainloop;
- pa_context *context;
- GHashTable *devices;
+ GHashTable *devices;
+ gboolean lists_loaded;
+ GHashTable *cards;
+ GHashTable *sinks;
+ GHashTable *sink_inputs;
+ GHashTable *sources;
+ GHashTable *source_outputs;
+ MateMixerPulseConnection *connection;
};
/* Support function for dynamic loading of the backend module */
void backend_module_init (GTypeModule *module);
-const MateMixerBackendModuleInfo *backend_module_get_info (void);
+const MateMixerBackendInfo *backend_module_get_info (void);
-static void mate_mixer_backend_interface_init (MateMixerBackendInterface *iface);
+static void mate_mixer_backend_interface_init (MateMixerBackendInterface *iface);
-static void pulse_card_info_cb (pa_context *c,
- const pa_card_info *info,
- int eol,
- void *userdata);
+static void pulse_card_cb (MateMixerPulseConnection *connection,
+ const pa_card_info *info,
+ MateMixerPulse *pulse);
-static void pulse_card_update (MateMixerPulse *pulse, const pa_card_info *i);
+static void pulse_sink_cb (MateMixerPulseConnection *connection,
+ const pa_sink_info *info,
+ MateMixerPulse *pulse);
-static void pulse_state_cb (pa_context *c, void *userdata);
+static void pulse_sink_input_cb (MateMixerPulseConnection *connection,
+ const pa_sink_input_info *info,
+ MateMixerPulse *pulse);
-static void pulse_subscribe_cb (pa_context *c,
- pa_subscription_event_type_t t,
- uint32_t idx,
- void *userdata);
+static void pulse_source_cb (MateMixerPulseConnection *connection,
+ const pa_source_info *info,
+ MateMixerPulse *pulse);
-static gchar *pulse_get_app_name (void);
+static void pulse_source_output_cb (MateMixerPulseConnection *connection,
+ const pa_source_output_info *info,
+ MateMixerPulse *pulse);
G_DEFINE_DYNAMIC_TYPE_EXTENDED (MateMixerPulse, mate_mixer_pulse,
G_TYPE_OBJECT, 0,
G_IMPLEMENT_INTERFACE_DYNAMIC (MATE_MIXER_TYPE_BACKEND,
mate_mixer_backend_interface_init))
-static MateMixerBackendModuleInfo info;
+static MateMixerBackendInfo info;
void
backend_module_init (GTypeModule *module)
@@ -77,10 +87,10 @@ backend_module_init (GTypeModule *module)
info.name = BACKEND_NAME;
info.priority = BACKEND_PRIORITY;
info.g_type = MATE_MIXER_TYPE_PULSE;
- info.backend_type = MATE_MIXER_BACKEND_TYPE_PULSE;
+ info.backend_type = MATE_MIXER_BACKEND_PULSE;
}
-const MateMixerBackendModuleInfo *
+const MateMixerBackendInfo *
backend_module_get_info (void)
{
return &info;
@@ -107,18 +117,70 @@ mate_mixer_pulse_init (MateMixerPulse *pulse)
g_direct_equal,
NULL,
g_object_unref);
+
+ pulse->priv->cards = g_hash_table_new_full (
+ g_direct_hash,
+ g_direct_equal,
+ NULL,
+ g_object_unref);
+ pulse->priv->sinks = g_hash_table_new_full (
+ g_direct_hash,
+ g_direct_equal,
+ NULL,
+ g_object_unref);
+ pulse->priv->sink_inputs = g_hash_table_new_full (
+ g_direct_hash,
+ g_direct_equal,
+ NULL,
+ g_object_unref);
+ pulse->priv->sources = g_hash_table_new_full (
+ g_direct_hash,
+ g_direct_equal,
+ NULL,
+ g_object_unref);
+ pulse->priv->source_outputs = g_hash_table_new_full (
+ g_direct_hash,
+ g_direct_equal,
+ NULL,
+ g_object_unref);
}
static void
-mate_mixer_pulse_finalize (GObject *object)
+mate_mixer_pulse_dispose (GObject *object)
{
MateMixerPulse *pulse;
pulse = MATE_MIXER_PULSE (object);
- g_hash_table_destroy (pulse->priv->devices);
+ if (pulse->priv->devices) {
+ g_hash_table_destroy (pulse->priv->devices);
+ pulse->priv->devices = NULL;
+ }
+
+ if (pulse->priv->cards) {
+ g_hash_table_destroy (pulse->priv->cards);
+ pulse->priv->cards = NULL;
+ }
+ if (pulse->priv->sinks) {
+ g_hash_table_destroy (pulse->priv->sinks);
+ pulse->priv->devices = NULL;
+ }
+ if (pulse->priv->sink_inputs) {
+ g_hash_table_destroy (pulse->priv->sink_inputs);
+ pulse->priv->devices = NULL;
+ }
+ if (pulse->priv->sources) {
+ g_hash_table_destroy (pulse->priv->sources);
+ pulse->priv->devices = NULL;
+ }
+ if (pulse->priv->source_outputs) {
+ g_hash_table_destroy (pulse->priv->source_outputs);
+ pulse->priv->source_outputs = NULL;
+ }
+
+ g_clear_object (&pulse->priv->connection);
- G_OBJECT_CLASS (mate_mixer_pulse_parent_class)->finalize (object);
+ G_OBJECT_CLASS (mate_mixer_pulse_parent_class)->dispose (object);
}
static void
@@ -127,7 +189,7 @@ mate_mixer_pulse_class_init (MateMixerPulseClass *klass)
GObjectClass *object_class;
object_class = G_OBJECT_CLASS (klass);
- object_class->finalize = mate_mixer_pulse_finalize;
+ object_class->dispose = mate_mixer_pulse_dispose;
g_type_class_add_private (object_class, sizeof (MateMixerPulsePrivate));
}
@@ -141,83 +203,48 @@ mate_mixer_pulse_class_finalize (MateMixerPulseClass *klass)
gboolean
mate_mixer_pulse_open (MateMixerBackend *backend)
{
- int ret;
- gchar *app_name;
- MateMixerPulse *pulse;
+ MateMixerPulse *pulse;
+ MateMixerPulseConnection *connection;
- g_return_val_if_fail (MATE_MIXER_IS_BACKEND (backend), FALSE);
+ g_return_val_if_fail (MATE_MIXER_IS_PULSE (backend), FALSE);
pulse = MATE_MIXER_PULSE (backend);
- g_return_val_if_fail (pulse->priv->mainloop == NULL, FALSE);
+ g_return_val_if_fail (pulse->priv->connection == NULL, FALSE);
- pulse->priv->mainloop = pa_threaded_mainloop_new ();
- if (G_UNLIKELY (pulse->priv->mainloop == NULL)) {
- g_warning ("Failed to created PulseAudio main loop");
+ connection = mate_mixer_pulse_connection_new (NULL, NULL);
+ if (G_UNLIKELY (connection == NULL)) {
+ g_object_unref (connection);
return FALSE;
}
- app_name = pulse_get_app_name ();
-
- pulse->priv->context = pa_context_new (
- pa_threaded_mainloop_get_api (pulse->priv->mainloop),
- app_name);
-
- g_free (app_name);
-
- if (G_UNLIKELY (pulse->priv->context == NULL)) {
- g_warning ("Failed to created PulseAudio context");
-
- pa_threaded_mainloop_free (pulse->priv->mainloop);
- pulse->priv->mainloop = NULL;
- return FALSE;
- }
-
- // XXX: investigate PA_CONTEXT_NOFAIL
- ret = pa_context_connect (pulse->priv->context, NULL, PA_CONTEXT_NOFLAGS, NULL);
- if (ret < 0) {
- g_warning ("Failed to connect to PulseAudio server: %s", pa_strerror (ret));
-
- pa_context_unref (pulse->priv->context);
- pa_threaded_mainloop_free (pulse->priv->mainloop);
-
- pulse->priv->context = NULL;
- pulse->priv->mainloop = NULL;
+ if (!mate_mixer_pulse_connection_connect (connection)) {
+ g_object_unref (connection);
return FALSE;
}
- g_debug ("Connected to PulseAudio server");
-
- pa_threaded_mainloop_lock (pulse->priv->mainloop);
-
- pa_context_set_state_callback (pulse->priv->context,
- pulse_state_cb,
- backend);
- pa_context_set_subscribe_callback (pulse->priv->context,
- pulse_subscribe_cb,
- backend);
-
- ret = pa_threaded_mainloop_start (pulse->priv->mainloop);
- if (ret < 0) {
- g_warning ("Failed to start PulseAudio main loop: %s", pa_strerror (ret));
-
- pa_threaded_mainloop_unlock (pulse->priv->mainloop);
-
- pa_context_unref (pulse->priv->context);
- pa_threaded_mainloop_free (pulse->priv->mainloop);
-
- pulse->priv->context = NULL;
- pulse->priv->mainloop = NULL;
- return FALSE;
- }
-
- while (pa_context_get_state (pulse->priv->context) != PA_CONTEXT_READY) {
- // XXX this will get stuck if connection fails
- pa_threaded_mainloop_wait (pulse->priv->mainloop);
- }
-
- pa_threaded_mainloop_unlock (pulse->priv->mainloop);
-
+ g_signal_connect (connection,
+ "list-item-card",
+ G_CALLBACK (pulse_card_cb),
+ pulse);
+ g_signal_connect (connection,
+ "list-item-sink",
+ G_CALLBACK (pulse_sink_cb),
+ pulse);
+ g_signal_connect (connection,
+ "list-item-sink-input",
+ G_CALLBACK (pulse_sink_input_cb),
+ pulse);
+ g_signal_connect (connection,
+ "list-item-source",
+ G_CALLBACK (pulse_source_cb),
+ pulse);
+ g_signal_connect (connection,
+ "list-item-source-output",
+ G_CALLBACK (pulse_source_output_cb),
+ pulse);
+
+ pulse->priv->connection = connection;
return TRUE;
}
@@ -226,140 +253,118 @@ mate_mixer_pulse_close (MateMixerBackend *backend)
{
MateMixerPulse *pulse;
- g_return_if_fail (MATE_MIXER_IS_BACKEND (backend));
+ g_return_if_fail (MATE_MIXER_IS_PULSE (backend));
pulse = MATE_MIXER_PULSE (backend);
- g_return_if_fail (pulse->priv->mainloop != NULL);
-
- pa_threaded_mainloop_stop (pulse->priv->mainloop);
+ g_clear_object (&pulse->priv->connection);
+}
- pa_context_unref (pulse->priv->context);
- pa_threaded_mainloop_free (pulse->priv->mainloop);
+static gboolean
+pulse_load_lists (MateMixerPulse *pulse)
+{
+ /* The Pulse server is queried for initial lists, each of the functions
+ * waits until the list is available and then continues with the next.
+ *
+ * One possible improvement would be to load the lists asynchronously right
+ * after we connect to Pulse and when the application calls one of the
+ * list_* () functions, check if the initial list is already available and
+ * eventually wait until it's available. However, this would be
+ * tricky with the way the Pulse API is currently used and might not
+ * be beneficial at all.
+ */
+
+ // XXX figure out how to handle server reconnects, ideally everything
+ // we know should be ditched and read again asynchronously and
+ // the user should only be notified about actual differences
+ // from the state before we were disconnected
+
+ // mate_mixer_pulse_connection_get_server_info (pulse->priv->connection);
+ mate_mixer_pulse_connection_get_card_list (pulse->priv->connection);
+ mate_mixer_pulse_connection_get_sink_list (pulse->priv->connection);
+ mate_mixer_pulse_connection_get_sink_input_list (pulse->priv->connection);
+ mate_mixer_pulse_connection_get_source_list (pulse->priv->connection);
+ mate_mixer_pulse_connection_get_source_output_list (pulse->priv->connection);
- pulse->priv->context = NULL;
- pulse->priv->mainloop = NULL;
+ return TRUE;
}
GList *
mate_mixer_pulse_list_devices (MateMixerBackend *backend)
{
- MateMixerPulse *pulse;
- pa_operation *o;
+ MateMixerPulse *pulse;
+ GList *list;
- g_return_val_if_fail (MATE_MIXER_IS_BACKEND (backend), NULL);
+ g_return_val_if_fail (MATE_MIXER_IS_PULSE (backend), NULL);
pulse = MATE_MIXER_PULSE (backend);
- pa_threaded_mainloop_lock (pulse->priv->mainloop);
+ if (!pulse->priv->lists_loaded)
+ pulse_load_lists (pulse);
- o = pa_context_get_card_info_list (pulse->priv->context, pulse_card_info_cb, pulse);
- if (o == NULL) {
- g_warning ("Failed to read card list: %s",
- pa_strerror (pa_context_errno (pulse->priv->context)));
-
- pa_threaded_mainloop_unlock (pulse->priv->mainloop);
- return NULL;
- }
+ list = g_hash_table_get_values (pulse->priv->devices);
- while (pa_operation_get_state (o) == PA_OPERATION_RUNNING)
- pa_threaded_mainloop_wait (pulse->priv->mainloop);
-
- pa_operation_unref (o);
- pa_threaded_mainloop_unlock (pulse->priv->mainloop);
+ g_list_foreach (list, (GFunc) g_object_ref, NULL);
+ return list;
+}
- return g_hash_table_get_values (pulse->priv->devices);
+GList *
+mate_mixer_pulse_list_streams (MateMixerBackend *backend)
+{
+ // TODO
+ return NULL;
}
static void
-pulse_card_info_cb (pa_context *c, const pa_card_info *info, int eol, void *userdata)
+pulse_card_cb (MateMixerPulseConnection *connection,
+ const pa_card_info *info,
+ MateMixerPulse *pulse)
{
- MateMixerPulse *pulse;
-
- pulse = MATE_MIXER_PULSE (userdata);
-
- if (!eol)
- pulse_card_update (pulse, info);
-
- pa_threaded_mainloop_signal (pulse->priv->mainloop, 0);
+ MateMixerPulseDevice *device;
+
+ device = mate_mixer_pulse_device_new (connection, info);
+ if (G_LIKELY (device))
+ g_hash_table_insert (
+ pulse->priv->devices,
+ GINT_TO_POINTER (mate_mixer_pulse_device_get_index (device)),
+ device);
}
static void
-pulse_card_update (MateMixerPulse *pulse, const pa_card_info *info)
+pulse_sink_cb (MateMixerPulseConnection *connection,
+ const pa_sink_info *info,
+ MateMixerPulse *pulse)
{
- gpointer item;
-
- item = g_hash_table_lookup (pulse->priv->devices, GINT_TO_POINTER (info->index));
- if (item) {
- /* The card is already known, just update the fields that may
- * have changed */
- mate_mixer_pulse_device_update (MATE_MIXER_PULSE_DEVICE (item), info);
- } else {
- MateMixerPulseDevice *device = mate_mixer_pulse_device_new (info);
-
- if (G_UNLIKELY (device == NULL))
- g_warning ("Failed to process PulseAudio sound device");
- else
- g_hash_table_insert (
- pulse->priv->devices,
- GINT_TO_POINTER (info->index),
- device);
- }
+ MateMixerPulseStream *stream;
+
+ stream = mate_mixer_pulse_sink_new (connection, info);
+ if (G_LIKELY (stream))
+ g_hash_table_insert (
+ pulse->priv->sinks,
+ GINT_TO_POINTER (mate_mixer_pulse_stream_get_index (stream)),
+ stream);
}
static void
-pulse_state_cb (pa_context *c, void *userdata)
+pulse_sink_input_cb (MateMixerPulseConnection *connection,
+ const pa_sink_input_info *info,
+ MateMixerPulse *pulse)
{
- MateMixerPulse *pulse;
- pulse = MATE_MIXER_PULSE (userdata);
-
- // TODO: handle errors
-
- switch (pa_context_get_state (c)) {
- case PA_CONTEXT_UNCONNECTED:
- break;
- case PA_CONTEXT_CONNECTING:
- break;
- case PA_CONTEXT_AUTHORIZING:
- break;
- case PA_CONTEXT_SETTING_NAME:
- break;
- case PA_CONTEXT_READY:
- break;
- case PA_CONTEXT_FAILED:
- break;
- case PA_CONTEXT_TERMINATED:
- break;
- default:
- break;
- }
-
- pa_threaded_mainloop_signal (pulse->priv->mainloop, FALSE);
}
static void
-pulse_subscribe_cb (pa_context *c,
- pa_subscription_event_type_t t,
- uint32_t idx,
- void *userdata)
+pulse_source_cb (MateMixerPulseConnection *connection,
+ const pa_source_info *info,
+ MateMixerPulse *pulse)
{
- // TODO
+
}
-static gchar *
-pulse_get_app_name (void)
+static void
+pulse_source_output_cb (MateMixerPulseConnection *connection,
+ const pa_source_output_info *info,
+ MateMixerPulse *pulse)
{
- const char *name_app;
- char name_buf[256];
-
- /* Inspired by GStreamer's pulse plugin */
- name_app = g_get_application_name ();
- if (name_app != NULL)
- return g_strdup (name_app);
-
- if (pa_get_binary_name (name_buf, sizeof (name_buf)) != NULL)
- return g_strdup (name_buf);
- return g_strdup_printf ("libmatemixer-%lu", (gulong) getpid ());
}
diff --git a/backends/pulse/pulse.h b/backends/pulse/pulse.h
index 2f8414f..d94a543 100644
--- a/backends/pulse/pulse.h
+++ b/backends/pulse/pulse.h
@@ -54,8 +54,10 @@ struct _MateMixerPulseClass
GType mate_mixer_pulse_get_type (void) G_GNUC_CONST;
+/* Interface implementation */
gboolean mate_mixer_pulse_open (MateMixerBackend *backend);
void mate_mixer_pulse_close (MateMixerBackend *backend);
GList *mate_mixer_pulse_list_devices (MateMixerBackend *backend);
+GList *mate_mixer_pulse_list_streams (MateMixerBackend *backend);
#endif /* MATEMIXER_PULSE_H */
diff --git a/configure.ac b/configure.ac
index fdd632b..e004f47 100644
--- a/configure.ac
+++ b/configure.ac
@@ -138,7 +138,7 @@ backends/null/Makefile
backends/pulse/Makefile
data/Makefile
data/libmatemixer.pc
-doc/Makefile
+docs/Makefile
])
AC_OUTPUT
diff --git a/doc/Makefile.am b/docs/Makefile.am
index 9b582ee..9b582ee 100644
--- a/doc/Makefile.am
+++ b/docs/Makefile.am
diff --git a/libmatemixer/Makefile.am b/libmatemixer/Makefile.am
index a269397..0280b27 100644
--- a/libmatemixer/Makefile.am
+++ b/libmatemixer/Makefile.am
@@ -1,7 +1,6 @@
lib_LTLIBRARIES = libmatemixer.la
AM_CPPFLAGS = \
- $(GLIB_CFLAGS) \
-I$(top_srcdir) \
-I$(top_srcdir)/libmatemixer \
-DG_LOG_DOMAIN=\"libmatemixer\" \
@@ -13,10 +12,12 @@ libmatemixer_include_HEADERS = \
matemixer.h \
matemixer-control.h \
matemixer-device.h \
- matemixer-device-port.h \
- matemixer-device-profile.h \
matemixer-enums.h \
- matemixer-track.h
+ matemixer-port.h \
+ matemixer-profile.h \
+ matemixer-stream.h
+
+libmatemixer_la_CFLAGS = $(GLIB_CFLAGS)
libmatemixer_la_SOURCES = \
matemixer.c \
@@ -24,13 +25,14 @@ libmatemixer_la_SOURCES = \
matemixer-backend.c \
matemixer-backend.h \
matemixer-backend-module.c \
+ matemixer-backend-module.h \
matemixer-control.c \
matemixer-device.c \
- matemixer-device-port.c \
- matemixer-device-profile.c \
matemixer-enum-types.c \
matemixer-enum-types.h \
- matemixer-track.c
+ matemixer-port.c \
+ matemixer-profile.c \
+ matemixer-stream.c
libmatemixer_la_LIBADD = $(GLIB_LIBS)
diff --git a/libmatemixer/matemixer-backend-module.c b/libmatemixer/matemixer-backend-module.c
index 7846359..5ad2836 100644
--- a/libmatemixer/matemixer-backend-module.c
+++ b/libmatemixer/matemixer-backend-module.c
@@ -33,19 +33,40 @@ struct _MateMixerBackendModulePrivate
void (*init) (GTypeModule *type_module);
void (*deinit) (void);
- const MateMixerBackendModuleInfo *(*get_info) (void);
+ const MateMixerBackendInfo *(*get_info) (void);
};
-static gboolean mate_mixer_backend_module_load (GTypeModule *gmodule);
-static void mate_mixer_backend_module_unload (GTypeModule *gmodule);
+static void mate_mixer_backend_module_class_init (MateMixerBackendModuleClass *klass);
+static void mate_mixer_backend_module_init (MateMixerBackendModule *module);
+static void mate_mixer_backend_module_dispose (GObject *object);
+static void mate_mixer_backend_module_finalize (GObject *object);
+
+static gboolean mate_mixer_backend_module_load (GTypeModule *gmodule);
+static void mate_mixer_backend_module_unload (GTypeModule *gmodule);
+
+static void
+mate_mixer_backend_module_class_init (MateMixerBackendModuleClass *klass)
+{
+ GObjectClass *object_class;
+ GTypeModuleClass *module_class;
+
+ object_class = G_OBJECT_CLASS (klass);
+ object_class->dispose = mate_mixer_backend_module_dispose;
+ object_class->finalize = mate_mixer_backend_module_finalize;
+
+ module_class = G_TYPE_MODULE_CLASS (klass);
+ module_class->load = mate_mixer_backend_module_load;
+ module_class->unload = mate_mixer_backend_module_unload;
+
+ g_type_class_add_private (object_class, sizeof (MateMixerBackendModulePrivate));
+}
static void
mate_mixer_backend_module_init (MateMixerBackendModule *module)
{
- module->priv = G_TYPE_INSTANCE_GET_PRIVATE (
- module,
- MATE_MIXER_TYPE_BACKEND_MODULE,
- MateMixerBackendModulePrivate);
+ module->priv = G_TYPE_INSTANCE_GET_PRIVATE (module,
+ MATE_MIXER_TYPE_BACKEND_MODULE,
+ MateMixerBackendModulePrivate);
}
static void
@@ -76,23 +97,6 @@ mate_mixer_backend_module_finalize (GObject *object)
G_OBJECT_CLASS (mate_mixer_backend_module_parent_class)->finalize (object);
}
-static void
-mate_mixer_backend_module_class_init (MateMixerBackendModuleClass *klass)
-{
- GObjectClass *object_class;
- GTypeModuleClass *gtype_class;
-
- object_class = G_OBJECT_CLASS (klass);
- object_class->dispose = mate_mixer_backend_module_dispose;
- object_class->finalize = mate_mixer_backend_module_finalize;
-
- gtype_class = G_TYPE_MODULE_CLASS (klass);
- gtype_class->load = mate_mixer_backend_module_load;
- gtype_class->unload = mate_mixer_backend_module_unload;
-
- g_type_class_add_private (object_class, sizeof (MateMixerBackendModulePrivate));
-}
-
static gboolean
mate_mixer_backend_module_load (GTypeModule *type_module)
{
@@ -101,28 +105,27 @@ mate_mixer_backend_module_load (GTypeModule *type_module)
module = MATE_MIXER_BACKEND_MODULE (type_module);
if (!module->priv->loaded) {
- module->priv->gmodule = g_module_open (
- module->priv->path,
- G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL);
-
+ module->priv->gmodule = g_module_open (module->priv->path,
+ G_MODULE_BIND_LAZY |
+ G_MODULE_BIND_LOCAL);
if (module->priv->gmodule == NULL) {
g_warning ("Failed to load backend module %s: %s",
- module->priv->path,
- g_module_error ());
+ module->priv->path,
+ g_module_error ());
return FALSE;
}
/* Validate library symbols that each backend module must provide */
if (!g_module_symbol (module->priv->gmodule,
- "backend_module_init",
- (gpointer *) &module->priv->init) ||
+ "backend_module_init",
+ (gpointer *) &module->priv->init) ||
!g_module_symbol (module->priv->gmodule,
- "backend_module_get_info",
- (gpointer *) &module->priv->get_info)) {
+ "backend_module_get_info",
+ (gpointer *) &module->priv->get_info)) {
g_warning ("Failed to load backend module %s: %s",
- module->priv->path,
- g_module_error ());
+ module->priv->path,
+ g_module_error ());
g_module_close (module->priv->gmodule);
return FALSE;
@@ -130,8 +133,8 @@ mate_mixer_backend_module_load (GTypeModule *type_module)
/* Optional backend functions */
g_module_symbol (module->priv->gmodule,
- "backend_module_deinit",
- (gpointer *) &module->priv->deinit);
+ "backend_module_deinit",
+ (gpointer *) &module->priv->deinit);
module->priv->init (type_module);
module->priv->loaded = TRUE;
@@ -140,7 +143,7 @@ mate_mixer_backend_module_load (GTypeModule *type_module)
* it in other parts of the library */
if (G_UNLIKELY (module->priv->get_info () == NULL)) {
g_warning ("Backend module %s does not provide module information",
- module->priv->path);
+ module->priv->path);
/* Close the module but keep the loaded flag to avoid unreffing
* this instance as the GType has most likely been registered */
@@ -150,7 +153,7 @@ mate_mixer_backend_module_load (GTypeModule *type_module)
/* It is not possible to unref this instance, so let's avoid unloading
* the module and just let the backend module (de)initialize when
- * (un)load are called repeatedly */
+ * (de)init functions are called repeatedly */
g_module_make_resident (module->priv->gmodule);
g_debug ("Loaded backend module %s", module->priv->path);
@@ -189,7 +192,7 @@ mate_mixer_backend_module_new (const gchar *path)
return module;
}
-const MateMixerBackendModuleInfo *
+const MateMixerBackendInfo *
mate_mixer_backend_module_get_info (MateMixerBackendModule *module)
{
g_return_val_if_fail (MATE_MIXER_IS_BACKEND_MODULE (module), NULL);
diff --git a/libmatemixer/matemixer-backend-module.h b/libmatemixer/matemixer-backend-module.h
index 4cba866..b629bfc 100644
--- a/libmatemixer/matemixer-backend-module.h
+++ b/libmatemixer/matemixer-backend-module.h
@@ -25,6 +25,13 @@
G_BEGIN_DECLS
+typedef struct {
+ gchar *name;
+ guint priority;
+ GType g_type;
+ MateMixerBackendType backend_type;
+} MateMixerBackendInfo;
+
#define MATE_MIXER_TYPE_BACKEND_MODULE \
(mate_mixer_backend_module_get_type ())
#define MATE_MIXER_BACKEND_MODULE(o) \
@@ -40,18 +47,8 @@ G_BEGIN_DECLS
typedef struct _MateMixerBackendModule MateMixerBackendModule;
typedef struct _MateMixerBackendModuleClass MateMixerBackendModuleClass;
-typedef struct _MateMixerBackendModuleInfo MateMixerBackendModuleInfo;
typedef struct _MateMixerBackendModulePrivate MateMixerBackendModulePrivate;
-struct _MateMixerBackendModuleInfo
-{
- gchar *name;
- guint priority;
- GType g_type;
-
- MateMixerBackendType backend_type;
-};
-
struct _MateMixerBackendModule
{
GTypeModule parent;
@@ -66,9 +63,9 @@ struct _MateMixerBackendModuleClass
GType mate_mixer_backend_module_get_type (void) G_GNUC_CONST;
-MateMixerBackendModule *mate_mixer_backend_module_new (const gchar *path);
-const MateMixerBackendModuleInfo *mate_mixer_backend_module_get_info (MateMixerBackendModule *module);
-const gchar *mate_mixer_backend_module_get_path (MateMixerBackendModule *module);
+MateMixerBackendModule *mate_mixer_backend_module_new (const gchar *path);
+const MateMixerBackendInfo *mate_mixer_backend_module_get_info (MateMixerBackendModule *module);
+const gchar *mate_mixer_backend_module_get_path (MateMixerBackendModule *module);
G_END_DECLS
diff --git a/libmatemixer/matemixer-backend.c b/libmatemixer/matemixer-backend.c
index 18e622f..890c34b 100644
--- a/libmatemixer/matemixer-backend.c
+++ b/libmatemixer/matemixer-backend.c
@@ -19,6 +19,7 @@
#include <glib-object.h>
#include "matemixer-backend.h"
+#include "matemixer-stream.h"
G_DEFINE_INTERFACE (MateMixerBackend, mate_mixer_backend, G_TYPE_OBJECT)
@@ -32,9 +33,10 @@ mate_mixer_backend_open (MateMixerBackend *backend)
{
MateMixerBackendInterface *iface;
- g_return_val_if_fail (MATE_MIXER_IS_BACKEND (backend), NULL);
+ g_return_val_if_fail (MATE_MIXER_IS_BACKEND (backend), FALSE);
iface = MATE_MIXER_BACKEND_GET_INTERFACE (backend);
+
if (iface->open)
return iface->open (backend);
@@ -46,9 +48,10 @@ mate_mixer_backend_close (MateMixerBackend *backend)
{
MateMixerBackendInterface *iface;
- g_return_val_if_fail (MATE_MIXER_IS_BACKEND (backend), NULL);
+ g_return_if_fail (MATE_MIXER_IS_BACKEND (backend));
iface = MATE_MIXER_BACKEND_GET_INTERFACE (backend);
+
if (iface->close)
iface->close (backend);
}
@@ -61,6 +64,7 @@ mate_mixer_backend_list_devices (MateMixerBackend *backend)
g_return_val_if_fail (MATE_MIXER_IS_BACKEND (backend), NULL);
iface = MATE_MIXER_BACKEND_GET_INTERFACE (backend);
+
if (iface->list_devices)
return iface->list_devices (backend);
@@ -68,15 +72,46 @@ mate_mixer_backend_list_devices (MateMixerBackend *backend)
}
GList *
-mate_mixer_backend_list_tracks (MateMixerBackend *backend)
+mate_mixer_backend_list_streams (MateMixerBackend *backend)
+{
+ MateMixerBackendInterface *iface;
+
+ g_return_val_if_fail (MATE_MIXER_IS_BACKEND (backend), NULL);
+
+ iface = MATE_MIXER_BACKEND_GET_INTERFACE (backend);
+
+ if (iface->list_streams)
+ return iface->list_streams (backend);
+
+ return NULL;
+}
+
+MateMixerStream *
+mate_mixer_backend_get_default_input_stream (MateMixerBackend *backend)
+{
+ MateMixerBackendInterface *iface;
+
+ g_return_val_if_fail (MATE_MIXER_IS_BACKEND (backend), NULL);
+
+ iface = MATE_MIXER_BACKEND_GET_INTERFACE (backend);
+
+ if (iface->get_default_input_stream)
+ return iface->get_default_input_stream (backend);
+
+ return NULL;
+}
+
+MateMixerStream *
+mate_mixer_backend_get_default_output_stream (MateMixerBackend *backend)
{
MateMixerBackendInterface *iface;
g_return_val_if_fail (MATE_MIXER_IS_BACKEND (backend), NULL);
iface = MATE_MIXER_BACKEND_GET_INTERFACE (backend);
- if (iface->list_tracks)
- return iface->list_tracks (backend);
+
+ if (iface->get_default_output_stream)
+ return iface->get_default_output_stream (backend);
return NULL;
}
diff --git a/libmatemixer/matemixer-backend.h b/libmatemixer/matemixer-backend.h
index e5a8585..897641f 100644
--- a/libmatemixer/matemixer-backend.h
+++ b/libmatemixer/matemixer-backend.h
@@ -21,7 +21,7 @@
#include <glib.h>
#include <glib-object.h>
-#include <libmatemixer/matemixer-enums.h>
+#include "matemixer-stream.h"
G_BEGIN_DECLS
@@ -42,19 +42,23 @@ struct _MateMixerBackendInterface
GTypeInterface parent;
/* Required */
- gboolean (*open) (MateMixerBackend *backend);
+ gboolean (*open) (MateMixerBackend *backend);
- void (*close) (MateMixerBackend *backend);
- GList *(*list_devices) (MateMixerBackend *backend);
- GList *(*list_tracks) (MateMixerBackend *backend);
+ void (*close) (MateMixerBackend *backend);
+ GList *(*list_devices) (MateMixerBackend *backend);
+ GList *(*list_streams) (MateMixerBackend *backend);
+ MateMixerStream *(*get_default_input_stream) (MateMixerBackend *backend);
+ MateMixerStream *(*get_default_output_stream) (MateMixerBackend *backend);
};
GType mate_mixer_backend_get_type (void) G_GNUC_CONST;
-gboolean mate_mixer_backend_open (MateMixerBackend *backend);
-void mate_mixer_backend_close (MateMixerBackend *backend);
-GList *mate_mixer_backend_list_devices (MateMixerBackend *backend);
-GList *mate_mixer_backend_list_tracks (MateMixerBackend *backend);
+gboolean mate_mixer_backend_open (MateMixerBackend *backend);
+void mate_mixer_backend_close (MateMixerBackend *backend);
+GList *mate_mixer_backend_list_devices (MateMixerBackend *backend);
+GList *mate_mixer_backend_list_streams (MateMixerBackend *backend);
+MateMixerStream *mate_mixer_backend_get_default_input_stream (MateMixerBackend *backend);
+MateMixerStream *mate_mixer_backend_get_default_output_stream (MateMixerBackend *backend);
G_END_DECLS
diff --git a/libmatemixer/matemixer-control.c b/libmatemixer/matemixer-control.c
index cf59ad5..c122a7e 100644
--- a/libmatemixer/matemixer-control.c
+++ b/libmatemixer/matemixer-control.c
@@ -23,64 +23,73 @@
#include "matemixer-control.h"
#include "matemixer-enums.h"
#include "matemixer-private.h"
-#include "matemixer-track.h"
+#include "matemixer-stream.h"
struct _MateMixerControlPrivate
{
GList *devices;
- GList *tracks;
+ GList *streams;
MateMixerBackend *backend;
MateMixerBackendModule *module;
};
G_DEFINE_TYPE (MateMixerControl, mate_mixer_control, G_TYPE_OBJECT);
-static MateMixerBackend *mixer_control_init_module (MateMixerBackendModule *module);
+static void mate_mixer_control_class_init (MateMixerControlClass *klass);
+static void mate_mixer_control_init (MateMixerControl *control);
+static void mate_mixer_control_dispose (GObject *object);
+
+static MateMixerBackend *mixer_control_init_module (MateMixerBackendModule *module);
+
+static void
+mate_mixer_control_class_init (MateMixerControlClass *klass)
+{
+ GObjectClass *object_class;
+
+ object_class = G_OBJECT_CLASS (klass);
+ object_class->dispose = mate_mixer_control_dispose;
+
+ g_type_class_add_private (object_class, sizeof (MateMixerControlPrivate));
+}
static void
mate_mixer_control_init (MateMixerControl *control)
{
- control->priv = G_TYPE_INSTANCE_GET_PRIVATE (
- control,
- MATE_MIXER_TYPE_CONTROL,
- MateMixerControlPrivate);
+ control->priv = G_TYPE_INSTANCE_GET_PRIVATE (control,
+ MATE_MIXER_TYPE_CONTROL,
+ MateMixerControlPrivate);
}
static void
-mate_mixer_control_finalize (GObject *object)
+mate_mixer_control_dispose (GObject *object)
{
MateMixerControl *control;
control = MATE_MIXER_CONTROL (object);
- mate_mixer_backend_close (control->priv->backend);
+ if (control->priv->backend) {
+ mate_mixer_backend_close (control->priv->backend);
+ g_clear_object (&control->priv->backend);
+ }
- g_object_unref (control->priv->backend);
- g_object_unref (control->priv->module);
+ g_clear_object (&control->priv->module);
- if (control->priv->devices)
+ if (control->priv->devices) {
g_list_free_full (control->priv->devices, g_object_unref);
- if (control->priv->tracks)
- g_list_free_full (control->priv->tracks, g_object_unref);
-
- G_OBJECT_CLASS (mate_mixer_control_parent_class)->finalize (object);
-}
-
-static void
-mate_mixer_control_class_init (MateMixerControlClass *klass)
-{
- GObjectClass *object_class;
-
- object_class = G_OBJECT_CLASS (klass);
- object_class->finalize = mate_mixer_control_finalize;
+ control->priv->devices = NULL;
+ }
+ if (control->priv->streams) {
+ g_list_free_full (control->priv->streams, g_object_unref);
+ control->priv->streams = NULL;
+ }
- g_type_class_add_private (object_class, sizeof (MateMixerControlPrivate));
+ G_OBJECT_CLASS (mate_mixer_control_parent_class)->dispose (object);
}
MateMixerControl *
mate_mixer_control_new (void)
{
- GList *modules;
+ const GList *modules;
MateMixerControl *control;
MateMixerBackend *backend = NULL;
MateMixerBackendModule *module = NULL;
@@ -101,7 +110,7 @@ mate_mixer_control_new (void)
}
/* The last module in the priority list is the "null" module which
- * should always be initialized correctly, but in case "null" is absent
+ * should always be initialized correctly, but in case "null" is absent,
* all the other modules might fail their initializations */
if (backend == NULL)
return NULL;
@@ -117,7 +126,7 @@ mate_mixer_control_new (void)
MateMixerControl *
mate_mixer_control_new_backend (MateMixerBackendType backend_type)
{
- GList *modules;
+ const GList *modules;
MateMixerControl *control;
MateMixerBackend *backend = NULL;
MateMixerBackendModule *module = NULL;
@@ -129,7 +138,7 @@ mate_mixer_control_new_backend (MateMixerBackendType backend_type)
modules = mate_mixer_get_modules ();
while (modules) {
- const MateMixerBackendModuleInfo *info;
+ const MateMixerBackendInfo *info;
module = MATE_MIXER_BACKEND_MODULE (modules->data);
info = mate_mixer_backend_module_get_info (module);
@@ -158,35 +167,49 @@ mate_mixer_control_list_devices (MateMixerControl *control)
{
g_return_val_if_fail (MATE_MIXER_IS_CONTROL (control), NULL);
- /* This list is cached here and invalidated when the backend
- * notifies us about a change */
+ /* This list is cached here and invalidated when the backend notifies us
+ * about a change */
if (control->priv->devices == NULL)
- control->priv->devices = mate_mixer_backend_list_devices (
- MATE_MIXER_BACKEND (control->priv->backend));
-
- // TODO: notification signals from backend
+ control->priv->devices =
+ mate_mixer_backend_list_devices (MATE_MIXER_BACKEND (control->priv->backend));
return (const GList *) control->priv->devices;
}
const GList *
-mate_mixer_control_list_tracks (MateMixerControl *control)
+mate_mixer_control_list_streams (MateMixerControl *control)
{
g_return_val_if_fail (MATE_MIXER_IS_CONTROL (control), NULL);
- /* This list is cached here and invalidated when the backend
- * notifies us about a change */
- if (control->priv->tracks == NULL)
- control->priv->tracks = mate_mixer_backend_list_tracks (
- MATE_MIXER_BACKEND (control->priv->backend));
+ /* This list is cached here and invalidated when the backend notifies us
+ * about a change */
+ if (control->priv->streams == NULL)
+ control->priv->streams =
+ mate_mixer_backend_list_streams (MATE_MIXER_BACKEND (control->priv->backend));
+
+ return (const GList *) control->priv->streams;
+}
+
+MateMixerStream *
+mate_mixer_control_get_default_input_stream (MateMixerControl *control)
+{
+ g_return_val_if_fail (MATE_MIXER_IS_CONTROL (control), NULL);
+
+ return mate_mixer_backend_get_default_input_stream (control->priv->backend);
+}
+
+MateMixerStream *
+mate_mixer_control_get_default_output_stream (MateMixerControl *control)
+{
+ g_return_val_if_fail (MATE_MIXER_IS_CONTROL (control), NULL);
- return (const GList *) control->priv->tracks;
+ return mate_mixer_backend_get_default_output_stream (control->priv->backend);
}
const gchar *
mate_mixer_control_get_backend_name (MateMixerControl *control)
{
- const MateMixerBackendModuleInfo *info;
+ const MateMixerBackendInfo *info;
g_return_val_if_fail (MATE_MIXER_IS_CONTROL (control), NULL);
@@ -198,7 +221,7 @@ mate_mixer_control_get_backend_name (MateMixerControl *control)
MateMixerBackendType
mate_mixer_control_get_backend_type (MateMixerControl *control)
{
- const MateMixerBackendModuleInfo *info;
+ const MateMixerBackendInfo *info;
g_return_val_if_fail (MATE_MIXER_IS_CONTROL (control), FALSE);
@@ -210,8 +233,8 @@ mate_mixer_control_get_backend_type (MateMixerControl *control)
static MateMixerBackend *
mixer_control_init_module (MateMixerBackendModule *module)
{
- MateMixerBackend *backend;
- const MateMixerBackendModuleInfo *info;
+ MateMixerBackend *backend;
+ const MateMixerBackendInfo *info;
info = mate_mixer_backend_module_get_info (module);
backend = g_object_newv (info->g_type, 0, NULL);
diff --git a/libmatemixer/matemixer-control.h b/libmatemixer/matemixer-control.h
index 739eabd..3482fbb 100644
--- a/libmatemixer/matemixer-control.h
+++ b/libmatemixer/matemixer-control.h
@@ -21,7 +21,8 @@
#include <glib.h>
#include <glib-object.h>
-#include "matemixer-enums.h"
+#include <libmatemixer/matemixer-enums.h>
+#include <libmatemixer/matemixer-stream.h>
G_BEGIN_DECLS
@@ -51,18 +52,19 @@ struct _MateMixerControl
struct _MateMixerControlClass
{
- GObjectClass parent;
+ GObjectClass parent;
};
GType mate_mixer_control_get_type (void) G_GNUC_CONST;
-MateMixerControl *mate_mixer_control_new (void);
-MateMixerControl *mate_mixer_control_new_backend (MateMixerBackendType backend_type);
-const GList *mate_mixer_control_list_devices (MateMixerControl *control);
-const GList *mate_mixer_control_list_tracks (MateMixerControl *control);
-
-const gchar *mate_mixer_control_get_backend_name (MateMixerControl *control);
-MateMixerBackendType mate_mixer_control_get_backend_type (MateMixerControl *control);
+MateMixerControl * mate_mixer_control_new (void);
+MateMixerControl * mate_mixer_control_new_backend (MateMixerBackendType backend_type);
+const GList * mate_mixer_control_list_devices (MateMixerControl *control);
+const GList * mate_mixer_control_list_streams (MateMixerControl *control);
+MateMixerStream * mate_mixer_control_get_default_input_stream (MateMixerControl *control);
+MateMixerStream * mate_mixer_control_get_default_output_stream (MateMixerControl *control);
+const gchar * mate_mixer_control_get_backend_name (MateMixerControl *control);
+MateMixerBackendType mate_mixer_control_get_backend_type (MateMixerControl *control);
G_END_DECLS
diff --git a/libmatemixer/matemixer-device-port.c b/libmatemixer/matemixer-device-port.c
deleted file mode 100644
index ca84ef6..0000000
--- a/libmatemixer/matemixer-device-port.c
+++ /dev/null
@@ -1,270 +0,0 @@
-/*
- * Copyright (C) 2014 Michal Ratajsky <[email protected]>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the licence, or (at your option) any later version.
- *
- * This 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <glib.h>
-#include <glib-object.h>
-
-#include "matemixer-device-port.h"
-#include "matemixer-enums.h"
-#include "matemixer-enum-types.h"
-
-struct _MateMixerDevicePortPrivate
-{
- gchar *identifier;
- gchar *name;
- gchar *icon;
- guint32 priority;
-
- MateMixerDevicePortDirection direction;
- MateMixerDevicePortStatus status;
-};
-
-enum
-{
- PROP_0,
- PROP_IDENTIFIER,
- PROP_NAME,
- PROP_ICON,
- PROP_PRIORITY,
- PROP_DIRECTION,
- PROP_STATUS,
- N_PROPERTIES
-};
-
-static GParamSpec *properties[N_PROPERTIES] = { NULL, };
-
-G_DEFINE_TYPE (MateMixerDevicePort, mate_mixer_device_port, G_TYPE_OBJECT);
-
-static void
-mate_mixer_device_port_init (MateMixerDevicePort *port)
-{
- port->priv = G_TYPE_INSTANCE_GET_PRIVATE (
- port,
- MATE_MIXER_TYPE_DEVICE_PORT,
- MateMixerDevicePortPrivate);
-}
-
-static void
-mate_mixer_device_port_get_property (GObject *object,
- guint param_id,
- GValue *value,
- GParamSpec *pspec)
-{
- MateMixerDevicePort *port;
-
- port = MATE_MIXER_DEVICE_PORT (object);
-
- switch (param_id) {
- case PROP_IDENTIFIER:
- g_value_set_string (value, port->priv->identifier);
- break;
- case PROP_NAME:
- g_value_set_string (value, port->priv->name);
- break;
- case PROP_ICON:
- g_value_set_string (value, port->priv->icon);
- break;
- case PROP_PRIORITY:
- g_value_set_uint (value, port->priv->priority);
- break;
- case PROP_DIRECTION:
- g_value_set_flags (value, port->priv->direction);
- break;
- case PROP_STATUS:
- g_value_set_flags (value, port->priv->status);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
- break;
- }
-}
-
-static void
-mate_mixer_device_port_set_property (GObject *object,
- guint param_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- MateMixerDevicePort *port;
-
- port = MATE_MIXER_DEVICE_PORT (object);
-
- switch (param_id) {
- case PROP_IDENTIFIER:
- port->priv->identifier = g_strdup (g_value_get_string (value));
- break;
- case PROP_NAME:
- port->priv->name = g_strdup (g_value_get_string (value));
- break;
- case PROP_ICON:
- port->priv->icon = g_strdup (g_value_get_string (value));
- break;
- case PROP_PRIORITY:
- port->priv->priority = g_value_get_uint (value);
- break;
- case PROP_DIRECTION:
- port->priv->direction = g_value_get_flags (value);
- break;
- case PROP_STATUS:
- port->priv->status = g_value_get_flags (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
- break;
- }
-}
-
-static void
-mate_mixer_device_port_finalize (GObject *object)
-{
- MateMixerDevicePort *port;
-
- port = MATE_MIXER_DEVICE_PORT (object);
-
- g_free (port->priv->identifier);
- g_free (port->priv->name);
- g_free (port->priv->icon);
-
- G_OBJECT_CLASS (mate_mixer_device_port_parent_class)->finalize (object);
-}
-
-static void
-mate_mixer_device_port_class_init (MateMixerDevicePortClass *klass)
-{
- GObjectClass *object_class;
-
- object_class = G_OBJECT_CLASS (klass);
- object_class->finalize = mate_mixer_device_port_finalize;
- object_class->get_property = mate_mixer_device_port_get_property;
- object_class->set_property = mate_mixer_device_port_set_property;
-
- properties[PROP_IDENTIFIER] = g_param_spec_string (
- "identifier",
- "Identifier",
- "Identifier of the device port",
- NULL,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
-
- properties[PROP_NAME] = g_param_spec_string (
- "name",
- "Name",
- "Name of the device port",
- NULL,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
-
- properties[PROP_ICON] = g_param_spec_string (
- "icon",
- "Icon",
- "Icon name for the device port",
- NULL,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
-
- properties[PROP_PRIORITY] = g_param_spec_uint (
- "priority",
- "Priority",
- "Priority of the device port",
- 0,
- G_MAXUINT32,
- 0,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
-
- properties[PROP_DIRECTION] = g_param_spec_flags (
- "direction",
- "Direction",
- "Direction(s) for the device port",
- MATE_MIXER_TYPE_DEVICE_PORT_DIRECTION,
- 0,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
-
- properties[PROP_STATUS] = g_param_spec_flags (
- "status",
- "Status",
- "Status for the device port",
- MATE_MIXER_TYPE_DEVICE_PORT_STATUS,
- 0,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
-
- g_object_class_install_properties (object_class, N_PROPERTIES, properties);
-
- g_type_class_add_private (object_class, sizeof (MateMixerDevicePortPrivate));
-}
-
-MateMixerDevicePort *
-mate_mixer_device_port_new (const gchar *identifier,
- const gchar *name,
- const gchar *icon,
- guint32 priority,
- MateMixerDevicePortDirection direction,
- MateMixerDevicePortStatus status)
-{
- return g_object_new (MATE_MIXER_TYPE_DEVICE_PORT,
- "identifier", identifier,
- "name", name,
- "icon", icon,
- "priority", priority,
- "direction", direction,
- "status", status,
- NULL);
-}
-
-const gchar *
-mate_mixer_device_port_get_identifier (MateMixerDevicePort *port)
-{
- g_return_val_if_fail (MATE_MIXER_IS_DEVICE_PORT (port), NULL);
-
- return port->priv->identifier;
-}
-
-const gchar *
-mate_mixer_device_port_get_name (MateMixerDevicePort *port)
-{
- g_return_val_if_fail (MATE_MIXER_IS_DEVICE_PORT (port), NULL);
-
- return port->priv->name;
-}
-
-const gchar *
-mate_mixer_device_port_get_icon (MateMixerDevicePort *port)
-{
- g_return_val_if_fail (MATE_MIXER_IS_DEVICE_PORT (port), NULL);
-
- return port->priv->icon;
-}
-
-guint32
-mate_mixer_device_port_get_priority (MateMixerDevicePort *port)
-{
- g_return_val_if_fail (MATE_MIXER_IS_DEVICE_PORT (port), 0);
-
- return port->priv->priority;
-}
-
-MateMixerDevicePortDirection
-mate_mixer_device_port_get_direction (MateMixerDevicePort *port)
-{
- g_return_val_if_fail (MATE_MIXER_IS_DEVICE_PORT (port), 0);
-
- return port->priv->direction;
-}
-
-MateMixerDevicePortStatus
-mate_mixer_device_port_get_status (MateMixerDevicePort *port)
-{
- g_return_val_if_fail (MATE_MIXER_IS_DEVICE_PORT (port), 0);
-
- return port->priv->status;
-}
diff --git a/libmatemixer/matemixer-device-port.h b/libmatemixer/matemixer-device-port.h
deleted file mode 100644
index f21caaf..0000000
--- a/libmatemixer/matemixer-device-port.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2014 Michal Ratajsky <[email protected]>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the licence, or (at your option) any later version.
- *
- * This 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef MATEMIXER_DEVICE_PORT_H
-#define MATEMIXER_DEVICE_PORT_H
-
-#include <glib.h>
-#include <glib-object.h>
-
-#include <libmatemixer/matemixer-enums.h>
-
-G_BEGIN_DECLS
-
-#define MATE_MIXER_TYPE_DEVICE_PORT \
- (mate_mixer_device_port_get_type ())
-#define MATE_MIXER_DEVICE_PORT(o) \
- (G_TYPE_CHECK_INSTANCE_CAST ((o), MATE_MIXER_TYPE_DEVICE_PORT, MateMixerDevicePort))
-#define MATE_MIXER_IS_DEVICE_PORT(o) \
- (G_TYPE_CHECK_INSTANCE_TYPE ((o), MATE_MIXER_TYPE_DEVICE_PORT))
-#define MATE_MIXER_DEVICE_PORT_CLASS(k) \
- (G_TYPE_CHECK_CLASS_CAST ((k), MATE_MIXER_TYPE_DEVICE_PORT, MateMixerDevicePortClass))
-#define MATE_MIXER_IS_DEVICE_PORT_CLASS(k) \
- (G_TYPE_CLASS_CHECK_CLASS_TYPE ((k), MATE_MIXER_TYPE_DEVICE_PORT))
-#define MATE_MIXER_DEVICE_PORT_GET_CLASS(o) \
- (G_TYPE_INSTANCE_GET_CLASS ((o), MATE_MIXER_TYPE_DEVICE_PORT, MateMixerDevicePortClass))
-
-typedef struct _MateMixerDevicePort MateMixerDevicePort;
-typedef struct _MateMixerDevicePortClass MateMixerDevicePortClass;
-typedef struct _MateMixerDevicePortPrivate MateMixerDevicePortPrivate;
-
-struct _MateMixerDevicePort
-{
- GObject parent;
-
- MateMixerDevicePortPrivate *priv;
-};
-
-struct _MateMixerDevicePortClass
-{
- GObjectClass parent;
-};
-
-GType mate_mixer_device_port_get_type (void) G_GNUC_CONST;
-
-MateMixerDevicePort *mate_mixer_device_port_new (const gchar *identifier,
- const gchar *name,
- const gchar *icon,
- guint32 priority,
- MateMixerDevicePortDirection direction,
- MateMixerDevicePortStatus status);
-
-const gchar *mate_mixer_device_port_get_identifier (MateMixerDevicePort *port);
-
-const gchar *mate_mixer_device_port_get_name (MateMixerDevicePort *port);
-
-const gchar *mate_mixer_device_port_get_icon (MateMixerDevicePort *port);
-
-guint32 mate_mixer_device_port_get_priority (MateMixerDevicePort *port);
-
-MateMixerDevicePortDirection mate_mixer_device_port_get_direction (MateMixerDevicePort *port);
-
-MateMixerDevicePortStatus mate_mixer_device_port_get_status (MateMixerDevicePort *port);
-
-G_END_DECLS
-
-#endif /* MATEMIXER_PORT_H */
diff --git a/libmatemixer/matemixer-device-profile.c b/libmatemixer/matemixer-device-profile.c
deleted file mode 100644
index 975f5ff..0000000
--- a/libmatemixer/matemixer-device-profile.c
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * Copyright (C) 2014 Michal Ratajsky <[email protected]>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the licence, or (at your option) any later version.
- *
- * This 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <glib.h>
-#include <glib-object.h>
-
-#include "matemixer-device-profile.h"
-
-struct _MateMixerDeviceProfilePrivate
-{
- gchar *identifier;
- gchar *name;
- guint32 priority;
-};
-
-enum
-{
- PROP_0,
- PROP_IDENTIFIER,
- PROP_NAME,
- PROP_PRIORITY,
- N_PROPERTIES
-};
-
-static GParamSpec *properties[N_PROPERTIES] = { NULL, };
-
-G_DEFINE_TYPE (MateMixerDeviceProfile, mate_mixer_device_profile, G_TYPE_OBJECT);
-
-static void
-mate_mixer_device_profile_init (MateMixerDeviceProfile *profile)
-{
- profile->priv = G_TYPE_INSTANCE_GET_PRIVATE (
- profile,
- MATE_MIXER_TYPE_DEVICE_PROFILE,
- MateMixerDeviceProfilePrivate);
-}
-
-static void
-mate_mixer_device_profile_get_property (GObject *object,
- guint param_id,
- GValue *value,
- GParamSpec *pspec)
-{
- MateMixerDeviceProfile *profile;
-
- profile = MATE_MIXER_DEVICE_PROFILE (object);
-
- switch (param_id) {
- case PROP_IDENTIFIER:
- g_value_set_string (value, profile->priv->identifier);
- break;
- case PROP_NAME:
- g_value_set_string (value, profile->priv->name);
- break;
- case PROP_PRIORITY:
- g_value_set_uint (value, profile->priv->priority);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
- break;
- }
-}
-
-static void
-mate_mixer_device_profile_set_property (GObject *object,
- guint param_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- MateMixerDeviceProfile *profile;
-
- profile = MATE_MIXER_DEVICE_PROFILE (object);
-
- switch (param_id) {
- case PROP_IDENTIFIER:
- profile->priv->identifier = g_strdup (g_value_get_string (value));
- break;
- case PROP_NAME:
- profile->priv->name = g_strdup (g_value_get_string (value));
- break;
- case PROP_PRIORITY:
- profile->priv->priority = g_value_get_uint (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
- break;
- }
-}
-
-static void
-mate_mixer_device_profile_finalize (GObject *object)
-{
- MateMixerDeviceProfile *profile;
-
- profile = MATE_MIXER_DEVICE_PROFILE (object);
-
- g_free (profile->priv->identifier);
- g_free (profile->priv->name);
-
- G_OBJECT_CLASS (mate_mixer_device_profile_parent_class)->finalize (object);
-}
-
-static void
-mate_mixer_device_profile_class_init (MateMixerDeviceProfileClass *klass)
-{
- GObjectClass *object_class;
-
- object_class = G_OBJECT_CLASS (klass);
- object_class->finalize = mate_mixer_device_profile_finalize;
- object_class->get_property = mate_mixer_device_profile_get_property;
- object_class->set_property = mate_mixer_device_profile_set_property;
-
- properties[PROP_IDENTIFIER] = g_param_spec_string (
- "identifier",
- "Identifier",
- "Identifier of the device profile",
- NULL,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
-
- properties[PROP_NAME] = g_param_spec_string (
- "name",
- "Name",
- "Name of the device profile",
- NULL,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
-
- properties[PROP_PRIORITY] = g_param_spec_uint (
- "priority",
- "Priority",
- "Priority of the device profile",
- 0,
- G_MAXUINT32,
- 0,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
-
- g_object_class_install_properties (object_class, N_PROPERTIES, properties);
-
- g_type_class_add_private (object_class, sizeof (MateMixerDeviceProfilePrivate));
-}
-
-MateMixerDeviceProfile *
-mate_mixer_device_profile_new (const gchar *identifier,
- const gchar *name,
- guint32 priority)
-{
- return g_object_new (MATE_MIXER_TYPE_DEVICE_PROFILE,
- "identifier", identifier,
- "name", name,
- "priority", priority,
- NULL);
-}
-
-const gchar *
-mate_mixer_device_profile_get_identifier (MateMixerDeviceProfile *profile)
-{
- g_return_val_if_fail (MATE_MIXER_IS_DEVICE_PROFILE (profile), NULL);
-
- return profile->priv->identifier;
-}
-
-const gchar *
-mate_mixer_device_profile_get_name (MateMixerDeviceProfile *profile)
-{
- g_return_val_if_fail (MATE_MIXER_IS_DEVICE_PROFILE (profile), NULL);
-
- return profile->priv->name;
-}
-
-guint32
-mate_mixer_device_profile_get_priority (MateMixerDeviceProfile *profile)
-{
- g_return_val_if_fail (MATE_MIXER_IS_DEVICE_PROFILE (profile), NULL);
-
- return profile->priv->priority;
-}
diff --git a/libmatemixer/matemixer-device-profile.h b/libmatemixer/matemixer-device-profile.h
deleted file mode 100644
index 1ac9020..0000000
--- a/libmatemixer/matemixer-device-profile.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2014 Michal Ratajsky <[email protected]>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the licence, or (at your option) any later version.
- *
- * This 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef MATEMIXER_DEVICE_PROFILE_H
-#define MATEMIXER_DEVICE_PROFILE_H
-
-#include <glib.h>
-#include <glib-object.h>
-
-G_BEGIN_DECLS
-
-#define MATE_MIXER_TYPE_DEVICE_PROFILE \
- (mate_mixer_device_profile_get_type ())
-#define MATE_MIXER_DEVICE_PROFILE(o) \
- (G_TYPE_CHECK_INSTANCE_CAST ((o), MATE_MIXER_TYPE_DEVICE_PROFILE, MateMixerDeviceProfile))
-#define MATE_MIXER_IS_DEVICE_PROFILE(o) \
- (G_TYPE_CHECK_INSTANCE_TYPE ((o), MATE_MIXER_TYPE_DEVICE_PROFILE))
-#define MATE_MIXER_DEVICE_PROFILE_CLASS(k) \
- (G_TYPE_CHECK_CLASS_CAST ((k), MATE_MIXER_TYPE_DEVICE_PROFILE, MateMixerDeviceProfileClass))
-#define MATE_MIXER_IS_DEVICE_PROFILE_CLASS(k) \
- (G_TYPE_CLASS_CHECK_CLASS_TYPE ((k), MATE_MIXER_TYPE_DEVICE_PROFILE))
-#define MATE_MIXER_DEVICE_PROFILE_GET_CLASS(o) \
- (G_TYPE_INSTANCE_GET_CLASS ((o), MATE_MIXER_TYPE_DEVICE_PROFILE, MateMixerDeviceProfileClass))
-
-typedef struct _MateMixerDeviceProfile MateMixerDeviceProfile;
-typedef struct _MateMixerDeviceProfileClass MateMixerDeviceProfileClass;
-typedef struct _MateMixerDeviceProfilePrivate MateMixerDeviceProfilePrivate;
-
-struct _MateMixerDeviceProfile
-{
- GObject parent;
-
- MateMixerDeviceProfilePrivate *priv;
-};
-
-struct _MateMixerDeviceProfileClass
-{
- GObjectClass parent;
-};
-
-GType mate_mixer_device_profile_get_type (void) G_GNUC_CONST;
-
-MateMixerDeviceProfile *mate_mixer_device_profile_new (const gchar *identifier,
- const gchar *name,
- guint32 priority);
-
-const gchar *mate_mixer_device_profile_get_identifier (MateMixerDeviceProfile *profile);
-const gchar *mate_mixer_device_profile_get_name (MateMixerDeviceProfile *profile);
-guint32 mate_mixer_device_profile_get_priority (MateMixerDeviceProfile *profile);
-
-G_END_DECLS
-
-#endif /* MATEMIXER_PROFILE_H */
diff --git a/libmatemixer/matemixer-device.c b/libmatemixer/matemixer-device.c
index 8e6a465..d4a7c39 100644
--- a/libmatemixer/matemixer-device.c
+++ b/libmatemixer/matemixer-device.c
@@ -19,89 +19,141 @@
#include <glib-object.h>
#include "matemixer-device.h"
-#include "matemixer-device-profile.h"
+#include "matemixer-enum-types.h"
+#include "matemixer-profile.h"
G_DEFINE_INTERFACE (MateMixerDevice, mate_mixer_device, G_TYPE_OBJECT)
static void
mate_mixer_device_default_init (MateMixerDeviceInterface *iface)
{
- g_object_interface_install_property (
- iface,
- g_param_spec_string ("identifier",
- "Identifier",
- "Identifier of the sound device",
- NULL,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE));
-
- g_object_interface_install_property (
- iface,
- g_param_spec_string ("name",
- "Name",
- "Name of the sound device",
- NULL,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE));
-
- g_object_interface_install_property (
- iface,
- g_param_spec_string ("icon",
- "Icon",
- "Name of the sound device icon",
- NULL,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE));
-
- g_object_interface_install_property (
- iface,
- g_param_spec_object ("active-profile",
- "Active profile",
- "Identifier of the currently active profile",
- MATE_MIXER_TYPE_DEVICE_PROFILE,
- G_PARAM_CONSTRUCT | G_PARAM_READWRITE));
+ g_object_interface_install_property (iface,
+ g_param_spec_string ("name",
+ "Name",
+ "Name of the sound device",
+ NULL,
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_interface_install_property (iface,
+ g_param_spec_string ("description",
+ "Description",
+ "Description of the sound device",
+ NULL,
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_interface_install_property (iface,
+ g_param_spec_string ("icon",
+ "Icon",
+ "Name of the sound device icon",
+ NULL,
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_interface_install_property (iface,
+ g_param_spec_object ("active-profile",
+ "Active profile",
+ "Name of the active profile",
+ MATE_MIXER_TYPE_PROFILE,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS));
+}
+
+const gchar *
+mate_mixer_device_get_name (MateMixerDevice *device)
+{
+ MateMixerDeviceInterface *iface;
+
+ g_return_val_if_fail (MATE_MIXER_IS_DEVICE (device), NULL);
+
+ iface = MATE_MIXER_DEVICE_GET_INTERFACE (device);
+
+ if (iface->get_name)
+ return iface->get_name (device);
+
+ return NULL;
+}
+
+const gchar *
+mate_mixer_device_get_description (MateMixerDevice *device)
+{
+ MateMixerDeviceInterface *iface;
+
+ g_return_val_if_fail (MATE_MIXER_IS_DEVICE (device), NULL);
+
+ iface = MATE_MIXER_DEVICE_GET_INTERFACE (device);
+
+ if (iface->get_description)
+ return iface->get_description (device);
+
+ return NULL;
+}
+
+const gchar *
+mate_mixer_device_get_icon (MateMixerDevice *device)
+{
+ MateMixerDeviceInterface *iface;
+
+ g_return_val_if_fail (MATE_MIXER_IS_DEVICE (device), NULL);
+
+ iface = MATE_MIXER_DEVICE_GET_INTERFACE (device);
+
+ if (iface->get_icon)
+ return iface->get_icon (device);
+
+ return NULL;
}
const GList *
-mate_mixer_device_list_tracks (MateMixerDevice *device)
+mate_mixer_device_list_streams (MateMixerDevice *device)
{
MateMixerDeviceInterface *iface;
g_return_val_if_fail (MATE_MIXER_IS_DEVICE (device), NULL);
iface = MATE_MIXER_DEVICE_GET_INTERFACE (device);
- if (iface->list_tracks)
- return iface->list_tracks (device);
+
+ if (iface->list_streams)
+ return iface->list_streams (device);
return NULL;
}
const GList *
-mate_mixer_device_get_ports (MateMixerDevice *device)
+mate_mixer_device_list_ports (MateMixerDevice *device)
{
MateMixerDeviceInterface *iface;
g_return_val_if_fail (MATE_MIXER_IS_DEVICE (device), NULL);
iface = MATE_MIXER_DEVICE_GET_INTERFACE (device);
- if (iface->get_ports)
- return iface->get_ports (device);
+
+ if (iface->list_ports)
+ return iface->list_ports (device);
return NULL;
}
const GList *
-mate_mixer_device_get_profiles (MateMixerDevice *device)
+mate_mixer_device_list_profiles (MateMixerDevice *device)
{
MateMixerDeviceInterface *iface;
g_return_val_if_fail (MATE_MIXER_IS_DEVICE (device), NULL);
iface = MATE_MIXER_DEVICE_GET_INTERFACE (device);
- if (iface->get_profiles)
- return iface->get_profiles (device);
+
+ if (iface->list_profiles)
+ return iface->list_profiles (device);
return NULL;
}
-MateMixerDeviceProfile *
+MateMixerProfile *
mate_mixer_device_get_active_profile (MateMixerDevice *device)
{
MateMixerDeviceInterface *iface;
@@ -109,6 +161,7 @@ mate_mixer_device_get_active_profile (MateMixerDevice *device)
g_return_val_if_fail (MATE_MIXER_IS_DEVICE (device), NULL);
iface = MATE_MIXER_DEVICE_GET_INTERFACE (device);
+
if (iface->get_active_profile)
return iface->get_active_profile (device);
@@ -116,17 +169,17 @@ mate_mixer_device_get_active_profile (MateMixerDevice *device)
}
gboolean
-mate_mixer_device_set_active_profile (MateMixerDevice *device,
- MateMixerDeviceProfile *profile)
+mate_mixer_device_set_active_profile (MateMixerDevice *device, const gchar *name)
{
MateMixerDeviceInterface *iface;
- g_return_val_if_fail (MATE_MIXER_IS_DEVICE (device), NULL);
- g_return_val_if_fail (MATE_MIXER_IS_DEVICE_PROFILE (profile), NULL);
+ g_return_val_if_fail (MATE_MIXER_IS_DEVICE (device), FALSE);
+ g_return_val_if_fail (name != NULL, FALSE);
iface = MATE_MIXER_DEVICE_GET_INTERFACE (device);
+
if (iface->set_active_profile)
- return iface->set_active_profile (device, profile);
+ return iface->set_active_profile (device, name);
return FALSE;
}
diff --git a/libmatemixer/matemixer-device.h b/libmatemixer/matemixer-device.h
index b601f7d..89c0187 100644
--- a/libmatemixer/matemixer-device.h
+++ b/libmatemixer/matemixer-device.h
@@ -21,8 +21,7 @@
#include <glib.h>
#include <glib-object.h>
-#include <libmatemixer/matemixer-device-port.h>
-#include <libmatemixer/matemixer-device-profile.h>
+#include <libmatemixer/matemixer-profile.h>
G_BEGIN_DECLS
@@ -42,25 +41,28 @@ struct _MateMixerDeviceInterface
{
GTypeInterface parent;
- const GList *(*list_tracks) (MateMixerDevice *device);
- const GList *(*get_ports) (MateMixerDevice *device);
- const GList *(*get_profiles) (MateMixerDevice *device);
- MateMixerDeviceProfile *(*get_active_profile) (MateMixerDevice *device);
- gboolean (*set_active_profile) (MateMixerDevice *device, MateMixerDeviceProfile *profile);
+ const gchar *(*get_name) (MateMixerDevice *device);
+ const gchar *(*get_description) (MateMixerDevice *device);
+ const gchar *(*get_icon) (MateMixerDevice *device);
+ const GList *(*list_streams) (MateMixerDevice *device);
+ const GList *(*list_ports) (MateMixerDevice *device);
+ const GList *(*list_profiles) (MateMixerDevice *device);
+ MateMixerProfile *(*get_active_profile) (MateMixerDevice *device);
+ gboolean (*set_active_profile) (MateMixerDevice *device,
+ const gchar *name);
};
GType mate_mixer_device_get_type (void) G_GNUC_CONST;
-const GList *mate_mixer_device_list_tracks (MateMixerDevice *device);
-
-const GList *mate_mixer_device_get_ports (MateMixerDevice *device);
-
-const GList *mate_mixer_device_get_profiles (MateMixerDevice *device);
-
-MateMixerDeviceProfile *mate_mixer_device_get_active_profile (MateMixerDevice *device);
-
-gboolean mate_mixer_device_set_active_profile (MateMixerDevice *device,
- MateMixerDeviceProfile *profile);
+const gchar * mate_mixer_device_get_name (MateMixerDevice *device);
+const gchar * mate_mixer_device_get_description (MateMixerDevice *device);
+const gchar * mate_mixer_device_get_icon (MateMixerDevice *device);
+const GList * mate_mixer_device_list_streams (MateMixerDevice *device);
+const GList * mate_mixer_device_list_ports (MateMixerDevice *device);
+const GList * mate_mixer_device_list_profiles (MateMixerDevice *device);
+MateMixerProfile *mate_mixer_device_get_active_profile (MateMixerDevice *device);
+gboolean mate_mixer_device_set_active_profile (MateMixerDevice *device,
+ const gchar *name);
G_END_DECLS
diff --git a/libmatemixer/matemixer-enum-types.c b/libmatemixer/matemixer-enum-types.c
index 390e32d..0d1c57d 100644
--- a/libmatemixer/matemixer-enum-types.c
+++ b/libmatemixer/matemixer-enum-types.c
@@ -30,9 +30,9 @@ mate_mixer_backend_type_get_type (void)
if (etype == 0) {
static const GEnumValue values[] = {
- { MATE_MIXER_BACKEND_TYPE_UNKNOWN, "MATE_MIXER_BACKEND_TYPE_UNKNOWN", "unknown" },
- { MATE_MIXER_BACKEND_TYPE_PULSE, "MATE_MIXER_BACKEND_TYPE_PULSE", "pulse" },
- { MATE_MIXER_BACKEND_TYPE_NULL, "MATE_MIXER_BACKEND_TYPE_NULL", "null" },
+ { MATE_MIXER_BACKEND_UNKNOWN, "MATE_MIXER_BACKEND_UNKNOWN", "unknown" },
+ { MATE_MIXER_BACKEND_PULSE, "MATE_MIXER_BACKEND_PULSE", "pulse" },
+ { MATE_MIXER_BACKEND_NULL, "MATE_MIXER_BACKEND_NULL", "null" },
{ 0, NULL, NULL }
};
etype = g_enum_register_static (
@@ -43,35 +43,99 @@ mate_mixer_backend_type_get_type (void)
}
GType
-mate_mixer_device_port_direction_get_type (void)
+mate_mixer_port_status_get_type (void)
{
static GType etype = 0;
if (etype == 0) {
- static const GFlagsValue values[] = {
- { MATE_MIXER_DEVICE_PORT_DIRECTION_INPUT, "MATE_MIXER_DEVICE_PORT_DIRECTION_INPUT", "input" },
- { MATE_MIXER_DEVICE_PORT_DIRECTION_OUTPUT, "MATE_MIXER_DEVICE_PORT_DIRECTION_OUTPUT", "output" },
+ static const GEnumValue values[] = {
+ { MATE_MIXER_PORT_UNKNOWN_STATUS, "MATE_MIXER_PORT_UNKNOWN_STATUS", "unknown-status" },
+ { MATE_MIXER_PORT_AVAILABLE, "MATE_MIXER_PORT_AVAILABLE", "available" },
+ { MATE_MIXER_PORT_UNAVAILABLE, "MATE_MIXER_PORT_UNAVAILABLE", "unavailable" },
{ 0, NULL, NULL }
};
- etype = g_flags_register_static (
- g_intern_static_string ("MateMixerDevicePortDirection"),
+ etype = g_enum_register_static (
+ g_intern_static_string ("MateMixerPortStatus"),
values);
}
return etype;
}
GType
-mate_mixer_device_port_status_get_type (void)
+mate_mixer_stream_flags_get_type (void)
{
static GType etype = 0;
if (etype == 0) {
static const GFlagsValue values[] = {
- { MATE_MIXER_DEVICE_PORT_STATUS_AVAILABLE, "MATE_MIXER_DEVICE_PORT_STATUS_AVAILABLE", "available" },
+ { MATE_MIXER_STREAM_INPUT, "MATE_MIXER_STREAM_INPUT", "input" },
+ { MATE_MIXER_STREAM_OUTPUT, "MATE_MIXER_STREAM_OUTPUT", "output" },
+ { MATE_MIXER_STREAM_CLIENT, "MATE_MIXER_STREAM_CLIENT", "client" },
+ { MATE_MIXER_STREAM_VIRTUAL, "MATE_MIXER_STREAM_VIRTUAL", "virtual" },
+ { MATE_MIXER_STREAM_OUTPUT_MONITOR, "MATE_MIXER_STREAM_OUTPUT_MONITOR", "output-monitor" },
+ { MATE_MIXER_STREAM_CAN_BALANCE, "MATE_MIXER_STREAM_CAN_BALANCE", "can-balance" },
+ { MATE_MIXER_STREAM_CAN_FADE, "MATE_MIXER_STREAM_CAN_FADE", "can-fade" },
+ { MATE_MIXER_STREAM_FLAT_VOLUME, "MATE_MIXER_STREAM_FLAT_VOLUME", "flat-volume" },
{ 0, NULL, NULL }
};
etype = g_flags_register_static (
- g_intern_static_string ("MateMixerDevicePortStatus"),
+ g_intern_static_string ("MateMixerStreamFlags"),
+ values);
+ }
+ return etype;
+}
+
+GType
+mate_mixer_stream_status_get_type (void)
+{
+ static GType etype = 0;
+
+ if (etype == 0) {
+ static const GEnumValue values[] = {
+ { MATE_MIXER_STREAM_UNKNOWN_STATUS, "MATE_MIXER_STREAM_UNKNOWN_STATUS", "unknown-status" },
+ { MATE_MIXER_STREAM_RUNNING, "MATE_MIXER_STREAM_RUNNING", "running" },
+ { MATE_MIXER_STREAM_IDLE, "MATE_MIXER_STREAM_IDLE", "idle" },
+ { MATE_MIXER_STREAM_SUSPENDED, "MATE_MIXER_STREAM_SUSPENDED", "suspended" },
+ { 0, NULL, NULL }
+ };
+ etype = g_enum_register_static (
+ g_intern_static_string ("MateMixerStreamStatus"),
+ values);
+ }
+ return etype;
+}
+
+GType
+mate_mixer_channel_position_get_type (void)
+{
+ static GType etype = 0;
+
+ if (etype == 0) {
+ static const GEnumValue values[] = {
+ { MATE_MIXER_CHANNEL_UNKNOWN_POSITION, "MATE_MIXER_CHANNEL_UNKNOWN_POSITION", "unknown-position" },
+ { MATE_MIXER_CHANNEL_MONO, "MATE_MIXER_CHANNEL_MONO", "mono" },
+ { MATE_MIXER_CHANNEL_FRONT_LEFT, "MATE_MIXER_CHANNEL_FRONT_LEFT", "front-left" },
+ { MATE_MIXER_CHANNEL_FRONT_RIGHT, "MATE_MIXER_CHANNEL_FRONT_RIGHT", "front-right" },
+ { MATE_MIXER_CHANNEL_FRONT_CENTER, "MATE_MIXER_CHANNEL_FRONT_CENTER", "front-center" },
+ { MATE_MIXER_CHANNEL_LFE, "MATE_MIXER_CHANNEL_LFE", "lfe" },
+ { MATE_MIXER_CHANNEL_BACK_LEFT, "MATE_MIXER_CHANNEL_BACK_LEFT", "back-left" },
+ { MATE_MIXER_CHANNEL_BACK_RIGHT, "MATE_MIXER_CHANNEL_BACK_RIGHT", "back-right" },
+ { MATE_MIXER_CHANNEL_FRONT_LEFT_CENTER, "MATE_MIXER_CHANNEL_FRONT_LEFT_CENTER", "front-left-center" },
+ { MATE_MIXER_CHANNEL_FRONT_RIGHT_CENTER, "MATE_MIXER_CHANNEL_FRONT_RIGHT_CENTER", "front-right-center" },
+ { MATE_MIXER_CHANNEL_BACK_CENTER, "MATE_MIXER_CHANNEL_BACK_CENTER", "back-center" },
+ { MATE_MIXER_CHANNEL_SIDE_LEFT, "MATE_MIXER_CHANNEL_SIDE_LEFT", "side-left" },
+ { MATE_MIXER_CHANNEL_SIDE_RIGHT, "MATE_MIXER_CHANNEL_SIDE_RIGHT", "side-right" },
+ { MATE_MIXER_CHANNEL_TOP_FRONT_LEFT, "MATE_MIXER_CHANNEL_TOP_FRONT_LEFT", "top-front-left" },
+ { MATE_MIXER_CHANNEL_TOP_FRONT_RIGHT, "MATE_MIXER_CHANNEL_TOP_FRONT_RIGHT", "top-front-right" },
+ { MATE_MIXER_CHANNEL_TOP_FRONT_CENTER, "MATE_MIXER_CHANNEL_TOP_FRONT_CENTER", "top-front-center" },
+ { MATE_MIXER_CHANNEL_TOP_CENTER, "MATE_MIXER_CHANNEL_TOP_CENTER", "top-center" },
+ { MATE_MIXER_CHANNEL_TOP_BACK_LEFT, "MATE_MIXER_CHANNEL_TOP_BACK_LEFT", "top-back-left" },
+ { MATE_MIXER_CHANNEL_TOP_BACK_RIGHT, "MATE_MIXER_CHANNEL_TOP_BACK_RIGHT", "top-back-right" },
+ { MATE_MIXER_CHANNEL_TOP_BACK_CENTER, "MATE_MIXER_CHANNEL_TOP_BACK_CENTER", "top-back-center" },
+ { 0, NULL, NULL }
+ };
+ etype = g_enum_register_static (
+ g_intern_static_string ("MateMixerChannelPosition"),
values);
}
return etype;
diff --git a/libmatemixer/matemixer-enum-types.h b/libmatemixer/matemixer-enum-types.h
index fa1551a..ccb87a6 100644
--- a/libmatemixer/matemixer-enum-types.h
+++ b/libmatemixer/matemixer-enum-types.h
@@ -18,6 +18,7 @@
#ifndef MATEMIXER_ENUM_TYPES_H
#define MATEMIXER_ENUM_TYPES_H
+#include <glib.h>
#include <glib-object.h>
G_BEGIN_DECLS
@@ -30,11 +31,17 @@ G_BEGIN_DECLS
#define MATE_MIXER_TYPE_BACKEND_TYPE (mate_mixer_backend_type_get_type ())
GType mate_mixer_backend_type_get_type (void) G_GNUC_CONST;
-#define MATE_MIXER_TYPE_DEVICE_PORT_DIRECTION (mate_mixer_device_port_direction_get_type ())
-GType mate_mixer_device_port_direction_get_type (void) G_GNUC_CONST;
+#define MATE_MIXER_TYPE_PORT_STATUS (mate_mixer_port_status_get_type ())
+GType mate_mixer_port_status_get_type (void) G_GNUC_CONST;
-#define MATE_MIXER_TYPE_DEVICE_PORT_STATUS (mate_mixer_device_port_status_get_type ())
-GType mate_mixer_device_port_status_get_type (void) G_GNUC_CONST;
+#define MATE_MIXER_TYPE_STREAM_FLAGS (mate_mixer_stream_flags_get_type ())
+GType mate_mixer_stream_flags_get_type (void) G_GNUC_CONST;
+
+#define MATE_MIXER_TYPE_STREAM_STATUS (mate_mixer_stream_status_get_type ())
+GType mate_mixer_stream_status_get_type (void) G_GNUC_CONST;
+
+#define MATE_MIXER_TYPE_CHANNEL_POSITION (mate_mixer_channel_position_get_type ())
+GType mate_mixer_channel_position_get_type (void) G_GNUC_CONST;
G_END_DECLS
diff --git a/libmatemixer/matemixer-enums.h b/libmatemixer/matemixer-enums.h
index d83f283..cccb70d 100644
--- a/libmatemixer/matemixer-enums.h
+++ b/libmatemixer/matemixer-enums.h
@@ -24,18 +24,56 @@
*/
typedef enum {
- MATE_MIXER_BACKEND_TYPE_UNKNOWN,
- MATE_MIXER_BACKEND_TYPE_PULSE,
- MATE_MIXER_BACKEND_TYPE_NULL
+ MATE_MIXER_BACKEND_UNKNOWN,
+ MATE_MIXER_BACKEND_PULSE,
+ MATE_MIXER_BACKEND_NULL
} MateMixerBackendType;
-typedef enum { /*< flags >*/
- MATE_MIXER_DEVICE_PORT_DIRECTION_INPUT = 1 << 0,
- MATE_MIXER_DEVICE_PORT_DIRECTION_OUTPUT = 1 << 1
-} MateMixerDevicePortDirection;
+typedef enum {
+ MATE_MIXER_PORT_UNKNOWN_STATUS,
+ MATE_MIXER_PORT_AVAILABLE,
+ MATE_MIXER_PORT_UNAVAILABLE
+} MateMixerPortStatus;
typedef enum { /*< flags >*/
- MATE_MIXER_DEVICE_PORT_STATUS_AVAILABLE = 1 << 0
-} MateMixerDevicePortStatus;
+ MATE_MIXER_STREAM_INPUT = 1 << 0,
+ MATE_MIXER_STREAM_OUTPUT = 1 << 1,
+ MATE_MIXER_STREAM_CLIENT = 1 << 2,
+ MATE_MIXER_STREAM_VIRTUAL = 1 << 3,
+ MATE_MIXER_STREAM_OUTPUT_MONITOR = 1 << 4,
+ MATE_MIXER_STREAM_CAN_BALANCE = 1 << 5,
+ MATE_MIXER_STREAM_CAN_FADE = 1 << 6,
+ MATE_MIXER_STREAM_FLAT_VOLUME = 1 << 7
+} MateMixerStreamFlags;
+
+typedef enum {
+ MATE_MIXER_STREAM_UNKNOWN_STATUS,
+ MATE_MIXER_STREAM_RUNNING,
+ MATE_MIXER_STREAM_IDLE,
+ MATE_MIXER_STREAM_SUSPENDED
+} MateMixerStreamStatus;
+
+typedef enum {
+ MATE_MIXER_CHANNEL_UNKNOWN_POSITION,
+ MATE_MIXER_CHANNEL_MONO,
+ MATE_MIXER_CHANNEL_FRONT_LEFT,
+ MATE_MIXER_CHANNEL_FRONT_RIGHT,
+ MATE_MIXER_CHANNEL_FRONT_CENTER,
+ MATE_MIXER_CHANNEL_LFE,
+ MATE_MIXER_CHANNEL_BACK_LEFT,
+ MATE_MIXER_CHANNEL_BACK_RIGHT,
+ MATE_MIXER_CHANNEL_FRONT_LEFT_CENTER,
+ MATE_MIXER_CHANNEL_FRONT_RIGHT_CENTER,
+ MATE_MIXER_CHANNEL_BACK_CENTER,
+ MATE_MIXER_CHANNEL_SIDE_LEFT,
+ MATE_MIXER_CHANNEL_SIDE_RIGHT,
+ MATE_MIXER_CHANNEL_TOP_FRONT_LEFT,
+ MATE_MIXER_CHANNEL_TOP_FRONT_RIGHT,
+ MATE_MIXER_CHANNEL_TOP_FRONT_CENTER,
+ MATE_MIXER_CHANNEL_TOP_CENTER,
+ MATE_MIXER_CHANNEL_TOP_BACK_LEFT,
+ MATE_MIXER_CHANNEL_TOP_BACK_RIGHT,
+ MATE_MIXER_CHANNEL_TOP_BACK_CENTER
+} MateMixerChannelPosition;
#endif /* MATEMIXER_ENUMS_H */
diff --git a/libmatemixer/matemixer-port.c b/libmatemixer/matemixer-port.c
new file mode 100644
index 0000000..c4b2de3
--- /dev/null
+++ b/libmatemixer/matemixer-port.c
@@ -0,0 +1,256 @@
+/*
+ * Copyright (C) 2014 Michal Ratajsky <[email protected]>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the licence, or (at your option) any later version.
+ *
+ * This 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <glib.h>
+#include <glib-object.h>
+
+#include "matemixer-enums.h"
+#include "matemixer-enum-types.h"
+#include "matemixer-port.h"
+
+struct _MateMixerPortPrivate
+{
+ gchar *name;
+ gchar *description;
+ gchar *icon;
+ guint32 priority;
+ MateMixerPortStatus status;
+};
+
+enum
+{
+ PROP_0,
+ PROP_NAME,
+ PROP_DESCRIPTION,
+ PROP_ICON,
+ PROP_PRIORITY,
+ PROP_STATUS,
+ N_PROPERTIES
+};
+
+static GParamSpec *properties[N_PROPERTIES] = { NULL, };
+
+static void mate_mixer_port_class_init (MateMixerPortClass *klass);
+static void mate_mixer_port_init (MateMixerPort *port);
+static void mate_mixer_port_finalize (GObject *object);
+
+G_DEFINE_TYPE (MateMixerPort, mate_mixer_port, G_TYPE_OBJECT);
+
+static void
+mate_mixer_port_get_property (GObject *object,
+ guint param_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ MateMixerPort *port;
+
+ port = MATE_MIXER_PORT (object);
+
+ switch (param_id) {
+ case PROP_NAME:
+ g_value_set_string (value, port->priv->name);
+ break;
+ case PROP_DESCRIPTION:
+ g_value_set_string (value, port->priv->description);
+ break;
+ case PROP_ICON:
+ g_value_set_string (value, port->priv->icon);
+ break;
+ case PROP_PRIORITY:
+ g_value_set_uint (value, port->priv->priority);
+ break;
+ case PROP_STATUS:
+ g_value_set_enum (value, port->priv->status);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+ break;
+ }
+}
+
+static void
+mate_mixer_port_set_property (GObject *object,
+ guint param_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ MateMixerPort *port;
+
+ port = MATE_MIXER_PORT (object);
+
+ switch (param_id) {
+ case PROP_NAME:
+ port->priv->name = g_strdup (g_value_get_string (value));
+ break;
+ case PROP_DESCRIPTION:
+ port->priv->description = g_strdup (g_value_get_string (value));
+ break;
+ case PROP_ICON:
+ port->priv->icon = g_strdup (g_value_get_string (value));
+ break;
+ case PROP_PRIORITY:
+ port->priv->priority = g_value_get_uint (value);
+ break;
+ case PROP_STATUS:
+ port->priv->status = g_value_get_enum (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+ break;
+ }
+}
+
+static void
+mate_mixer_port_class_init (MateMixerPortClass *klass)
+{
+ GObjectClass *object_class;
+
+ object_class = G_OBJECT_CLASS (klass);
+ object_class->finalize = mate_mixer_port_finalize;
+ object_class->get_property = mate_mixer_port_get_property;
+ object_class->set_property = mate_mixer_port_set_property;
+
+ properties[PROP_NAME] =
+ g_param_spec_string ("name",
+ "Name",
+ "Name of the port",
+ NULL,
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS);
+
+ properties[PROP_DESCRIPTION] =
+ g_param_spec_string ("description",
+ "Description",
+ "Description of the port",
+ NULL,
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS);
+
+ properties[PROP_ICON] =
+ g_param_spec_string ("icon",
+ "Icon",
+ "Name of the port icon",
+ NULL,
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS);
+
+ properties[PROP_PRIORITY] =
+ g_param_spec_uint ("priority",
+ "Priority",
+ "Priority of the port",
+ 0,
+ G_MAXUINT32,
+ 0,
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS);
+
+ properties[PROP_STATUS] =
+ g_param_spec_enum ("status",
+ "Status",
+ "Status for the port",
+ MATE_MIXER_TYPE_PORT_STATUS,
+ MATE_MIXER_PORT_UNKNOWN_STATUS,
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS);
+
+ g_object_class_install_properties (object_class, N_PROPERTIES, properties);
+
+ g_type_class_add_private (object_class, sizeof (MateMixerPortPrivate));
+}
+
+static void
+mate_mixer_port_init (MateMixerPort *port)
+{
+ port->priv = G_TYPE_INSTANCE_GET_PRIVATE (port,
+ MATE_MIXER_TYPE_PORT,
+ MateMixerPortPrivate);
+}
+
+static void
+mate_mixer_port_finalize (GObject *object)
+{
+ MateMixerPort *port;
+
+ port = MATE_MIXER_PORT (object);
+
+ g_free (port->priv->name);
+ g_free (port->priv->description);
+ g_free (port->priv->icon);
+
+ G_OBJECT_CLASS (mate_mixer_port_parent_class)->finalize (object);
+}
+
+MateMixerPort *
+mate_mixer_port_new (const gchar *name,
+ const gchar *description,
+ const gchar *icon,
+ guint32 priority,
+ MateMixerPortStatus status)
+{
+ return g_object_new (MATE_MIXER_TYPE_PORT,
+ "name", name,
+ "description", description,
+ "icon", icon,
+ "priority", priority,
+ "status", status,
+ NULL);
+}
+
+const gchar *
+mate_mixer_port_get_name (MateMixerPort *port)
+{
+ g_return_val_if_fail (MATE_MIXER_IS_PORT (port), NULL);
+
+ return port->priv->name;
+}
+
+const gchar *
+mate_mixer_port_get_description (MateMixerPort *port)
+{
+ g_return_val_if_fail (MATE_MIXER_IS_PORT (port), NULL);
+
+ return port->priv->description;
+}
+
+const gchar *
+mate_mixer_port_get_icon (MateMixerPort *port)
+{
+ g_return_val_if_fail (MATE_MIXER_IS_PORT (port), NULL);
+
+ return port->priv->icon;
+}
+
+guint32
+mate_mixer_port_get_priority (MateMixerPort *port)
+{
+ g_return_val_if_fail (MATE_MIXER_IS_PORT (port), 0);
+
+ return port->priv->priority;
+}
+
+MateMixerPortStatus
+mate_mixer_port_get_status (MateMixerPort *port)
+{
+ g_return_val_if_fail (MATE_MIXER_IS_PORT (port), MATE_MIXER_PORT_UNKNOWN_STATUS);
+
+ return port->priv->status;
+}
diff --git a/libmatemixer/matemixer-port.h b/libmatemixer/matemixer-port.h
new file mode 100644
index 0000000..581f4ec
--- /dev/null
+++ b/libmatemixer/matemixer-port.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2014 Michal Ratajsky <[email protected]>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the licence, or (at your option) any later version.
+ *
+ * This 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef MATEMIXER_PORT_H
+#define MATEMIXER_PORT_H
+
+#include <glib.h>
+#include <glib-object.h>
+
+#include <libmatemixer/matemixer-enums.h>
+
+G_BEGIN_DECLS
+
+#define MATE_MIXER_TYPE_PORT \
+ (mate_mixer_port_get_type ())
+#define MATE_MIXER_PORT(o) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((o), MATE_MIXER_TYPE_PORT, MateMixerPort))
+#define MATE_MIXER_IS_PORT(o) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((o), MATE_MIXER_TYPE_PORT))
+#define MATE_MIXER_PORT_CLASS(k) \
+ (G_TYPE_CHECK_CLASS_CAST ((k), MATE_MIXER_TYPE_PORT, MateMixerPortClass))
+#define MATE_MIXER_IS_PORT_CLASS(k) \
+ (G_TYPE_CLASS_CHECK_CLASS_TYPE ((k), MATE_MIXER_TYPE_PORT))
+#define MATE_MIXER_PORT_GET_CLASS(o) \
+ (G_TYPE_INSTANCE_GET_CLASS ((o), MATE_MIXER_TYPE_PORT, MateMixerPortClass))
+
+typedef struct _MateMixerPort MateMixerPort;
+typedef struct _MateMixerPortClass MateMixerPortClass;
+typedef struct _MateMixerPortPrivate MateMixerPortPrivate;
+
+struct _MateMixerPort
+{
+ GObject parent;
+
+ MateMixerPortPrivate *priv;
+};
+
+struct _MateMixerPortClass
+{
+ GObjectClass parent;
+};
+
+GType mate_mixer_port_get_type (void) G_GNUC_CONST;
+
+MateMixerPort * mate_mixer_port_new (const gchar *name,
+ const gchar *description,
+ const gchar *icon,
+ guint32 priority,
+ MateMixerPortStatus status);
+
+const gchar * mate_mixer_port_get_name (MateMixerPort *port);
+const gchar * mate_mixer_port_get_description (MateMixerPort *port);
+const gchar * mate_mixer_port_get_icon (MateMixerPort *port);
+guint32 mate_mixer_port_get_priority (MateMixerPort *port);
+MateMixerPortStatus mate_mixer_port_get_status (MateMixerPort *port);
+
+G_END_DECLS
+
+#endif /* MATEMIXER_PORT_H */
diff --git a/libmatemixer/matemixer-private.h b/libmatemixer/matemixer-private.h
index 8f95664..0eb012a 100644
--- a/libmatemixer/matemixer-private.h
+++ b/libmatemixer/matemixer-private.h
@@ -22,8 +22,8 @@
G_BEGIN_DECLS
-GList *mate_mixer_get_modules (void);
-gboolean mate_mixer_is_initialized (void);
+const GList *mate_mixer_get_modules (void);
+gboolean mate_mixer_is_initialized (void);
G_END_DECLS
diff --git a/libmatemixer/matemixer-profile.c b/libmatemixer/matemixer-profile.c
new file mode 100644
index 0000000..c32489f
--- /dev/null
+++ b/libmatemixer/matemixer-profile.c
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2014 Michal Ratajsky <[email protected]>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the licence, or (at your option) any later version.
+ *
+ * This 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <glib.h>
+#include <glib-object.h>
+
+#include "matemixer-profile.h"
+
+struct _MateMixerProfilePrivate
+{
+ gchar *name;
+ gchar *description;
+ guint32 priority;
+};
+
+enum
+{
+ PROP_0,
+ PROP_NAME,
+ PROP_DESCRIPTION,
+ PROP_PRIORITY,
+ N_PROPERTIES
+};
+
+static GParamSpec *properties[N_PROPERTIES] = { NULL, };
+
+static void mate_mixer_profile_class_init (MateMixerProfileClass *klass);
+static void mate_mixer_profile_init (MateMixerProfile *profile);
+static void mate_mixer_profile_finalize (GObject *object);
+
+G_DEFINE_TYPE (MateMixerProfile, mate_mixer_profile, G_TYPE_OBJECT);
+
+static void
+mate_mixer_profile_get_property (GObject *object,
+ guint param_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ MateMixerProfile *profile;
+
+ profile = MATE_MIXER_PROFILE (object);
+
+ switch (param_id) {
+ case PROP_NAME:
+ g_value_set_string (value, profile->priv->name);
+ break;
+ case PROP_DESCRIPTION:
+ g_value_set_string (value, profile->priv->description);
+ break;
+ case PROP_PRIORITY:
+ g_value_set_uint (value, profile->priv->priority);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+ break;
+ }
+}
+
+static void
+mate_mixer_profile_set_property (GObject *object,
+ guint param_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ MateMixerProfile *profile;
+
+ profile = MATE_MIXER_PROFILE (object);
+
+ switch (param_id) {
+ case PROP_NAME:
+ profile->priv->name = g_strdup (g_value_get_string (value));
+ break;
+ case PROP_DESCRIPTION:
+ profile->priv->description = g_strdup (g_value_get_string (value));
+ break;
+ case PROP_PRIORITY:
+ profile->priv->priority = g_value_get_uint (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+ break;
+ }
+}
+
+static void
+mate_mixer_profile_class_init (MateMixerProfileClass *klass)
+{
+ GObjectClass *object_class;
+
+ object_class = G_OBJECT_CLASS (klass);
+ object_class->finalize = mate_mixer_profile_finalize;
+ object_class->get_property = mate_mixer_profile_get_property;
+ object_class->set_property = mate_mixer_profile_set_property;
+
+ properties[PROP_NAME] =
+ g_param_spec_string ("name",
+ "Name",
+ "Name of the profile",
+ NULL,
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS);
+
+ properties[PROP_DESCRIPTION] =
+ g_param_spec_string ("description",
+ "Description",
+ "Description of the profile",
+ NULL,
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS);
+
+ properties[PROP_PRIORITY] =
+ g_param_spec_uint ("priority",
+ "Priority",
+ "Priority of the profile",
+ 0,
+ G_MAXUINT32,
+ 0,
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS);
+
+ g_object_class_install_properties (object_class, N_PROPERTIES, properties);
+
+ g_type_class_add_private (object_class, sizeof (MateMixerProfilePrivate));
+}
+
+static void
+mate_mixer_profile_init (MateMixerProfile *profile)
+{
+ profile->priv = G_TYPE_INSTANCE_GET_PRIVATE (profile,
+ MATE_MIXER_TYPE_PROFILE,
+ MateMixerProfilePrivate);
+}
+
+static void
+mate_mixer_profile_finalize (GObject *object)
+{
+ MateMixerProfile *profile;
+
+ profile = MATE_MIXER_PROFILE (object);
+
+ g_free (profile->priv->name);
+ g_free (profile->priv->description);
+
+ G_OBJECT_CLASS (mate_mixer_profile_parent_class)->finalize (object);
+}
+
+MateMixerProfile *
+mate_mixer_profile_new (const gchar *name, const gchar *description, guint32 priority)
+{
+ return g_object_new (MATE_MIXER_TYPE_PROFILE,
+ "name", name,
+ "description", description,
+ "priority", priority,
+ NULL);
+}
+
+const gchar *
+mate_mixer_profile_get_name (MateMixerProfile *profile)
+{
+ g_return_val_if_fail (MATE_MIXER_IS_PROFILE (profile), NULL);
+
+ return profile->priv->name;
+}
+
+const gchar *
+mate_mixer_profile_get_description (MateMixerProfile *profile)
+{
+ g_return_val_if_fail (MATE_MIXER_IS_PROFILE (profile), NULL);
+
+ return profile->priv->description;
+}
+
+guint32
+mate_mixer_profile_get_priority (MateMixerProfile *profile)
+{
+ g_return_val_if_fail (MATE_MIXER_IS_PROFILE (profile), G_MAXUINT32);
+
+ return profile->priv->priority;
+}
diff --git a/libmatemixer/matemixer-profile.h b/libmatemixer/matemixer-profile.h
new file mode 100644
index 0000000..7be140b
--- /dev/null
+++ b/libmatemixer/matemixer-profile.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2014 Michal Ratajsky <[email protected]>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the licence, or (at your option) any later version.
+ *
+ * This 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef MATEMIXER_PROFILE_H
+#define MATEMIXER_PROFILE_H
+
+#include <glib.h>
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define MATE_MIXER_TYPE_PROFILE \
+ (mate_mixer_profile_get_type ())
+#define MATE_MIXER_PROFILE(o) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((o), MATE_MIXER_TYPE_PROFILE, MateMixerProfile))
+#define MATE_MIXER_IS_PROFILE(o) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((o), MATE_MIXER_TYPE_PROFILE))
+#define MATE_MIXER_PROFILE_CLASS(k) \
+ (G_TYPE_CHECK_CLASS_CAST ((k), MATE_MIXER_TYPE_PROFILE, MateMixerProfileClass))
+#define MATE_MIXER_IS_PROFILE_CLASS(k) \
+ (G_TYPE_CLASS_CHECK_CLASS_TYPE ((k), MATE_MIXER_TYPE_PROFILE))
+#define MATE_MIXER_PROFILE_GET_CLASS(o) \
+ (G_TYPE_INSTANCE_GET_CLASS ((o), MATE_MIXER_TYPE_PROFILE, MateMixerProfileClass))
+
+typedef struct _MateMixerProfile MateMixerProfile;
+typedef struct _MateMixerProfileClass MateMixerProfileClass;
+typedef struct _MateMixerProfilePrivate MateMixerProfilePrivate;
+
+struct _MateMixerProfile
+{
+ GObject parent;
+
+ MateMixerProfilePrivate *priv;
+};
+
+struct _MateMixerProfileClass
+{
+ GObjectClass parent;
+};
+
+GType mate_mixer_profile_get_type (void) G_GNUC_CONST;
+
+MateMixerProfile *mate_mixer_profile_new (const gchar *name,
+ const gchar *description,
+ guint32 priority);
+
+const gchar * mate_mixer_profile_get_name (MateMixerProfile *profile);
+const gchar * mate_mixer_profile_get_description (MateMixerProfile *profile);
+guint32 mate_mixer_profile_get_priority (MateMixerProfile *profile);
+
+G_END_DECLS
+
+#endif /* MATEMIXER_PROFILE_H */
diff --git a/libmatemixer/matemixer-stream.c b/libmatemixer/matemixer-stream.c
new file mode 100644
index 0000000..62e0d2e
--- /dev/null
+++ b/libmatemixer/matemixer-stream.c
@@ -0,0 +1,531 @@
+/*
+ * Copyright (C) 2014 Michal Ratajsky <[email protected]>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the licence, or (at your option) any later version.
+ *
+ * This 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <glib.h>
+#include <glib-object.h>
+
+#include "matemixer-device.h"
+#include "matemixer-enums.h"
+#include "matemixer-enum-types.h"
+#include "matemixer-port.h"
+#include "matemixer-stream.h"
+
+G_DEFINE_INTERFACE (MateMixerStream, mate_mixer_stream, G_TYPE_OBJECT)
+
+static void
+mate_mixer_stream_default_init (MateMixerStreamInterface *iface)
+{
+ g_object_interface_install_property (iface,
+ g_param_spec_string ("name",
+ "Name",
+ "Name of the stream",
+ NULL,
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_interface_install_property (iface,
+ g_param_spec_string ("description",
+ "Description",
+ "Description of the stream",
+ NULL,
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_interface_install_property (iface,
+ g_param_spec_string ("icon",
+ "Icon",
+ "Name of the stream icon",
+ NULL,
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_interface_install_property (iface,
+ g_param_spec_object ("device",
+ "Device",
+ "Device the stream belongs to",
+ MATE_MIXER_TYPE_DEVICE,
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_interface_install_property (iface,
+ g_param_spec_enum ("status",
+ "Status",
+ "Status of the stream",
+ MATE_MIXER_TYPE_STREAM_STATUS,
+ MATE_MIXER_STREAM_UNKNOWN_STATUS,
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_interface_install_property (iface,
+ g_param_spec_double ("volume",
+ "Volume",
+ "Volume of the stream",
+ -1, 0, 1,
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_interface_install_property (iface,
+ g_param_spec_string ("mute",
+ "Mute",
+ "Mute state of the stream",
+ FALSE,
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+}
+
+const gchar *
+mate_mixer_stream_get_name (MateMixerStream *stream)
+{
+ MateMixerStreamInterface *iface;
+
+ g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), NULL);
+
+ iface = MATE_MIXER_STREAM_GET_INTERFACE (stream);
+
+ if (iface->get_name)
+ return iface->get_name (stream);
+
+ return NULL;
+}
+
+const gchar *
+mate_mixer_stream_get_description (MateMixerStream *stream)
+{
+ MateMixerStreamInterface *iface;
+
+ g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), NULL);
+
+ iface = MATE_MIXER_STREAM_GET_INTERFACE (stream);
+
+ if (iface->get_description)
+ return iface->get_description (stream);
+
+ return NULL;
+}
+
+const gchar *
+mate_mixer_stream_get_icon (MateMixerStream *stream)
+{
+ MateMixerStreamInterface *iface;
+
+ g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), NULL);
+
+ iface = MATE_MIXER_STREAM_GET_INTERFACE (stream);
+
+ if (iface->get_icon)
+ return iface->get_icon (stream);
+
+ return NULL;
+}
+
+MateMixerDevice *
+mate_mixer_stream_get_device (MateMixerStream *stream)
+{
+ MateMixerStreamInterface *iface;
+
+ g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), NULL);
+
+ iface = MATE_MIXER_STREAM_GET_INTERFACE (stream);
+
+ if (iface->get_device)
+ return iface->get_device (stream);
+
+ return NULL;
+}
+
+MateMixerStreamStatus
+mate_mixer_stream_get_status (MateMixerStream *stream)
+{
+ MateMixerStreamInterface *iface;
+
+ g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), MATE_MIXER_STREAM_UNKNOWN_STATUS);
+
+ iface = MATE_MIXER_STREAM_GET_INTERFACE (stream);
+
+ if (iface->get_status)
+ return iface->get_status (stream);
+
+ return MATE_MIXER_STREAM_UNKNOWN_STATUS;
+}
+
+gboolean
+mate_mixer_stream_get_mute (MateMixerStream *stream)
+{
+ MateMixerStreamInterface *iface;
+
+ g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), FALSE);
+
+ iface = MATE_MIXER_STREAM_GET_INTERFACE (stream);
+
+ if (iface->get_mute)
+ return iface->get_mute (stream);
+
+ return FALSE;
+}
+
+gboolean
+mate_mixer_stream_set_mute (MateMixerStream *stream, gboolean mute)
+{
+ MateMixerStreamInterface *iface;
+
+ g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), FALSE);
+
+ iface = MATE_MIXER_STREAM_GET_INTERFACE (stream);
+
+ if (iface->set_mute)
+ return iface->set_mute (stream, mute);
+
+ return FALSE;
+}
+
+guint32
+mate_mixer_stream_get_volume (MateMixerStream *stream)
+{
+ MateMixerStreamInterface *iface;
+
+ g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), 0);
+
+ iface = MATE_MIXER_STREAM_GET_INTERFACE (stream);
+
+ if (iface->get_volume)
+ return iface->get_volume (stream);
+
+ return 0;
+}
+
+gboolean
+mate_mixer_stream_set_volume (MateMixerStream *stream, guint32 volume)
+{
+ MateMixerStreamInterface *iface;
+
+ g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), FALSE);
+
+ iface = MATE_MIXER_STREAM_GET_INTERFACE (stream);
+
+ if (iface->set_volume)
+ return iface->set_volume (stream, volume);
+
+ return FALSE;
+}
+
+gdouble
+mate_mixer_stream_get_volume_db (MateMixerStream *stream)
+{
+ MateMixerStreamInterface *iface;
+
+ g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), 0);
+
+ iface = MATE_MIXER_STREAM_GET_INTERFACE (stream);
+
+ if (iface->get_volume_db)
+ return iface->get_volume_db (stream);
+
+ return 0;
+}
+
+gboolean
+mate_mixer_stream_set_volume_db (MateMixerStream *stream, gdouble volume_db)
+{
+ MateMixerStreamInterface *iface;
+
+ g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), FALSE);
+
+ iface = MATE_MIXER_STREAM_GET_INTERFACE (stream);
+
+ if (iface->set_volume_db)
+ return iface->set_volume_db (stream, volume_db);
+
+ return FALSE;
+}
+
+guint8
+mate_mixer_stream_get_num_channels (MateMixerStream *stream)
+{
+ MateMixerStreamInterface *iface;
+
+ g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), 0);
+
+ iface = MATE_MIXER_STREAM_GET_INTERFACE (stream);
+
+ if (iface->get_num_channels)
+ return iface->get_num_channels (stream);
+
+ return 0;
+}
+
+MateMixerChannelPosition
+mate_mixer_stream_get_channel_position (MateMixerStream *stream, guint8 channel)
+{
+ MateMixerStreamInterface *iface;
+
+ g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), MATE_MIXER_CHANNEL_UNKNOWN_POSITION);
+
+ iface = MATE_MIXER_STREAM_GET_INTERFACE (stream);
+
+ if (iface->get_channel_position)
+ return iface->get_channel_position (stream, channel);
+
+ return MATE_MIXER_CHANNEL_UNKNOWN_POSITION;
+}
+
+guint32
+mate_mixer_stream_get_channel_volume (MateMixerStream *stream, guint8 channel)
+{
+ MateMixerStreamInterface *iface;
+
+ g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), 0);
+
+ iface = MATE_MIXER_STREAM_GET_INTERFACE (stream);
+
+ if (iface->get_channel_volume)
+ return iface->get_channel_volume (stream, channel);
+
+ return 0;
+}
+
+gboolean
+mate_mixer_stream_set_channel_volume (MateMixerStream *stream, guint8 channel, guint32 volume)
+{
+ MateMixerStreamInterface *iface;
+
+ g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), FALSE);
+
+ iface = MATE_MIXER_STREAM_GET_INTERFACE (stream);
+
+ if (iface->set_channel_volume)
+ return iface->set_channel_volume (stream, channel, volume);
+
+ return FALSE;
+}
+
+gdouble
+mate_mixer_stream_get_channel_volume_db (MateMixerStream *stream, guint8 channel)
+{
+ MateMixerStreamInterface *iface;
+
+ g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), 0);
+
+ iface = MATE_MIXER_STREAM_GET_INTERFACE (stream);
+
+ if (iface->get_channel_volume_db)
+ return iface->get_channel_volume_db (stream, channel);
+
+ return 0;
+}
+
+gboolean
+mate_mixer_stream_set_channel_volume_db (MateMixerStream *stream, guint8 channel, gdouble volume_db)
+{
+ MateMixerStreamInterface *iface;
+
+ g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), FALSE);
+
+ iface = MATE_MIXER_STREAM_GET_INTERFACE (stream);
+
+ if (iface->set_channel_volume_db)
+ return iface->set_channel_volume_db (stream, channel, volume_db);
+
+ return FALSE;
+}
+
+gboolean
+mate_mixer_stream_has_position (MateMixerStream *stream, MateMixerChannelPosition position)
+{
+ MateMixerStreamInterface *iface;
+
+ g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), FALSE);
+
+ iface = MATE_MIXER_STREAM_GET_INTERFACE (stream);
+
+ if (iface->has_position)
+ return iface->has_position (stream, position);
+
+ return FALSE;
+}
+
+guint32
+mate_mixer_stream_get_position_volume (MateMixerStream *stream, MateMixerChannelPosition position)
+{
+ MateMixerStreamInterface *iface;
+
+ g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), 0);
+
+ iface = MATE_MIXER_STREAM_GET_INTERFACE (stream);
+
+ if (iface->get_position_volume)
+ return iface->get_position_volume (stream, position);
+
+ return 0;
+}
+
+gboolean
+mate_mixer_stream_set_position_volume (MateMixerStream *stream, MateMixerChannelPosition position, guint32 volume)
+{
+ MateMixerStreamInterface *iface;
+
+ g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), FALSE);
+
+ iface = MATE_MIXER_STREAM_GET_INTERFACE (stream);
+
+ if (iface->set_position_volume)
+ return iface->set_position_volume (stream, position, volume);
+
+ return FALSE;
+}
+
+gdouble
+mate_mixer_stream_get_position_volume_db (MateMixerStream *stream, MateMixerChannelPosition position)
+{
+ MateMixerStreamInterface *iface;
+
+ g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), 0);
+
+ iface = MATE_MIXER_STREAM_GET_INTERFACE (stream);
+
+ if (iface->get_position_volume_db)
+ return iface->get_position_volume_db (stream, position);
+
+ return 0;
+}
+
+gboolean
+mate_mixer_stream_set_position_volume_db (MateMixerStream *stream, MateMixerChannelPosition position, gdouble volume_db)
+{
+ MateMixerStreamInterface *iface;
+
+ g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), FALSE);
+
+ iface = MATE_MIXER_STREAM_GET_INTERFACE (stream);
+
+ if (iface->set_position_volume_db)
+ return iface->set_position_volume_db (stream, position, volume_db);
+
+ return FALSE;
+}
+
+gdouble
+mate_mixer_stream_get_balance (MateMixerStream *stream)
+{
+ MateMixerStreamInterface *iface;
+
+ g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), 0);
+
+ iface = MATE_MIXER_STREAM_GET_INTERFACE (stream);
+
+ if (iface->get_balance)
+ return iface->get_balance (stream);
+
+ return 0;
+}
+
+gboolean
+mate_mixer_stream_set_balance (MateMixerStream *stream, gdouble balance)
+{
+ MateMixerStreamInterface *iface;
+
+ g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), FALSE);
+
+ iface = MATE_MIXER_STREAM_GET_INTERFACE (stream);
+
+ if (iface->set_balance)
+ return iface->set_balance (stream, balance);
+
+ return FALSE;
+}
+
+gdouble
+mate_mixer_stream_get_fade (MateMixerStream *stream)
+{
+ MateMixerStreamInterface *iface;
+
+ g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), 0);
+
+ iface = MATE_MIXER_STREAM_GET_INTERFACE (stream);
+
+ if (iface->get_fade)
+ return iface->get_fade (stream);
+
+ return 0;
+}
+
+gboolean
+mate_mixer_stream_set_fade (MateMixerStream *stream, gdouble fade)
+{
+ MateMixerStreamInterface *iface;
+
+ g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), FALSE);
+
+ iface = MATE_MIXER_STREAM_GET_INTERFACE (stream);
+
+ if (iface->set_fade)
+ return iface->set_fade (stream, fade);
+
+ return FALSE;
+}
+
+const GList *
+mate_mixer_stream_list_ports (MateMixerStream *stream)
+{
+ MateMixerStreamInterface *iface;
+
+ g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), NULL);
+
+ iface = MATE_MIXER_STREAM_GET_INTERFACE (stream);
+
+ if (iface->list_ports)
+ return iface->list_ports (stream);
+
+ return NULL;
+}
+
+MateMixerPort *
+mate_mixer_stream_get_active_port (MateMixerStream *stream)
+{
+ MateMixerStreamInterface *iface;
+
+ g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), NULL);
+
+ iface = MATE_MIXER_STREAM_GET_INTERFACE (stream);
+
+ if (iface->get_active_port)
+ return iface->get_active_port (stream);
+
+ return NULL;
+}
+
+gboolean
+mate_mixer_stream_set_active_port (MateMixerStream *stream, MateMixerPort *port)
+{
+ MateMixerStreamInterface *iface;
+
+ g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), FALSE);
+ g_return_val_if_fail (MATE_MIXER_IS_PORT (port), FALSE);
+
+ iface = MATE_MIXER_STREAM_GET_INTERFACE (stream);
+
+ if (iface->set_active_port)
+ return iface->set_active_port (stream, port);
+
+ return FALSE;
+}
diff --git a/libmatemixer/matemixer-stream.h b/libmatemixer/matemixer-stream.h
new file mode 100644
index 0000000..f95f13f
--- /dev/null
+++ b/libmatemixer/matemixer-stream.h
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2014 Michal Ratajsky <[email protected]>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the licence, or (at your option) any later version.
+ *
+ * This 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef MATEMIXER_STREAM_H
+#define MATEMIXER_STREAM_H
+
+#include <glib.h>
+#include <glib-object.h>
+
+#include <libmatemixer/matemixer-device.h>
+#include <libmatemixer/matemixer-enums.h>
+#include <libmatemixer/matemixer-port.h>
+
+G_BEGIN_DECLS
+
+#define MATE_MIXER_TYPE_STREAM \
+ (mate_mixer_stream_get_type ())
+#define MATE_MIXER_STREAM(o) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((o), MATE_MIXER_TYPE_STREAM, MateMixerStream))
+#define MATE_MIXER_IS_STREAM(o) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((o), MATE_MIXER_TYPE_STREAM))
+#define MATE_MIXER_STREAM_GET_INTERFACE(o) \
+ (G_TYPE_INSTANCE_GET_INTERFACE ((o), MATE_MIXER_TYPE_STREAM, MateMixerStreamInterface))
+
+typedef struct _MateMixerStream MateMixerStream; /* dummy object */
+typedef struct _MateMixerStreamInterface MateMixerStreamInterface;
+
+struct _MateMixerStreamInterface
+{
+ GTypeInterface parent;
+
+ const gchar * (*get_name) (MateMixerStream *stream);
+ const gchar * (*get_description) (MateMixerStream *stream);
+ const gchar * (*get_icon) (MateMixerStream *stream);
+ MateMixerDevice * (*get_device) (MateMixerStream *stream);
+ MateMixerStreamStatus (*get_status) (MateMixerStream *stream);
+ gboolean (*get_mute) (MateMixerStream *stream);
+ gboolean (*set_mute) (MateMixerStream *stream,
+ gboolean mute);
+ guint32 (*get_volume) (MateMixerStream *stream);
+ gboolean (*set_volume) (MateMixerStream *stream,
+ guint32 volume);
+ gdouble (*get_volume_db) (MateMixerStream *stream);
+ gboolean (*set_volume_db) (MateMixerStream *stream,
+ gdouble volume_db);
+ guint8 (*get_num_channels) (MateMixerStream *stream);
+ MateMixerChannelPosition (*get_channel_position) (MateMixerStream *stream,
+ guint8 channel);
+ guint32 (*get_channel_volume) (MateMixerStream *stream,
+ guint8 channel);
+ gboolean (*set_channel_volume) (MateMixerStream *stream,
+ guint8 channel,
+ guint32 volume);
+ gdouble (*get_channel_volume_db) (MateMixerStream *stream,
+ guint8 channel);
+ gboolean (*set_channel_volume_db) (MateMixerStream *stream,
+ guint8 channel,
+ gdouble volume_db);
+ gboolean (*has_position) (MateMixerStream *stream,
+ MateMixerChannelPosition position);
+ guint32 (*get_position_volume) (MateMixerStream *stream,
+ MateMixerChannelPosition position);
+ gboolean (*set_position_volume) (MateMixerStream *stream,
+ MateMixerChannelPosition position,
+ guint32 volume);
+ gdouble (*get_position_volume_db) (MateMixerStream *stream,
+ MateMixerChannelPosition position);
+ gboolean (*set_position_volume_db) (MateMixerStream *stream,
+ MateMixerChannelPosition position,
+ gdouble volume);
+ gboolean (*get_balance) (MateMixerStream *stream);
+ gboolean (*set_balance) (MateMixerStream *stream,
+ gdouble balance);
+ gboolean (*get_fade) (MateMixerStream *stream);
+ gboolean (*set_fade) (MateMixerStream *stream,
+ gdouble fade);
+ MateMixerPort * (*get_active_port) (MateMixerStream *stream);
+ gboolean (*set_active_port) (MateMixerStream *stream,
+ MateMixerPort *port);
+ const GList * (*list_ports) (MateMixerStream *stream);
+};
+
+GType mate_mixer_stream_get_type (void) G_GNUC_CONST;
+
+const gchar * mate_mixer_stream_get_name (MateMixerStream *stream);
+const gchar * mate_mixer_stream_get_description (MateMixerStream *stream);
+const gchar * mate_mixer_stream_get_icon (MateMixerStream *stream);
+MateMixerDevice * mate_mixer_stream_get_device (MateMixerStream *stream);
+MateMixerStreamStatus mate_mixer_stream_get_status (MateMixerStream *stream);
+
+gboolean mate_mixer_stream_get_mute (MateMixerStream *stream);
+gboolean mate_mixer_stream_set_mute (MateMixerStream *stream,
+ gboolean mute);
+
+guint32 mate_mixer_stream_get_volume (MateMixerStream *stream);
+gboolean mate_mixer_stream_set_volume (MateMixerStream *stream,
+ guint32 volume);
+
+gdouble mate_mixer_stream_get_volume_db (MateMixerStream *stream);
+gboolean mate_mixer_stream_set_volume_db (MateMixerStream *stream,
+ gdouble volume_db);
+
+guint8 mate_mixer_stream_get_num_channels (MateMixerStream *stream);
+
+MateMixerChannelPosition mate_mixer_stream_get_channel_position (MateMixerStream *stream,
+ guint8 channel);
+
+guint32 mate_mixer_stream_get_channel_volume (MateMixerStream *stream,
+ guint8 channel);
+gboolean mate_mixer_stream_set_channel_volume (MateMixerStream *stream,
+ guint8 channel,
+ guint32 volume);
+
+gdouble mate_mixer_stream_get_channel_volume_db (MateMixerStream *stream,
+ guint8 channel);
+gboolean mate_mixer_stream_set_channel_volume_db (MateMixerStream *stream,
+ guint8 channel,
+ gdouble volume_db);
+
+gboolean mate_mixer_stream_has_position (MateMixerStream *stream,
+ MateMixerChannelPosition position);
+
+guint32 mate_mixer_stream_get_position_volume (MateMixerStream *stream,
+ MateMixerChannelPosition position);
+gboolean mate_mixer_stream_set_position_volume (MateMixerStream *stream,
+ MateMixerChannelPosition position,
+ guint32 volume);
+
+gdouble mate_mixer_stream_get_position_volume_db (MateMixerStream *stream,
+ MateMixerChannelPosition position);
+gboolean mate_mixer_stream_set_position_volume_db (MateMixerStream *stream,
+ MateMixerChannelPosition position,
+ gdouble volume_db);
+
+gdouble mate_mixer_stream_get_balance (MateMixerStream *stream);
+gboolean mate_mixer_stream_set_balance (MateMixerStream *stream,
+ gdouble balance);
+
+gdouble mate_mixer_stream_get_fade (MateMixerStream *stream);
+gboolean mate_mixer_stream_set_fade (MateMixerStream *stream,
+ gdouble fade);
+
+const GList * mate_mixer_stream_list_ports (MateMixerStream *stream);
+
+MateMixerPort * mate_mixer_stream_get_active_port (MateMixerStream *stream);
+gboolean mate_mixer_stream_set_active_port (MateMixerStream *stream,
+ MateMixerPort *port);
+
+G_END_DECLS
+
+#endif /* MATEMIXER_STREAM_H */
diff --git a/libmatemixer/matemixer-track.c b/libmatemixer/matemixer-track.c
deleted file mode 100644
index f78c4f8..0000000
--- a/libmatemixer/matemixer-track.c
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2014 Michal Ratajsky <[email protected]>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the licence, or (at your option) any later version.
- *
- * This 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <glib.h>
-#include <glib-object.h>
-
-#include "matemixer-track.h"
-
-G_DEFINE_INTERFACE (MateMixerTrack, mate_mixer_track, G_TYPE_OBJECT)
-
-static void
-mate_mixer_track_default_init (MateMixerTrackInterface *iface)
-{
- // TODO: properties
-}
diff --git a/libmatemixer/matemixer-track.h b/libmatemixer/matemixer-track.h
deleted file mode 100644
index a535b59..0000000
--- a/libmatemixer/matemixer-track.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2014 Michal Ratajsky <[email protected]>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the licence, or (at your option) any later version.
- *
- * This 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef MATEMIXER_TRACK_H
-#define MATEMIXER_TRACK_H
-
-#include <glib.h>
-#include <glib-object.h>
-
-G_BEGIN_DECLS
-
-#define MATE_MIXER_TYPE_TRACK \
- (mate_mixer_track_get_type ())
-#define MATE_MIXER_TRACK(o) \
- (G_TYPE_CHECK_INSTANCE_CAST ((o), MATE_MIXER_TYPE_TRACK, MateMixerTrack))
-#define MATE_MIXER_IS_TRACK(o) \
- (G_TYPE_CHECK_INSTANCE_TYPE ((o), MATE_MIXER_TYPE_TRACK))
-#define MATE_MIXER_TRACK_GET_INTERFACE(o) \
- (G_TYPE_INSTANCE_GET_INTERFACE ((o), MATE_MIXER_TYPE_TRACK, MateMixerTrackInterface))
-
-typedef struct _MateMixerTrack MateMixerTrack; /* dummy object */
-typedef struct _MateMixerTrackInterface MateMixerTrackInterface;
-
-struct _MateMixerTrackInterface
-{
- GTypeInterface parent;
-};
-
-GType mate_mixer_track_get_type (void) G_GNUC_CONST;
-
-G_END_DECLS
-
-#endif /* MATEMIXER_TRACK_H */
diff --git a/libmatemixer/matemixer.c b/libmatemixer/matemixer.c
index cc4b5f1..3c8f643 100644
--- a/libmatemixer/matemixer.c
+++ b/libmatemixer/matemixer.c
@@ -55,11 +55,8 @@ mate_mixer_init (void)
}
if (mixer_modules) {
- /* Sort the usable modules by the priority */
- mixer_modules = g_list_sort (
- mixer_modules,
- mixer_compare_modules);
-
+ /* Sort the usable modules by their priority */
+ mixer_modules = g_list_sort (mixer_modules, mixer_compare_modules);
mixer_initialized = TRUE;
} else
g_critical ("No usable backend modules have been found");
@@ -85,11 +82,11 @@ mate_mixer_deinit (void)
mixer_initialized = FALSE;
}
-/* Internal function: return a shared list of loaded backend modules */
-GList *
+/* Internal function: return a list of loaded backend modules */
+const GList *
mate_mixer_get_modules (void)
{
- return mixer_modules;
+ return (const GList *) mixer_modules;
}
/* Internal function: return TRUE if the library has been initialized */
@@ -124,10 +121,8 @@ mixer_load_modules (void)
continue;
file = g_build_filename (LIBMATEMIXER_BACKEND_DIR, name, NULL);
- mixer_modules = g_list_prepend (
- mixer_modules,
- mate_mixer_backend_module_new (file));
-
+ mixer_modules = g_list_prepend (mixer_modules,
+ mate_mixer_backend_module_new (file));
g_free (file);
}
@@ -151,7 +146,7 @@ mixer_load_modules (void)
static gint
mixer_compare_modules (gconstpointer a, gconstpointer b)
{
- const MateMixerBackendModuleInfo *info1, *info2;
+ const MateMixerBackendInfo *info1, *info2;
info1 = mate_mixer_backend_module_get_info (MATE_MIXER_BACKEND_MODULE (a));
info2 = mate_mixer_backend_module_get_info (MATE_MIXER_BACKEND_MODULE (b));
diff --git a/libmatemixer/matemixer.h b/libmatemixer/matemixer.h
index 8a62320..b43de79 100644
--- a/libmatemixer/matemixer.h
+++ b/libmatemixer/matemixer.h
@@ -22,7 +22,7 @@
#include <libmatemixer/matemixer-control.h>
#include <libmatemixer/matemixer-device.h>
#include <libmatemixer/matemixer-enums.h>
-#include <libmatemixer/matemixer-track.h>
+#include <libmatemixer/matemixer-stream.h>
G_BEGIN_DECLS