summaryrefslogtreecommitdiff
path: root/libmatemixer
diff options
context:
space:
mode:
authorMichal Ratajsky <[email protected]>2014-06-13 17:36:14 +0200
committerMichal Ratajsky <[email protected]>2014-06-13 17:36:14 +0200
commita2290d5e13ccee88fd9ae66a3895eb4da646f81f (patch)
tree4948171de11f476e5a0b7d7d44bdbad8b422d812 /libmatemixer
parent7cf09a2b40a507caf2bea0c54af00da84a8f88af (diff)
downloadlibmatemixer-a2290d5e13ccee88fd9ae66a3895eb4da646f81f.tar.bz2
libmatemixer-a2290d5e13ccee88fd9ae66a3895eb4da646f81f.tar.xz
Weekly update
Diffstat (limited to 'libmatemixer')
-rw-r--r--libmatemixer/Makefile.am8
-rw-r--r--libmatemixer/matemixer-backend-module.c22
-rw-r--r--libmatemixer/matemixer-backend-module.h6
-rw-r--r--libmatemixer/matemixer-backend.c163
-rw-r--r--libmatemixer/matemixer-backend.h70
-rw-r--r--libmatemixer/matemixer-client-stream.c83
-rw-r--r--libmatemixer/matemixer-client-stream.h59
-rw-r--r--libmatemixer/matemixer-control.c1043
-rw-r--r--libmatemixer/matemixer-control.h67
-rw-r--r--libmatemixer/matemixer-device.c7
-rw-r--r--libmatemixer/matemixer-device.h8
-rw-r--r--libmatemixer/matemixer-enum-types.c30
-rw-r--r--libmatemixer/matemixer-enum-types.h13
-rw-r--r--libmatemixer/matemixer-enums.h61
-rw-r--r--libmatemixer/matemixer-port.c102
-rw-r--r--libmatemixer/matemixer-port.h32
-rw-r--r--libmatemixer/matemixer-profile.c65
-rw-r--r--libmatemixer/matemixer-profile.h16
-rw-r--r--libmatemixer/matemixer-stream.c131
-rw-r--r--libmatemixer/matemixer-stream.h69
-rw-r--r--libmatemixer/matemixer-version.h.in64
-rw-r--r--libmatemixer/matemixer.c27
-rw-r--r--libmatemixer/matemixer.h4
23 files changed, 1848 insertions, 302 deletions
diff --git a/libmatemixer/Makefile.am b/libmatemixer/Makefile.am
index 0280b27..a45b29c 100644
--- a/libmatemixer/Makefile.am
+++ b/libmatemixer/Makefile.am
@@ -10,12 +10,14 @@ libmatemixer_includedir = $(includedir)/libmatemixer
libmatemixer_include_HEADERS = \
matemixer.h \
+ matemixer-client-stream.h \
matemixer-control.h \
matemixer-device.h \
matemixer-enums.h \
matemixer-port.h \
matemixer-profile.h \
- matemixer-stream.h
+ matemixer-stream.h \
+ matemixer-version.h
libmatemixer_la_CFLAGS = $(GLIB_CFLAGS)
@@ -26,6 +28,7 @@ libmatemixer_la_SOURCES = \
matemixer-backend.h \
matemixer-backend-module.c \
matemixer-backend-module.h \
+ matemixer-client-stream.c \
matemixer-control.c \
matemixer-device.c \
matemixer-enum-types.c \
@@ -38,6 +41,9 @@ libmatemixer_la_LIBADD = $(GLIB_LIBS)
libmatemixer_la_LDFLAGS = \
-version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) \
+ -no-undefined \
-export-dynamic
+EXTRA_DIST = matemixer-version.h.in
+
-include $(top_srcdir)/git.mk
diff --git a/libmatemixer/matemixer-backend-module.c b/libmatemixer/matemixer-backend-module.c
index 5ad2836..b04ad6f 100644
--- a/libmatemixer/matemixer-backend-module.c
+++ b/libmatemixer/matemixer-backend-module.c
@@ -22,8 +22,6 @@
#include "matemixer-backend.h"
#include "matemixer-backend-module.h"
-G_DEFINE_TYPE (MateMixerBackendModule, mate_mixer_backend_module, G_TYPE_TYPE_MODULE);
-
struct _MateMixerBackendModulePrivate
{
GModule *gmodule;
@@ -44,6 +42,8 @@ static void mate_mixer_backend_module_finalize (GObject
static gboolean mate_mixer_backend_module_load (GTypeModule *gmodule);
static void mate_mixer_backend_module_unload (GTypeModule *gmodule);
+G_DEFINE_TYPE (MateMixerBackendModule, mate_mixer_backend_module, G_TYPE_TYPE_MODULE);
+
static void
mate_mixer_backend_module_class_init (MateMixerBackendModuleClass *klass)
{
@@ -58,7 +58,7 @@ mate_mixer_backend_module_class_init (MateMixerBackendModuleClass *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));
+ g_type_class_add_private (klass, sizeof (MateMixerBackendModulePrivate));
}
static void
@@ -88,11 +88,7 @@ mate_mixer_backend_module_dispose (GObject *object)
static void
mate_mixer_backend_module_finalize (GObject *object)
{
- MateMixerBackendModule *module;
-
- module = MATE_MIXER_BACKEND_MODULE (object);
-
- g_free (module->priv->path);
+ g_free (MATE_MIXER_BACKEND_MODULE (object)->priv->path);
G_OBJECT_CLASS (mate_mixer_backend_module_parent_class)->finalize (object);
}
@@ -139,8 +135,8 @@ mate_mixer_backend_module_load (GTypeModule *type_module)
module->priv->init (type_module);
module->priv->loaded = TRUE;
- /* Make sure get_info () returns something so we can avoid checking
- * it in other parts of the library */
+ /* Make sure get_info() returns something so we can avoid checking 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);
@@ -158,7 +154,7 @@ mate_mixer_backend_module_load (GTypeModule *type_module)
g_debug ("Loaded backend module %s", module->priv->path);
} else {
- /* This function was called before so initialize only */
+ /* This function was called before, so initialize only */
module->priv->init (type_module);
}
return TRUE;
@@ -171,8 +167,8 @@ mate_mixer_backend_module_unload (GTypeModule *type_module)
module = MATE_MIXER_BACKEND_MODULE (type_module);
- /* Only deinitialize the backend module, do not modify the loaded
- * flag as the module remains loaded */
+ /* Only deinitialize the backend module, do not modify the loaded flag
+ * as the module remains loaded */
if (module->priv->deinit)
module->priv->deinit ();
}
diff --git a/libmatemixer/matemixer-backend-module.h b/libmatemixer/matemixer-backend-module.h
index b629bfc..61a426d 100644
--- a/libmatemixer/matemixer-backend-module.h
+++ b/libmatemixer/matemixer-backend-module.h
@@ -61,11 +61,11 @@ struct _MateMixerBackendModuleClass
GTypeModuleClass parent;
};
-GType mate_mixer_backend_module_get_type (void) G_GNUC_CONST;
+GType mate_mixer_backend_module_get_type (void) G_GNUC_CONST;
-MateMixerBackendModule *mate_mixer_backend_module_new (const gchar *path);
+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);
+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 890c34b..474edd4 100644
--- a/libmatemixer/matemixer-backend.c
+++ b/libmatemixer/matemixer-backend.c
@@ -19,15 +19,121 @@
#include <glib-object.h>
#include "matemixer-backend.h"
+#include "matemixer-enums.h"
+#include "matemixer-enum-types.h"
#include "matemixer-stream.h"
+enum {
+ DEVICE_ADDED,
+ DEVICE_CHANGED,
+ DEVICE_REMOVED,
+ STREAM_ADDED,
+ STREAM_CHANGED,
+ STREAM_REMOVED,
+ N_SIGNALS
+};
+
+static guint signals[N_SIGNALS] = { 0, };
+
G_DEFINE_INTERFACE (MateMixerBackend, mate_mixer_backend, G_TYPE_OBJECT)
static void
mate_mixer_backend_default_init (MateMixerBackendInterface *iface)
{
+ g_object_interface_install_property (iface,
+ g_param_spec_enum ("state",
+ "State",
+ "Backend connection state",
+ MATE_MIXER_TYPE_STATE,
+ MATE_MIXER_STATE_IDLE,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS));
+
+ signals[DEVICE_ADDED] = g_signal_new ("device-added",
+ G_TYPE_FROM_INTERFACE (iface),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (MateMixerBackendInterface, device_added),
+ NULL,
+ NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE,
+ 1,
+ G_TYPE_STRING);
+
+ signals[DEVICE_CHANGED] = g_signal_new ("device-changed",
+ G_TYPE_FROM_INTERFACE (iface),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (MateMixerBackendInterface, device_changed),
+ NULL,
+ NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE,
+ 1,
+ G_TYPE_STRING);
+
+ signals[DEVICE_REMOVED] = g_signal_new ("device-removed",
+ G_TYPE_FROM_INTERFACE (iface),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (MateMixerBackendInterface, device_removed),
+ NULL,
+ NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE,
+ 1,
+ G_TYPE_STRING);
+
+ signals[STREAM_ADDED] = g_signal_new ("stream-added",
+ G_TYPE_FROM_INTERFACE (iface),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (MateMixerBackendInterface, stream_added),
+ NULL,
+ NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE,
+ 1,
+ G_TYPE_STRING);
+
+ signals[STREAM_CHANGED] = g_signal_new ("stream-changed",
+ G_TYPE_FROM_INTERFACE (iface),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (MateMixerBackendInterface, stream_changed),
+ NULL,
+ NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE,
+ 1,
+ G_TYPE_STRING);
+
+ signals[STREAM_REMOVED] = g_signal_new ("stream-removed",
+ G_TYPE_FROM_INTERFACE (iface),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (MateMixerBackendInterface, stream_removed),
+ NULL,
+ NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE,
+ 1,
+ G_TYPE_STRING);
+}
+
+void
+mate_mixer_backend_set_data (MateMixerBackend *backend, const MateMixerBackendData *data)
+{
+ MateMixerBackendInterface *iface;
+
+ g_return_if_fail (MATE_MIXER_IS_BACKEND (backend));
+
+ iface = MATE_MIXER_BACKEND_GET_INTERFACE (backend);
+
+ if (iface->set_data)
+ iface->set_data (backend, data);
}
+/*
+ * Required behaviour:
+ * if the function returns TRUE, the state must be either MATE_MIXER_STATE_READY or
+ * MATE_MIXER_STATE_CONNECTING.
+ */
gboolean
mate_mixer_backend_open (MateMixerBackend *backend)
{
@@ -37,10 +143,11 @@ mate_mixer_backend_open (MateMixerBackend *backend)
iface = MATE_MIXER_BACKEND_GET_INTERFACE (backend);
- if (iface->open)
- return iface->open (backend);
-
- return FALSE;
+ if (!iface->open) {
+ g_critical ("Backend module does not implement the open() method");
+ return FALSE;
+ }
+ return iface->open (backend);
}
void
@@ -56,6 +163,22 @@ mate_mixer_backend_close (MateMixerBackend *backend)
iface->close (backend);
}
+MateMixerState
+mate_mixer_backend_get_state (MateMixerBackend *backend)
+{
+ MateMixerBackendInterface *iface;
+
+ g_return_val_if_fail (MATE_MIXER_IS_BACKEND (backend), MATE_MIXER_STATE_UNKNOWN);
+
+ iface = MATE_MIXER_BACKEND_GET_INTERFACE (backend);
+
+ if (!iface->get_state) {
+ g_critical ("Backend module does not implement the get_state() method");
+ return MATE_MIXER_STATE_UNKNOWN;
+ }
+ return iface->get_state (backend);
+}
+
GList *
mate_mixer_backend_list_devices (MateMixerBackend *backend)
{
@@ -101,6 +224,22 @@ mate_mixer_backend_get_default_input_stream (MateMixerBackend *backend)
return NULL;
}
+gboolean
+mate_mixer_backend_set_default_input_stream (MateMixerBackend *backend,
+ MateMixerStream *stream)
+{
+ MateMixerBackendInterface *iface;
+
+ g_return_val_if_fail (MATE_MIXER_IS_BACKEND (backend), FALSE);
+
+ iface = MATE_MIXER_BACKEND_GET_INTERFACE (backend);
+
+ if (iface->set_default_input_stream)
+ return iface->set_default_input_stream (backend, stream);
+
+ return FALSE;
+}
+
MateMixerStream *
mate_mixer_backend_get_default_output_stream (MateMixerBackend *backend)
{
@@ -115,3 +254,19 @@ mate_mixer_backend_get_default_output_stream (MateMixerBackend *backend)
return NULL;
}
+
+gboolean
+mate_mixer_backend_set_default_output_stream (MateMixerBackend *backend,
+ MateMixerStream *stream)
+{
+ MateMixerBackendInterface *iface;
+
+ g_return_val_if_fail (MATE_MIXER_IS_BACKEND (backend), FALSE);
+
+ iface = MATE_MIXER_BACKEND_GET_INTERFACE (backend);
+
+ if (iface->set_default_output_stream)
+ return iface->set_default_output_stream (backend, stream);
+
+ return FALSE;
+}
diff --git a/libmatemixer/matemixer-backend.h b/libmatemixer/matemixer-backend.h
index 897641f..1a5418f 100644
--- a/libmatemixer/matemixer-backend.h
+++ b/libmatemixer/matemixer-backend.h
@@ -25,6 +25,15 @@
G_BEGIN_DECLS
+typedef struct
+{
+ gchar *app_name;
+ gchar *app_id;
+ gchar *app_version;
+ gchar *app_icon;
+ gchar *server_address;
+} MateMixerBackendData;
+
#define MATE_MIXER_TYPE_BACKEND \
(mate_mixer_backend_get_type ())
#define MATE_MIXER_BACKEND(o) \
@@ -42,23 +51,58 @@ struct _MateMixerBackendInterface
GTypeInterface parent;
/* Required */
- gboolean (*open) (MateMixerBackend *backend);
+ gboolean (*open) (MateMixerBackend *backend);
+ MateMixerState (*get_state) (MateMixerBackend *backend);
+
+ /* Optional */
+ void (*set_data) (MateMixerBackend *backend,
+ const MateMixerBackendData *data);
- 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);
+ void (*close) (MateMixerBackend *backend);
+ GList *(*list_devices) (MateMixerBackend *backend);
+ GList *(*list_streams) (MateMixerBackend *backend);
+ MateMixerStream *(*get_default_input_stream) (MateMixerBackend *backend);
+ gboolean (*set_default_input_stream) (MateMixerBackend *backend,
+ MateMixerStream *stream);
+ MateMixerStream *(*get_default_output_stream) (MateMixerBackend *backend);
+ gboolean (*set_default_output_stream) (MateMixerBackend *backend,
+ MateMixerStream *stream);
+
+ /* Signals */
+ void (*device_added) (MateMixerBackend *backend,
+ const gchar *name);
+ void (*device_changed) (MateMixerBackend *backend,
+ const gchar *name);
+ void (*device_removed) (MateMixerBackend *backend,
+ const gchar *name);
+ void (*stream_added) (MateMixerBackend *backend,
+ const gchar *name);
+ void (*stream_changed) (MateMixerBackend *backend,
+ const gchar *name);
+ void (*stream_removed) (MateMixerBackend *backend,
+ const gchar *name);
};
-GType mate_mixer_backend_get_type (void) G_GNUC_CONST;
+GType mate_mixer_backend_get_type (void) G_GNUC_CONST;
+
+void mate_mixer_backend_set_data (MateMixerBackend *backend,
+ const MateMixerBackendData *data);
+
+gboolean mate_mixer_backend_open (MateMixerBackend *backend);
+void mate_mixer_backend_close (MateMixerBackend *backend);
+
+MateMixerState mate_mixer_backend_get_state (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);
+gboolean mate_mixer_backend_set_default_input_stream (MateMixerBackend *backend,
+ MateMixerStream *stream);
-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);
+MateMixerStream *mate_mixer_backend_get_default_output_stream (MateMixerBackend *backend);
+gboolean mate_mixer_backend_set_default_output_stream (MateMixerBackend *backend,
+ MateMixerStream *stream);
G_END_DECLS
diff --git a/libmatemixer/matemixer-client-stream.c b/libmatemixer/matemixer-client-stream.c
new file mode 100644
index 0000000..80f48a9
--- /dev/null
+++ b/libmatemixer/matemixer-client-stream.c
@@ -0,0 +1,83 @@
+/*
+ * 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-client-stream.h"
+#include "matemixer-stream.h"
+
+G_DEFINE_INTERFACE (MateMixerClientStream, mate_mixer_client_stream, G_TYPE_OBJECT)
+
+static void
+mate_mixer_client_stream_default_init (MateMixerClientStreamInterface *iface)
+{
+ g_object_interface_install_property (iface,
+ g_param_spec_object ("parent",
+ "Parent",
+ "Parent stream of the client stream",
+ MATE_MIXER_TYPE_STREAM,
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+}
+
+MateMixerStream *
+mate_mixer_client_stream_get_parent (MateMixerClientStream *client)
+{
+ MateMixerClientStreamInterface *iface;
+
+ g_return_val_if_fail (MATE_MIXER_IS_CLIENT_STREAM (client), NULL);
+
+ iface = MATE_MIXER_CLIENT_STREAM_GET_INTERFACE (client);
+
+ if (iface->get_parent)
+ return iface->get_parent (client);
+
+ return NULL;
+}
+
+gboolean
+mate_mixer_client_stream_set_parent (MateMixerClientStream *client, MateMixerStream *parent)
+{
+ MateMixerClientStreamInterface *iface;
+
+ g_return_val_if_fail (MATE_MIXER_IS_CLIENT_STREAM (client), FALSE);
+ g_return_val_if_fail (MATE_MIXER_IS_STREAM (parent), FALSE);
+
+ iface = MATE_MIXER_CLIENT_STREAM_GET_INTERFACE (client);
+
+ if (iface->set_parent)
+ return iface->set_parent (client, parent);
+
+ return FALSE;
+}
+
+gboolean
+mate_mixer_client_stream_remove (MateMixerClientStream *client)
+{
+ MateMixerClientStreamInterface *iface;
+
+ g_return_val_if_fail (MATE_MIXER_IS_CLIENT_STREAM (client), FALSE);
+
+ iface = MATE_MIXER_CLIENT_STREAM_GET_INTERFACE (client);
+
+ if (iface->remove)
+ return iface->remove (client);
+
+ return FALSE;
+}
diff --git a/libmatemixer/matemixer-client-stream.h b/libmatemixer/matemixer-client-stream.h
new file mode 100644
index 0000000..2c690c5
--- /dev/null
+++ b/libmatemixer/matemixer-client-stream.h
@@ -0,0 +1,59 @@
+/*
+ * 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_CLIENT_STREAM_H
+#define MATEMIXER_CLIENT_STREAM_H
+
+#include <glib.h>
+#include <glib-object.h>
+
+#include <libmatemixer/matemixer-stream.h>
+
+G_BEGIN_DECLS
+
+#define MATE_MIXER_TYPE_CLIENT_STREAM \
+ (mate_mixer_client_stream_get_type ())
+#define MATE_MIXER_CLIENT_STREAM(o) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((o), MATE_MIXER_TYPE_CLIENT_STREAM, MateMixerClientStream))
+#define MATE_MIXER_IS_CLIENT_STREAM(o) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((o), MATE_MIXER_TYPE_CLIENT_STREAM))
+#define MATE_MIXER_CLIENT_STREAM_GET_INTERFACE(o) \
+ (G_TYPE_INSTANCE_GET_INTERFACE ((o), MATE_MIXER_TYPE_CLIENT_STREAM, MateMixerClientStreamInterface))
+
+typedef struct _MateMixerClientStream MateMixerClientStream; /* dummy object */
+typedef struct _MateMixerClientStreamInterface MateMixerClientStreamInterface;
+
+struct _MateMixerClientStreamInterface
+{
+ /*< private >*/
+ GTypeInterface parent;
+
+ MateMixerStream *(*get_parent) (MateMixerClientStream *client);
+ gboolean (*set_parent) (MateMixerClientStream *client,
+ MateMixerStream *stream);
+ gboolean (*remove) (MateMixerClientStream *client);
+};
+
+GType mate_mixer_client_stream_get_type (void) G_GNUC_CONST;
+MateMixerStream *mate_mixer_client_stream_get_parent (MateMixerClientStream *client);
+gboolean mate_mixer_client_stream_set_parent (MateMixerClientStream *client,
+ MateMixerStream *parent);
+gboolean mate_mixer_client_stream_remove (MateMixerClientStream *client);
+
+G_END_DECLS
+
+#endif /* MATEMIXER_CLIENT_STREAM_H */
diff --git a/libmatemixer/matemixer-control.c b/libmatemixer/matemixer-control.c
index c122a7e..3e3045e 100644
--- a/libmatemixer/matemixer-control.c
+++ b/libmatemixer/matemixer-control.c
@@ -15,6 +15,7 @@
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
+#include <string.h>
#include <glib.h>
#include <glib-object.h>
@@ -22,6 +23,7 @@
#include "matemixer-backend-module.h"
#include "matemixer-control.h"
#include "matemixer-enums.h"
+#include "matemixer-enum-types.h"
#include "matemixer-private.h"
#include "matemixer-stream.h"
@@ -29,17 +31,146 @@ struct _MateMixerControlPrivate
{
GList *devices;
GList *streams;
+ MateMixerState state;
MateMixerBackend *backend;
+ MateMixerBackendData backend_data;
+ MateMixerBackendType backend_type;
MateMixerBackendModule *module;
};
+enum {
+ PROP_0,
+ PROP_APP_NAME,
+ PROP_APP_ID,
+ PROP_APP_VERSION,
+ PROP_APP_ICON,
+ PROP_SERVER_ADDRESS,
+ PROP_STATE,
+ PROP_DEFAULT_INPUT,
+ PROP_DEFAULT_OUTPUT,
+ N_PROPERTIES
+};
+
+enum {
+ DEVICE_ADDED,
+ DEVICE_CHANGED,
+ DEVICE_REMOVED,
+ STREAM_ADDED,
+ STREAM_CHANGED,
+ STREAM_REMOVED,
+ N_SIGNALS
+};
+
+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 void mate_mixer_control_finalize (GObject *object);
+
+static gboolean control_try_next_backend (MateMixerControl *control);
+static void control_change_state (MateMixerControl *control,
+ MateMixerState state);
+static void control_state_changed_cb (MateMixerBackend *backend,
+ GParamSpec *pspec,
+ MateMixerControl *control);
+
+static void control_device_added_cb (MateMixerBackend *backend,
+ const gchar *name,
+ MateMixerControl *control);
+static void control_device_changed_cb (MateMixerBackend *backend,
+ const gchar *name,
+ MateMixerControl *control);
+static void control_device_removed_cb (MateMixerBackend *backend,
+ const gchar *name,
+ MateMixerControl *control);
+
+static void control_stream_added_cb (MateMixerBackend *backend,
+ const gchar *name,
+ MateMixerControl *control);
+static void control_stream_changed_cb (MateMixerBackend *backend,
+ const gchar *name,
+ MateMixerControl *control);
+static void control_stream_removed_cb (MateMixerBackend *backend,
+ const gchar *name,
+ MateMixerControl *control);
+
G_DEFINE_TYPE (MateMixerControl, mate_mixer_control, G_TYPE_OBJECT);
-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 GParamSpec *properties[N_PROPERTIES] = { NULL, };
+
+static guint signals[N_SIGNALS] = { 0, };
+
+static void
+mate_mixer_control_get_property (GObject *object,
+ guint param_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ MateMixerControl *control;
+
+ control = MATE_MIXER_CONTROL (object);
+
+ switch (param_id) {
+ case PROP_APP_NAME:
+ g_value_set_string (value, control->priv->backend_data.app_name);
+ break;
+ case PROP_APP_ID:
+ g_value_set_string (value, control->priv->backend_data.app_id);
+ break;
+ case PROP_APP_VERSION:
+ g_value_set_string (value, control->priv->backend_data.app_version);
+ break;
+ case PROP_APP_ICON:
+ g_value_set_string (value, control->priv->backend_data.app_icon);
+ break;
+ case PROP_SERVER_ADDRESS:
+ g_value_set_string (value, control->priv->backend_data.server_address);
+ break;
+ case PROP_STATE:
+ g_value_set_enum (value, control->priv->state);
+ break;
+ case PROP_DEFAULT_INPUT:
+ g_value_set_object (value, mate_mixer_control_get_default_input_stream (control));
+ break;
+ case PROP_DEFAULT_OUTPUT:
+ g_value_set_object (value, mate_mixer_control_get_default_output_stream (control));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+ break;
+ }
+}
+
+static void
+mate_mixer_control_set_property (GObject *object,
+ guint param_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ MateMixerControl *control;
+
+ control = MATE_MIXER_CONTROL (object);
-static MateMixerBackend *mixer_control_init_module (MateMixerBackendModule *module);
+ switch (param_id) {
+ case PROP_APP_NAME:
+ mate_mixer_control_set_app_name (control, g_value_get_string (value));
+ break;
+ case PROP_APP_ID:
+ mate_mixer_control_set_app_id (control, g_value_get_string (value));
+ break;
+ case PROP_APP_VERSION:
+ mate_mixer_control_set_app_version (control, g_value_get_string (value));
+ break;
+ case PROP_APP_ICON:
+ mate_mixer_control_set_app_icon (control, g_value_get_string (value));
+ break;
+ case PROP_SERVER_ADDRESS:
+ mate_mixer_control_set_server_address (control, g_value_get_string (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+ break;
+ }
+}
static void
mate_mixer_control_class_init (MateMixerControlClass *klass)
@@ -47,7 +178,160 @@ mate_mixer_control_class_init (MateMixerControlClass *klass)
GObjectClass *object_class;
object_class = G_OBJECT_CLASS (klass);
- object_class->dispose = mate_mixer_control_dispose;
+ object_class->dispose = mate_mixer_control_dispose;
+ object_class->finalize = mate_mixer_control_finalize;
+ object_class->get_property = mate_mixer_control_get_property;
+ object_class->set_property = mate_mixer_control_set_property;
+
+ /**
+ * MateMixerControl:app-name:
+ *
+ * Localized human readable name of the application.
+ */
+ properties[PROP_APP_NAME] = g_param_spec_string ("app-name",
+ "App name",
+ "Application name",
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS);
+ /**
+ * MateMixerControl:app-id:
+ *
+ * Identifier of the application (e.g. org.example.app).
+ */
+ properties[PROP_APP_ID] = g_param_spec_string ("app-id",
+ "App ID",
+ "Application identifier",
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS);
+ /**
+ * MateMixerControl:app-version:
+ *
+ * Version of the application.
+ */
+ properties[PROP_APP_VERSION] = g_param_spec_string ("app-version",
+ "App version",
+ "Application version",
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS);
+ /**
+ * MateMixerControl:app-icon:
+ *
+ * An XDG icon name for the application.
+ */
+ properties[PROP_APP_ICON] = g_param_spec_string ("app-icon",
+ "App icon",
+ "Application icon",
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS);
+
+ /**
+ * MateMixerControl:server-address:
+ *
+ * Address of the sound server to connect to.
+ *
+ * This feature is only supported in the PulseAudio backend. There is
+ * no need to specify an address in order to connect to the local daemon.
+ */
+ properties[PROP_SERVER_ADDRESS] = g_param_spec_string ("server-address",
+ "Server address",
+ "Sound server address",
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS);
+
+ properties[PROP_STATE] = g_param_spec_enum ("state",
+ "State",
+ "Current backend connection state",
+ MATE_MIXER_TYPE_STATE,
+ MATE_MIXER_STATE_IDLE,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS);
+
+ properties[PROP_DEFAULT_INPUT] = g_param_spec_object ("default-input",
+ "Default input",
+ "Default input stream",
+ MATE_MIXER_TYPE_STREAM,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS);
+
+ properties[PROP_DEFAULT_OUTPUT] = g_param_spec_object ("default-output",
+ "Default output",
+ "Default output stream",
+ MATE_MIXER_TYPE_STREAM,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS);
+
+ signals[DEVICE_ADDED] = g_signal_new ("device-added",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (MateMixerControlClass, device_added),
+ NULL,
+ NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE,
+ 1,
+ G_TYPE_STRING);
+
+ signals[DEVICE_CHANGED] = g_signal_new ("device-changed",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (MateMixerControlClass, device_changed),
+ NULL,
+ NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE,
+ 1,
+ G_TYPE_STRING);
+
+ signals[DEVICE_REMOVED] = g_signal_new ("device-removed",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (MateMixerControlClass, device_removed),
+ NULL,
+ NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE,
+ 1,
+ G_TYPE_STRING);
+
+ signals[STREAM_ADDED] = g_signal_new ("stream-added",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (MateMixerControlClass, stream_added),
+ NULL,
+ NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE,
+ 1,
+ G_TYPE_STRING);
+
+ signals[STREAM_CHANGED] = g_signal_new ("stream-changed",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (MateMixerControlClass, stream_changed),
+ NULL,
+ NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE,
+ 1,
+ G_TYPE_STRING);
+
+ signals[STREAM_REMOVED] = g_signal_new ("stream-removed",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (MateMixerControlClass, stream_removed),
+ NULL,
+ NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE,
+ 1,
+ G_TYPE_STRING);
+
+ g_object_class_install_properties (object_class, N_PROPERTIES, properties);
g_type_class_add_private (object_class, sizeof (MateMixerControlPrivate));
}
@@ -86,86 +370,443 @@ mate_mixer_control_dispose (GObject *object)
G_OBJECT_CLASS (mate_mixer_control_parent_class)->dispose (object);
}
-MateMixerControl *
-mate_mixer_control_new (void)
+static void
+mate_mixer_control_finalize (GObject *object)
{
- const GList *modules;
- MateMixerControl *control;
- MateMixerBackend *backend = NULL;
- MateMixerBackendModule *module = NULL;
+ MateMixerControl *control;
+
+ control = MATE_MIXER_CONTROL (object);
+
+ g_free (control->priv->backend_data.app_name);
+ g_free (control->priv->backend_data.app_id);
+ g_free (control->priv->backend_data.app_version);
+ g_free (control->priv->backend_data.app_icon);
+ g_free (control->priv->backend_data.server_address);
+ G_OBJECT_CLASS (mate_mixer_control_parent_class)->finalize (object);
+}
+
+/**
+ * mate_mixer_control_new:
+ *
+ * Creates a new #MateMixerControl instance.
+ *
+ * Returns: a new #MateMixerControl instance or %NULL if the library has not
+ * been initialized using mate_mixer_init().
+ */
+MateMixerControl *mate_mixer_control_new (void)
+{
if (!mate_mixer_is_initialized ()) {
g_critical ("The library has not been initialized");
return NULL;
}
+ return g_object_new (MATE_MIXER_TYPE_CONTROL, NULL);
+}
+
+/**
+ * mate_mixer_control_set_backend_type:
+ * @control: a #MateMixerControl
+ * @backend_type: the sound system backend to use
+ *
+ * Makes the #MateMixerControl use the given #MateMixerBackendType.
+ *
+ * By default the backend type is determined automatically. This function can
+ * be used before mate_mixer_control_open() to alter this behavior and make the
+ * @control use the given backend.
+ *
+ * This function will fail if support for the backend is not installed in
+ * the system.
+ *
+ * Returns: %TRUE on success or %FALSE on failure.
+ */
+gboolean
+mate_mixer_control_set_backend_type (MateMixerControl *control,
+ MateMixerBackendType backend_type)
+{
+ MateMixerBackendModule *module;
+ const GList *modules;
+ const MateMixerBackendInfo *info;
+
+ g_return_val_if_fail (MATE_MIXER_IS_CONTROL (control), FALSE);
modules = mate_mixer_get_modules ();
while (modules) {
- module = MATE_MIXER_BACKEND_MODULE (modules->data);
- backend = mixer_control_init_module (module);
- if (backend != NULL)
- break;
+ module = MATE_MIXER_BACKEND_MODULE (modules->data);
+ info = mate_mixer_backend_module_get_info (module);
+ if (info->backend_type == backend_type) {
+ control->priv->backend_type = backend_type;
+ return TRUE;
+ }
modules = modules->next;
}
+ return FALSE;
+}
- /* The last module in the priority list is the "null" module which
- * should always be initialized correctly, but in case "null" is absent,
- * all the other modules might fail their initializations */
- if (backend == NULL)
- return NULL;
+/**
+ * mate_mixer_control_set_app_name:
+ * @control: a #MateMixerControl
+ * @app_name: the name of your application, or %NULL to unset
+ *
+ * Sets the name of the application. This feature is only supported in the
+ * PulseAudio backend.
+ *
+ * This function will fail if the current state is either
+ * %MATE_MIXER_STATE_CONNECTING or %MATE_MIXER_STATE_READY, therefore you should
+ * use it before opening a connection to the sound system.
+ *
+ * Returns: %TRUE on success or %FALSE on failure.
+ */
+gboolean
+mate_mixer_control_set_app_name (MateMixerControl *control, const gchar *app_name)
+{
+ g_return_val_if_fail (MATE_MIXER_IS_CONTROL (control), FALSE);
- control = g_object_new (MATE_MIXER_TYPE_CONTROL, NULL);
+ if (control->priv->state == MATE_MIXER_STATE_CONNECTING ||
+ control->priv->state == MATE_MIXER_STATE_READY)
+ return FALSE;
- control->priv->module = g_object_ref (module);
- control->priv->backend = backend;
+ g_free (control->priv->backend_data.app_name);
+
+ control->priv->backend_data.app_name = g_strdup (app_name);
- return control;
+ g_object_notify_by_pspec (G_OBJECT (control), properties[PROP_APP_NAME]);
+ return TRUE;
}
-MateMixerControl *
-mate_mixer_control_new_backend (MateMixerBackendType backend_type)
+/**
+ * mate_mixer_control_set_app_id:
+ * @control: a #MateMixerControl
+ * @app_id: the identifier of your application, or %NULL to unset
+ *
+ * Sets the identifier of the application (e.g. org.example.app). This feature
+ * is only supported in the PulseAudio backend.
+ *
+ * This function will fail if the current state is either
+ * %MATE_MIXER_STATE_CONNECTING or %MATE_MIXER_STATE_READY, therefore you should
+ * use it before opening a connection to the sound system.
+ *
+ * Returns: %TRUE on success or %FALSE on failure.
+ */
+gboolean
+mate_mixer_control_set_app_id (MateMixerControl *control, const gchar *app_id)
{
- const GList *modules;
- MateMixerControl *control;
- MateMixerBackend *backend = NULL;
- MateMixerBackendModule *module = NULL;
+ g_return_val_if_fail (MATE_MIXER_IS_CONTROL (control), FALSE);
- if (!mate_mixer_is_initialized ()) {
- g_critical ("The library has not been initialized");
- return NULL;
- }
+ if (control->priv->state == MATE_MIXER_STATE_CONNECTING ||
+ control->priv->state == MATE_MIXER_STATE_READY)
+ return FALSE;
+
+ g_free (control->priv->backend_data.app_id);
+
+ control->priv->backend_data.app_id = g_strdup (app_id);
+
+ g_object_notify_by_pspec (G_OBJECT (control), properties[PROP_APP_ID]);
+ return TRUE;
+}
+
+/**
+ * mate_mixer_control_set_app_version:
+ * @control: a #MateMixerControl
+ * @app_version: the version of your application, or %NULL to unset
+ *
+ * Sets the version of the application. This feature is only supported in the
+ * PulseAudio backend.
+ *
+ * This function will fail if the current state is either
+ * %MATE_MIXER_STATE_CONNECTING or %MATE_MIXER_STATE_READY, therefore you should
+ * use it before opening a connection to the sound system.
+ *
+ * Returns: %TRUE on success or %FALSE on failure.
+ */
+gboolean
+mate_mixer_control_set_app_version (MateMixerControl *control, const gchar *app_version)
+{
+ g_return_val_if_fail (MATE_MIXER_IS_CONTROL (control), FALSE);
+
+ if (control->priv->state == MATE_MIXER_STATE_CONNECTING ||
+ control->priv->state == MATE_MIXER_STATE_READY)
+ return FALSE;
+
+ g_free (control->priv->backend_data.app_version);
+
+ control->priv->backend_data.app_version = g_strdup (app_version);
+
+ g_object_notify_by_pspec (G_OBJECT (control), properties[PROP_APP_VERSION]);
+ return TRUE;
+}
+
+/**
+ * mate_mixer_control_set_app_icon:
+ * @control: a #MateMixerControl
+ * @app_icon: the XDG icon name of your application, or %NULL to unset
+ *
+ * Sets the XDG icon name of the application. This feature is only supported in
+ * the PulseAudio backend.
+ *
+ * This function will fail if the current state is either
+ * %MATE_MIXER_STATE_CONNECTING or %MATE_MIXER_STATE_READY, therefore you should
+ * use it before opening a connection to the sound system.
+ *
+ * Returns: %TRUE on success or %FALSE on failure.
+ */
+gboolean
+mate_mixer_control_set_app_icon (MateMixerControl *control, const gchar *app_icon)
+{
+ g_return_val_if_fail (MATE_MIXER_IS_CONTROL (control), FALSE);
+
+ if (control->priv->state == MATE_MIXER_STATE_CONNECTING ||
+ control->priv->state == MATE_MIXER_STATE_READY)
+ return FALSE;
+
+ g_free (control->priv->backend_data.app_icon);
+
+ control->priv->backend_data.app_icon = g_strdup (app_icon);
+
+ g_object_notify_by_pspec (G_OBJECT (control), properties[PROP_APP_ICON]);
+ return TRUE;
+}
+
+/**
+ * mate_mixer_control_set_server_address:
+ * @control: a #MateMixerControl
+ * @address: the address of the sound server to connect to or %NULL
+ *
+ * Sets the address of the sound server. This feature is only supported in the
+ * PulseAudio backend. If the address is not set, the default PulseAudio sound
+ * server will be used, which is normally the local daemon.
+ *
+ * This function will fail if the current state is either
+ * %MATE_MIXER_STATE_CONNECTING or %MATE_MIXER_STATE_READY, therefore you should
+ * use it before opening a connection to the sound system.
+ *
+ * Returns: %TRUE on success or %FALSE on failure.
+ */
+gboolean
+mate_mixer_control_set_server_address (MateMixerControl *control, const gchar *address)
+{
+ g_return_val_if_fail (MATE_MIXER_IS_CONTROL (control), FALSE);
+
+ if (control->priv->state == MATE_MIXER_STATE_CONNECTING ||
+ control->priv->state == MATE_MIXER_STATE_READY)
+ return FALSE;
+
+ g_free (control->priv->backend_data.server_address);
+
+ control->priv->backend_data.server_address = g_strdup (address);
+
+ g_object_notify_by_pspec (G_OBJECT (control), properties[PROP_SERVER_ADDRESS]);
+ return TRUE;
+}
+
+/**
+ * mate_mixer_control_open:
+ * @control: a #MateMixerControl
+ *
+ * Opens connection to a sound system. Unless the backend type was given
+ * beforehand, the library will find a working sound system automatically.
+ * If the automatic discovery fails to find a working sound system, it will
+ * use the "Null" backend, which provides no functionality.
+ *
+ * This function can complete the operation either synchronously or
+ * asynchronously.
+ *
+ * In case this function returns %TRUE, you should check the current state of
+ * the connection using mate_mixer_control_get_state(). If the current state
+ * is %MATE_MIXER_STATE_READY, the connection has been established successfully.
+ * Otherwise the state will be set to %MATE_MIXER_STATE_CONNECTING and the
+ * result of the operation will be determined asynchronously. You should wait
+ * for the state transition by connecting to the notification signal of the
+ * #MateMixerControl:state property.
+ *
+ * In case this function returns %FALSE, it is not possible to use the selected
+ * backend and the state will be set to %MATE_MIXER_STATE_FAILED.
+ *
+ * Returns: %TRUE on success or if the result will be determined asynchronously,
+ * or %FALSE on failure.
+ */
+gboolean
+mate_mixer_control_open (MateMixerControl *control)
+{
+ MateMixerBackendModule *module = NULL;
+ MateMixerState state;
+ const GList *modules;
+ const MateMixerBackendInfo *info = NULL;
+
+ g_return_val_if_fail (MATE_MIXER_IS_CONTROL (control), FALSE);
+ g_return_val_if_fail (control->priv->state != MATE_MIXER_STATE_CONNECTING &&
+ control->priv->state != MATE_MIXER_STATE_READY, FALSE);
+ /* We are going to choose the first backend to try. It will be either the one
+ * specified by the user or the one with the highest priority */
modules = mate_mixer_get_modules ();
- while (modules) {
- const MateMixerBackendInfo *info;
- module = MATE_MIXER_BACKEND_MODULE (modules->data);
- info = mate_mixer_backend_module_get_info (module);
+ if (control->priv->backend_type != MATE_MIXER_BACKEND_UNKNOWN) {
+ while (modules) {
+ const MateMixerBackendInfo *info;
- if (info->backend_type == backend_type) {
- backend = mixer_control_init_module (module);
- break;
+ module = MATE_MIXER_BACKEND_MODULE (modules->data);
+ info = mate_mixer_backend_module_get_info (module);
+
+ if (info->backend_type == control->priv->backend_type)
+ break;
+
+ module = NULL;
+ modules = modules->next;
}
- modules = modules->next;
+ } else {
+ /* The highest priority module is on the top of the list */
+ module = MATE_MIXER_BACKEND_MODULE (modules->data);
}
- /* The initialization might fail or the selected module might be absent */
- if (backend == NULL)
- return NULL;
+ if (module == NULL) {
+ /* Most likely the selected backend is not installed */
+ control_change_state (control, MATE_MIXER_STATE_FAILED);
+ return FALSE;
+ }
- control = g_object_new (MATE_MIXER_TYPE_CONTROL, NULL);
+ if (info == NULL)
+ info = mate_mixer_backend_module_get_info (module);
control->priv->module = g_object_ref (module);
- control->priv->backend = backend;
+ control->priv->backend = g_object_newv (info->g_type, 0, NULL);
+
+ mate_mixer_backend_set_data (control->priv->backend, &control->priv->backend_data);
+
+ /* This transitional state is always present, it will change to MATE_MIXER_STATE_READY
+ * or MATE_MIXER_STATE_FAILED either instantly or asynchronously */
+ control_change_state (control, MATE_MIXER_STATE_CONNECTING);
+
+ /* The backend initialization might fail in case it is known right now that
+ * it is unusable */
+ if (!mate_mixer_backend_open (control->priv->backend)) {
+ if (control->priv->backend_type == MATE_MIXER_BACKEND_UNKNOWN) {
+ /* User didn't request a specific backend, so try another one */
+ return control_try_next_backend (control);
+ }
+
+ /* User requested a specific backend and it failed */
+ g_clear_object (&control->priv->module);
+ g_clear_object (&control->priv->backend);
+
+ control_change_state (control, MATE_MIXER_STATE_FAILED);
+ return FALSE;
+ }
- return control;
+ state = mate_mixer_backend_get_state (control->priv->backend);
+
+ if (G_UNLIKELY (state != MATE_MIXER_STATE_READY &&
+ state != MATE_MIXER_STATE_CONNECTING)) {
+ /* The backend should not be in this state */
+ g_warn_if_reached ();
+
+ g_clear_object (&control->priv->module);
+ g_clear_object (&control->priv->backend);
+ control_change_state (control, MATE_MIXER_STATE_FAILED);
+ return FALSE;
+ }
+
+ g_signal_connect (control->priv->backend,
+ "notify::state",
+ G_CALLBACK (control_state_changed_cb),
+ control);
+
+ control_change_state (control, state);
+ return TRUE;
+}
+
+/**
+ * mate_mixer_control_get_state:
+ * @control: a #MateMixerControl
+ *
+ * Gets the current backend connection state of the #MateMixerControl.
+ *
+ * Returns: The current connection state.
+ */
+MateMixerState
+mate_mixer_control_get_state (MateMixerControl *control)
+{
+ g_return_val_if_fail (MATE_MIXER_IS_CONTROL (control), MATE_MIXER_STATE_UNKNOWN);
+
+ return control->priv->state;
}
+/**
+ * mate_mixer_control_get_device:
+ * @control: a #MateMixerControl
+ * @name: a device name
+ *
+ * Gets the devices with the given name.
+ *
+ * Returns: a #MateMixerDevice or %NULL if there is no such device.
+ */
+MateMixerDevice *
+mate_mixer_control_get_device (MateMixerControl *control, const gchar *name)
+{
+ GList *list;
+
+ g_return_val_if_fail (MATE_MIXER_IS_CONTROL (control), NULL);
+ g_return_val_if_fail (name != NULL, NULL);
+
+ list = control->priv->devices;
+ while (list) {
+ MateMixerDevice *device = MATE_MIXER_DEVICE (list->data);
+
+ if (!strcmp (name, mate_mixer_device_get_name (device)))
+ return device;
+
+ list = list->next;
+ }
+ return NULL;
+}
+
+/**
+ * mate_mixer_control_get_stream:
+ * @control: a #MateMixerControl
+ * @name: a stream name
+ *
+ * Gets the stream with the given name.
+ *
+ * Returns: a #MateMixerStream or %NULL if there is no such stream.
+ */
+MateMixerStream *
+mate_mixer_control_get_stream (MateMixerControl *control, const gchar *name)
+{
+ GList *list;
+
+ g_return_val_if_fail (MATE_MIXER_IS_CONTROL (control), NULL);
+ g_return_val_if_fail (name != NULL, NULL);
+
+ list = control->priv->streams;
+ while (list) {
+ MateMixerStream *stream = MATE_MIXER_STREAM (list->data);
+
+ if (!strcmp (name, mate_mixer_stream_get_name (stream)))
+ return stream;
+
+ list = list->next;
+ }
+ return NULL;
+}
+
+/**
+ * mate_mixer_control_list_devices:
+ * @control: a #MateMixerControl
+ *
+ * Gets a list of devices. Each list item is a #MateMixerDevice representing a
+ * hardware or software sound device in the system.
+ *
+ * The returned #GList is owned by the #MateMixerControl and may be invalidated
+ * at any time.
+ *
+ * Returns: a #GList of all devices in the system or %NULL if there are none or
+ * you are not connected to a sound system.
+ */
const GList *
mate_mixer_control_list_devices (MateMixerControl *control)
{
g_return_val_if_fail (MATE_MIXER_IS_CONTROL (control), NULL);
+ g_return_val_if_fail (control->priv->state == MATE_MIXER_STATE_READY, NULL);
/* This list is cached here and invalidated when the backend notifies us
* about a change */
@@ -176,10 +817,24 @@ mate_mixer_control_list_devices (MateMixerControl *control)
return (const GList *) control->priv->devices;
}
+/**
+ * mate_mixer_control_list_streams:
+ * @control: a #MateMixerControl
+ *
+ * Gets a list of streams. Each list item is a #MateMixerStream representing an
+ * input or output of a sound device.
+ *
+ * The returned #GList is owned by the #MateMixerControl and may be invalidated
+ * at any time.
+ *
+ * Returns: a #GList of all streams in the system or %NULL if there are none or
+ * you are not connected to a sound system.
+ */
const GList *
mate_mixer_control_list_streams (MateMixerControl *control)
{
g_return_val_if_fail (MATE_MIXER_IS_CONTROL (control), NULL);
+ g_return_val_if_fail (control->priv->state == MATE_MIXER_STATE_READY, NULL);
/* This list is cached here and invalidated when the backend notifies us
* about a change */
@@ -190,58 +845,330 @@ mate_mixer_control_list_streams (MateMixerControl *control)
return (const GList *) control->priv->streams;
}
+/**
+ * mate_mixer_control_get_default_input_stream:
+ * @control: a #MateMixerControl
+ *
+ * Gets the default input stream. The returned stream is where sound input is
+ * directed to by default.
+ *
+ * Returns: a #MateMixerStream or %NULL if there are no input streams in
+ * the system.
+ */
MateMixerStream *
mate_mixer_control_get_default_input_stream (MateMixerControl *control)
{
g_return_val_if_fail (MATE_MIXER_IS_CONTROL (control), NULL);
+ g_return_val_if_fail (control->priv->state == MATE_MIXER_STATE_READY, NULL);
return mate_mixer_backend_get_default_input_stream (control->priv->backend);
}
+/**
+ * mate_mixer_control_set_default_input_stream:
+ * @control: a #MateMixerControl
+ * @stream: a #MateMixerStream to set as the default input stream
+ *
+ * Changes the default input stream in the system.
+ *
+ * Returns: %TRUE on success or %FALSE on failure.
+ */
+gboolean
+mate_mixer_control_set_default_input_stream (MateMixerControl *control,
+ MateMixerStream *stream)
+{
+ g_return_val_if_fail (MATE_MIXER_IS_CONTROL (control), NULL);
+ g_return_val_if_fail (control->priv->state == MATE_MIXER_STATE_READY, NULL);
+
+ return mate_mixer_backend_set_default_input_stream (control->priv->backend, stream);
+}
+
+/**
+ * mate_mixer_control_get_default_output_stream:
+ * @control: a #MateMixerControl
+ *
+ * Gets the default output stream. The returned stream is where sound output is
+ * directed to by default.
+ *
+ * Returns: a #MateMixerStream or %NULL if there are no output streams in
+ * the system.
+ */
MateMixerStream *
mate_mixer_control_get_default_output_stream (MateMixerControl *control)
{
g_return_val_if_fail (MATE_MIXER_IS_CONTROL (control), NULL);
+ g_return_val_if_fail (control->priv->state == MATE_MIXER_STATE_READY, NULL);
return mate_mixer_backend_get_default_output_stream (control->priv->backend);
}
+/**
+ * mate_mixer_control_set_default_output_stream:
+ * @control: a #MateMixerControl
+ * @stream: a #MateMixerStream to set as the default output stream
+ *
+ * Changes the default output stream in the system.
+ *
+ * Returns: %TRUE on success or %FALSE on failure.
+ */
+gboolean
+mate_mixer_control_set_default_output_stream (MateMixerControl *control,
+ MateMixerStream *stream)
+{
+ g_return_val_if_fail (MATE_MIXER_IS_CONTROL (control), NULL);
+ g_return_val_if_fail (control->priv->state == MATE_MIXER_STATE_READY, NULL);
+
+ return mate_mixer_backend_set_default_input_stream (control->priv->backend, stream);
+}
+
+/**
+ * mate_mixer_control_get_backend_name:
+ * @control: a #MateMixerControl
+ *
+ * Gets the name of the currently used backend. The @control must be in the
+ * %MATE_MIXER_STATE_READY state.
+ *
+ * Returns: the name or %NULL on error.
+ */
const gchar *
mate_mixer_control_get_backend_name (MateMixerControl *control)
{
const MateMixerBackendInfo *info;
g_return_val_if_fail (MATE_MIXER_IS_CONTROL (control), NULL);
+ g_return_val_if_fail (control->priv->state == MATE_MIXER_STATE_READY, NULL);
info = mate_mixer_backend_module_get_info (control->priv->module);
return info->name;
}
+/**
+ * mate_mixer_control_get_backend_type:
+ * @control: a #MateMixerControl
+ *
+ * Gets the type of the currently used backend. The @control must be in the
+ * %MATE_MIXER_STATE_READY state.
+ *
+ * Returns: the backend type or %MATE_MIXER_BACKEND_UNKNOWN on error.
+ */
MateMixerBackendType
mate_mixer_control_get_backend_type (MateMixerControl *control)
{
const MateMixerBackendInfo *info;
g_return_val_if_fail (MATE_MIXER_IS_CONTROL (control), FALSE);
+ g_return_val_if_fail (control->priv->state == MATE_MIXER_STATE_READY, FALSE);
info = mate_mixer_backend_module_get_info (control->priv->module);
return info->backend_type;
}
-static MateMixerBackend *
-mixer_control_init_module (MateMixerBackendModule *module)
+static gboolean
+control_try_next_backend (MateMixerControl *control)
{
- MateMixerBackend *backend;
- const MateMixerBackendInfo *info;
+ const GList *modules;
+ MateMixerBackendModule *module = NULL;
+
+ modules = mate_mixer_get_modules ();
+ while (modules) {
+ if (control->priv->module == modules->data) {
+ /* Found the last tested backend, try to use the next one with a lower
+ * priority unless we have reached the end of the list */
+ if (modules->next)
+ module = MATE_MIXER_BACKEND_MODULE (modules->next->data);
+ break;
+ }
+ modules = modules->next;
+ }
+ g_clear_object (&control->priv->module);
+ g_clear_object (&control->priv->backend);
- info = mate_mixer_backend_module_get_info (module);
- backend = g_object_newv (info->g_type, 0, NULL);
+ if (module == NULL) {
+ /* This shouldn't happen under normal circumstances as the lowest
+ * priority module is the "Null" module which never fails to initialize,
+ * but in a broken installation this module could be missing */
+ control_change_state (control, MATE_MIXER_STATE_FAILED);
+ return FALSE;
+ }
- if (!mate_mixer_backend_open (backend)) {
- g_object_unref (backend);
- return NULL;
+ control->priv->module = g_object_ref (module);
+ control->priv->backend =
+ g_object_newv (mate_mixer_backend_module_get_info (module)->g_type,
+ 0,
+ NULL);
+
+ if (!mate_mixer_backend_open (control->priv->backend))
+ return control_try_next_backend (control);
+
+ g_signal_connect (control->priv->backend,
+ "notify::state",
+ G_CALLBACK (control_state_changed_cb),
+ control);
+ return TRUE;
+}
+
+static void
+control_change_state (MateMixerControl *control, MateMixerState state)
+{
+ if (control->priv->state == state)
+ return;
+
+ control->priv->state = state;
+
+ if (state == MATE_MIXER_STATE_READY) {
+ /* It is safe to connect to the backend signals after reaching the READY
+ * state, because the app is not allowed to query any data before that state */
+ g_signal_connect (control->priv->backend,
+ "device-added",
+ G_CALLBACK (control_device_added_cb),
+ control);
+ g_signal_connect (control->priv->backend,
+ "device-changed",
+ G_CALLBACK (control_device_changed_cb),
+ control);
+ g_signal_connect (control->priv->backend,
+ "device-removed",
+ G_CALLBACK (control_device_removed_cb),
+ control);
+ g_signal_connect (control->priv->backend,
+ "stream-added",
+ G_CALLBACK (control_stream_added_cb),
+ control);
+ g_signal_connect (control->priv->backend,
+ "stream-changed",
+ G_CALLBACK (control_stream_changed_cb),
+ control);
+ g_signal_connect (control->priv->backend,
+ "stream-removed",
+ G_CALLBACK (control_stream_removed_cb),
+ control);
+ }
+ g_object_notify_by_pspec (G_OBJECT (control), properties[PROP_STATE]);
+}
+
+static void
+control_state_changed_cb (MateMixerBackend *backend,
+ GParamSpec *pspec,
+ MateMixerControl *control)
+{
+ MateMixerState state = mate_mixer_backend_get_state (backend);
+
+ switch (state) {
+ case MATE_MIXER_STATE_READY:
+ control_change_state (control, state);
+ break;
+
+ case MATE_MIXER_STATE_FAILED:
+ control_try_next_backend (control);
+ break;
+
+ default:
+ break;
+ }
+}
+
+static void
+control_device_added_cb (MateMixerBackend *backend,
+ const gchar *name,
+ MateMixerControl *control)
+{
+ if (control->priv->devices) {
+ g_list_free_full (control->priv->devices, g_object_unref);
+ control->priv->devices = NULL;
+ }
+
+ g_debug ("Device added: %s", name);
+
+ g_signal_emit (G_OBJECT (control),
+ signals[DEVICE_ADDED],
+ 0,
+ name);
+}
+
+static void
+control_device_changed_cb (MateMixerBackend *backend,
+ const gchar *name,
+ MateMixerControl *control)
+{
+ /* Do not invalidate the list of devices here as the list has not changed,
+ * only some properties of a device */
+
+ g_debug ("Device changed: %s", name);
+
+ g_signal_emit (G_OBJECT (control),
+ signals[DEVICE_CHANGED],
+ 0,
+ name);
+}
+
+static void
+control_device_removed_cb (MateMixerBackend *backend,
+ const gchar *name,
+ MateMixerControl *control)
+{
+ if (control->priv->devices) {
+ g_list_free_full (control->priv->devices, g_object_unref);
+ control->priv->devices = NULL;
}
- return backend;
+
+ g_debug ("Device removed: %s", name);
+
+ g_signal_emit (G_OBJECT (control),
+ signals[DEVICE_REMOVED],
+ 0,
+ name);
+}
+
+static void
+control_stream_added_cb (MateMixerBackend *backend,
+ const gchar *name,
+ MateMixerControl *control)
+{
+ if (control->priv->streams) {
+ g_list_free_full (control->priv->streams, g_object_unref);
+ control->priv->streams = NULL;
+ }
+
+ g_debug ("Stream added: %s", name);
+
+ g_signal_emit (G_OBJECT (control),
+ signals[STREAM_ADDED],
+ 0,
+ name);
+}
+
+static void
+control_stream_changed_cb (MateMixerBackend *backend,
+ const gchar *name,
+ MateMixerControl *control)
+{
+ /* Do not invalidate the list of streams here as the list has not changed,
+ * only some properties of a stream */
+
+ g_debug ("Stream changed: %s", name);
+
+ g_signal_emit (G_OBJECT (control),
+ signals[STREAM_CHANGED],
+ 0,
+ name);
+}
+
+static void
+control_stream_removed_cb (MateMixerBackend *backend,
+ const gchar *name,
+ MateMixerControl *control)
+{
+ if (control->priv->streams) {
+ g_list_free_full (control->priv->streams, g_object_unref);
+ control->priv->streams = NULL;
+ }
+
+ g_debug ("Stream removed: %s", name);
+
+ g_signal_emit (G_OBJECT (control),
+ signals[STREAM_REMOVED],
+ 0,
+ name);
}
diff --git a/libmatemixer/matemixer-control.h b/libmatemixer/matemixer-control.h
index 3482fbb..ad48768 100644
--- a/libmatemixer/matemixer-control.h
+++ b/libmatemixer/matemixer-control.h
@@ -43,26 +43,79 @@ typedef struct _MateMixerControl MateMixerControl;
typedef struct _MateMixerControlClass MateMixerControlClass;
typedef struct _MateMixerControlPrivate MateMixerControlPrivate;
+/**
+ * MateMixerControl:
+ *
+ * The #MateMixerControl structure contains only private data and should only
+ * be accessed using the provided API.
+ */
struct _MateMixerControl
{
- GObject parent;
-
- MateMixerControlPrivate *priv;
+ /*< private >*/
+ GObject parent;
+ MateMixerControlPrivate *priv;
};
+/**
+ * MateMixerControlClass:
+ *
+ * The class structure of #MateMixerControl.
+ */
struct _MateMixerControlClass
{
- GObjectClass parent;
-};
+ /*< private >*/
+ GObjectClass parent;
-GType mate_mixer_control_get_type (void) G_GNUC_CONST;
+ /* Signals */
+ void (*device_added) (MateMixerControl *control,
+ const gchar *name);
+ void (*device_changed) (MateMixerControl *control,
+ const gchar *name);
+ void (*device_removed) (MateMixerControl *control,
+ const gchar *name);
+ void (*stream_added) (MateMixerControl *control,
+ const gchar *name);
+ void (*stream_changed) (MateMixerControl *control,
+ const gchar *name);
+ void (*stream_removed) (MateMixerControl *control,
+ const gchar *name);
+};
+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);
+
+gboolean mate_mixer_control_set_backend_type (MateMixerControl *control,
+ MateMixerBackendType backend_type);
+gboolean mate_mixer_control_set_app_name (MateMixerControl *control,
+ const gchar *app_name);
+gboolean mate_mixer_control_set_app_id (MateMixerControl *control,
+ const gchar *app_id);
+gboolean mate_mixer_control_set_app_version (MateMixerControl *control,
+ const gchar *app_version);
+gboolean mate_mixer_control_set_app_icon (MateMixerControl *control,
+ const gchar *app_icon);
+gboolean mate_mixer_control_set_server_address (MateMixerControl *control,
+ const gchar *address);
+gboolean mate_mixer_control_open (MateMixerControl *control);
+
+MateMixerState mate_mixer_control_get_state (MateMixerControl *control);
+
+MateMixerDevice * mate_mixer_control_get_device (MateMixerControl *control,
+ const gchar *name);
+MateMixerStream * mate_mixer_control_get_stream (MateMixerControl *control,
+ const gchar *name);
+
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);
+gboolean mate_mixer_control_set_default_input_stream (MateMixerControl *control,
+ MateMixerStream *stream);
+
MateMixerStream * mate_mixer_control_get_default_output_stream (MateMixerControl *control);
+gboolean mate_mixer_control_set_default_output_stream (MateMixerControl *control,
+ MateMixerStream *stream);
+
const gchar * mate_mixer_control_get_backend_name (MateMixerControl *control);
MateMixerBackendType mate_mixer_control_get_backend_type (MateMixerControl *control);
diff --git a/libmatemixer/matemixer-device.c b/libmatemixer/matemixer-device.c
index cd5a47c..a022877 100644
--- a/libmatemixer/matemixer-device.c
+++ b/libmatemixer/matemixer-device.c
@@ -19,7 +19,6 @@
#include <glib-object.h>
#include "matemixer-device.h"
-#include "matemixer-enum-types.h"
#include "matemixer-profile.h"
G_DEFINE_INTERFACE (MateMixerDevice, mate_mixer_device, G_TYPE_OBJECT)
@@ -169,17 +168,17 @@ mate_mixer_device_get_active_profile (MateMixerDevice *device)
}
gboolean
-mate_mixer_device_set_active_profile (MateMixerDevice *device, const gchar *profile_name)
+mate_mixer_device_set_active_profile (MateMixerDevice *device, const gchar *profile)
{
MateMixerDeviceInterface *iface;
g_return_val_if_fail (MATE_MIXER_IS_DEVICE (device), FALSE);
- g_return_val_if_fail (profile_name != NULL, FALSE);
+ g_return_val_if_fail (profile != NULL, FALSE);
iface = MATE_MIXER_DEVICE_GET_INTERFACE (device);
if (iface->set_active_profile)
- return iface->set_active_profile (device, profile_name);
+ return iface->set_active_profile (device, profile);
return FALSE;
}
diff --git a/libmatemixer/matemixer-device.h b/libmatemixer/matemixer-device.h
index 3b25313..d814847 100644
--- a/libmatemixer/matemixer-device.h
+++ b/libmatemixer/matemixer-device.h
@@ -39,6 +39,7 @@ typedef struct _MateMixerDeviceInterface MateMixerDeviceInterface;
struct _MateMixerDeviceInterface
{
+ /*< private >*/
GTypeInterface parent;
const gchar *(*get_name) (MateMixerDevice *device);
@@ -49,11 +50,10 @@ struct _MateMixerDeviceInterface
const GList *(*list_profiles) (MateMixerDevice *device);
MateMixerProfile *(*get_active_profile) (MateMixerDevice *device);
gboolean (*set_active_profile) (MateMixerDevice *device,
- const gchar *profile_name);
+ const gchar *profile);
};
-GType mate_mixer_device_get_type (void) G_GNUC_CONST;
-
+GType mate_mixer_device_get_type (void) G_GNUC_CONST;
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);
@@ -62,7 +62,7 @@ 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 *profile_name);
+ const gchar *profile);
G_END_DECLS
diff --git a/libmatemixer/matemixer-enum-types.c b/libmatemixer/matemixer-enum-types.c
index 0d1c57d..43249a3 100644
--- a/libmatemixer/matemixer-enum-types.c
+++ b/libmatemixer/matemixer-enum-types.c
@@ -24,6 +24,27 @@
*/
GType
+mate_mixer_state_get_type (void)
+{
+ static GType etype = 0;
+
+ if (etype == 0) {
+ static const GEnumValue values[] = {
+ { MATE_MIXER_STATE_IDLE, "MATE_MIXER_STATE_IDLE", "idle" },
+ { MATE_MIXER_STATE_CONNECTING, "MATE_MIXER_STATE_CONNECTING", "connecting" },
+ { MATE_MIXER_STATE_READY, "MATE_MIXER_STATE_READY", "ready" },
+ { MATE_MIXER_STATE_FAILED, "MATE_MIXER_STATE_FAILED", "failed" },
+ { MATE_MIXER_STATE_UNKNOWN, "MATE_MIXER_STATE_UNKNOWN", "unknown" },
+ { 0, NULL, NULL }
+ };
+ etype = g_enum_register_static (
+ g_intern_static_string ("MateMixerState"),
+ values);
+ }
+ return etype;
+}
+
+GType
mate_mixer_backend_type_get_type (void)
{
static GType etype = 0;
@@ -68,14 +89,19 @@ mate_mixer_stream_flags_get_type (void)
if (etype == 0) {
static const GFlagsValue values[] = {
+ { MATE_MIXER_STREAM_NO_FLAGS, "MATE_MIXER_STREAM_NO_FLAGS", "no-flags" },
{ 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_APPLICATION, "MATE_MIXER_STREAM_APPLICATION", "application" },
{ MATE_MIXER_STREAM_OUTPUT_MONITOR, "MATE_MIXER_STREAM_OUTPUT_MONITOR", "output-monitor" },
+ { MATE_MIXER_STREAM_HAS_MUTE, "MATE_MIXER_STREAM_HAS_MUTE", "has-mute" },
+ { MATE_MIXER_STREAM_HAS_VOLUME, "MATE_MIXER_STREAM_HAS_VOLUME", "has-volume" },
+ { MATE_MIXER_STREAM_HAS_DECIBEL_VOLUME, "MATE_MIXER_STREAM_HAS_DECIBEL_VOLUME", "has-decibel-volume" },
+ { MATE_MIXER_STREAM_HAS_FLAT_VOLUME, "MATE_MIXER_STREAM_HAS_FLAT_VOLUME", "has-flat-volume" },
{ 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" },
+ { MATE_MIXER_STREAM_CAN_SET_VOLUME, "MATE_MIXER_STREAM_CAN_SET_VOLUME", "can-set-volume" },
{ 0, NULL, NULL }
};
etype = g_flags_register_static (
diff --git a/libmatemixer/matemixer-enum-types.h b/libmatemixer/matemixer-enum-types.h
index ccb87a6..0275c27 100644
--- a/libmatemixer/matemixer-enum-types.h
+++ b/libmatemixer/matemixer-enum-types.h
@@ -28,19 +28,22 @@ G_BEGIN_DECLS
* https://bugzilla.gnome.org/show_bug.cgi?id=621942
*/
-#define MATE_MIXER_TYPE_BACKEND_TYPE (mate_mixer_backend_type_get_type ())
+#define MATE_MIXER_TYPE_STATE (mate_mixer_state_get_type ())
+GType mate_mixer_state_get_type (void) G_GNUC_CONST;
+
+#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_PORT_STATUS (mate_mixer_port_status_get_type ())
+#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_STREAM_FLAGS (mate_mixer_stream_flags_get_type ())
+#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 ())
+#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 ())
+#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 cccb70d..5fc348d 100644
--- a/libmatemixer/matemixer-enums.h
+++ b/libmatemixer/matemixer-enums.h
@@ -24,7 +24,15 @@
*/
typedef enum {
- MATE_MIXER_BACKEND_UNKNOWN,
+ MATE_MIXER_STATE_IDLE = 0,
+ MATE_MIXER_STATE_CONNECTING,
+ MATE_MIXER_STATE_READY,
+ MATE_MIXER_STATE_FAILED,
+ MATE_MIXER_STATE_UNKNOWN
+} MateMixerState;
+
+typedef enum {
+ MATE_MIXER_BACKEND_UNKNOWN = 0,
MATE_MIXER_BACKEND_PULSE,
MATE_MIXER_BACKEND_NULL
} MateMixerBackendType;
@@ -36,29 +44,34 @@ typedef enum {
} MateMixerPortStatus;
typedef enum { /*< flags >*/
- 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
+ MATE_MIXER_STREAM_NO_FLAGS = 0,
+ MATE_MIXER_STREAM_INPUT = 1 << 0,
+ MATE_MIXER_STREAM_OUTPUT = 1 << 1,
+ MATE_MIXER_STREAM_CLIENT = 1 << 2,
+ MATE_MIXER_STREAM_APPLICATION = 1 << 3,
+ MATE_MIXER_STREAM_OUTPUT_MONITOR = 1 << 4,
+ MATE_MIXER_STREAM_HAS_MUTE = 1 << 5,
+ MATE_MIXER_STREAM_HAS_VOLUME = 1 << 6,
+ MATE_MIXER_STREAM_HAS_DECIBEL_VOLUME = 1 << 7,
+ MATE_MIXER_STREAM_HAS_FLAT_VOLUME = 1 << 8,
+ MATE_MIXER_STREAM_CAN_BALANCE = 1 << 9,
+ MATE_MIXER_STREAM_CAN_FADE = 1 << 10,
+ MATE_MIXER_STREAM_CAN_SET_VOLUME = 1 << 11
} MateMixerStreamFlags;
typedef enum {
- MATE_MIXER_STREAM_UNKNOWN_STATUS,
- MATE_MIXER_STREAM_RUNNING,
- MATE_MIXER_STREAM_IDLE,
- MATE_MIXER_STREAM_SUSPENDED
+ 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_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,
@@ -67,13 +80,13 @@ typedef enum {
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_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
+ 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
index c4b2de3..7ac21f7 100644
--- a/libmatemixer/matemixer-port.c
+++ b/libmatemixer/matemixer-port.c
@@ -27,12 +27,11 @@ struct _MateMixerPortPrivate
gchar *name;
gchar *description;
gchar *icon;
- guint32 priority;
+ gulong priority;
MateMixerPortStatus status;
};
-enum
-{
+enum {
PROP_0,
PROP_NAME,
PROP_DESCRIPTION,
@@ -71,7 +70,7 @@ mate_mixer_port_get_property (GObject *object,
g_value_set_string (value, port->priv->icon);
break;
case PROP_PRIORITY:
- g_value_set_uint (value, port->priv->priority);
+ g_value_set_ulong (value, port->priv->priority);
break;
case PROP_STATUS:
g_value_set_enum (value, port->priv->status);
@@ -103,7 +102,7 @@ mate_mixer_port_set_property (GObject *object,
port->priv->icon = g_strdup (g_value_get_string (value));
break;
case PROP_PRIORITY:
- port->priv->priority = g_value_get_uint (value);
+ port->priv->priority = g_value_get_ulong (value);
break;
case PROP_STATUS:
port->priv->status = g_value_get_enum (value);
@@ -124,53 +123,48 @@ mate_mixer_port_class_init (MateMixerPortClass *klass)
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);
+ 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_ulong ("priority",
+ "Priority",
+ "Priority of the port",
+ 0,
+ G_MAXULONG,
+ 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);
@@ -203,7 +197,7 @@ MateMixerPort *
mate_mixer_port_new (const gchar *name,
const gchar *description,
const gchar *icon,
- guint32 priority,
+ gulong priority,
MateMixerPortStatus status)
{
return g_object_new (MATE_MIXER_TYPE_PORT,
@@ -239,7 +233,7 @@ mate_mixer_port_get_icon (MateMixerPort *port)
return port->priv->icon;
}
-guint32
+gulong
mate_mixer_port_get_priority (MateMixerPort *port)
{
g_return_val_if_fail (MATE_MIXER_IS_PORT (port), 0);
diff --git a/libmatemixer/matemixer-port.h b/libmatemixer/matemixer-port.h
index 581f4ec..e0a9f79 100644
--- a/libmatemixer/matemixer-port.h
+++ b/libmatemixer/matemixer-port.h
@@ -44,29 +44,29 @@ typedef struct _MateMixerPortPrivate MateMixerPortPrivate;
struct _MateMixerPort
{
- GObject parent;
-
- MateMixerPortPrivate *priv;
+ /*< private >*/
+ GObject parent;
+ MateMixerPortPrivate *priv;
};
struct _MateMixerPortClass
{
- GObjectClass parent;
+ /*< private >*/
+ 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);
+GType mate_mixer_port_get_type (void) G_GNUC_CONST;
+MateMixerPort * mate_mixer_port_new (const gchar *name,
+ const gchar *description,
+ const gchar *icon,
+ gulong 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);
+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);
+gulong mate_mixer_port_get_priority (MateMixerPort *port);
+MateMixerPortStatus mate_mixer_port_get_status (MateMixerPort *port);
G_END_DECLS
diff --git a/libmatemixer/matemixer-profile.c b/libmatemixer/matemixer-profile.c
index c32489f..38f17c7 100644
--- a/libmatemixer/matemixer-profile.c
+++ b/libmatemixer/matemixer-profile.c
@@ -24,7 +24,7 @@ struct _MateMixerProfilePrivate
{
gchar *name;
gchar *description;
- guint32 priority;
+ gulong priority;
};
enum
@@ -62,7 +62,7 @@ mate_mixer_profile_get_property (GObject *object,
g_value_set_string (value, profile->priv->description);
break;
case PROP_PRIORITY:
- g_value_set_uint (value, profile->priv->priority);
+ g_value_set_ulong (value, profile->priv->priority);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
@@ -88,7 +88,7 @@ mate_mixer_profile_set_property (GObject *object,
profile->priv->description = g_strdup (g_value_get_string (value));
break;
case PROP_PRIORITY:
- profile->priv->priority = g_value_get_uint (value);
+ profile->priv->priority = g_value_get_ulong (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
@@ -106,34 +106,31 @@ mate_mixer_profile_class_init (MateMixerProfileClass *klass)
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);
+ 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_ulong ("priority",
+ "Priority",
+ "Priority of the profile",
+ 0,
+ G_MAXULONG,
+ 0,
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (object_class, N_PROPERTIES, properties);
@@ -162,7 +159,7 @@ mate_mixer_profile_finalize (GObject *object)
}
MateMixerProfile *
-mate_mixer_profile_new (const gchar *name, const gchar *description, guint32 priority)
+mate_mixer_profile_new (const gchar *name, const gchar *description, gulong priority)
{
return g_object_new (MATE_MIXER_TYPE_PROFILE,
"name", name,
@@ -187,10 +184,10 @@ mate_mixer_profile_get_description (MateMixerProfile *profile)
return profile->priv->description;
}
-guint32
+gulong
mate_mixer_profile_get_priority (MateMixerProfile *profile)
{
- g_return_val_if_fail (MATE_MIXER_IS_PROFILE (profile), G_MAXUINT32);
+ g_return_val_if_fail (MATE_MIXER_IS_PROFILE (profile), 0);
return profile->priv->priority;
}
diff --git a/libmatemixer/matemixer-profile.h b/libmatemixer/matemixer-profile.h
index 7be140b..4ce0d1a 100644
--- a/libmatemixer/matemixer-profile.h
+++ b/libmatemixer/matemixer-profile.h
@@ -42,25 +42,25 @@ typedef struct _MateMixerProfilePrivate MateMixerProfilePrivate;
struct _MateMixerProfile
{
- GObject parent;
-
- MateMixerProfilePrivate *priv;
+ /*< private >*/
+ GObject parent;
+ MateMixerProfilePrivate *priv;
};
struct _MateMixerProfileClass
{
- GObjectClass parent;
+ /*< private >*/
+ GObjectClass parent;
};
-GType mate_mixer_profile_get_type (void) G_GNUC_CONST;
-
+GType mate_mixer_profile_get_type (void) G_GNUC_CONST;
MateMixerProfile *mate_mixer_profile_new (const gchar *name,
const gchar *description,
- guint32 priority);
+ gulong 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);
+gulong mate_mixer_profile_get_priority (MateMixerProfile *profile);
G_END_DECLS
diff --git a/libmatemixer/matemixer-stream.c b/libmatemixer/matemixer-stream.c
index 8fd309d..e2c9820 100644
--- a/libmatemixer/matemixer-stream.c
+++ b/libmatemixer/matemixer-stream.c
@@ -66,6 +66,16 @@ mate_mixer_stream_default_init (MateMixerStreamInterface *iface)
G_PARAM_STATIC_STRINGS));
g_object_interface_install_property (iface,
+ g_param_spec_flags ("flags",
+ "Flags",
+ "Capability flags of the stream",
+ MATE_MIXER_TYPE_STREAM_FLAGS,
+ MATE_MIXER_STREAM_NO_FLAGS,
+ 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",
@@ -80,13 +90,14 @@ mate_mixer_stream_default_init (MateMixerStreamInterface *iface)
"Mute",
"Mute state of the stream",
FALSE,
- G_PARAM_READABLE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
g_object_interface_install_property (iface,
- g_param_spec_uint ("volume",
- "Volume",
- "Volume of the stream",
+ g_param_spec_uint ("num-channels",
+ "Number of channels",
+ "Number of volume channels in the stream",
0,
G_MAXUINT,
0,
@@ -94,6 +105,16 @@ mate_mixer_stream_default_init (MateMixerStreamInterface *iface)
G_PARAM_STATIC_STRINGS));
g_object_interface_install_property (iface,
+ g_param_spec_int64 ("volume",
+ "Volume",
+ "Volume of the stream",
+ G_MININT64,
+ G_MAXINT64,
+ 0,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_interface_install_property (iface,
g_param_spec_double ("volume-db",
"Volume dB",
"Volume of the stream in decibels",
@@ -128,7 +149,8 @@ mate_mixer_stream_default_init (MateMixerStreamInterface *iface)
"Active port",
"The currently active port of the stream",
MATE_MIXER_TYPE_PORT,
- G_PARAM_READABLE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
}
@@ -237,7 +259,7 @@ mate_mixer_stream_set_mute (MateMixerStream *stream, gboolean mute)
return FALSE;
}
-guint32
+gint64
mate_mixer_stream_get_volume (MateMixerStream *stream)
{
MateMixerStreamInterface *iface;
@@ -253,7 +275,7 @@ mate_mixer_stream_get_volume (MateMixerStream *stream)
}
gboolean
-mate_mixer_stream_set_volume (MateMixerStream *stream, guint32 volume)
+mate_mixer_stream_set_volume (MateMixerStream *stream, gint64 volume)
{
MateMixerStreamInterface *iface;
@@ -297,7 +319,7 @@ mate_mixer_stream_set_volume_db (MateMixerStream *stream, gdouble volume_db)
return FALSE;
}
-guint8
+guint
mate_mixer_stream_get_num_channels (MateMixerStream *stream)
{
MateMixerStreamInterface *iface;
@@ -313,7 +335,7 @@ mate_mixer_stream_get_num_channels (MateMixerStream *stream)
}
MateMixerChannelPosition
-mate_mixer_stream_get_channel_position (MateMixerStream *stream, guint8 channel)
+mate_mixer_stream_get_channel_position (MateMixerStream *stream, guint channel)
{
MateMixerStreamInterface *iface;
@@ -327,8 +349,8 @@ mate_mixer_stream_get_channel_position (MateMixerStream *stream, guint8 channel)
return MATE_MIXER_CHANNEL_UNKNOWN_POSITION;
}
-guint32
-mate_mixer_stream_get_channel_volume (MateMixerStream *stream, guint8 channel)
+gint64
+mate_mixer_stream_get_channel_volume (MateMixerStream *stream, guint channel)
{
MateMixerStreamInterface *iface;
@@ -344,8 +366,8 @@ mate_mixer_stream_get_channel_volume (MateMixerStream *stream, guint8 channel)
gboolean
mate_mixer_stream_set_channel_volume (MateMixerStream *stream,
- guint8 channel,
- guint32 volume)
+ guint channel,
+ gint64 volume)
{
MateMixerStreamInterface *iface;
@@ -360,7 +382,7 @@ mate_mixer_stream_set_channel_volume (MateMixerStream *stream,
}
gdouble
-mate_mixer_stream_get_channel_volume_db (MateMixerStream *stream, guint8 channel)
+mate_mixer_stream_get_channel_volume_db (MateMixerStream *stream, guint channel)
{
MateMixerStreamInterface *iface;
@@ -376,7 +398,7 @@ mate_mixer_stream_get_channel_volume_db (MateMixerStream *stream, guint8 channel
gboolean
mate_mixer_stream_set_channel_volume_db (MateMixerStream *stream,
- guint8 channel,
+ guint channel,
gdouble volume_db)
{
MateMixerStreamInterface *iface;
@@ -407,7 +429,7 @@ mate_mixer_stream_has_position (MateMixerStream *stream,
return FALSE;
}
-guint32
+gint64
mate_mixer_stream_get_position_volume (MateMixerStream *stream,
MateMixerChannelPosition position)
{
@@ -426,7 +448,7 @@ mate_mixer_stream_get_position_volume (MateMixerStream *stream,
gboolean
mate_mixer_stream_set_position_volume (MateMixerStream *stream,
MateMixerChannelPosition position,
- guint32 volume)
+ gint64 volume)
{
MateMixerStreamInterface *iface;
@@ -533,6 +555,36 @@ mate_mixer_stream_set_fade (MateMixerStream *stream, gdouble fade)
return FALSE;
}
+gboolean
+mate_mixer_stream_suspend (MateMixerStream *stream)
+{
+ MateMixerStreamInterface *iface;
+
+ g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), FALSE);
+
+ iface = MATE_MIXER_STREAM_GET_INTERFACE (stream);
+
+ if (iface->suspend)
+ return iface->suspend (stream);
+
+ return FALSE;
+}
+
+gboolean
+mate_mixer_stream_resume (MateMixerStream *stream)
+{
+ MateMixerStreamInterface *iface;
+
+ g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), FALSE);
+
+ iface = MATE_MIXER_STREAM_GET_INTERFACE (stream);
+
+ if (iface->resume)
+ return iface->resume (stream);
+
+ return FALSE;
+}
+
const GList *
mate_mixer_stream_list_ports (MateMixerStream *stream)
{
@@ -578,3 +630,48 @@ mate_mixer_stream_set_active_port (MateMixerStream *stream, const gchar *port_na
return FALSE;
}
+
+gint64
+mate_mixer_stream_get_min_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_min_volume)
+ return iface->get_min_volume (stream);
+
+ return 0;
+}
+
+gint64
+mate_mixer_stream_get_max_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_max_volume)
+ return iface->get_max_volume (stream);
+
+ return 0;
+}
+
+gint64
+mate_mixer_stream_get_normal_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_normal_volume)
+ return iface->get_normal_volume (stream);
+
+ return 0;
+}
diff --git a/libmatemixer/matemixer-stream.h b/libmatemixer/matemixer-stream.h
index a6e8dde..d773398 100644
--- a/libmatemixer/matemixer-stream.h
+++ b/libmatemixer/matemixer-stream.h
@@ -41,42 +41,44 @@ typedef struct _MateMixerStreamInterface MateMixerStreamInterface;
struct _MateMixerStreamInterface
{
+ /*< private >*/
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);
+ MateMixerStreamFlags (*get_flags) (MateMixerStream *stream);
MateMixerStreamStatus (*get_status) (MateMixerStream *stream);
gboolean (*get_mute) (MateMixerStream *stream);
gboolean (*set_mute) (MateMixerStream *stream,
gboolean mute);
- guint32 (*get_volume) (MateMixerStream *stream);
+ guint (*get_num_channels) (MateMixerStream *stream);
+ gint64 (*get_volume) (MateMixerStream *stream);
gboolean (*set_volume) (MateMixerStream *stream,
- guint32 volume);
+ gint64 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);
+ guint channel);
+ gint64 (*get_channel_volume) (MateMixerStream *stream,
+ guint channel);
gboolean (*set_channel_volume) (MateMixerStream *stream,
- guint8 channel,
- guint32 volume);
+ guint channel,
+ gint64 volume);
gdouble (*get_channel_volume_db) (MateMixerStream *stream,
- guint8 channel);
+ guint channel);
gboolean (*set_channel_volume_db) (MateMixerStream *stream,
- guint8 channel,
+ guint channel,
gdouble volume_db);
gboolean (*has_position) (MateMixerStream *stream,
MateMixerChannelPosition position);
- guint32 (*get_position_volume) (MateMixerStream *stream,
+ gint64 (*get_position_volume) (MateMixerStream *stream,
MateMixerChannelPosition position);
gboolean (*set_position_volume) (MateMixerStream *stream,
MateMixerChannelPosition position,
- guint32 volume);
+ gint64 volume);
gdouble (*get_position_volume_db) (MateMixerStream *stream,
MateMixerChannelPosition position);
gboolean (*set_position_volume_db) (MateMixerStream *stream,
@@ -88,57 +90,63 @@ struct _MateMixerStreamInterface
gdouble (*get_fade) (MateMixerStream *stream);
gboolean (*set_fade) (MateMixerStream *stream,
gdouble fade);
+ gboolean (*suspend) (MateMixerStream *stream);
+ gboolean (*resume) (MateMixerStream *stream);
+ const GList * (*list_ports) (MateMixerStream *stream);
MateMixerPort * (*get_active_port) (MateMixerStream *stream);
gboolean (*set_active_port) (MateMixerStream *stream,
const gchar *port_name);
- const GList * (*list_ports) (MateMixerStream *stream);
+ gint64 (*get_min_volume) (MateMixerStream *stream);
+ gint64 (*get_max_volume) (MateMixerStream *stream);
+ gint64 (*get_normal_volume) (MateMixerStream *stream);
};
-GType mate_mixer_stream_get_type (void) G_GNUC_CONST;
+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);
+MateMixerStreamFlags mate_mixer_stream_get_flags (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);
+guint mate_mixer_stream_get_num_channels (MateMixerStream *stream);
+
+gint64 mate_mixer_stream_get_volume (MateMixerStream *stream);
gboolean mate_mixer_stream_set_volume (MateMixerStream *stream,
- guint32 volume);
+ gint64 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);
+ guint channel);
-guint32 mate_mixer_stream_get_channel_volume (MateMixerStream *stream,
- guint8 channel);
+gint64 mate_mixer_stream_get_channel_volume (MateMixerStream *stream,
+ guint channel);
gboolean mate_mixer_stream_set_channel_volume (MateMixerStream *stream,
- guint8 channel,
- guint32 volume);
+ guint channel,
+ gint64 volume);
gdouble mate_mixer_stream_get_channel_volume_db (MateMixerStream *stream,
- guint8 channel);
+ guint channel);
gboolean mate_mixer_stream_set_channel_volume_db (MateMixerStream *stream,
- guint8 channel,
+ guint channel,
gdouble volume_db);
gboolean mate_mixer_stream_has_position (MateMixerStream *stream,
MateMixerChannelPosition position);
-guint32 mate_mixer_stream_get_position_volume (MateMixerStream *stream,
+gint64 mate_mixer_stream_get_position_volume (MateMixerStream *stream,
MateMixerChannelPosition position);
gboolean mate_mixer_stream_set_position_volume (MateMixerStream *stream,
MateMixerChannelPosition position,
- guint32 volume);
+ gint64 volume);
gdouble mate_mixer_stream_get_position_volume_db (MateMixerStream *stream,
MateMixerChannelPosition position);
@@ -154,12 +162,19 @@ gdouble mate_mixer_stream_get_fade (MateMixerStre
gboolean mate_mixer_stream_set_fade (MateMixerStream *stream,
gdouble fade);
+gboolean mate_mixer_stream_suspend (MateMixerStream *stream);
+gboolean mate_mixer_stream_resume (MateMixerStream *stream);
+
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,
const gchar *port);
+gint64 mate_mixer_stream_get_min_volume (MateMixerStream *stream);
+gint64 mate_mixer_stream_get_max_volume (MateMixerStream *stream);
+gint64 mate_mixer_stream_get_normal_volume (MateMixerStream *stream);
+
G_END_DECLS
#endif /* MATEMIXER_STREAM_H */
diff --git a/libmatemixer/matemixer-version.h.in b/libmatemixer/matemixer-version.h.in
new file mode 100644
index 0000000..17ea7b4
--- /dev/null
+++ b/libmatemixer/matemixer-version.h.in
@@ -0,0 +1,64 @@
+/*
+ * 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_VERSION_H
+#define MATEMIXER_VERSION_H
+
+/**
+ * LIBMATEMIXER_MAJOR_VERSION:
+ *
+ * Libmatemixer major version component (e.g. 1 if %LIBMATEMIXER_VERSION is 1.2.3).
+ */
+#define LIBMATEMIXER_MAJOR_VERSION (@LIBMATEMIXER_MAJOR_VERSION@)
+
+/**
+ * LIBMATEMIXER_MINOR_VERSION:
+ *
+ * Libmatemixer minor version component (e.g. 2 if %LIBMATEMIXER_VERSION is 1.2.3).
+ */
+#define LIBMATEMIXER_MINOR_VERSION (@LIBMATEMIXER_MINOR_VERSION@)
+
+/**
+ * LIBMATEMIXER_MICRO_VERSION:
+ *
+ * Libmatemixer micro version component (e.g. 3 if %LIBMATEMIXER_VERSION is 1.2.3).
+ */
+#define LIBMATEMIXER_MICRO_VERSION (@LIBMATEMIXER_MICRO_VERSION@)
+
+/**
+ * LIBMATEMIXER_VERSION:
+ *
+ * Libmatemixer version.
+ */
+#define LIBMATEMIXER_VERSION (@LIBMATEMIXER_VERSION@)
+
+/**
+ * LIBMATEMIXER_CHECK_VERSION:
+ * @major: major version number
+ * @minor: minor version number
+ * @micro: micro version number
+ *
+ * Compile-time version checking. Evaluates to %TRUE if the version of the
+ * library is greater than the required one.
+ */
+#define LIBMATEMIXER_CHECK_VERSION(major, minor, micro) \
+ (LIBMATEMIXER_MAJOR_VERSION > (major) || \
+ (LIBMATEMIXER_MAJOR_VERSION == (major) && LIBMATEMIXER_MINOR_VERSION > (minor)) || \
+ (LIBMATEMIXER_MAJOR_VERSION == (major) && LIBMATEMIXER_MINOR_VERSION == (minor) && \
+ LIBMATEMIXER_MICRO_VERSION >= (micro)))
+
+#endif /* LIBMATEMIXER_VERSION_H */
diff --git a/libmatemixer/matemixer.c b/libmatemixer/matemixer.c
index 3c8f643..1e5d4e0 100644
--- a/libmatemixer/matemixer.c
+++ b/libmatemixer/matemixer.c
@@ -25,12 +25,21 @@
#include "matemixer-private.h"
#include "matemixer-backend-module.h"
-static void mixer_load_modules (void);
-static gint mixer_compare_modules (gconstpointer a, gconstpointer b);
+static void mixer_load_modules (void);
+static gint mixer_compare_modules (gconstpointer a, gconstpointer b);
static GList *mixer_modules = NULL;
static gboolean mixer_initialized = FALSE;
+/**
+ * mate_mixer_init:
+ *
+ * Initializes the library. You must call this function before using any other
+ * function from the library.
+ *
+ * Returns: %TRUE on success, or %FALSE if the library installation is broken and
+ * does not provide support for any sound systems.
+ */
gboolean
mate_mixer_init (void)
{
@@ -66,6 +75,12 @@ mate_mixer_init (void)
return mixer_initialized;
}
+/**
+ * mate_mixer_deinit:
+ *
+ * Deinitializes the library. You should call this function when you do not need
+ * to use the library any longer or before exitting the application.
+ */
void
mate_mixer_deinit (void)
{
@@ -135,14 +150,14 @@ mixer_load_modules (void)
g_error_free (error);
}
} else {
- g_critical ("Unable to load backend modules: GModule not supported");
+ g_critical ("Unable to load backend modules: GModule is not supported in your system");
}
loaded = TRUE;
}
-/* GCompareFunc function to sort backend modules by the priority, lower
- * number means higher priority */
+/* GCompareFunc function to sort backend modules by the priority, higher number means
+ * higher priority */
static gint
mixer_compare_modules (gconstpointer a, gconstpointer b)
{
@@ -151,5 +166,5 @@ mixer_compare_modules (gconstpointer a, gconstpointer b)
info1 = mate_mixer_backend_module_get_info (MATE_MIXER_BACKEND_MODULE (a));
info2 = mate_mixer_backend_module_get_info (MATE_MIXER_BACKEND_MODULE (b));
- return info1->priority - info2->priority;
+ return info2->priority - info1->priority;
}
diff --git a/libmatemixer/matemixer.h b/libmatemixer/matemixer.h
index b43de79..99df233 100644
--- a/libmatemixer/matemixer.h
+++ b/libmatemixer/matemixer.h
@@ -26,8 +26,8 @@
G_BEGIN_DECLS
-gboolean mate_mixer_init (void);
-void mate_mixer_deinit (void);
+gboolean mate_mixer_init (void);
+void mate_mixer_deinit (void);
G_END_DECLS