diff options
author | Michal Ratajsky <[email protected]> | 2014-06-20 00:12:40 +0200 |
---|---|---|
committer | Michal Ratajsky <[email protected]> | 2014-06-20 00:12:40 +0200 |
commit | 6be9a89195e0d3bf8408cea661f22cb97b638f24 (patch) | |
tree | 745cfec763facc62b6c3bc51cd246e5cad4d9f68 /libmatemixer | |
parent | a2290d5e13ccee88fd9ae66a3895eb4da646f81f (diff) | |
download | libmatemixer-6be9a89195e0d3bf8408cea661f22cb97b638f24.tar.bz2 libmatemixer-6be9a89195e0d3bf8408cea661f22cb97b638f24.tar.xz |
Pulse and API updates, fixes
Diffstat (limited to 'libmatemixer')
23 files changed, 1341 insertions, 845 deletions
diff --git a/libmatemixer/Makefile.am b/libmatemixer/Makefile.am index a45b29c..9d79e9d 100644 --- a/libmatemixer/Makefile.am +++ b/libmatemixer/Makefile.am @@ -44,6 +44,4 @@ libmatemixer_la_LDFLAGS = \ -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 b04ad6f..5825c13 100644 --- a/libmatemixer/matemixer-backend-module.c +++ b/libmatemixer/matemixer-backend-module.c @@ -34,16 +34,32 @@ struct _MateMixerBackendModulePrivate const MateMixerBackendInfo *(*get_info) (void); }; -static void mate_mixer_backend_module_class_init (MateMixerBackendModuleClass *klass); -static void mate_mixer_backend_module_init (MateMixerBackendModule *module); -static void mate_mixer_backend_module_dispose (GObject *object); -static void mate_mixer_backend_module_finalize (GObject *object); +enum { + PROP_0, + PROP_PATH, + N_PROPERTIES +}; + +static void mate_mixer_backend_module_class_init (MateMixerBackendModuleClass *klass); + +static void mate_mixer_backend_module_get_property (GObject *object, + guint param_id, + GValue *value, + GParamSpec *pspec); +static void mate_mixer_backend_module_set_property (GObject *object, + guint param_id, + const GValue *value, + GParamSpec *pspec); -static gboolean mate_mixer_backend_module_load (GTypeModule *gmodule); -static void mate_mixer_backend_module_unload (GTypeModule *gmodule); +static void mate_mixer_backend_module_init (MateMixerBackendModule *module); +static void mate_mixer_backend_module_dispose (GObject *object); +static void mate_mixer_backend_module_finalize (GObject *object); G_DEFINE_TYPE (MateMixerBackendModule, mate_mixer_backend_module, G_TYPE_TYPE_MODULE); +static gboolean backend_module_load (GTypeModule *gmodule); +static void backend_module_unload (GTypeModule *gmodule); + static void mate_mixer_backend_module_class_init (MateMixerBackendModuleClass *klass) { @@ -51,14 +67,67 @@ mate_mixer_backend_module_class_init (MateMixerBackendModuleClass *klass) GTypeModuleClass *module_class; object_class = G_OBJECT_CLASS (klass); - object_class->dispose = mate_mixer_backend_module_dispose; - object_class->finalize = mate_mixer_backend_module_finalize; + object_class->dispose = mate_mixer_backend_module_dispose; + object_class->finalize = mate_mixer_backend_module_finalize; + object_class->get_property = mate_mixer_backend_module_get_property; + object_class->set_property = mate_mixer_backend_module_set_property; + + g_object_class_install_property (object_class, + PROP_PATH, + g_param_spec_string ("path", + "Path", + "File path to the module", + 0, + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); module_class = G_TYPE_MODULE_CLASS (klass); - module_class->load = mate_mixer_backend_module_load; - module_class->unload = mate_mixer_backend_module_unload; + module_class->load = backend_module_load; + module_class->unload = backend_module_unload; - g_type_class_add_private (klass, sizeof (MateMixerBackendModulePrivate)); + g_type_class_add_private (object_class, sizeof (MateMixerBackendModulePrivate)); +} + +static void +mate_mixer_backend_module_get_property (GObject *object, + guint param_id, + GValue *value, + GParamSpec *pspec) +{ + MateMixerBackendModule *module; + + module = MATE_MIXER_BACKEND_MODULE (object); + + switch (param_id) { + case PROP_PATH: + g_value_set_string (value, module->priv->path); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); + break; + } +} + +static void +mate_mixer_backend_module_set_property (GObject *object, + guint param_id, + const GValue *value, + GParamSpec *pspec) +{ + MateMixerBackendModule *module; + + module = MATE_MIXER_BACKEND_MODULE (object); + + switch (param_id) { + case PROP_PATH: + /* Construct-only string property */ + module->priv->path = g_strdup (g_value_get_string (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); + break; + } } static void @@ -88,13 +157,70 @@ mate_mixer_backend_module_dispose (GObject *object) static void mate_mixer_backend_module_finalize (GObject *object) { + /* This is in fact never called */ g_free (MATE_MIXER_BACKEND_MODULE (object)->priv->path); G_OBJECT_CLASS (mate_mixer_backend_module_parent_class)->finalize (object); } +/** + * mate_mixer_backend_module_new: + * @path: path to a backend module + * + * Creates a new #MateMixerBackendModule instance. + * + * Returns: a new #MateMixerBackendModule instance. + */ +MateMixerBackendModule * +mate_mixer_backend_module_new (const gchar *path) +{ + MateMixerBackendModule *module; + + g_return_val_if_fail (path != NULL, NULL); + + module = g_object_new (MATE_MIXER_TYPE_BACKEND_MODULE, + "path", path, + NULL); + + g_type_module_set_name (G_TYPE_MODULE (module), path); + + return module; +} + +/** + * mate_mixer_backend_module_get_info: + * @module: a #MateMixerBackendModule + * + * Gets information about the loaded backend. + * + * Returns: a #MateMixerBackendInfo. + */ +const MateMixerBackendInfo * +mate_mixer_backend_module_get_info (MateMixerBackendModule *module) +{ + g_return_val_if_fail (MATE_MIXER_IS_BACKEND_MODULE (module), NULL); + + return module->priv->get_info (); +} + +/** + * mate_mixer_backend_module_get_path: + * @module: a #MateMixerBackendModule + * + * Gets file path to the backend module. + * + * Returns: string containing the path. + */ +const gchar * +mate_mixer_backend_module_get_path (MateMixerBackendModule *module) +{ + g_return_val_if_fail (MATE_MIXER_IS_BACKEND_MODULE (module), NULL); + + return module->priv->path; +} + static gboolean -mate_mixer_backend_module_load (GTypeModule *type_module) +backend_module_load (GTypeModule *type_module) { MateMixerBackendModule *module; @@ -127,7 +253,7 @@ mate_mixer_backend_module_load (GTypeModule *type_module) return FALSE; } - /* Optional backend functions */ + /* Optional backend function */ g_module_symbol (module->priv->gmodule, "backend_module_deinit", (gpointer *) &module->priv->deinit); @@ -135,11 +261,11 @@ 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 + /* 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); + g_critical ("Backend module %s does not provide module information", + module->priv->path); /* Close the module but keep the loaded flag to avoid unreffing * this instance as the GType has most likely been registered */ @@ -154,14 +280,14 @@ 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 avoid loading and initialize only */ module->priv->init (type_module); } return TRUE; } static void -mate_mixer_backend_module_unload (GTypeModule *type_module) +backend_module_unload (GTypeModule *type_module) { MateMixerBackendModule *module; @@ -172,34 +298,3 @@ mate_mixer_backend_module_unload (GTypeModule *type_module) if (module->priv->deinit) module->priv->deinit (); } - -MateMixerBackendModule * -mate_mixer_backend_module_new (const gchar *path) -{ - MateMixerBackendModule *module; - - g_return_val_if_fail (path != NULL, NULL); - - module = g_object_newv (MATE_MIXER_TYPE_BACKEND_MODULE, 0, NULL); - module->priv->path = g_strdup (path); - - g_type_module_set_name (G_TYPE_MODULE (module), path); - - return module; -} - -const MateMixerBackendInfo * -mate_mixer_backend_module_get_info (MateMixerBackendModule *module) -{ - g_return_val_if_fail (MATE_MIXER_IS_BACKEND_MODULE (module), NULL); - - return module->priv->get_info (); -} - -const gchar * -mate_mixer_backend_module_get_path (MateMixerBackendModule *module) -{ - g_return_val_if_fail (MATE_MIXER_IS_BACKEND_MODULE (module), NULL); - - return module->priv->path; -} diff --git a/libmatemixer/matemixer-backend-module.h b/libmatemixer/matemixer-backend-module.h index 61a426d..e654413 100644 --- a/libmatemixer/matemixer-backend-module.h +++ b/libmatemixer/matemixer-backend-module.h @@ -21,8 +21,6 @@ #include <glib.h> #include <glib-object.h> -#include "matemixer-enums.h" - G_BEGIN_DECLS typedef struct { @@ -41,7 +39,7 @@ typedef struct { #define MATE_MIXER_BACKEND_MODULE_CLASS(k) \ (G_TYPE_CHECK_CLASS_CAST ((k), MATE_MIXER_TYPE_BACKEND_MODULE, MateMixerBackendModuleClass)) #define MATE_MIXER_IS_BACKEND_MODULE_CLASS(k) \ - (G_TYPE_CLASS_CHECK_CLASS_TYPE ((k), MATE_MIXER_TYPE_BACKEND_MODULE)) + (G_TYPE_CHECK_CLASS_TYPE ((k), MATE_MIXER_TYPE_BACKEND_MODULE)) #define MATE_MIXER_BACKEND_MODULE_GET_CLASS(o) \ (G_TYPE_INSTANCE_GET_CLASS ((o), MATE_MIXER_TYPE_BACKEND_MODULE, MateMixerBackendModuleClass)) @@ -53,12 +51,13 @@ struct _MateMixerBackendModule { GTypeModule parent; + /*< private >*/ MateMixerBackendModulePrivate *priv; }; struct _MateMixerBackendModuleClass { - GTypeModuleClass parent; + GTypeModuleClass parent_class; }; GType mate_mixer_backend_module_get_type (void) G_GNUC_CONST; diff --git a/libmatemixer/matemixer-backend.c b/libmatemixer/matemixer-backend.c index 474edd4..32f7f1b 100644 --- a/libmatemixer/matemixer-backend.c +++ b/libmatemixer/matemixer-backend.c @@ -43,77 +43,99 @@ mate_mixer_backend_default_init (MateMixerBackendInterface *iface) g_object_interface_install_property (iface, g_param_spec_enum ("state", "State", - "Backend connection state", + "Current 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); + g_object_interface_install_property (iface, + g_param_spec_object ("default-input", + "Default input", + "Default input stream", + MATE_MIXER_TYPE_STREAM, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + g_object_interface_install_property (iface, + 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_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 @@ -129,25 +151,12 @@ mate_mixer_backend_set_data (MateMixerBackend *backend, const MateMixerBackendDa 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) { - MateMixerBackendInterface *iface; - g_return_val_if_fail (MATE_MIXER_IS_BACKEND (backend), FALSE); - iface = MATE_MIXER_BACKEND_GET_INTERFACE (backend); - - if (!iface->open) { - g_critical ("Backend module does not implement the open() method"); - return FALSE; - } - return iface->open (backend); + return MATE_MIXER_BACKEND_GET_INTERFACE (backend)->open (backend); } void @@ -166,17 +175,9 @@ mate_mixer_backend_close (MateMixerBackend *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); + return MATE_MIXER_BACKEND_GET_INTERFACE (backend)->get_state (backend); } GList * diff --git a/libmatemixer/matemixer-backend.h b/libmatemixer/matemixer-backend.h index 1a5418f..559f256 100644 --- a/libmatemixer/matemixer-backend.h +++ b/libmatemixer/matemixer-backend.h @@ -21,6 +21,7 @@ #include <glib.h> #include <glib-object.h> +#include "matemixer-enums.h" #include "matemixer-stream.h" G_BEGIN_DECLS @@ -48,22 +49,24 @@ typedef struct _MateMixerBackendInterface MateMixerBackendInterface; struct _MateMixerBackendInterface { - GTypeInterface parent; + GTypeInterface parent_iface; - /* Required */ - gboolean (*open) (MateMixerBackend *backend); - MateMixerState (*get_state) (MateMixerBackend *backend); - - /* Optional */ + /*< private >*/ void (*set_data) (MateMixerBackend *backend, const MateMixerBackendData *data); + gboolean (*open) (MateMixerBackend *backend); void (*close) (MateMixerBackend *backend); + + MateMixerState (*get_state) (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); diff --git a/libmatemixer/matemixer-client-stream.c b/libmatemixer/matemixer-client-stream.c index 80f48a9..d05b1bf 100644 --- a/libmatemixer/matemixer-client-stream.c +++ b/libmatemixer/matemixer-client-stream.c @@ -21,6 +21,18 @@ #include "matemixer-client-stream.h" #include "matemixer-stream.h" +/** + * SECTION:matemixer-client-stream + * @short_description: An interface providing extra functionality for client streams + * @see_also: #MateMixerStream + * @include: libmatemixer/matemixer.h + * + * #MateMixerClientStream represents a special kind of stream, which belongs + * to a parent input or output stream. + * + * A typical example of a client stream is a stream provided by an application. + */ + G_DEFINE_INTERFACE (MateMixerClientStream, mate_mixer_client_stream, G_TYPE_OBJECT) static void @@ -31,11 +43,50 @@ mate_mixer_client_stream_default_init (MateMixerClientStreamInterface *iface) "Parent", "Parent stream of the client stream", MATE_MIXER_TYPE_STREAM, - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_READWRITE | + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + g_object_interface_install_property (iface, + g_param_spec_string ("app-name", + "App name", + "Name of the client stream application", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + g_object_interface_install_property (iface, + g_param_spec_string ("app-id", + "App ID", + "Identifier of the client stream application", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + g_object_interface_install_property (iface, + g_param_spec_string ("app-version", + "App version", + "Version of the client stream application", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + g_object_interface_install_property (iface, + g_param_spec_string ("app-icon", + "App icon", + "Icon name of the client stream application", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); } +/** + * mate_mixer_client_stream_get_parent: + * @client: a #MateMixerClientStream + * + * Gets the parent stream of the client stream. + * + * Returns: a #MateMixerStream or %NULL on failure. + */ MateMixerStream * mate_mixer_client_stream_get_parent (MateMixerClientStream *client) { @@ -51,6 +102,16 @@ mate_mixer_client_stream_get_parent (MateMixerClientStream *client) return NULL; } +/** + * mate_mixer_client_stream_set_parent: + * @client: a #MateMixerClientStream + * @parent: a #MateMixerStream + * + * Changes the parent stream of the client stream. The parent stream must be a + * non-client output stream. + * + * Returns: %TRUE on success or %FALSE on failure. + */ gboolean mate_mixer_client_stream_set_parent (MateMixerClientStream *client, MateMixerStream *parent) { @@ -67,6 +128,14 @@ mate_mixer_client_stream_set_parent (MateMixerClientStream *client, MateMixerStr return FALSE; } +/** + * mate_mixer_client_stream_remove: + * @client: a #MateMixerClientStream + * + * Removes the client stream. + * + * Returns: %TRUE on success or %FALSE on failure. + */ gboolean mate_mixer_client_stream_remove (MateMixerClientStream *client) { @@ -81,3 +150,103 @@ mate_mixer_client_stream_remove (MateMixerClientStream *client) return FALSE; } + +/** + * mate_mixer_client_stream_get_app_name: + * @client: a #MateMixerClientStream + * + * Gets the name of the application in case the stream is an application + * stream. + * + * Returns: a string on success, or %NULL if the stream is not an application + * stream or if the application does not provide a name. + */ +const gchar * +mate_mixer_client_stream_get_app_name (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_app_name) + return iface->get_app_name (client); + + return NULL; +} + +/** + * mate_mixer_client_stream_get_app_id: + * @client: a #MateMixerClientStream + * + * Gets the identifier (e.g. org.example.app) of the application in case the + * stream is an application stream. + * + * Returns: a string on success, or %NULL if the stream is not an application + * stream or if the application does not provide an identifier. + */ +const gchar * +mate_mixer_client_stream_get_app_id (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_app_id) + return iface->get_app_id (client); + + return NULL; +} + +/** + * mate_mixer_client_stream_get_app_version: + * @client: a #MateMixerClientStream + * + * Gets the version of the application in case the stream is an application + * stream. + * + * Returns: a string on success, or %NULL if the stream is not an application + * stream or if the application does not provide a version string. + */ +const gchar * +mate_mixer_client_stream_get_app_version (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_app_version) + return iface->get_app_version (client); + + return NULL; +} + +/** + * mate_mixer_client_stream_get_app_icon: + * @client: a #MateMixerClientStream + * + * Gets the XDG icon name of the application in case the stream is an + * application stream. + * + * Returns: a string on success, or %NULL if the stream is not an application + * stream or if the application does not provide an icon name. + */ +const gchar * +mate_mixer_client_stream_get_app_icon (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_app_icon) + return iface->get_app_icon (client); + + return NULL; +} diff --git a/libmatemixer/matemixer-client-stream.h b/libmatemixer/matemixer-client-stream.h index 2c690c5..1375cb3 100644 --- a/libmatemixer/matemixer-client-stream.h +++ b/libmatemixer/matemixer-client-stream.h @@ -39,20 +39,29 @@ typedef struct _MateMixerClientStreamInterface MateMixerClientStreamInterface; struct _MateMixerClientStreamInterface { - /*< private >*/ - GTypeInterface parent; + GTypeInterface parent_iface; - MateMixerStream *(*get_parent) (MateMixerClientStream *client); - gboolean (*set_parent) (MateMixerClientStream *client, - MateMixerStream *stream); - gboolean (*remove) (MateMixerClientStream *client); + /*< private >*/ + MateMixerStream *(*get_parent) (MateMixerClientStream *client); + gboolean (*set_parent) (MateMixerClientStream *client, + MateMixerStream *stream); + gboolean (*remove) (MateMixerClientStream *client); + const gchar *(*get_app_name) (MateMixerClientStream *client); + const gchar *(*get_app_id) (MateMixerClientStream *client); + const gchar *(*get_app_version) (MateMixerClientStream *client); + const gchar *(*get_app_icon) (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); +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); + +const gchar * mate_mixer_client_stream_get_app_name (MateMixerClientStream *client); +const gchar * mate_mixer_client_stream_get_app_id (MateMixerClientStream *client); +const gchar * mate_mixer_client_stream_get_app_version (MateMixerClientStream *client); +const gchar * mate_mixer_client_stream_get_app_icon (MateMixerClientStream *client); G_END_DECLS diff --git a/libmatemixer/matemixer-control.c b/libmatemixer/matemixer-control.c index 3e3045e..3619a94 100644 --- a/libmatemixer/matemixer-control.c +++ b/libmatemixer/matemixer-control.c @@ -27,10 +27,16 @@ #include "matemixer-private.h" #include "matemixer-stream.h" +/** + * SECTION:matemixer-control + * @include: libmatemixer/matemixer.h + */ + struct _MateMixerControlPrivate { GList *devices; GList *streams; + gboolean backend_chosen; MateMixerState state; MateMixerBackend *backend; MateMixerBackendData backend_data; @@ -51,6 +57,8 @@ enum { N_PROPERTIES }; +static GParamSpec *properties[N_PROPERTIES] = { NULL, }; + enum { DEVICE_ADDED, DEVICE_CHANGED, @@ -61,43 +69,276 @@ enum { 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); +static guint signals[N_SIGNALS] = { 0, }; + +static void mate_mixer_control_class_init (MateMixerControlClass *klass); + +static void mate_mixer_control_get_property (GObject *object, + guint param_id, + GValue *value, + GParamSpec *pspec); +static void mate_mixer_control_set_property (GObject *object, + guint param_id, + const GValue *value, + GParamSpec *pspec); + +static void mate_mixer_control_init (MateMixerControl *control); +static void mate_mixer_control_dispose (GObject *object); +static void mate_mixer_control_finalize (GObject *object); G_DEFINE_TYPE (MateMixerControl, mate_mixer_control, G_TYPE_OBJECT); -static GParamSpec *properties[N_PROPERTIES] = { NULL, }; +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); + +static gboolean control_try_next_backend (MateMixerControl *control); + +static void control_change_state (MateMixerControl *control, + MateMixerState state); + +static void control_close (MateMixerControl *control); + +static void control_free_backend (MateMixerControl *control); +static void control_free_devices (MateMixerControl *control); +static void control_free_streams (MateMixerControl *control); -static guint signals[N_SIGNALS] = { 0, }; +static void +mate_mixer_control_class_init (MateMixerControlClass *klass) +{ + GObjectClass *object_class; + + object_class = G_OBJECT_CLASS (klass); + object_class->dispose = mate_mixer_control_dispose; + 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 name", + 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); + + g_object_class_install_properties (object_class, N_PROPERTIES, properties); + + /** + * MateMixerControl::device-added: + * @control: a #MateMixerControl + * @name: name of the added device + * + * The signal is emitted each time a device is added to the system. + */ + 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); + + /** + * MateMixerControl::device-changed: + * @control: a #MateMixerControl + * @name: name of the changed device + * + * The signal is emitted each time a change occurs on one of the known + * devices. + */ + 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); + + /** + * MateMixerControl::device-removed: + * @control: a #MateMixerControl + * @name: name of the removed device + * + * The signal is emitted each time a device is removed from the system. + */ + 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); + + /** + * MateMixerControl::stream-added: + * @control: a #MateMixerControl + * @name: name of the added stream + * + * The signal is emitted each time a stream is added to the system. + */ + 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); + + /** + * MateMixerControl::stream-changed: + * @control: a #MateMixerControl + * @name: name of the changed stream + * + * The signal is emitted each time a change occurs on one of the known + * streams. + */ + 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); + + /** + * MateMixerControl::stream-removed: + * @control: a #MateMixerControl + * @name: name of the removed stream + * + * The signal is emitted each time a stream is removed from the system. + */ + 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_type_class_add_private (object_class, sizeof (MateMixerControlPrivate)); +} static void mate_mixer_control_get_property (GObject *object, @@ -173,170 +414,6 @@ mate_mixer_control_set_property (GObject *object, } static void -mate_mixer_control_class_init (MateMixerControlClass *klass) -{ - GObjectClass *object_class; - - object_class = G_OBJECT_CLASS (klass); - object_class->dispose = mate_mixer_control_dispose; - 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)); -} - -static void mate_mixer_control_init (MateMixerControl *control) { control->priv = G_TYPE_INSTANCE_GET_PRIVATE (control, @@ -347,25 +424,7 @@ mate_mixer_control_init (MateMixerControl *control) static void mate_mixer_control_dispose (GObject *object) { - MateMixerControl *control; - - control = MATE_MIXER_CONTROL (object); - - if (control->priv->backend) { - mate_mixer_backend_close (control->priv->backend); - g_clear_object (&control->priv->backend); - } - - g_clear_object (&control->priv->module); - - if (control->priv->devices) { - g_list_free_full (control->priv->devices, g_object_unref); - control->priv->devices = NULL; - } - if (control->priv->streams) { - g_list_free_full (control->priv->streams, g_object_unref); - control->priv->streams = NULL; - } + control_close (MATE_MIXER_CONTROL (object)); G_OBJECT_CLASS (mate_mixer_control_parent_class)->dispose (object); } @@ -394,7 +453,8 @@ mate_mixer_control_finalize (GObject *object) * Returns: a new #MateMixerControl instance or %NULL if the library has not * been initialized using mate_mixer_init(). */ -MateMixerControl *mate_mixer_control_new (void) +MateMixerControl * +mate_mixer_control_new (void) { if (!mate_mixer_is_initialized ()) { g_critical ("The library has not been initialized"); @@ -415,7 +475,8 @@ MateMixerControl *mate_mixer_control_new (void) * @control use the given backend. * * This function will fail if support for the backend is not installed in - * the system. + * the system or if the current state is either %MATE_MIXER_STATE_CONNECTING or + * %MATE_MIXER_STATE_READY. * * Returns: %TRUE on success or %FALSE on failure. */ @@ -429,6 +490,10 @@ mate_mixer_control_set_backend_type (MateMixerControl *control, 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; + modules = mate_mixer_get_modules (); while (modules) { module = MATE_MIXER_BACKEND_MODULE (modules->data); @@ -634,11 +699,13 @@ mate_mixer_control_open (MateMixerControl *control) 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); + + if (control->priv->state == MATE_MIXER_STATE_CONNECTING || + control->priv->state == MATE_MIXER_STATE_READY) + return 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 */ + * specified by the application or the one with the highest priority */ modules = mate_mixer_get_modules (); if (control->priv->backend_type != MATE_MIXER_BACKEND_UNKNOWN) { @@ -658,7 +725,6 @@ mate_mixer_control_open (MateMixerControl *control) /* The highest priority module is on the top of the list */ module = MATE_MIXER_BACKEND_MODULE (modules->data); } - if (module == NULL) { /* Most likely the selected backend is not installed */ control_change_state (control, MATE_MIXER_STATE_FAILED); @@ -669,7 +735,7 @@ mate_mixer_control_open (MateMixerControl *control) info = mate_mixer_backend_module_get_info (module); control->priv->module = g_object_ref (module); - control->priv->backend = g_object_newv (info->g_type, 0, NULL); + control->priv->backend = g_object_new (info->g_type, NULL); mate_mixer_backend_set_data (control->priv->backend, &control->priv->backend_data); @@ -678,7 +744,7 @@ mate_mixer_control_open (MateMixerControl *control) control_change_state (control, MATE_MIXER_STATE_CONNECTING); /* The backend initialization might fail in case it is known right now that - * it is unusable */ + * the backend 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 */ @@ -686,9 +752,7 @@ mate_mixer_control_open (MateMixerControl *control) } /* User requested a specific backend and it failed */ - g_clear_object (&control->priv->module); - g_clear_object (&control->priv->backend); - + control_close (control); control_change_state (control, MATE_MIXER_STATE_FAILED); return FALSE; } @@ -697,11 +761,10 @@ mate_mixer_control_open (MateMixerControl *control) if (G_UNLIKELY (state != MATE_MIXER_STATE_READY && state != MATE_MIXER_STATE_CONNECTING)) { - /* The backend should not be in this state */ + /* This would a backend bug */ g_warn_if_reached (); - g_clear_object (&control->priv->module); - g_clear_object (&control->priv->backend); + control_close (control); control_change_state (control, MATE_MIXER_STATE_FAILED); return FALSE; } @@ -716,6 +779,22 @@ mate_mixer_control_open (MateMixerControl *control) } /** + * mate_mixer_control_close: + * @control: a #MateMixerControl + * + * Closes connection to the currently used sound system. The state will be + * set to %MATE_MIXER_STATE_IDLE. + */ +void +mate_mixer_control_close (MateMixerControl *control) +{ + g_return_if_fail (MATE_MIXER_IS_CONTROL (control)); + + control_close (control); + control_change_state (control, MATE_MIXER_STATE_IDLE); +} + +/** * mate_mixer_control_get_state: * @control: a #MateMixerControl * @@ -743,12 +822,12 @@ mate_mixer_control_get_state (MateMixerControl *control) MateMixerDevice * mate_mixer_control_get_device (MateMixerControl *control, const gchar *name) { - GList *list; + const 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; + list = mate_mixer_control_list_devices (control); while (list) { MateMixerDevice *device = MATE_MIXER_DEVICE (list->data); @@ -772,12 +851,12 @@ mate_mixer_control_get_device (MateMixerControl *control, const gchar *name) MateMixerStream * mate_mixer_control_get_stream (MateMixerControl *control, const gchar *name) { - GList *list; + const 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; + list = mate_mixer_control_list_streams (control); while (list) { MateMixerStream *stream = MATE_MIXER_STREAM (list->data); @@ -806,7 +885,9 @@ 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); + + if (control->priv->state != MATE_MIXER_STATE_READY) + return NULL; /* This list is cached here and invalidated when the backend notifies us * about a change */ @@ -834,7 +915,9 @@ 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); + + if (control->priv->state != MATE_MIXER_STATE_READY) + return NULL; /* This list is cached here and invalidated when the backend notifies us * about a change */ @@ -859,7 +942,9 @@ 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); + + if (control->priv->state != MATE_MIXER_STATE_READY) + return NULL; return mate_mixer_backend_get_default_input_stream (control->priv->backend); } @@ -877,8 +962,10 @@ 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); + g_return_val_if_fail (MATE_MIXER_IS_CONTROL (control), FALSE); + + if (control->priv->state != MATE_MIXER_STATE_READY) + return FALSE; return mate_mixer_backend_set_default_input_stream (control->priv->backend, stream); } @@ -897,7 +984,9 @@ 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); + + if (control->priv->state != MATE_MIXER_STATE_READY) + return NULL; return mate_mixer_backend_get_default_output_stream (control->priv->backend); } @@ -915,8 +1004,10 @@ 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); + g_return_val_if_fail (MATE_MIXER_IS_CONTROL (control), FALSE); + + if (control->priv->state != MATE_MIXER_STATE_READY) + return FALSE; return mate_mixer_backend_set_default_input_stream (control->priv->backend, stream); } @@ -925,44 +1016,160 @@ mate_mixer_control_set_default_output_stream (MateMixerControl *control, * 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. + * Gets the name of the currently used backend. This function will not + * work until connected to a sound system. * * 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); + if (!control->priv->backend_chosen) + return NULL; - return info->name; + return mate_mixer_backend_module_get_info (control->priv->module)->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. + * Gets the type of the currently used backend. This function will not + * work until connected to a sound system. * * 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), MATE_MIXER_BACKEND_UNKNOWN); - g_return_val_if_fail (MATE_MIXER_IS_CONTROL (control), FALSE); - g_return_val_if_fail (control->priv->state == MATE_MIXER_STATE_READY, FALSE); + if (!control->priv->backend_chosen) + return MATE_MIXER_BACKEND_UNKNOWN; - info = mate_mixer_backend_module_get_info (control->priv->module); + return mate_mixer_backend_module_get_info (control->priv->module)->backend_type; +} - return info->backend_type; +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_CONNECTING: + g_debug ("Backend %s changed state to CONNECTING", + mate_mixer_backend_module_get_info (control->priv->module)->name); + + if (control->priv->backend_chosen) { + /* Invalidate cached data when reconnecting */ + control_free_devices (control); + control_free_devices (control); + } + control_change_state (control, state); + break; + + case MATE_MIXER_STATE_READY: + g_debug ("Backend %s changed state to READY", + mate_mixer_backend_module_get_info (control->priv->module)->name); + + control_change_state (control, state); + break; + + case MATE_MIXER_STATE_FAILED: + g_debug ("Backend %s changed state to FAILED", + mate_mixer_backend_module_get_info (control->priv->module)->name); + + if (control->priv->backend_type == MATE_MIXER_BACKEND_UNKNOWN) { + /* User didn't request a specific backend, so try another one */ + control_try_next_backend (control); + } else { + /* User requested a specific backend and it failed */ + control_close (control); + control_change_state (control, state); + } + break; + + default: + break; + } +} + +static void +control_device_added_cb (MateMixerBackend *backend, + const gchar *name, + MateMixerControl *control) +{ + control_free_devices (control); + + g_signal_emit (G_OBJECT (control), + signals[DEVICE_ADDED], + 0, + name); +} + +static void +control_device_changed_cb (MateMixerBackend *backend, + const gchar *name, + MateMixerControl *control) +{ + g_signal_emit (G_OBJECT (control), + signals[DEVICE_CHANGED], + 0, + name); +} + +static void +control_device_removed_cb (MateMixerBackend *backend, + const gchar *name, + MateMixerControl *control) +{ + control_free_devices (control); + + g_signal_emit (G_OBJECT (control), + signals[DEVICE_REMOVED], + 0, + name); +} + +static void +control_stream_added_cb (MateMixerBackend *backend, + const gchar *name, + MateMixerControl *control) +{ + control_free_streams (control); + + g_signal_emit (G_OBJECT (control), + signals[STREAM_ADDED], + 0, + name); +} + +static void +control_stream_changed_cb (MateMixerBackend *backend, + const gchar *name, + MateMixerControl *control) +{ + g_signal_emit (G_OBJECT (control), + signals[STREAM_CHANGED], + 0, + name); +} + +static void +control_stream_removed_cb (MateMixerBackend *backend, + const gchar *name, + MateMixerControl *control) +{ + control_free_streams (control); + + g_signal_emit (G_OBJECT (control), + signals[STREAM_REMOVED], + 0, + name); } static gboolean @@ -982,8 +1189,7 @@ control_try_next_backend (MateMixerControl *control) } modules = modules->next; } - g_clear_object (&control->priv->module); - g_clear_object (&control->priv->backend); + control_close (control); if (module == NULL) { /* This shouldn't happen under normal circumstances as the lowest @@ -995,9 +1201,9 @@ control_try_next_backend (MateMixerControl *control) control->priv->module = g_object_ref (module); control->priv->backend = - g_object_newv (mate_mixer_backend_module_get_info (module)->g_type, - 0, - NULL); + g_object_new (mate_mixer_backend_module_get_info (module)->g_type, NULL); + + mate_mixer_backend_set_data (control->priv->backend, &control->priv->backend_data); if (!mate_mixer_backend_open (control->priv->backend)) return control_try_next_backend (control); @@ -1017,9 +1223,11 @@ control_change_state (MateMixerControl *control, MateMixerState state) control->priv->state = state; - if (state == MATE_MIXER_STATE_READY) { + if (state == MATE_MIXER_STATE_READY && !control->priv->backend_chosen) { /* 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 */ + * state, because the app is not allowed to query any data before that state; + * therefore we won't end up in an inconsistent state by caching a list and + * then missing a notification about a change in the list */ g_signal_connect (control->priv->backend, "device-added", G_CALLBACK (control_device_added_cb), @@ -1044,131 +1252,52 @@ control_change_state (MateMixerControl *control, MateMixerState state) "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; + control->priv->backend_chosen = TRUE; } - 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); + g_object_notify_by_pspec (G_OBJECT (control), properties[PROP_STATE]); } static void -control_device_removed_cb (MateMixerBackend *backend, - const gchar *name, - MateMixerControl *control) +control_close (MateMixerControl *control) { - if (control->priv->devices) { - g_list_free_full (control->priv->devices, g_object_unref); - control->priv->devices = NULL; - } - - g_debug ("Device removed: %s", name); + control_free_backend (control); + control_free_devices (control); + control_free_streams (control); - g_signal_emit (G_OBJECT (control), - signals[DEVICE_REMOVED], - 0, - name); + g_clear_object (&control->priv->module); } static void -control_stream_added_cb (MateMixerBackend *backend, - const gchar *name, - MateMixerControl *control) +control_free_backend (MateMixerControl *control) { - if (control->priv->streams) { - g_list_free_full (control->priv->streams, g_object_unref); - control->priv->streams = NULL; - } + if (control->priv->backend == NULL) + return; - g_debug ("Stream added: %s", name); + mate_mixer_backend_close (control->priv->backend); - g_signal_emit (G_OBJECT (control), - signals[STREAM_ADDED], - 0, - name); + g_clear_object (&control->priv->backend); } static void -control_stream_changed_cb (MateMixerBackend *backend, - const gchar *name, - MateMixerControl *control) +control_free_devices (MateMixerControl *control) { - /* Do not invalidate the list of streams here as the list has not changed, - * only some properties of a stream */ + if (control->priv->devices == NULL) + return; - g_debug ("Stream changed: %s", name); + g_list_free_full (control->priv->devices, g_object_unref); - g_signal_emit (G_OBJECT (control), - signals[STREAM_CHANGED], - 0, - name); + control->priv->devices = NULL; } static void -control_stream_removed_cb (MateMixerBackend *backend, - const gchar *name, - MateMixerControl *control) +control_free_streams (MateMixerControl *control) { - if (control->priv->streams) { - g_list_free_full (control->priv->streams, g_object_unref); - control->priv->streams = NULL; - } + if (control->priv->streams == NULL) + return; - g_debug ("Stream removed: %s", name); + g_list_free_full (control->priv->streams, g_object_unref); - g_signal_emit (G_OBJECT (control), - signals[STREAM_REMOVED], - 0, - name); + control->priv->streams = NULL; } diff --git a/libmatemixer/matemixer-control.h b/libmatemixer/matemixer-control.h index ad48768..5598ade 100644 --- a/libmatemixer/matemixer-control.h +++ b/libmatemixer/matemixer-control.h @@ -21,6 +21,7 @@ #include <glib.h> #include <glib-object.h> +#include <libmatemixer/matemixer-device.h> #include <libmatemixer/matemixer-enums.h> #include <libmatemixer/matemixer-stream.h> @@ -35,7 +36,7 @@ G_BEGIN_DECLS #define MATE_MIXER_CONTROL_CLASS(k) \ (G_TYPE_CHECK_CLASS_CAST ((k), MATE_MIXER_TYPE_CONTROL, MateMixerControlClass)) #define MATE_MIXER_IS_CONTROL_CLASS(k) \ - (G_TYPE_CLASS_CHECK_CLASS_TYPE ((k), MATE_MIXER_TYPE_CONTROL)) + (G_TYPE_CHECK_CLASS_TYPE ((k), MATE_MIXER_TYPE_CONTROL)) #define MATE_MIXER_CONTROL_GET_CLASS(o) \ (G_TYPE_INSTANCE_GET_CLASS ((o), MATE_MIXER_TYPE_CONTROL, MateMixerControlClass)) @@ -51,9 +52,10 @@ typedef struct _MateMixerControlPrivate MateMixerControlPrivate; */ struct _MateMixerControl { + GObject parent; + /*< private >*/ - GObject parent; - MateMixerControlPrivate *priv; + MateMixerControlPrivate *priv; }; /** @@ -63,10 +65,9 @@ struct _MateMixerControl */ struct _MateMixerControlClass { - /*< private >*/ - GObjectClass parent; + GObjectClass parent_class; - /* Signals */ + /*< private >*/ void (*device_added) (MateMixerControl *control, const gchar *name); void (*device_changed) (MateMixerControl *control, @@ -97,6 +98,7 @@ gboolean mate_mixer_control_set_app_icon (MateMixerCon gboolean mate_mixer_control_set_server_address (MateMixerControl *control, const gchar *address); gboolean mate_mixer_control_open (MateMixerControl *control); +void mate_mixer_control_close (MateMixerControl *control); MateMixerState mate_mixer_control_get_state (MateMixerControl *control); diff --git a/libmatemixer/matemixer-device.c b/libmatemixer/matemixer-device.c index a022877..e74dc23 100644 --- a/libmatemixer/matemixer-device.c +++ b/libmatemixer/matemixer-device.c @@ -21,6 +21,11 @@ #include "matemixer-device.h" #include "matemixer-profile.h" +/** + * SECTION:matemixer-device + * @include: libmatemixer/matemixer.h + */ + G_DEFINE_INTERFACE (MateMixerDevice, mate_mixer_device, G_TYPE_OBJECT) static void @@ -31,8 +36,7 @@ mate_mixer_device_default_init (MateMixerDeviceInterface *iface) "Name", "Name of the sound device", NULL, - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_READWRITE | + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); g_object_interface_install_property (iface, @@ -40,8 +44,7 @@ mate_mixer_device_default_init (MateMixerDeviceInterface *iface) "Description", "Description of the sound device", NULL, - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_READWRITE | + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); g_object_interface_install_property (iface, @@ -49,11 +52,24 @@ mate_mixer_device_default_init (MateMixerDeviceInterface *iface) "Icon", "Name of the sound device icon", NULL, - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_READWRITE | + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); g_object_interface_install_property (iface, + g_param_spec_pointer ("ports", + "Ports", + "GList of the sound device ports", + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + g_object_interface_install_property (iface, + g_param_spec_pointer ("profiles", + "Profiles", + "GList of the sound device profiles", + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + g_object_interface_install_property (iface, g_param_spec_object ("active-profile", "Active profile", "The currently active profile of the sound device", @@ -65,16 +81,9 @@ mate_mixer_device_default_init (MateMixerDeviceInterface *iface) const gchar * mate_mixer_device_get_name (MateMixerDevice *device) { - MateMixerDeviceInterface *iface; - g_return_val_if_fail (MATE_MIXER_IS_DEVICE (device), NULL); - iface = MATE_MIXER_DEVICE_GET_INTERFACE (device); - - if (iface->get_name) - return iface->get_name (device); - - return NULL; + return MATE_MIXER_DEVICE_GET_INTERFACE (device)->get_name (device); } const gchar * @@ -108,21 +117,6 @@ mate_mixer_device_get_icon (MateMixerDevice *device) } const GList * -mate_mixer_device_list_streams (MateMixerDevice *device) -{ - MateMixerDeviceInterface *iface; - - g_return_val_if_fail (MATE_MIXER_IS_DEVICE (device), NULL); - - iface = MATE_MIXER_DEVICE_GET_INTERFACE (device); - - if (iface->list_streams) - return iface->list_streams (device); - - return NULL; -} - -const GList * mate_mixer_device_list_ports (MateMixerDevice *device) { MateMixerDeviceInterface *iface; diff --git a/libmatemixer/matemixer-device.h b/libmatemixer/matemixer-device.h index d814847..a1422e3 100644 --- a/libmatemixer/matemixer-device.h +++ b/libmatemixer/matemixer-device.h @@ -39,9 +39,9 @@ typedef struct _MateMixerDeviceInterface MateMixerDeviceInterface; struct _MateMixerDeviceInterface { - /*< private >*/ - GTypeInterface parent; + GTypeInterface parent_iface; + /*< private >*/ const gchar *(*get_name) (MateMixerDevice *device); const gchar *(*get_description) (MateMixerDevice *device); const gchar *(*get_icon) (MateMixerDevice *device); @@ -54,12 +54,14 @@ struct _MateMixerDeviceInterface }; 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); -const GList * mate_mixer_device_list_streams (MateMixerDevice *device); + const GList * mate_mixer_device_list_ports (MateMixerDevice *device); const GList * mate_mixer_device_list_profiles (MateMixerDevice *device); + MateMixerProfile *mate_mixer_device_get_active_profile (MateMixerDevice *device); gboolean mate_mixer_device_set_active_profile (MateMixerDevice *device, const gchar *profile); diff --git a/libmatemixer/matemixer-enum-types.c b/libmatemixer/matemixer-enum-types.c index 43249a3..e353e0c 100644 --- a/libmatemixer/matemixer-enum-types.c +++ b/libmatemixer/matemixer-enum-types.c @@ -64,19 +64,20 @@ mate_mixer_backend_type_get_type (void) } GType -mate_mixer_port_status_get_type (void) +mate_mixer_port_flags_get_type (void) { static GType etype = 0; if (etype == 0) { - static const GEnumValue values[] = { - { MATE_MIXER_PORT_UNKNOWN_STATUS, "MATE_MIXER_PORT_UNKNOWN_STATUS", "unknown-status" }, + static const GFlagsValue values[] = { + { MATE_MIXER_PORT_NO_FLAGS, "MATE_MIXER_PORT_NO_FLAGS", "no-flags" }, { MATE_MIXER_PORT_AVAILABLE, "MATE_MIXER_PORT_AVAILABLE", "available" }, - { MATE_MIXER_PORT_UNAVAILABLE, "MATE_MIXER_PORT_UNAVAILABLE", "unavailable" }, + { MATE_MIXER_PORT_INPUT, "MATE_MIXER_PORT_INPUT", "input" }, + { MATE_MIXER_PORT_OUTPUT, "MATE_MIXER_PORT_OUTPUT", "output" }, { 0, NULL, NULL } }; - etype = g_enum_register_static ( - g_intern_static_string ("MateMixerPortStatus"), + etype = g_flags_register_static ( + g_intern_static_string ("MateMixerPortFlags"), values); } return etype; @@ -94,14 +95,16 @@ mate_mixer_stream_flags_get_type (void) { MATE_MIXER_STREAM_OUTPUT, "MATE_MIXER_STREAM_OUTPUT", "output" }, { MATE_MIXER_STREAM_CLIENT, "MATE_MIXER_STREAM_CLIENT", "client" }, { MATE_MIXER_STREAM_APPLICATION, "MATE_MIXER_STREAM_APPLICATION", "application" }, - { MATE_MIXER_STREAM_OUTPUT_MONITOR, "MATE_MIXER_STREAM_OUTPUT_MONITOR", "output-monitor" }, + { MATE_MIXER_STREAM_EVENT, "MATE_MIXER_STREAM_EVENT", "event" }, { 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_HAS_MONITOR, "MATE_MIXER_STREAM_HAS_MONITOR", "has-monitor" }, { MATE_MIXER_STREAM_CAN_BALANCE, "MATE_MIXER_STREAM_CAN_BALANCE", "can-balance" }, { MATE_MIXER_STREAM_CAN_FADE, "MATE_MIXER_STREAM_CAN_FADE", "can-fade" }, { MATE_MIXER_STREAM_CAN_SET_VOLUME, "MATE_MIXER_STREAM_CAN_SET_VOLUME", "can-set-volume" }, + { MATE_MIXER_STREAM_CAN_SUSPEND, "MATE_MIXER_STREAM_CAN_SUSPEND", "can-suspend" }, { 0, NULL, NULL } }; etype = g_flags_register_static ( @@ -112,20 +115,20 @@ mate_mixer_stream_flags_get_type (void) } GType -mate_mixer_stream_status_get_type (void) +mate_mixer_stream_state_get_type (void) { static GType etype = 0; if (etype == 0) { static const GEnumValue values[] = { - { MATE_MIXER_STREAM_UNKNOWN_STATUS, "MATE_MIXER_STREAM_UNKNOWN_STATUS", "unknown-status" }, + { MATE_MIXER_STREAM_UNKNOWN_STATE, "MATE_MIXER_STREAM_UNKNOWN_STATE", "unknown-state" }, { MATE_MIXER_STREAM_RUNNING, "MATE_MIXER_STREAM_RUNNING", "running" }, { MATE_MIXER_STREAM_IDLE, "MATE_MIXER_STREAM_IDLE", "idle" }, { MATE_MIXER_STREAM_SUSPENDED, "MATE_MIXER_STREAM_SUSPENDED", "suspended" }, { 0, NULL, NULL } }; etype = g_enum_register_static ( - g_intern_static_string ("MateMixerStreamStatus"), + g_intern_static_string ("MateMixerStreamState"), values); } return etype; diff --git a/libmatemixer/matemixer-enum-types.h b/libmatemixer/matemixer-enum-types.h index 0275c27..7b6fcf0 100644 --- a/libmatemixer/matemixer-enum-types.h +++ b/libmatemixer/matemixer-enum-types.h @@ -34,14 +34,14 @@ 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 ()) -GType mate_mixer_port_status_get_type (void) G_GNUC_CONST; +#define MATE_MIXER_TYPE_PORT_FLAGS (mate_mixer_port_flags_get_type ()) +GType mate_mixer_port_flags_get_type (void) G_GNUC_CONST; #define MATE_MIXER_TYPE_STREAM_FLAGS (mate_mixer_stream_flags_get_type ()) GType mate_mixer_stream_flags_get_type (void) G_GNUC_CONST; -#define MATE_MIXER_TYPE_STREAM_STATUS (mate_mixer_stream_status_get_type ()) -GType mate_mixer_stream_status_get_type (void) G_GNUC_CONST; +#define MATE_MIXER_TYPE_STREAM_STATE (mate_mixer_stream_state_get_type ()) +GType mate_mixer_stream_state_get_type (void) G_GNUC_CONST; #define MATE_MIXER_TYPE_CHANNEL_POSITION (mate_mixer_channel_position_get_type ()) GType mate_mixer_channel_position_get_type (void) G_GNUC_CONST; diff --git a/libmatemixer/matemixer-enums.h b/libmatemixer/matemixer-enums.h index 5fc348d..4552141 100644 --- a/libmatemixer/matemixer-enums.h +++ b/libmatemixer/matemixer-enums.h @@ -31,17 +31,32 @@ typedef enum { MATE_MIXER_STATE_UNKNOWN } MateMixerState; +/** + * MateMixerBackendType: + * @MATE_MIXER_BACKEND_UNKNOWN: + * Unknown or undefined backend type. + * @MATE_MIXER_BACKEND_PULSE: + * PulseAudio sound system backend. It has the highest priority and + * will be the first one to try unless you select a specific backend + * to connect to. + * @MATE_MIXER_BACKEND_NULL: + * Fallback backend which never fails to initialize, but provides no + * functionality. This backend has the lowest priority and will be used + * if you do not select a specific backend to connect to and all the + * "real" backends fail to initialize. + */ typedef enum { MATE_MIXER_BACKEND_UNKNOWN = 0, MATE_MIXER_BACKEND_PULSE, MATE_MIXER_BACKEND_NULL } MateMixerBackendType; -typedef enum { - MATE_MIXER_PORT_UNKNOWN_STATUS, - MATE_MIXER_PORT_AVAILABLE, - MATE_MIXER_PORT_UNAVAILABLE -} MateMixerPortStatus; +typedef enum { /*< flags >*/ + MATE_MIXER_PORT_NO_FLAGS = 0, + MATE_MIXER_PORT_AVAILABLE = 1 << 0, + MATE_MIXER_PORT_INPUT = 1 << 1, + MATE_MIXER_PORT_OUTPUT = 1 << 2 +} MateMixerPortFlags; typedef enum { /*< flags >*/ MATE_MIXER_STREAM_NO_FLAGS = 0, @@ -49,22 +64,24 @@ typedef enum { /*< flags >*/ 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_EVENT = 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 + MATE_MIXER_STREAM_HAS_MONITOR = 1 << 9, + MATE_MIXER_STREAM_CAN_BALANCE = 1 << 10, + MATE_MIXER_STREAM_CAN_FADE = 1 << 11, + MATE_MIXER_STREAM_CAN_SET_VOLUME = 1 << 12, + MATE_MIXER_STREAM_CAN_SUSPEND = 1 << 13 } MateMixerStreamFlags; typedef enum { - MATE_MIXER_STREAM_UNKNOWN_STATUS, + MATE_MIXER_STREAM_UNKNOWN_STATE, MATE_MIXER_STREAM_RUNNING, MATE_MIXER_STREAM_IDLE, MATE_MIXER_STREAM_SUSPENDED -} MateMixerStreamStatus; +} MateMixerStreamState; typedef enum { MATE_MIXER_CHANNEL_UNKNOWN_POSITION, diff --git a/libmatemixer/matemixer-port.c b/libmatemixer/matemixer-port.c index 7ac21f7..3a7670d 100644 --- a/libmatemixer/matemixer-port.c +++ b/libmatemixer/matemixer-port.c @@ -22,13 +22,18 @@ #include "matemixer-enum-types.h" #include "matemixer-port.h" +/** + * SECTION:matemixer-port + * @include: libmatemixer/matemixer.h + */ + struct _MateMixerPortPrivate { - gchar *name; - gchar *description; - gchar *icon; - gulong priority; - MateMixerPortStatus status; + gchar *name; + gchar *description; + gchar *icon; + gulong priority; + MateMixerPortFlags flags; }; enum { @@ -37,19 +42,92 @@ enum { PROP_DESCRIPTION, PROP_ICON, PROP_PRIORITY, - PROP_STATUS, + PROP_FLAGS, N_PROPERTIES }; static GParamSpec *properties[N_PROPERTIES] = { NULL, }; static void mate_mixer_port_class_init (MateMixerPortClass *klass); -static void mate_mixer_port_init (MateMixerPort *port); -static void mate_mixer_port_finalize (GObject *object); + +static void mate_mixer_port_get_property (GObject *object, + guint param_id, + GValue *value, + GParamSpec *pspec); +static void mate_mixer_port_set_property (GObject *object, + guint param_id, + const GValue *value, + GParamSpec *pspec); + +static void mate_mixer_port_init (MateMixerPort *port); +static void mate_mixer_port_finalize (GObject *object); G_DEFINE_TYPE (MateMixerPort, mate_mixer_port, G_TYPE_OBJECT); static void +mate_mixer_port_class_init (MateMixerPortClass *klass) +{ + GObjectClass *object_class; + + object_class = G_OBJECT_CLASS (klass); + object_class->finalize = mate_mixer_port_finalize; + object_class->get_property = mate_mixer_port_get_property; + object_class->set_property = mate_mixer_port_set_property; + + properties[PROP_NAME] = + g_param_spec_string ("name", + "Name", + "Name of the port", + NULL, + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS); + + properties[PROP_DESCRIPTION] = + g_param_spec_string ("description", + "Description", + "Description of the port", + NULL, + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS); + + properties[PROP_ICON] = + g_param_spec_string ("icon", + "Icon", + "Name of the port icon", + NULL, + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS); + + properties[PROP_PRIORITY] = + g_param_spec_ulong ("priority", + "Priority", + "Priority of the port", + 0, + G_MAXULONG, + 0, + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS); + + properties[PROP_FLAGS] = + g_param_spec_flags ("flags", + "Flags", + "Capability flags of the port", + MATE_MIXER_TYPE_PORT_FLAGS, + MATE_MIXER_PORT_NO_FLAGS, + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties (object_class, N_PROPERTIES, properties); + + g_type_class_add_private (object_class, sizeof (MateMixerPortPrivate)); +} + +static void mate_mixer_port_get_property (GObject *object, guint param_id, GValue *value, @@ -72,8 +150,8 @@ mate_mixer_port_get_property (GObject *object, case PROP_PRIORITY: g_value_set_ulong (value, port->priv->priority); break; - case PROP_STATUS: - g_value_set_enum (value, port->priv->status); + case PROP_FLAGS: + g_value_set_flags (value, port->priv->flags); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); @@ -93,19 +171,22 @@ mate_mixer_port_set_property (GObject *object, switch (param_id) { case PROP_NAME: + /* Construct-only string */ port->priv->name = g_strdup (g_value_get_string (value)); break; case PROP_DESCRIPTION: + /* Construct-only string */ port->priv->description = g_strdup (g_value_get_string (value)); break; case PROP_ICON: + /* Construct-only string */ port->priv->icon = g_strdup (g_value_get_string (value)); break; case PROP_PRIORITY: port->priv->priority = g_value_get_ulong (value); break; - case PROP_STATUS: - port->priv->status = g_value_get_enum (value); + case PROP_FLAGS: + port->priv->flags = g_value_get_flags (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); @@ -114,64 +195,6 @@ mate_mixer_port_set_property (GObject *object, } static void -mate_mixer_port_class_init (MateMixerPortClass *klass) -{ - GObjectClass *object_class; - - object_class = G_OBJECT_CLASS (klass); - object_class->finalize = mate_mixer_port_finalize; - object_class->get_property = mate_mixer_port_get_property; - object_class->set_property = mate_mixer_port_set_property; - - properties[PROP_NAME] = g_param_spec_string ("name", - "Name", - "Name of the port", - NULL, - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - - properties[PROP_DESCRIPTION] = g_param_spec_string ("description", - "Description", - "Description of the port", - NULL, - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - - properties[PROP_ICON] = g_param_spec_string ("icon", - "Icon", - "Name of the port icon", - NULL, - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - - properties[PROP_PRIORITY] = g_param_spec_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); - - g_type_class_add_private (object_class, sizeof (MateMixerPortPrivate)); -} - -static void mate_mixer_port_init (MateMixerPort *port) { port->priv = G_TYPE_INSTANCE_GET_PRIVATE (port, @@ -194,18 +217,18 @@ mate_mixer_port_finalize (GObject *object) } MateMixerPort * -mate_mixer_port_new (const gchar *name, - const gchar *description, - const gchar *icon, - gulong priority, - MateMixerPortStatus status) +mate_mixer_port_new (const gchar *name, + const gchar *description, + const gchar *icon, + gulong priority, + MateMixerPortFlags flags) { return g_object_new (MATE_MIXER_TYPE_PORT, "name", name, "description", description, "icon", icon, "priority", priority, - "status", status, + "flags", flags, NULL); } @@ -241,10 +264,10 @@ mate_mixer_port_get_priority (MateMixerPort *port) return port->priv->priority; } -MateMixerPortStatus -mate_mixer_port_get_status (MateMixerPort *port) +MateMixerPortFlags +mate_mixer_port_get_flags (MateMixerPort *port) { - g_return_val_if_fail (MATE_MIXER_IS_PORT (port), MATE_MIXER_PORT_UNKNOWN_STATUS); + g_return_val_if_fail (MATE_MIXER_IS_PORT (port), MATE_MIXER_PORT_NO_FLAGS); - return port->priv->status; + return port->priv->flags; } diff --git a/libmatemixer/matemixer-port.h b/libmatemixer/matemixer-port.h index e0a9f79..bda13ad 100644 --- a/libmatemixer/matemixer-port.h +++ b/libmatemixer/matemixer-port.h @@ -34,7 +34,7 @@ G_BEGIN_DECLS #define MATE_MIXER_PORT_CLASS(k) \ (G_TYPE_CHECK_CLASS_CAST ((k), MATE_MIXER_TYPE_PORT, MateMixerPortClass)) #define MATE_MIXER_IS_PORT_CLASS(k) \ - (G_TYPE_CLASS_CHECK_CLASS_TYPE ((k), MATE_MIXER_TYPE_PORT)) + (G_TYPE_CHECK_CLASS_TYPE ((k), MATE_MIXER_TYPE_PORT)) #define MATE_MIXER_PORT_GET_CLASS(o) \ (G_TYPE_INSTANCE_GET_CLASS ((o), MATE_MIXER_TYPE_PORT, MateMixerPortClass)) @@ -44,29 +44,30 @@ typedef struct _MateMixerPortPrivate MateMixerPortPrivate; struct _MateMixerPort { + GObject parent; + /*< private >*/ - GObject parent; - MateMixerPortPrivate *priv; + MateMixerPortPrivate *priv; }; struct _MateMixerPortClass { - /*< private >*/ - GObjectClass parent; + GObjectClass parent_class; }; -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); +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, + MateMixerPortFlags flags); -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); +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); +MateMixerPortFlags mate_mixer_port_get_flags (MateMixerPort *port); G_END_DECLS diff --git a/libmatemixer/matemixer-profile.c b/libmatemixer/matemixer-profile.c index 38f17c7..c98af30 100644 --- a/libmatemixer/matemixer-profile.c +++ b/libmatemixer/matemixer-profile.c @@ -20,15 +20,19 @@ #include "matemixer-profile.h" +/** + * SECTION:matemixer-profile + * @include: libmatemixer/matemixer.h + */ + struct _MateMixerProfilePrivate { - gchar *name; - gchar *description; - gulong priority; + gchar *name; + gchar *description; + gulong priority; }; -enum -{ +enum { PROP_0, PROP_NAME, PROP_DESCRIPTION, @@ -39,12 +43,66 @@ enum static GParamSpec *properties[N_PROPERTIES] = { NULL, }; static void mate_mixer_profile_class_init (MateMixerProfileClass *klass); -static void mate_mixer_profile_init (MateMixerProfile *profile); -static void mate_mixer_profile_finalize (GObject *object); + +static void mate_mixer_profile_get_property (GObject *object, + guint param_id, + GValue *value, + GParamSpec *pspec); +static void mate_mixer_profile_set_property (GObject *object, + guint param_id, + const GValue *value, + GParamSpec *pspec); + +static void mate_mixer_profile_init (MateMixerProfile *profile); +static void mate_mixer_profile_finalize (GObject *object); G_DEFINE_TYPE (MateMixerProfile, mate_mixer_profile, G_TYPE_OBJECT); static void +mate_mixer_profile_class_init (MateMixerProfileClass *klass) +{ + GObjectClass *object_class; + + object_class = G_OBJECT_CLASS (klass); + object_class->finalize = mate_mixer_profile_finalize; + object_class->get_property = mate_mixer_profile_get_property; + object_class->set_property = mate_mixer_profile_set_property; + + properties[PROP_NAME] = + g_param_spec_string ("name", + "Name", + "Name of the profile", + NULL, + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS); + + properties[PROP_DESCRIPTION] = + g_param_spec_string ("description", + "Description", + "Description of the profile", + NULL, + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS); + + properties[PROP_PRIORITY] = + g_param_spec_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); + + g_type_class_add_private (object_class, sizeof (MateMixerProfilePrivate)); +} + +static void mate_mixer_profile_get_property (GObject *object, guint param_id, GValue *value, @@ -82,9 +140,11 @@ mate_mixer_profile_set_property (GObject *object, switch (param_id) { case PROP_NAME: + /* Construct-only string */ profile->priv->name = g_strdup (g_value_get_string (value)); break; case PROP_DESCRIPTION: + /* Construct-only string */ profile->priv->description = g_strdup (g_value_get_string (value)); break; case PROP_PRIORITY: @@ -97,47 +157,6 @@ mate_mixer_profile_set_property (GObject *object, } static void -mate_mixer_profile_class_init (MateMixerProfileClass *klass) -{ - GObjectClass *object_class; - - object_class = G_OBJECT_CLASS (klass); - object_class->finalize = mate_mixer_profile_finalize; - object_class->get_property = mate_mixer_profile_get_property; - object_class->set_property = mate_mixer_profile_set_property; - - properties[PROP_NAME] = g_param_spec_string ("name", - "Name", - "Name of the profile", - NULL, - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - - properties[PROP_DESCRIPTION] = g_param_spec_string ("description", - "Description", - "Description of the profile", - NULL, - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - - properties[PROP_PRIORITY] = g_param_spec_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); - - g_type_class_add_private (object_class, sizeof (MateMixerProfilePrivate)); -} - -static void mate_mixer_profile_init (MateMixerProfile *profile) { profile->priv = G_TYPE_INSTANCE_GET_PRIVATE (profile, diff --git a/libmatemixer/matemixer-profile.h b/libmatemixer/matemixer-profile.h index 4ce0d1a..b652085 100644 --- a/libmatemixer/matemixer-profile.h +++ b/libmatemixer/matemixer-profile.h @@ -32,7 +32,7 @@ G_BEGIN_DECLS #define MATE_MIXER_PROFILE_CLASS(k) \ (G_TYPE_CHECK_CLASS_CAST ((k), MATE_MIXER_TYPE_PROFILE, MateMixerProfileClass)) #define MATE_MIXER_IS_PROFILE_CLASS(k) \ - (G_TYPE_CLASS_CHECK_CLASS_TYPE ((k), MATE_MIXER_TYPE_PROFILE)) + (G_TYPE_CHECK_CLASS_TYPE ((k), MATE_MIXER_TYPE_PROFILE)) #define MATE_MIXER_PROFILE_GET_CLASS(o) \ (G_TYPE_INSTANCE_GET_CLASS ((o), MATE_MIXER_TYPE_PROFILE, MateMixerProfileClass)) @@ -42,18 +42,19 @@ typedef struct _MateMixerProfilePrivate MateMixerProfilePrivate; struct _MateMixerProfile { + GObject parent; + /*< private >*/ - GObject parent; - MateMixerProfilePrivate *priv; + MateMixerProfilePrivate *priv; }; struct _MateMixerProfileClass { - /*< private >*/ - GObjectClass parent; + GObjectClass parent_class; }; GType mate_mixer_profile_get_type (void) G_GNUC_CONST; + MateMixerProfile *mate_mixer_profile_new (const gchar *name, const gchar *description, gulong priority); diff --git a/libmatemixer/matemixer-stream.c b/libmatemixer/matemixer-stream.c index e2c9820..1ad4c50 100644 --- a/libmatemixer/matemixer-stream.c +++ b/libmatemixer/matemixer-stream.c @@ -24,6 +24,18 @@ #include "matemixer-port.h" #include "matemixer-stream.h" +/** + * SECTION:matemixer-stream + * @include: libmatemixer/matemixer.h + */ + +enum { + MONITOR_VALUE, + N_SIGNALS +}; + +static guint signals[N_SIGNALS] = { 0, }; + G_DEFINE_INTERFACE (MateMixerStream, mate_mixer_stream, G_TYPE_OBJECT) static void @@ -34,8 +46,7 @@ mate_mixer_stream_default_init (MateMixerStreamInterface *iface) "Name", "Name of the stream", NULL, - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_READWRITE | + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); g_object_interface_install_property (iface, @@ -43,17 +54,7 @@ mate_mixer_stream_default_init (MateMixerStreamInterface *iface) "Description", "Description of the stream", NULL, - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS)); - - g_object_interface_install_property (iface, - g_param_spec_string ("icon", - "Icon", - "Name of the stream icon", - NULL, - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_READWRITE | + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); g_object_interface_install_property (iface, @@ -61,8 +62,7 @@ mate_mixer_stream_default_init (MateMixerStreamInterface *iface) "Device", "Device the stream belongs to", MATE_MIXER_TYPE_DEVICE, - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_READWRITE | + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); g_object_interface_install_property (iface, @@ -71,18 +71,16 @@ mate_mixer_stream_default_init (MateMixerStreamInterface *iface) "Capability flags of the stream", MATE_MIXER_TYPE_STREAM_FLAGS, MATE_MIXER_STREAM_NO_FLAGS, - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_READWRITE | + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); g_object_interface_install_property (iface, - g_param_spec_enum ("status", - "Status", - "Status of the stream", - MATE_MIXER_TYPE_STREAM_STATUS, - MATE_MIXER_STREAM_UNKNOWN_STATUS, - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_READWRITE | + g_param_spec_enum ("state", + "State", + "Current state of the stream", + MATE_MIXER_TYPE_STREAM_STATE, + MATE_MIXER_STREAM_UNKNOWN_STATE, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); g_object_interface_install_property (iface, @@ -90,8 +88,7 @@ mate_mixer_stream_default_init (MateMixerStreamInterface *iface) "Mute", "Mute state of the stream", FALSE, - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_READWRITE | + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); g_object_interface_install_property (iface, @@ -115,16 +112,6 @@ mate_mixer_stream_default_init (MateMixerStreamInterface *iface) G_PARAM_STATIC_STRINGS)); g_object_interface_install_property (iface, - g_param_spec_double ("volume-db", - "Volume dB", - "Volume of the stream in decibels", - -G_MAXDOUBLE, - G_MAXDOUBLE, - 0.0, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); - - g_object_interface_install_property (iface, g_param_spec_double ("balance", "Balance", "Balance value of the stream", @@ -145,28 +132,37 @@ mate_mixer_stream_default_init (MateMixerStreamInterface *iface) G_PARAM_STATIC_STRINGS)); g_object_interface_install_property (iface, + g_param_spec_pointer ("ports", + "Ports", + "GList of the sound device ports", + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS)); + + g_object_interface_install_property (iface, g_param_spec_object ("active-port", "Active port", "The currently active port of the stream", MATE_MIXER_TYPE_PORT, - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_READWRITE | + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); + + signals[MONITOR_VALUE] = + g_signal_new ("monitor-value", + G_TYPE_FROM_INTERFACE (iface), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (MateMixerStreamInterface, monitor_value), + NULL, + NULL, + g_cclosure_marshal_VOID__DOUBLE, + G_TYPE_NONE, + 1, + G_TYPE_DOUBLE); } const gchar * mate_mixer_stream_get_name (MateMixerStream *stream) { - MateMixerStreamInterface *iface; - - g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), NULL); - - iface = MATE_MIXER_STREAM_GET_INTERFACE (stream); - - if (iface->get_name) - return iface->get_name (stream); - - return NULL; + return MATE_MIXER_STREAM_GET_INTERFACE (stream)->get_name (stream); } const gchar * @@ -184,8 +180,8 @@ mate_mixer_stream_get_description (MateMixerStream *stream) return NULL; } -const gchar * -mate_mixer_stream_get_icon (MateMixerStream *stream) +MateMixerDevice * +mate_mixer_stream_get_device (MateMixerStream *stream) { MateMixerStreamInterface *iface; @@ -193,40 +189,40 @@ mate_mixer_stream_get_icon (MateMixerStream *stream) iface = MATE_MIXER_STREAM_GET_INTERFACE (stream); - if (iface->get_icon) - return iface->get_icon (stream); + if (iface->get_device) + return iface->get_device (stream); return NULL; } -MateMixerDevice * -mate_mixer_stream_get_device (MateMixerStream *stream) +MateMixerStreamFlags +mate_mixer_stream_get_flags (MateMixerStream *stream) { MateMixerStreamInterface *iface; - g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), NULL); + g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), MATE_MIXER_STREAM_NO_FLAGS); iface = MATE_MIXER_STREAM_GET_INTERFACE (stream); - if (iface->get_device) - return iface->get_device (stream); + if (iface->get_flags) + return iface->get_flags (stream); - return NULL; + return MATE_MIXER_STREAM_NO_FLAGS; } -MateMixerStreamStatus -mate_mixer_stream_get_status (MateMixerStream *stream) +MateMixerStreamState +mate_mixer_stream_get_state (MateMixerStream *stream) { MateMixerStreamInterface *iface; - g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), MATE_MIXER_STREAM_UNKNOWN_STATUS); + g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), MATE_MIXER_STREAM_UNKNOWN_STATE); iface = MATE_MIXER_STREAM_GET_INTERFACE (stream); - if (iface->get_status) - return iface->get_status (stream); + if (iface->get_state) + return iface->get_state (stream); - return MATE_MIXER_STREAM_UNKNOWN_STATUS; + return MATE_MIXER_STREAM_UNKNOWN_STATE; } gboolean @@ -585,6 +581,49 @@ mate_mixer_stream_resume (MateMixerStream *stream) return FALSE; } +gboolean +mate_mixer_stream_monitor_start (MateMixerStream *stream) +{ + MateMixerStreamInterface *iface; + + g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), FALSE); + + iface = MATE_MIXER_STREAM_GET_INTERFACE (stream); + + if (iface->monitor_start) + return iface->monitor_start (stream); + + return FALSE; +} + +void +mate_mixer_stream_monitor_stop (MateMixerStream *stream) +{ + MateMixerStreamInterface *iface; + + g_return_if_fail (MATE_MIXER_IS_STREAM (stream)); + + iface = MATE_MIXER_STREAM_GET_INTERFACE (stream); + + if (iface->monitor_stop) + iface->monitor_stop (stream); +} + +gboolean +mate_mixer_stream_monitor_is_running (MateMixerStream *stream) +{ + MateMixerStreamInterface *iface; + + g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), FALSE); + + iface = MATE_MIXER_STREAM_GET_INTERFACE (stream); + + if (iface->monitor_is_running) + return iface->monitor_is_running (stream); + + return FALSE; +} + const GList * mate_mixer_stream_list_ports (MateMixerStream *stream) { @@ -616,17 +655,17 @@ mate_mixer_stream_get_active_port (MateMixerStream *stream) } gboolean -mate_mixer_stream_set_active_port (MateMixerStream *stream, const gchar *port_name) +mate_mixer_stream_set_active_port (MateMixerStream *stream, const gchar *port) { MateMixerStreamInterface *iface; g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), FALSE); - g_return_val_if_fail (port_name != NULL, FALSE); + g_return_val_if_fail (port != NULL, FALSE); iface = MATE_MIXER_STREAM_GET_INTERFACE (stream); if (iface->set_active_port) - return iface->set_active_port (stream, port_name); + return iface->set_active_port (stream, port); return FALSE; } diff --git a/libmatemixer/matemixer-stream.h b/libmatemixer/matemixer-stream.h index d773398..d39cc43 100644 --- a/libmatemixer/matemixer-stream.h +++ b/libmatemixer/matemixer-stream.h @@ -41,15 +41,14 @@ typedef struct _MateMixerStreamInterface MateMixerStreamInterface; struct _MateMixerStreamInterface { - /*< private >*/ - GTypeInterface parent; + GTypeInterface parent_iface; + /*< private >*/ 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); + MateMixerStreamState (*get_state) (MateMixerStream *stream); gboolean (*get_mute) (MateMixerStream *stream); gboolean (*set_mute) (MateMixerStream *stream, gboolean mute); @@ -83,7 +82,7 @@ struct _MateMixerStreamInterface MateMixerChannelPosition position); gboolean (*set_position_volume_db) (MateMixerStream *stream, MateMixerChannelPosition position, - gdouble volume); + gdouble volume_db); gdouble (*get_balance) (MateMixerStream *stream); gboolean (*set_balance) (MateMixerStream *stream, gdouble balance); @@ -92,23 +91,29 @@ struct _MateMixerStreamInterface gdouble fade); gboolean (*suspend) (MateMixerStream *stream); gboolean (*resume) (MateMixerStream *stream); + gboolean (*monitor_start) (MateMixerStream *stream); + void (*monitor_stop) (MateMixerStream *stream); + gboolean (*monitor_is_running) (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 gchar *port); gint64 (*get_min_volume) (MateMixerStream *stream); gint64 (*get_max_volume) (MateMixerStream *stream); gint64 (*get_normal_volume) (MateMixerStream *stream); + + /* Signals */ + void (*monitor_value) (MateMixerStream *stream, + gdouble value); }; 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); +MateMixerStreamState mate_mixer_stream_get_state (MateMixerStream *stream); gboolean mate_mixer_stream_get_mute (MateMixerStream *stream); gboolean mate_mixer_stream_set_mute (MateMixerStream *stream, @@ -165,6 +170,11 @@ gboolean mate_mixer_stream_set_fade (MateMixerStre gboolean mate_mixer_stream_suspend (MateMixerStream *stream); gboolean mate_mixer_stream_resume (MateMixerStream *stream); +gboolean mate_mixer_stream_monitor_start (MateMixerStream *stream); +void mate_mixer_stream_monitor_stop (MateMixerStream *stream); + +gboolean mate_mixer_stream_monitor_is_running (MateMixerStream *stream); + const GList * mate_mixer_stream_list_ports (MateMixerStream *stream); MateMixerPort * mate_mixer_stream_get_active_port (MateMixerStream *stream); diff --git a/libmatemixer/matemixer-version.h.in b/libmatemixer/matemixer-version.h index 17ea7b4..ff32f1a 100644 --- a/libmatemixer/matemixer-version.h.in +++ b/libmatemixer/matemixer-version.h @@ -18,33 +18,7 @@ #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@) +G_BEGIN_DECLS /** * LIBMATEMIXER_CHECK_VERSION: @@ -61,4 +35,6 @@ (LIBMATEMIXER_MAJOR_VERSION == (major) && LIBMATEMIXER_MINOR_VERSION == (minor) && \ LIBMATEMIXER_MICRO_VERSION >= (micro))) -#endif /* LIBMATEMIXER_VERSION_H */ +G_END_DECLS + +#endif /* MATEMIXER_VERSION_H */ diff --git a/libmatemixer/matemixer.c b/libmatemixer/matemixer.c index 1e5d4e0..602d5d2 100644 --- a/libmatemixer/matemixer.c +++ b/libmatemixer/matemixer.c @@ -37,8 +37,8 @@ static gboolean mixer_initialized = FALSE; * 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. + * Returns: %TRUE on success or %FALSE if the library installation does not + * provide support for any sound system backends. */ gboolean mate_mixer_init (void) @@ -52,7 +52,7 @@ mate_mixer_init (void) list = mixer_modules; while (list) { GTypeModule *module = G_TYPE_MODULE (list->data); - GList *next = list->next; + GList *next = list->next; /* Attempt to load the module and remove it from the list * if it isn't usable */ diff --git a/libmatemixer/matemixer.h b/libmatemixer/matemixer.h index 99df233..a36c89c 100644 --- a/libmatemixer/matemixer.h +++ b/libmatemixer/matemixer.h @@ -19,10 +19,16 @@ #define MATEMIXER_H #include <glib.h> +#include <glib-object.h> + +#include <libmatemixer/matemixer-client-stream.h> #include <libmatemixer/matemixer-control.h> #include <libmatemixer/matemixer-device.h> #include <libmatemixer/matemixer-enums.h> +#include <libmatemixer/matemixer-port.h> +#include <libmatemixer/matemixer-profile.h> #include <libmatemixer/matemixer-stream.h> +#include <libmatemixer/matemixer-version.h> G_BEGIN_DECLS |