diff options
author | Michal Ratajsky <[email protected]> | 2014-08-12 05:06:12 +0200 |
---|---|---|
committer | Michal Ratajsky <[email protected]> | 2014-08-12 05:06:12 +0200 |
commit | 1e1847069eb58c2b62f2b3c11e1e9adf3a17ebde (patch) | |
tree | 4bcd30db2bdf4032c4a49844570ce4227cf2510e /libmatemixer | |
parent | 7396148c328d9f2a0d933374547c7e93a46b8efa (diff) | |
parent | 6c6d4239ddc807e922df3874654f99eea291aadb (diff) | |
download | libmatemixer-1e1847069eb58c2b62f2b3c11e1e9adf3a17ebde.tar.bz2 libmatemixer-1e1847069eb58c2b62f2b3c11e1e9adf3a17ebde.tar.xz |
Merge branch 'oss-alsa'
Diffstat (limited to 'libmatemixer')
39 files changed, 4298 insertions, 2332 deletions
diff --git a/libmatemixer/Makefile.am b/libmatemixer/Makefile.am index 8c219d4..8858b90 100644 --- a/libmatemixer/Makefile.am +++ b/libmatemixer/Makefile.am @@ -11,12 +11,16 @@ libmatemixer_includedir = $(includedir)/libmatemixer libmatemixer_include_HEADERS = \ matemixer.h \ matemixer-client-stream.h \ - matemixer-control.h \ + matemixer-context.h \ matemixer-device.h \ matemixer-device-profile.h \ matemixer-enums.h \ - matemixer-port.h \ matemixer-stream.h \ + matemixer-stream-control.h \ + matemixer-switch.h \ + matemixer-switch-option.h \ + matemixer-toggle.h \ + matemixer-types.h \ matemixer-version.h libmatemixer_la_CFLAGS = $(GLIB_CFLAGS) @@ -26,18 +30,24 @@ libmatemixer_la_SOURCES = \ matemixer-private.h \ matemixer-backend.c \ matemixer-backend.h \ + matemixer-backend-private.h \ matemixer-backend-module.c \ matemixer-backend-module.h \ matemixer-client-stream.c \ - matemixer-control.c \ + matemixer-context.c \ matemixer-device.c \ matemixer-device-profile.c \ matemixer-device-profile-private.h \ matemixer-enum-types.c \ matemixer-enum-types.h \ - matemixer-port.c \ - matemixer-port-private.h \ - matemixer-stream.c + matemixer-stream.c \ + matemixer-stream-control.c \ + matemixer-stream-control-private.h \ + matemixer-switch.c \ + matemixer-switch-private.h \ + matemixer-switch-option.c \ + matemixer-switch-option-private.h \ + matemixer-toggle.c libmatemixer_la_LIBADD = $(GLIB_LIBS) diff --git a/libmatemixer/matemixer-backend-module.c b/libmatemixer/matemixer-backend-module.c index a3146d2..0e7716e 100644 --- a/libmatemixer/matemixer-backend-module.c +++ b/libmatemixer/matemixer-backend-module.c @@ -22,16 +22,19 @@ #include "matemixer-backend.h" #include "matemixer-backend-module.h" -struct _MateMixerBackendModulePrivate -{ - GModule *gmodule; - gchar *path; - gboolean loaded; +/* Initialize backend */ +typedef void (*BackendInit) (GTypeModule *type_module); - void (*init) (GTypeModule *type_module); - void (*deinit) (void); +/* Return information about backend */ +typedef const MateMixerBackendInfo *(*BackendGetInfo) (void); - const MateMixerBackendInfo *(*get_info) (void); +struct _MateMixerBackendModulePrivate +{ + GModule *gmodule; + gchar *path; + gboolean loaded; + BackendInit init; + BackendGetInfo get_info; }; enum { @@ -102,6 +105,7 @@ mate_mixer_backend_module_get_property (GObject *object, case PROP_PATH: g_value_set_string (value, module->priv->path); break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); break; @@ -122,7 +126,10 @@ mate_mixer_backend_module_set_property (GObject *object, case PROP_PATH: /* Construct-only string */ module->priv->path = g_strdup (g_value_get_string (value)); + + g_type_module_set_name (G_TYPE_MODULE (object), module->priv->path); break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); break; @@ -157,8 +164,11 @@ 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); + MateMixerBackendModule *module; + + module = MATE_MIXER_BACKEND_MODULE (object); + + g_free (module->priv->path); G_OBJECT_CLASS (mate_mixer_backend_module_parent_class)->finalize (object); } @@ -174,17 +184,11 @@ mate_mixer_backend_module_finalize (GObject *object) 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; + return g_object_new (MATE_MIXER_TYPE_BACKEND_MODULE, + "path", path, + NULL); } /** @@ -227,76 +231,57 @@ backend_module_load (GTypeModule *type_module) module = MATE_MIXER_BACKEND_MODULE (type_module); - if (module->priv->loaded == FALSE) { - module->priv->gmodule = g_module_open (module->priv->path, - G_MODULE_BIND_LAZY | - G_MODULE_BIND_LOCAL); - if (module->priv->gmodule == NULL) { - g_warning ("Failed to load backend module %s: %s", - module->priv->path, - g_module_error ()); - - return FALSE; - } - - /* Validate library symbols that each backend module must provide */ - if (g_module_symbol (module->priv->gmodule, - "backend_module_init", - (gpointer *) &module->priv->init) == FALSE || - g_module_symbol (module->priv->gmodule, - "backend_module_get_info", - (gpointer *) &module->priv->get_info) == FALSE) { - g_warning ("Failed to load backend module %s: %s", - module->priv->path, - g_module_error ()); - - g_module_close (module->priv->gmodule); - return FALSE; - } - - /* Optional backend function */ + if (module->priv->loaded == TRUE) + return TRUE; + + module->priv->gmodule = g_module_open (module->priv->path, + G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL); + if (module->priv->gmodule == NULL) { + g_warning ("Failed to load backend module %s: %s", + module->priv->path, + g_module_error ()); + + return FALSE; + } + + /* Validate library symbols that each backend module must provide */ + if (g_module_symbol (module->priv->gmodule, + "backend_module_init", + (gpointer *) &module->priv->init) == FALSE || g_module_symbol (module->priv->gmodule, - "backend_module_deinit", - (gpointer *) &module->priv->deinit); - - module->priv->init (type_module); - module->priv->loaded = TRUE; - - /* Make sure get_info() returns something, so we can avoid checking it - * in other parts of the library */ - if (G_UNLIKELY (module->priv->get_info () == NULL)) { - 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 */ - g_module_close (module->priv->gmodule); - return FALSE; - } - - /* It is not possible to unref this instance, so let's avoid unloading - * the module and just let the backend module (de)initialize when - * (de)init functions are called repeatedly */ - g_module_make_resident (module->priv->gmodule); - - g_debug ("Loaded backend module %s", module->priv->path); - } else { - /* This function was called before, so avoid loading and initialize only */ - module->priv->init (type_module); + "backend_module_get_info", + (gpointer *) &module->priv->get_info) == FALSE) { + g_warning ("Failed to load backend module %s: %s", + module->priv->path, + g_module_error ()); + + g_module_close (module->priv->gmodule); + return FALSE; + } + + module->priv->init (type_module); + module->priv->loaded = TRUE; + + /* Make sure get_info() returns something, so we can avoid checking it + * in other parts of the library */ + if (G_UNLIKELY (module->priv->get_info () == NULL)) { + 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 */ + g_module_close (module->priv->gmodule); + return FALSE; } + /* It is not possible to unref this instance, so keep the module alive */ + g_module_make_resident (module->priv->gmodule); + + g_debug ("Loaded backend module %s", module->priv->path); return TRUE; } static void backend_module_unload (GTypeModule *type_module) { - MateMixerBackendModule *module; - - module = MATE_MIXER_BACKEND_MODULE (type_module); - - /* Only deinitialize the backend module, do not modify the loaded flag - * as the module remains loaded */ - if (module->priv->deinit) - module->priv->deinit (); } diff --git a/libmatemixer/matemixer-backend-module.h b/libmatemixer/matemixer-backend-module.h index 62b0a43..e1dfd8d 100644 --- a/libmatemixer/matemixer-backend-module.h +++ b/libmatemixer/matemixer-backend-module.h @@ -21,17 +21,10 @@ #include <glib.h> #include <glib-object.h> -#include "matemixer-enums.h" +#include <libmatemixer/matemixer-enums.h> G_BEGIN_DECLS -typedef struct { - gchar *name; - guint priority; - GType g_type; - MateMixerBackendType backend_type; -} MateMixerBackendInfo; - #define MATE_MIXER_TYPE_BACKEND_MODULE \ (mate_mixer_backend_module_get_type ()) #define MATE_MIXER_BACKEND_MODULE(o) \ @@ -45,6 +38,7 @@ typedef struct { #define MATE_MIXER_BACKEND_MODULE_GET_CLASS(o) \ (G_TYPE_INSTANCE_GET_CLASS ((o), MATE_MIXER_TYPE_BACKEND_MODULE, MateMixerBackendModuleClass)) +typedef struct _MateMixerBackendInfo MateMixerBackendInfo; typedef struct _MateMixerBackendModule MateMixerBackendModule; typedef struct _MateMixerBackendModuleClass MateMixerBackendModuleClass; typedef struct _MateMixerBackendModulePrivate MateMixerBackendModulePrivate; @@ -62,6 +56,14 @@ struct _MateMixerBackendModuleClass GTypeModuleClass parent_class; }; +struct _MateMixerBackendInfo +{ + gchar *name; + guint priority; + GType g_type; + MateMixerBackendType backend_type; +}; + GType mate_mixer_backend_module_get_type (void) G_GNUC_CONST; MateMixerBackendModule * mate_mixer_backend_module_new (const gchar *path); diff --git a/libmatemixer/matemixer-backend-private.h b/libmatemixer/matemixer-backend-private.h new file mode 100644 index 0000000..b5de8ae --- /dev/null +++ b/libmatemixer/matemixer-backend-private.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2014 Michal Ratajsky <[email protected]> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the licence, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef MATEMIXER_BACKEND_PRIVATE_H +#define MATEMIXER_BACKEND_PRIVATE_H + +#include <glib.h> + +#include "matemixer-backend.h" +#include "matemixer-enums.h" +#include "matemixer-stream.h" + +G_BEGIN_DECLS + +void _mate_mixer_backend_set_state (MateMixerBackend *backend, + MateMixerState state); + +void _mate_mixer_backend_set_default_input_stream (MateMixerBackend *backend, + MateMixerStream *stream); + +void _mate_mixer_backend_set_default_output_stream (MateMixerBackend *backend, + MateMixerStream *stream); + +G_END_DECLS + +#endif /* MATEMIXER_BACKEND_PRIVATE_H */ diff --git a/libmatemixer/matemixer-backend.c b/libmatemixer/matemixer-backend.c index be5c704..fab0883 100644 --- a/libmatemixer/matemixer-backend.c +++ b/libmatemixer/matemixer-backend.c @@ -15,61 +15,122 @@ * License along with this library; if not, see <http://www.gnu.org/licenses/>. */ +#include <string.h> #include <glib.h> #include <glib-object.h> #include "matemixer-backend.h" +#include "matemixer-backend-private.h" #include "matemixer-enums.h" #include "matemixer-enum-types.h" #include "matemixer-stream.h" +struct _MateMixerBackendPrivate +{ + GList *devices; + GList *streams; + GList *stored_streams; + MateMixerStream *default_input; + MateMixerStream *default_output; + MateMixerState state; + MateMixerBackendFlags flags; +}; + +enum { + PROP_0, + PROP_STATE, + PROP_DEFAULT_INPUT_STREAM, + PROP_DEFAULT_OUTPUT_STREAM, + N_PROPERTIES +}; + +static GParamSpec *properties[N_PROPERTIES] = { NULL, }; + enum { DEVICE_ADDED, DEVICE_REMOVED, STREAM_ADDED, STREAM_REMOVED, - CACHED_STREAM_ADDED, - CACHED_STREAM_REMOVED, + STORED_STREAM_ADDED, + STORED_STREAM_REMOVED, N_SIGNALS }; static guint signals[N_SIGNALS] = { 0, }; -G_DEFINE_INTERFACE (MateMixerBackend, mate_mixer_backend, G_TYPE_OBJECT) +static void mate_mixer_backend_class_init (MateMixerBackendClass *klass); + +static void mate_mixer_backend_init (MateMixerBackend *backend); + +static void mate_mixer_backend_get_property (GObject *object, + guint param_id, + GValue *value, + GParamSpec *pspec); +static void mate_mixer_backend_set_property (GObject *object, + guint param_id, + const GValue *value, + GParamSpec *pspec); + +static void mate_mixer_backend_dispose (GObject *object); + +G_DEFINE_ABSTRACT_TYPE (MateMixerBackend, mate_mixer_backend, G_TYPE_OBJECT) + +static void device_added (MateMixerBackend *backend, const gchar *name); +static void device_removed (MateMixerBackend *backend, const gchar *name); + +static void device_stream_added (MateMixerDevice *device, + const gchar *name); +static void device_stream_removed (MateMixerDevice *device, + const gchar *name); + +static void free_devices (MateMixerBackend *backend); +static void free_streams (MateMixerBackend *backend); +static void free_stored_streams (MateMixerBackend *backend); +static void stream_removed (MateMixerBackend *backend, + const gchar *name); static void -mate_mixer_backend_default_init (MateMixerBackendInterface *iface) +mate_mixer_backend_class_init (MateMixerBackendClass *klass) { - g_object_interface_install_property (iface, - 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)); - - 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)); + GObjectClass *object_class; + + object_class = G_OBJECT_CLASS (klass); + object_class->dispose = mate_mixer_backend_dispose; + object_class->get_property = mate_mixer_backend_get_property; + object_class->set_property = mate_mixer_backend_set_property; + + 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_STREAM] = + g_param_spec_object ("default-input-stream", + "Default input stream", + "Default input stream", + MATE_MIXER_TYPE_STREAM, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); + + properties[PROP_DEFAULT_OUTPUT_STREAM] = + g_param_spec_object ("default-output-stream", + "Default output stream", + "Default output stream", + MATE_MIXER_TYPE_STREAM, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties (object_class, N_PROPERTIES, properties); signals[DEVICE_ADDED] = g_signal_new ("device-added", - G_TYPE_FROM_INTERFACE (iface), + G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (MateMixerBackendInterface, device_added), + G_STRUCT_OFFSET (MateMixerBackendClass, device_added), NULL, NULL, g_cclosure_marshal_VOID__STRING, @@ -79,9 +140,9 @@ mate_mixer_backend_default_init (MateMixerBackendInterface *iface) signals[DEVICE_REMOVED] = g_signal_new ("device-removed", - G_TYPE_FROM_INTERFACE (iface), + G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (MateMixerBackendInterface, device_removed), + G_STRUCT_OFFSET (MateMixerBackendClass, device_removed), NULL, NULL, g_cclosure_marshal_VOID__STRING, @@ -91,9 +152,9 @@ mate_mixer_backend_default_init (MateMixerBackendInterface *iface) signals[STREAM_ADDED] = g_signal_new ("stream-added", - G_TYPE_FROM_INTERFACE (iface), + G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (MateMixerBackendInterface, stream_added), + G_STRUCT_OFFSET (MateMixerBackendClass, stream_added), NULL, NULL, g_cclosure_marshal_VOID__STRING, @@ -103,9 +164,9 @@ mate_mixer_backend_default_init (MateMixerBackendInterface *iface) signals[STREAM_REMOVED] = g_signal_new ("stream-removed", - G_TYPE_FROM_INTERFACE (iface), + G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (MateMixerBackendInterface, stream_removed), + G_STRUCT_OFFSET (MateMixerBackendClass, stream_removed), NULL, NULL, g_cclosure_marshal_VOID__STRING, @@ -113,11 +174,11 @@ mate_mixer_backend_default_init (MateMixerBackendInterface *iface) 1, G_TYPE_STRING); - signals[CACHED_STREAM_ADDED] = - g_signal_new ("cached-stream-added", - G_TYPE_FROM_INTERFACE (iface), + signals[STORED_STREAM_ADDED] = + g_signal_new ("stored-stream-added", + G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (MateMixerBackendInterface, cached_stream_added), + G_STRUCT_OFFSET (MateMixerBackendClass, stored_stream_added), NULL, NULL, g_cclosure_marshal_VOID__STRING, @@ -125,30 +186,149 @@ mate_mixer_backend_default_init (MateMixerBackendInterface *iface) 1, G_TYPE_STRING); - signals[CACHED_STREAM_REMOVED] = - g_signal_new ("cached-stream-removed", - G_TYPE_FROM_INTERFACE (iface), + signals[STORED_STREAM_REMOVED] = + g_signal_new ("stored-stream-removed", + G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (MateMixerBackendInterface, cached_stream_removed), + G_STRUCT_OFFSET (MateMixerBackendClass, stored_stream_removed), NULL, NULL, g_cclosure_marshal_VOID__STRING, G_TYPE_NONE, 1, G_TYPE_STRING); + + g_type_class_add_private (object_class, sizeof (MateMixerBackendPrivate)); +} + +static void +mate_mixer_backend_get_property (GObject *object, + guint param_id, + GValue *value, + GParamSpec *pspec) +{ + MateMixerBackend *backend; + + backend = MATE_MIXER_BACKEND (object); + + switch (param_id) { + case PROP_STATE: + g_value_set_enum (value, backend->priv->state); + break; + + case PROP_DEFAULT_INPUT_STREAM: + g_value_set_object (value, backend->priv->default_input); + break; + + case PROP_DEFAULT_OUTPUT_STREAM: + g_value_set_object (value, backend->priv->default_output); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); + break; + } +} + +static void +mate_mixer_backend_set_property (GObject *object, + guint param_id, + const GValue *value, + GParamSpec *pspec) +{ + MateMixerBackend *backend; + + backend = MATE_MIXER_BACKEND (object); + + switch (param_id) { + case PROP_DEFAULT_INPUT_STREAM: + mate_mixer_backend_set_default_input_stream (backend, g_value_get_object (value)); + break; + + case PROP_DEFAULT_OUTPUT_STREAM: + mate_mixer_backend_set_default_output_stream (backend, g_value_get_object (value)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); + break; + } +} + +static void +mate_mixer_backend_init (MateMixerBackend *backend) +{ + backend->priv = G_TYPE_INSTANCE_GET_PRIVATE (backend, + MATE_MIXER_TYPE_BACKEND, + MateMixerBackendPrivate); + + g_signal_connect (G_OBJECT (backend), + "device-added", + G_CALLBACK (free_devices), + NULL); + g_signal_connect (G_OBJECT (backend), + "device-added", + G_CALLBACK (device_added), + NULL); + + g_signal_connect (G_OBJECT (backend), + "device-removed", + G_CALLBACK (free_devices), + NULL); + g_signal_connect (G_OBJECT (backend), + "device-removed", + G_CALLBACK (device_removed), + NULL); + + g_signal_connect (G_OBJECT (backend), + "stream-added", + G_CALLBACK (free_streams), + NULL); + g_signal_connect (G_OBJECT (backend), + "stream-removed", + G_CALLBACK (free_streams), + NULL); + + g_signal_connect (G_OBJECT (backend), + "stored-stream-added", + G_CALLBACK (free_stored_streams), + NULL); + g_signal_connect (G_OBJECT (backend), + "stored-stream-removed", + G_CALLBACK (free_stored_streams), + NULL); + + // XXX also free when changing state +} + +static void +mate_mixer_backend_dispose (GObject *object) +{ + MateMixerBackend *backend; + + backend = MATE_MIXER_BACKEND (object); + + free_devices (backend); + free_streams (backend); + free_stored_streams (backend); + + g_clear_object (&backend->priv->default_input); + g_clear_object (&backend->priv->default_output); + + G_OBJECT_CLASS (mate_mixer_backend_parent_class)->dispose (object); } void -mate_mixer_backend_set_data (MateMixerBackend *backend, const MateMixerBackendData *data) +mate_mixer_backend_set_data (MateMixerBackend *backend, MateMixerBackendData *data) { - MateMixerBackendInterface *iface; + MateMixerBackendClass *klass; g_return_if_fail (MATE_MIXER_IS_BACKEND (backend)); - iface = MATE_MIXER_BACKEND_GET_INTERFACE (backend); + klass = MATE_MIXER_BACKEND_GET_CLASS (backend); - if (iface->set_data) - iface->set_data (backend, data); + if (klass->set_data != NULL) + klass->set_data (backend, data); } gboolean @@ -157,20 +337,20 @@ mate_mixer_backend_open (MateMixerBackend *backend) g_return_val_if_fail (MATE_MIXER_IS_BACKEND (backend), FALSE); /* Implementation required */ - return MATE_MIXER_BACKEND_GET_INTERFACE (backend)->open (backend); + return MATE_MIXER_BACKEND_GET_CLASS (backend)->open (backend); } void mate_mixer_backend_close (MateMixerBackend *backend) { - MateMixerBackendInterface *iface; + MateMixerBackendClass *klass; g_return_if_fail (MATE_MIXER_IS_BACKEND (backend)); - iface = MATE_MIXER_BACKEND_GET_INTERFACE (backend); + klass = MATE_MIXER_BACKEND_GET_CLASS (backend); - if (iface->close) - iface->close (backend); + if (klass->close != NULL) + klass->close (backend); } MateMixerState @@ -178,113 +358,266 @@ mate_mixer_backend_get_state (MateMixerBackend *backend) { g_return_val_if_fail (MATE_MIXER_IS_BACKEND (backend), MATE_MIXER_STATE_UNKNOWN); - /* Implementation required */ - return MATE_MIXER_BACKEND_GET_INTERFACE (backend)->get_state (backend); + return backend->priv->state; } -GList * -mate_mixer_backend_list_devices (MateMixerBackend *backend) +MateMixerBackendFlags +mate_mixer_backend_get_flags (MateMixerBackend *backend) { - MateMixerBackendInterface *iface; + g_return_val_if_fail (MATE_MIXER_IS_BACKEND (backend), MATE_MIXER_BACKEND_NO_FLAGS); + return backend->priv->flags; +} + +const GList * +mate_mixer_backend_list_devices (MateMixerBackend *backend) +{ g_return_val_if_fail (MATE_MIXER_IS_BACKEND (backend), NULL); - iface = MATE_MIXER_BACKEND_GET_INTERFACE (backend); + if (backend->priv->devices == NULL) { + MateMixerBackendClass *klass; - if (iface->list_devices) - return iface->list_devices (backend); + klass = MATE_MIXER_BACKEND_GET_CLASS (backend); - return NULL; + if (klass->list_devices != NULL) + backend->priv->devices = klass->list_devices (backend); + } + + return backend->priv->devices; } -GList * +const GList * mate_mixer_backend_list_streams (MateMixerBackend *backend) { - MateMixerBackendInterface *iface; - g_return_val_if_fail (MATE_MIXER_IS_BACKEND (backend), NULL); - iface = MATE_MIXER_BACKEND_GET_INTERFACE (backend); + if (backend->priv->streams == NULL) { + MateMixerBackendClass *klass; - if (iface->list_streams) - return iface->list_streams (backend); + klass = MATE_MIXER_BACKEND_GET_CLASS (backend); - return NULL; + if (klass->list_streams != NULL) + backend->priv->streams = klass->list_streams (backend); + } + + return backend->priv->streams; } -GList * -mate_mixer_backend_list_cached_streams (MateMixerBackend *backend) +const GList * +mate_mixer_backend_list_stored_streams (MateMixerBackend *backend) { - MateMixerBackendInterface *iface; - g_return_val_if_fail (MATE_MIXER_IS_BACKEND (backend), NULL); - iface = MATE_MIXER_BACKEND_GET_INTERFACE (backend); + if (backend->priv->stored_streams == NULL) { + MateMixerBackendClass *klass; - if (iface->list_cached_streams) - return iface->list_cached_streams (backend); + klass = MATE_MIXER_BACKEND_GET_CLASS (backend); - return NULL; + if (klass->list_stored_streams != NULL) + backend->priv->stored_streams = klass->list_stored_streams (backend); + } + + return backend->priv->stored_streams; } MateMixerStream * mate_mixer_backend_get_default_input_stream (MateMixerBackend *backend) { - MateMixerBackendInterface *iface; + MateMixerStream *stream = NULL; g_return_val_if_fail (MATE_MIXER_IS_BACKEND (backend), NULL); - iface = MATE_MIXER_BACKEND_GET_INTERFACE (backend); + g_object_get (G_OBJECT (backend), + "default-input-stream", &stream, + NULL); - if (iface->get_default_input_stream) - return iface->get_default_input_stream (backend); + if (stream != NULL) + g_object_unref (stream); - return NULL; + return stream; } gboolean mate_mixer_backend_set_default_input_stream (MateMixerBackend *backend, MateMixerStream *stream) { - MateMixerBackendInterface *iface; - g_return_val_if_fail (MATE_MIXER_IS_BACKEND (backend), FALSE); + g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), FALSE); + + if (backend->priv->default_input != stream) { + MateMixerBackendClass *klass; + + klass = MATE_MIXER_BACKEND_GET_CLASS (backend); - iface = MATE_MIXER_BACKEND_GET_INTERFACE (backend); + if (klass->set_default_input_stream == NULL || + klass->set_default_input_stream (backend, stream) == FALSE) + return FALSE; - if (iface->set_default_input_stream) - return iface->set_default_input_stream (backend, stream); + _mate_mixer_backend_set_default_input_stream (backend, stream); + } - return FALSE; + return TRUE; } MateMixerStream * mate_mixer_backend_get_default_output_stream (MateMixerBackend *backend) { - MateMixerBackendInterface *iface; + MateMixerStream *stream = NULL; g_return_val_if_fail (MATE_MIXER_IS_BACKEND (backend), NULL); - iface = MATE_MIXER_BACKEND_GET_INTERFACE (backend); + g_object_get (G_OBJECT (backend), + "default-output-stream", &stream, + NULL); - if (iface->get_default_output_stream) - return iface->get_default_output_stream (backend); + if (stream != NULL) + g_object_unref (stream); - return NULL; + return stream; } gboolean mate_mixer_backend_set_default_output_stream (MateMixerBackend *backend, MateMixerStream *stream) { - MateMixerBackendInterface *iface; - g_return_val_if_fail (MATE_MIXER_IS_BACKEND (backend), FALSE); + g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), FALSE); + + if (backend->priv->default_input != stream) { + MateMixerBackendClass *klass; + + klass = MATE_MIXER_BACKEND_GET_CLASS (backend); + + if (klass->set_default_output_stream == NULL || + klass->set_default_output_stream (backend, stream) == FALSE) + return FALSE; + + _mate_mixer_backend_set_default_output_stream (backend, stream); + } + + return TRUE; +} + +static void +device_added (MateMixerBackend *backend, const gchar *name) +{ + MateMixerDevice *device; + + // device = mate_mixer_backend_get_device (backend, name); + +/* + g_signal_connect (G_OBJECT (device), + "stream-added", + G_CALLBACK (device_stream_added)); + */ +} + +static void +device_removed (MateMixerBackend *backend, const gchar *name) +{ +} + +static void +device_stream_added (MateMixerDevice *device, const gchar *name) +{ + g_signal_emit (G_OBJECT (device), + signals[STREAM_ADDED], + 0, + name); +} + +static void +device_stream_removed (MateMixerDevice *device, const gchar *name) +{ + g_signal_emit (G_OBJECT (device), + signals[STREAM_REMOVED], + 0, + name); +} + +static void +free_devices (MateMixerBackend *backend) +{ + if (backend->priv->devices == NULL) + return; + + g_list_free_full (backend->priv->devices, g_object_unref); + + backend->priv->devices = NULL; +} + +static void +free_streams (MateMixerBackend *backend) +{ + if (backend->priv->streams == NULL) + return; + + g_list_free_full (backend->priv->streams, g_object_unref); + + backend->priv->streams = NULL; +} + +static void +free_stored_streams (MateMixerBackend *backend) +{ + if (backend->priv->stored_streams == NULL) + return; + + g_list_free_full (backend->priv->stored_streams, g_object_unref); + + backend->priv->stored_streams = NULL; +} + +/* Protected */ +void +_mate_mixer_backend_set_state (MateMixerBackend *backend, MateMixerState state) +{ + if (backend->priv->state == state) + return; + + backend->priv->state = state; + + g_object_notify_by_pspec (G_OBJECT (backend), properties[PROP_STATE]); +} + +void +_mate_mixer_backend_set_default_input_stream (MateMixerBackend *backend, + MateMixerStream *stream) +{ + if (backend->priv->default_input == stream) + return; + + if (backend->priv->default_input != NULL) + g_object_unref (backend->priv->default_input); + + if (stream != NULL) + backend->priv->default_input = g_object_ref (stream); + else + backend->priv->default_input = NULL; + + g_debug ("Default input stream changed to %s", + (stream != NULL) ? mate_mixer_stream_get_name (stream) : "none"); + + g_object_notify_by_pspec (G_OBJECT (backend), properties[PROP_DEFAULT_INPUT_STREAM]); +} + +void +_mate_mixer_backend_set_default_output_stream (MateMixerBackend *backend, + MateMixerStream *stream) +{ + if (backend->priv->default_output == stream) + return; + + if (backend->priv->default_output != NULL) + g_object_unref (backend->priv->default_output); - iface = MATE_MIXER_BACKEND_GET_INTERFACE (backend); + if (stream != NULL) + backend->priv->default_output = g_object_ref (stream); + else + backend->priv->default_output = NULL; - if (iface->set_default_output_stream) - return iface->set_default_output_stream (backend, stream); + g_debug ("Default output stream changed to %s", + (stream != NULL) ? mate_mixer_stream_get_name (stream) : "none"); - return FALSE; + g_object_notify_by_pspec (G_OBJECT (backend), properties[PROP_DEFAULT_OUTPUT_STREAM]); } diff --git a/libmatemixer/matemixer-backend.h b/libmatemixer/matemixer-backend.h index 8bedfe0..1c918c9 100644 --- a/libmatemixer/matemixer-backend.h +++ b/libmatemixer/matemixer-backend.h @@ -21,94 +21,103 @@ #include <glib.h> #include <glib-object.h> -#include "matemixer-enums.h" -#include "matemixer-stream.h" +#include <libmatemixer/matemixer-enums.h> +#include <libmatemixer/matemixer-types.h> G_BEGIN_DECLS -typedef struct -{ - gchar *app_name; - gchar *app_id; - gchar *app_version; - gchar *app_icon; - gchar *server_address; -} MateMixerBackendData; - #define MATE_MIXER_TYPE_BACKEND \ (mate_mixer_backend_get_type ()) #define MATE_MIXER_BACKEND(o) \ (G_TYPE_CHECK_INSTANCE_CAST ((o), MATE_MIXER_TYPE_BACKEND, MateMixerBackend)) #define MATE_MIXER_IS_BACKEND(o) \ (G_TYPE_CHECK_INSTANCE_TYPE ((o), MATE_MIXER_TYPE_BACKEND)) -#define MATE_MIXER_BACKEND_GET_INTERFACE(o) \ - (G_TYPE_INSTANCE_GET_INTERFACE ((o), MATE_MIXER_TYPE_BACKEND, MateMixerBackendInterface)) - -typedef struct _MateMixerBackend MateMixerBackend; /* dummy object */ -typedef struct _MateMixerBackendInterface MateMixerBackendInterface; - -struct _MateMixerBackendInterface +#define MATE_MIXER_BACKEND_CLASS(k) \ + (G_TYPE_CHECK_CLASS_CAST ((k), MATE_MIXER_TYPE_BACKEND, MateMixerBackendClass)) +#define MATE_MIXER_IS_BACKEND_CLASS(k) \ + (G_TYPE_CHECK_CLASS_TYPE ((k), MATE_MIXER_TYPE_BACKEND)) +#define MATE_MIXER_BACKEND_GET_CLASS(o) \ + (G_TYPE_INSTANCE_GET_CLASS ((o), MATE_MIXER_TYPE_BACKEND, MateMixerBackendClass)) + +typedef struct _MateMixerBackend MateMixerBackend; +typedef struct _MateMixerBackendClass MateMixerBackendClass; +typedef struct _MateMixerBackendData MateMixerBackendData; +typedef struct _MateMixerBackendPrivate MateMixerBackendPrivate; + +struct _MateMixerBackend { - GTypeInterface parent_iface; + GObject object; /*< private >*/ - /* Virtual table */ - void (*set_data) (MateMixerBackend *backend, - const MateMixerBackendData *data); + MateMixerBackendPrivate *priv; +}; - gboolean (*open) (MateMixerBackend *backend); - void (*close) (MateMixerBackend *backend); +struct _MateMixerBackendClass +{ + GObjectClass parent_class; - MateMixerState (*get_state) (MateMixerBackend *backend); + /*< private >*/ + void (*set_data) (MateMixerBackend *backend, + MateMixerBackendData *data); - GList *(*list_devices) (MateMixerBackend *backend); - GList *(*list_streams) (MateMixerBackend *backend); - GList *(*list_cached_streams) (MateMixerBackend *backend); + gboolean (*open) (MateMixerBackend *backend); + void (*close) (MateMixerBackend *backend); - MateMixerStream *(*get_default_input_stream) (MateMixerBackend *backend); - gboolean (*set_default_input_stream) (MateMixerBackend *backend, - MateMixerStream *stream); + GList *(*list_devices) (MateMixerBackend *backend); + GList *(*list_streams) (MateMixerBackend *backend); + GList *(*list_stored_streams) (MateMixerBackend *backend); - MateMixerStream *(*get_default_output_stream) (MateMixerBackend *backend); - gboolean (*set_default_output_stream) (MateMixerBackend *backend, - MateMixerStream *stream); + gboolean (*set_default_input_stream) (MateMixerBackend *backend, + MateMixerStream *stream); + gboolean (*set_default_output_stream) (MateMixerBackend *backend, + MateMixerStream *stream); /* Signals */ - void (*device_added) (MateMixerBackend *backend, - const gchar *name); - void (*device_removed) (MateMixerBackend *backend, - const gchar *name); - void (*stream_added) (MateMixerBackend *backend, - const gchar *name); - void (*stream_removed) (MateMixerBackend *backend, - const gchar *name); - void (*cached_stream_added) (MateMixerBackend *backend, - const gchar *name); - void (*cached_stream_removed) (MateMixerBackend *backend, - const gchar *name); + void (*device_added) (MateMixerBackend *backend, + const gchar *name); + void (*device_removed) (MateMixerBackend *backend, + const gchar *name); + void (*stream_added) (MateMixerBackend *backend, + const gchar *name); + void (*stream_removed) (MateMixerBackend *backend, + const gchar *name); + void (*stored_stream_added) (MateMixerBackend *backend, + const gchar *name); + void (*stored_stream_removed) (MateMixerBackend *backend, + const gchar *name); +}; + +struct _MateMixerBackendData +{ + gchar *app_name; + gchar *app_id; + gchar *app_version; + gchar *app_icon; + gchar *server_address; }; -GType mate_mixer_backend_get_type (void) G_GNUC_CONST; +GType mate_mixer_backend_get_type (void) G_GNUC_CONST; -void mate_mixer_backend_set_data (MateMixerBackend *backend, - const MateMixerBackendData *data); +void mate_mixer_backend_set_data (MateMixerBackend *backend, + MateMixerBackendData *data); -gboolean mate_mixer_backend_open (MateMixerBackend *backend); -void mate_mixer_backend_close (MateMixerBackend *backend); +gboolean mate_mixer_backend_open (MateMixerBackend *backend); +void mate_mixer_backend_close (MateMixerBackend *backend); -MateMixerState mate_mixer_backend_get_state (MateMixerBackend *backend); +MateMixerState mate_mixer_backend_get_state (MateMixerBackend *backend); +MateMixerBackendFlags mate_mixer_backend_get_flags (MateMixerBackend *backend); -GList * mate_mixer_backend_list_devices (MateMixerBackend *backend); -GList * mate_mixer_backend_list_streams (MateMixerBackend *backend); -GList * mate_mixer_backend_list_cached_streams (MateMixerBackend *backend); +const GList * mate_mixer_backend_list_devices (MateMixerBackend *backend); +const GList * mate_mixer_backend_list_streams (MateMixerBackend *backend); +const GList * mate_mixer_backend_list_stored_streams (MateMixerBackend *backend); -MateMixerStream *mate_mixer_backend_get_default_input_stream (MateMixerBackend *backend); -gboolean mate_mixer_backend_set_default_input_stream (MateMixerBackend *backend, - MateMixerStream *stream); +MateMixerStream * mate_mixer_backend_get_default_input_stream (MateMixerBackend *backend); +gboolean mate_mixer_backend_set_default_input_stream (MateMixerBackend *backend, + MateMixerStream *stream); -MateMixerStream *mate_mixer_backend_get_default_output_stream (MateMixerBackend *backend); -gboolean mate_mixer_backend_set_default_output_stream (MateMixerBackend *backend, - MateMixerStream *stream); +MateMixerStream * mate_mixer_backend_get_default_output_stream (MateMixerBackend *backend); +gboolean mate_mixer_backend_set_default_output_stream (MateMixerBackend *backend, + MateMixerStream *stream); G_END_DECLS diff --git a/libmatemixer/matemixer-client-stream.c b/libmatemixer/matemixer-client-stream.c index 3ff3c54..fc34622 100644 --- a/libmatemixer/matemixer-client-stream.c +++ b/libmatemixer/matemixer-client-stream.c @@ -35,68 +35,170 @@ * 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) +struct _MateMixerClientStreamPrivate +{ + gchar *app_name; + gchar *app_id; + gchar *app_version; + gchar *app_icon; + MateMixerStream *parent; + MateMixerClientStreamFlags client_flags; + MateMixerClientStreamRole client_role; +}; + +enum { + PROP_0, + PROP_CLIENT_FLAGS, + PROP_CLIENT_ROLE, + PROP_PARENT, + PROP_APP_NAME, + PROP_APP_ID, + PROP_APP_VERSION, + PROP_APP_ICON, + N_PROPERTIES +}; + +static GParamSpec *properties[N_PROPERTIES] = { NULL, }; + +static void mate_mixer_client_stream_class_init (MateMixerClientStreamClass *klass); + +static void mate_mixer_client_stream_init (MateMixerClientStream *client); + +static void mate_mixer_client_stream_get_property (GObject *object, + guint param_id, + GValue *value, + GParamSpec *pspec); +static void mate_mixer_client_stream_set_property (GObject *object, + guint param_id, + const GValue *value, + GParamSpec *pspec); + +static void mate_mixer_client_stream_dispose (GObject *object); +static void mate_mixer_client_stream_finalize (GObject *object); + +G_DEFINE_ABSTRACT_TYPE (MateMixerClientStream, mate_mixer_client_stream, MATE_MIXER_TYPE_STREAM) + +static void +mate_mixer_client_stream_class_init (MateMixerClientStreamClass *klass) +{ + GObjectClass *object_class; + + object_class = G_OBJECT_CLASS (klass); + object_class->dispose = mate_mixer_client_stream_dispose; + object_class->finalize = mate_mixer_client_stream_finalize; + object_class->get_property = mate_mixer_client_stream_get_property; + object_class->set_property = mate_mixer_client_stream_set_property; + + properties[PROP_CLIENT_FLAGS] = + g_param_spec_flags ("client-flags", + "Client flags", + "Capability flags of the client stream", + MATE_MIXER_TYPE_CLIENT_STREAM_FLAGS, + MATE_MIXER_CLIENT_STREAM_NO_FLAGS, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); + + properties[PROP_CLIENT_ROLE] = + g_param_spec_enum ("role", + "Role", + "Role of the client stream", + MATE_MIXER_TYPE_CLIENT_STREAM_ROLE, + MATE_MIXER_CLIENT_STREAM_ROLE_NONE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); + + properties[PROP_PARENT] = + g_param_spec_object ("parent", + "Parent", + "Parent stream of the client stream", + MATE_MIXER_TYPE_STREAM, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); + + properties[PROP_APP_NAME] = + g_param_spec_string ("app-name", + "App name", + "Name of the client stream application", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); + + properties[PROP_APP_ID] = + g_param_spec_string ("app-id", + "App ID", + "Identifier of the client stream application", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); + + properties[PROP_APP_VERSION] = + g_param_spec_string ("app-version", + "App version", + "Version of the client stream application", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); + + properties[PROP_APP_ICON] = + g_param_spec_string ("app-icon", + "App icon", + "Icon name of the client stream application", + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties (object_class, N_PROPERTIES, properties); +} + +static void +mate_mixer_client_stream_init (MateMixerClientStream *client) +{ + client->priv = G_TYPE_INSTANCE_GET_PRIVATE (client, + MATE_MIXER_TYPE_CLIENT_STREAM, + MateMixerClientStreamPrivate); +} static void -mate_mixer_client_stream_default_init (MateMixerClientStreamInterface *iface) +mate_mixer_client_stream_get_property (GObject *object, + guint param_id, + GValue *value, + GParamSpec *pspec) { - g_object_interface_install_property (iface, - g_param_spec_flags ("client-flags", - "Client flags", - "Capability flags of the client stream", - MATE_MIXER_TYPE_CLIENT_STREAM_FLAGS, - MATE_MIXER_CLIENT_STREAM_NO_FLAGS, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); - - g_object_interface_install_property (iface, - g_param_spec_enum ("role", - "Role", - "Role of the client stream", - MATE_MIXER_TYPE_CLIENT_STREAM_ROLE, - MATE_MIXER_CLIENT_STREAM_ROLE_NONE, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); - - g_object_interface_install_property (iface, - g_param_spec_object ("parent", - "Parent", - "Parent stream of the client stream", - MATE_MIXER_TYPE_STREAM, - 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)); +} + +static void +mate_mixer_client_stream_set_property (GObject *object, + guint param_id, + const GValue *value, + GParamSpec *pspec) +{ +} + +static void +mate_mixer_client_stream_dispose (GObject *object) +{ + MateMixerClientStream *client; + + client = MATE_MIXER_CLIENT_STREAM (object); + + g_clear_object (&client->priv->parent); + + G_OBJECT_CLASS (mate_mixer_client_stream_parent_class)->dispose (object); +} + +static void +mate_mixer_client_stream_finalize (GObject *object) +{ + MateMixerClientStream *client; + + client = MATE_MIXER_CLIENT_STREAM (object); + + g_free (client->priv->app_name); + g_free (client->priv->app_id); + g_free (client->priv->app_version); + g_free (client->priv->app_icon); + + G_OBJECT_CLASS (mate_mixer_client_stream_parent_class)->finalize (object); } /** @@ -107,16 +209,9 @@ mate_mixer_client_stream_default_init (MateMixerClientStreamInterface *iface) MateMixerClientStreamFlags mate_mixer_client_stream_get_flags (MateMixerClientStream *client) { - MateMixerClientStreamInterface *iface; - g_return_val_if_fail (MATE_MIXER_IS_CLIENT_STREAM (client), MATE_MIXER_CLIENT_STREAM_NO_FLAGS); - iface = MATE_MIXER_CLIENT_STREAM_GET_INTERFACE (client); - - if (iface->get_flags) - return iface->get_flags (client); - - return MATE_MIXER_CLIENT_STREAM_NO_FLAGS; + return client->priv->client_flags; } /** @@ -127,16 +222,9 @@ mate_mixer_client_stream_get_flags (MateMixerClientStream *client) MateMixerClientStreamRole mate_mixer_client_stream_get_role (MateMixerClientStream *client) { - MateMixerClientStreamInterface *iface; - g_return_val_if_fail (MATE_MIXER_IS_CLIENT_STREAM (client), MATE_MIXER_CLIENT_STREAM_ROLE_NONE); - iface = MATE_MIXER_CLIENT_STREAM_GET_INTERFACE (client); - - if (iface->get_role) - return iface->get_role (client); - - return MATE_MIXER_CLIENT_STREAM_ROLE_NONE; + return client->priv->client_role; } /** @@ -150,16 +238,9 @@ mate_mixer_client_stream_get_role (MateMixerClientStream *client) MateMixerStream * mate_mixer_client_stream_get_parent (MateMixerClientStream *client) { - MateMixerClientStreamInterface *iface; - g_return_val_if_fail (MATE_MIXER_IS_CLIENT_STREAM (client), NULL); - iface = MATE_MIXER_CLIENT_STREAM_GET_INTERFACE (client); - - if (iface->get_parent) - return iface->get_parent (client); - - return NULL; + return client->priv->parent; } /** @@ -175,17 +256,25 @@ mate_mixer_client_stream_get_parent (MateMixerClientStream *client) gboolean mate_mixer_client_stream_set_parent (MateMixerClientStream *client, MateMixerStream *parent) { - MateMixerClientStreamInterface *iface; - g_return_val_if_fail (MATE_MIXER_IS_CLIENT_STREAM (client), FALSE); g_return_val_if_fail (MATE_MIXER_IS_STREAM (parent), FALSE); - iface = MATE_MIXER_CLIENT_STREAM_GET_INTERFACE (client); + if (client->priv->parent != parent) { + MateMixerClientStreamClass *klass; - if (iface->set_parent) - return iface->set_parent (client, parent); + klass = MATE_MIXER_CLIENT_STREAM_GET_CLASS (client); - return FALSE; + if (klass->set_parent == NULL || + klass->set_parent (client, parent) == FALSE) + return FALSE; + + if (client->priv->parent != NULL) + g_object_unref (client->priv->parent); + + client->priv->parent = g_object_ref (parent); + } + + return TRUE; } /** @@ -199,14 +288,14 @@ mate_mixer_client_stream_set_parent (MateMixerClientStream *client, MateMixerStr gboolean mate_mixer_client_stream_remove (MateMixerClientStream *client) { - MateMixerClientStreamInterface *iface; + MateMixerClientStreamClass *klass; g_return_val_if_fail (MATE_MIXER_IS_CLIENT_STREAM (client), FALSE); - iface = MATE_MIXER_CLIENT_STREAM_GET_INTERFACE (client); + klass = MATE_MIXER_CLIENT_STREAM_GET_CLASS (client); - if (iface->remove) - return iface->remove (client); + if (klass->remove != NULL) + return klass->remove (client); return FALSE; } @@ -224,16 +313,9 @@ mate_mixer_client_stream_remove (MateMixerClientStream *client) 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; + return client->priv->app_name; } /** @@ -249,16 +331,9 @@ mate_mixer_client_stream_get_app_name (MateMixerClientStream *client) 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; + return client->priv->app_id; } /** @@ -274,16 +349,9 @@ mate_mixer_client_stream_get_app_id (MateMixerClientStream *client) 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; + return client->priv->app_version; } /** @@ -299,14 +367,7 @@ mate_mixer_client_stream_get_app_version (MateMixerClientStream *client) 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; + return client->priv->app_icon; } diff --git a/libmatemixer/matemixer-client-stream.h b/libmatemixer/matemixer-client-stream.h index fae5934..43ab3f0 100644 --- a/libmatemixer/matemixer-client-stream.h +++ b/libmatemixer/matemixer-client-stream.h @@ -22,28 +22,39 @@ #include <glib-object.h> #include <libmatemixer/matemixer-enums.h> -#include <libmatemixer/matemixer-stream.h> +#include <libmatemixer/matemixer-types.h> G_BEGIN_DECLS -#define MATE_MIXER_TYPE_CLIENT_STREAM \ +#define MATE_MIXER_TYPE_CLIENT_STREAM \ (mate_mixer_client_stream_get_type ()) -#define MATE_MIXER_CLIENT_STREAM(o) \ +#define MATE_MIXER_CLIENT_STREAM(o) \ (G_TYPE_CHECK_INSTANCE_CAST ((o), MATE_MIXER_TYPE_CLIENT_STREAM, MateMixerClientStream)) -#define MATE_MIXER_IS_CLIENT_STREAM(o) \ +#define MATE_MIXER_IS_CLIENT_STREAM(o) \ (G_TYPE_CHECK_INSTANCE_TYPE ((o), MATE_MIXER_TYPE_CLIENT_STREAM)) -#define MATE_MIXER_CLIENT_STREAM_GET_INTERFACE(o) \ - (G_TYPE_INSTANCE_GET_INTERFACE ((o), MATE_MIXER_TYPE_CLIENT_STREAM, MateMixerClientStreamInterface)) +#define MATE_MIXER_CLIENT_STREAM_CLASS(k) \ + (G_TYPE_CHECK_CLASS_CAST ((k), MATE_MIXER_TYPE_CLIENT_STREAM, MateMixerClientStreamClass)) +#define MATE_MIXER_IS_CLIENT_STREAM_CLASS(k) \ + (G_TYPE_CHECK_CLASS_TYPE ((k), MATE_MIXER_TYPE_CLIENT_STREAM)) +#define MATE_MIXER_CLIENT_STREAM_GET_CLASS(o) \ + (G_TYPE_INSTANCE_GET_CLASS ((o), MATE_MIXER_TYPE_CLIENT_STREAM, MateMixerClientStreamClass)) -typedef struct _MateMixerClientStream MateMixerClientStream; /* dummy object */ -typedef struct _MateMixerClientStreamInterface MateMixerClientStreamInterface; +typedef struct _MateMixerClientStreamClass MateMixerClientStreamClass; +typedef struct _MateMixerClientStreamPrivate MateMixerClientStreamPrivate; -struct _MateMixerClientStreamInterface +struct _MateMixerClientStream +{ + GObject *parent; + + /*< private >*/ + MateMixerClientStreamPrivate *priv; +}; + +struct _MateMixerClientStreamClass { GTypeInterface parent_iface; /*< private >*/ - /* Virtual table */ MateMixerClientStreamFlags (*get_flags) (MateMixerClientStream *client); MateMixerClientStreamRole (*get_role) (MateMixerClientStream *client); diff --git a/libmatemixer/matemixer-control.c b/libmatemixer/matemixer-context.c index 45316d5..ecd617f 100644 --- a/libmatemixer/matemixer-control.c +++ b/libmatemixer/matemixer-context.c @@ -23,23 +23,20 @@ #include "matemixer-backend.h" #include "matemixer-backend-module.h" #include "matemixer-client-stream.h" -#include "matemixer-control.h" +#include "matemixer-context.h" #include "matemixer-enums.h" #include "matemixer-enum-types.h" #include "matemixer-private.h" #include "matemixer-stream.h" /** - * SECTION:matemixer-control + * SECTION:matemixer-context * @short_description:The main class for interfacing with the library * @include: libmatemixer/matemixer.h */ -struct _MateMixerControlPrivate +struct _MateMixerContextPrivate { - GList *devices; - GList *streams; - GList *cached_streams; gboolean backend_chosen; MateMixerState state; MateMixerBackend *backend; @@ -56,8 +53,8 @@ enum { PROP_APP_ICON, PROP_SERVER_ADDRESS, PROP_STATE, - PROP_DEFAULT_INPUT, - PROP_DEFAULT_OUTPUT, + PROP_DEFAULT_INPUT_STREAM, + PROP_DEFAULT_OUTPUT_STREAM, N_PROPERTIES }; @@ -68,87 +65,82 @@ enum { DEVICE_REMOVED, STREAM_ADDED, STREAM_REMOVED, - CACHED_STREAM_ADDED, - CACHED_STREAM_REMOVED, + STORED_STREAM_ADDED, + STORED_STREAM_REMOVED, N_SIGNALS }; static guint signals[N_SIGNALS] = { 0, }; -static void mate_mixer_control_class_init (MateMixerControlClass *klass); +static void mate_mixer_context_class_init (MateMixerContextClass *klass); -static void mate_mixer_control_get_property (GObject *object, +static void mate_mixer_context_get_property (GObject *object, guint param_id, GValue *value, GParamSpec *pspec); -static void mate_mixer_control_set_property (GObject *object, +static void mate_mixer_context_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); +static void mate_mixer_context_init (MateMixerContext *context); +static void mate_mixer_context_dispose (GObject *object); +static void mate_mixer_context_finalize (GObject *object); -G_DEFINE_TYPE (MateMixerControl, mate_mixer_control, G_TYPE_OBJECT); +G_DEFINE_TYPE (MateMixerContext, mate_mixer_context, G_TYPE_OBJECT); -static void on_backend_state_notify (MateMixerBackend *backend, - GParamSpec *pspec, - MateMixerControl *control); +static void on_backend_state_notify (MateMixerBackend *backend, + GParamSpec *pspec, + MateMixerContext *context); -static void on_backend_device_added (MateMixerBackend *backend, - const gchar *name, - MateMixerControl *control); -static void on_backend_device_removed (MateMixerBackend *backend, - const gchar *name, - MateMixerControl *control); +static void on_backend_device_added (MateMixerBackend *backend, + const gchar *name, + MateMixerContext *context); +static void on_backend_device_removed (MateMixerBackend *backend, + const gchar *name, + MateMixerContext *context); -static void on_backend_stream_added (MateMixerBackend *backend, - const gchar *name, - MateMixerControl *control); -static void on_backend_stream_removed (MateMixerBackend *backend, - const gchar *name, - MateMixerControl *control); +static void on_backend_stream_added (MateMixerBackend *backend, + const gchar *name, + MateMixerContext *context); +static void on_backend_stream_removed (MateMixerBackend *backend, + const gchar *name, + MateMixerContext *context); -static void on_backend_cached_stream_added (MateMixerBackend *backend, - const gchar *name, - MateMixerControl *control); -static void on_backend_cached_stream_removed (MateMixerBackend *backend, - const gchar *name, - MateMixerControl *control); +static void on_backend_stored_stream_added (MateMixerBackend *backend, + const gchar *name, + MateMixerContext *context); +static void on_backend_stored_stream_removed (MateMixerBackend *backend, + const gchar *name, + MateMixerContext *context); -static void on_backend_default_input_notify (MateMixerBackend *backend, - GParamSpec *pspec, - MateMixerControl *control); -static void on_backend_default_output_notify (MateMixerBackend *backend, - GParamSpec *pspec, - MateMixerControl *control); +static void on_backend_default_input_stream_notify (MateMixerBackend *backend, + GParamSpec *pspec, + MateMixerContext *context); +static void on_backend_default_output_stream_notify (MateMixerBackend *backend, + GParamSpec *pspec, + MateMixerContext *context); -static gboolean try_next_backend (MateMixerControl *control); +static gboolean try_next_backend (MateMixerContext *context); -static void change_state (MateMixerControl *control, - MateMixerState state); +static void change_state (MateMixerContext *context, + MateMixerState state); -static void close_control (MateMixerControl *control); - -static void free_backend (MateMixerControl *control); -static void free_devices (MateMixerControl *control); -static void free_streams (MateMixerControl *control); -static void free_cached_streams (MateMixerControl *control); +static void close_context (MateMixerContext *context); static void -mate_mixer_control_class_init (MateMixerControlClass *klass) +mate_mixer_context_class_init (MateMixerContextClass *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; + object_class->dispose = mate_mixer_context_dispose; + object_class->finalize = mate_mixer_context_finalize; + object_class->get_property = mate_mixer_context_get_property; + object_class->set_property = mate_mixer_context_set_property; /** - * MateMixerControl:app-name: + * MateMixerContext:app-name: * * Localized human readable name of the application. */ @@ -160,7 +152,7 @@ mate_mixer_control_class_init (MateMixerControlClass *klass) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); /** - * MateMixerControl:app-id: + * MateMixerContext:app-id: * * Identifier of the application (e.g. org.example.app). */ @@ -172,7 +164,7 @@ mate_mixer_control_class_init (MateMixerControlClass *klass) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); /** - * MateMixerControl:app-version: + * MateMixerContext:app-version: * * Version of the application. */ @@ -184,7 +176,7 @@ mate_mixer_control_class_init (MateMixerControlClass *klass) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); /** - * MateMixerControl:app-icon: + * MateMixerContext:app-icon: * * An XDG icon name for the application. */ @@ -196,7 +188,7 @@ mate_mixer_control_class_init (MateMixerControlClass *klass) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); /** - * MateMixerControl:server-address: + * MateMixerContext:server-address: * * Address of the sound server to connect to. * @@ -218,16 +210,16 @@ mate_mixer_control_class_init (MateMixerControlClass *klass) MATE_MIXER_STATE_IDLE, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - properties[PROP_DEFAULT_INPUT] = - g_param_spec_object ("default-input", - "Default input", + properties[PROP_DEFAULT_INPUT_STREAM] = + g_param_spec_object ("default-input-stream", + "Default input stream", "Default input stream", MATE_MIXER_TYPE_STREAM, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - properties[PROP_DEFAULT_OUTPUT] = - g_param_spec_object ("default-output", - "Default output", + properties[PROP_DEFAULT_OUTPUT_STREAM] = + g_param_spec_object ("default-output-stream", + "Default output stream", "Default output stream", MATE_MIXER_TYPE_STREAM, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); @@ -235,8 +227,8 @@ mate_mixer_control_class_init (MateMixerControlClass *klass) g_object_class_install_properties (object_class, N_PROPERTIES, properties); /** - * MateMixerControl::device-added: - * @control: a #MateMixerControl + * MateMixerContext::device-added: + * @context: a #MateMixerContext * @name: name of the added device * * The signal is emitted each time a device is added to the system. @@ -245,7 +237,7 @@ mate_mixer_control_class_init (MateMixerControlClass *klass) g_signal_new ("device-added", G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (MateMixerControlClass, device_added), + G_STRUCT_OFFSET (MateMixerContextClass, device_added), NULL, NULL, g_cclosure_marshal_VOID__STRING, @@ -254,8 +246,8 @@ mate_mixer_control_class_init (MateMixerControlClass *klass) G_TYPE_STRING); /** - * MateMixerControl::device-removed: - * @control: a #MateMixerControl + * MateMixerContext::device-removed: + * @context: a #MateMixerContext * @name: name of the removed device * * The signal is emitted each time a device is removed from the system. @@ -264,7 +256,7 @@ mate_mixer_control_class_init (MateMixerControlClass *klass) g_signal_new ("device-removed", G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (MateMixerControlClass, device_removed), + G_STRUCT_OFFSET (MateMixerContextClass, device_removed), NULL, NULL, g_cclosure_marshal_VOID__STRING, @@ -273,8 +265,8 @@ mate_mixer_control_class_init (MateMixerControlClass *klass) G_TYPE_STRING); /** - * MateMixerControl::stream-added: - * @control: a #MateMixerControl + * MateMixerContext::stream-added: + * @context: a #MateMixerContext * @name: name of the added stream * * The signal is emitted each time a stream is created. @@ -283,7 +275,7 @@ mate_mixer_control_class_init (MateMixerControlClass *klass) g_signal_new ("stream-added", G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (MateMixerControlClass, stream_added), + G_STRUCT_OFFSET (MateMixerContextClass, stream_added), NULL, NULL, g_cclosure_marshal_VOID__STRING, @@ -292,8 +284,8 @@ mate_mixer_control_class_init (MateMixerControlClass *klass) G_TYPE_STRING); /** - * MateMixerControl::stream-removed: - * @control: a #MateMixerControl + * MateMixerContext::stream-removed: + * @context: a #MateMixerContext * @name: name of the removed stream * * The signal is emitted each time a stream is removed. @@ -302,7 +294,7 @@ mate_mixer_control_class_init (MateMixerControlClass *klass) g_signal_new ("stream-removed", G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (MateMixerControlClass, stream_removed), + G_STRUCT_OFFSET (MateMixerContextClass, stream_removed), NULL, NULL, g_cclosure_marshal_VOID__STRING, @@ -311,17 +303,17 @@ mate_mixer_control_class_init (MateMixerControlClass *klass) G_TYPE_STRING); /** - * MateMixerControl::cached-stream-added: - * @control: a #MateMixerControl - * @name: name of the added cached stream + * MateMixerContext::stored-stream-added: + * @context: a #MateMixerContext + * @name: name of the added stored stream * - * The signal is emitted each time a cached stream is created. + * The signal is emitted each time a stored stream is created. */ - signals[CACHED_STREAM_ADDED] = - g_signal_new ("cached-stream-added", + signals[STORED_STREAM_ADDED] = + g_signal_new ("stored-control-added", G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (MateMixerControlClass, cached_stream_added), + G_STRUCT_OFFSET (MateMixerContextClass, stored_stream_added), NULL, NULL, g_cclosure_marshal_VOID__STRING, @@ -330,17 +322,17 @@ mate_mixer_control_class_init (MateMixerControlClass *klass) G_TYPE_STRING); /** - * MateMixerControl::stream-removed: - * @control: a #MateMixerControl + * MateMixerContext::stream-removed: + * @context: a #MateMixerContext * @name: name of the removed stream * * The signal is emitted each time a stream is removed. */ - signals[CACHED_STREAM_REMOVED] = - g_signal_new ("cached-stream-removed", + signals[STORED_STREAM_REMOVED] = + g_signal_new ("stored-stream-removed", G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (MateMixerControlClass, cached_stream_removed), + G_STRUCT_OFFSET (MateMixerContextClass, stored_stream_removed), NULL, NULL, g_cclosure_marshal_VOID__STRING, @@ -348,43 +340,43 @@ mate_mixer_control_class_init (MateMixerControlClass *klass) 1, G_TYPE_STRING); - g_type_class_add_private (object_class, sizeof (MateMixerControlPrivate)); + g_type_class_add_private (object_class, sizeof (MateMixerContextPrivate)); } static void -mate_mixer_control_get_property (GObject *object, +mate_mixer_context_get_property (GObject *object, guint param_id, GValue *value, GParamSpec *pspec) { - MateMixerControl *control; + MateMixerContext *context; - control = MATE_MIXER_CONTROL (object); + context = MATE_MIXER_CONTEXT (object); switch (param_id) { case PROP_APP_NAME: - g_value_set_string (value, control->priv->backend_data.app_name); + g_value_set_string (value, context->priv->backend_data.app_name); break; case PROP_APP_ID: - g_value_set_string (value, control->priv->backend_data.app_id); + g_value_set_string (value, context->priv->backend_data.app_id); break; case PROP_APP_VERSION: - g_value_set_string (value, control->priv->backend_data.app_version); + g_value_set_string (value, context->priv->backend_data.app_version); break; case PROP_APP_ICON: - g_value_set_string (value, control->priv->backend_data.app_icon); + g_value_set_string (value, context->priv->backend_data.app_icon); break; case PROP_SERVER_ADDRESS: - g_value_set_string (value, control->priv->backend_data.server_address); + g_value_set_string (value, context->priv->backend_data.server_address); break; case PROP_STATE: - g_value_set_enum (value, control->priv->state); + g_value_set_enum (value, context->priv->state); break; - case PROP_DEFAULT_INPUT: - g_value_set_object (value, mate_mixer_control_get_default_input_stream (control)); + case PROP_DEFAULT_INPUT_STREAM: + g_value_set_object (value, mate_mixer_context_get_default_input_stream (context)); break; - case PROP_DEFAULT_OUTPUT: - g_value_set_object (value, mate_mixer_control_get_default_output_stream (control)); + case PROP_DEFAULT_OUTPUT_STREAM: + g_value_set_object (value, mate_mixer_context_get_default_output_stream (context)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); @@ -393,36 +385,36 @@ mate_mixer_control_get_property (GObject *object, } static void -mate_mixer_control_set_property (GObject *object, +mate_mixer_context_set_property (GObject *object, guint param_id, const GValue *value, GParamSpec *pspec) { - MateMixerControl *control; + MateMixerContext *context; - control = MATE_MIXER_CONTROL (object); + context = MATE_MIXER_CONTEXT (object); switch (param_id) { case PROP_APP_NAME: - mate_mixer_control_set_app_name (control, g_value_get_string (value)); + mate_mixer_context_set_app_name (context, g_value_get_string (value)); break; case PROP_APP_ID: - mate_mixer_control_set_app_id (control, g_value_get_string (value)); + mate_mixer_context_set_app_id (context, g_value_get_string (value)); break; case PROP_APP_VERSION: - mate_mixer_control_set_app_version (control, g_value_get_string (value)); + mate_mixer_context_set_app_version (context, g_value_get_string (value)); break; case PROP_APP_ICON: - mate_mixer_control_set_app_icon (control, g_value_get_string (value)); + mate_mixer_context_set_app_icon (context, g_value_get_string (value)); break; case PROP_SERVER_ADDRESS: - mate_mixer_control_set_server_address (control, g_value_get_string (value)); + mate_mixer_context_set_server_address (context, g_value_get_string (value)); break; - case PROP_DEFAULT_INPUT: - mate_mixer_control_set_default_input_stream (control, g_value_get_object (value)); + case PROP_DEFAULT_INPUT_STREAM: + mate_mixer_context_set_default_input_stream (context, g_value_get_object (value)); break; - case PROP_DEFAULT_OUTPUT: - mate_mixer_control_set_default_output_stream (control, g_value_get_object (value)); + case PROP_DEFAULT_OUTPUT_STREAM: + mate_mixer_context_set_default_output_stream (context, g_value_get_object (value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); @@ -431,66 +423,66 @@ mate_mixer_control_set_property (GObject *object, } static void -mate_mixer_control_init (MateMixerControl *control) +mate_mixer_context_init (MateMixerContext *context) { - control->priv = G_TYPE_INSTANCE_GET_PRIVATE (control, - MATE_MIXER_TYPE_CONTROL, - MateMixerControlPrivate); + context->priv = G_TYPE_INSTANCE_GET_PRIVATE (context, + MATE_MIXER_TYPE_CONTEXT, + MateMixerContextPrivate); } static void -mate_mixer_control_dispose (GObject *object) +mate_mixer_context_dispose (GObject *object) { - close_control (MATE_MIXER_CONTROL (object)); + close_context (MATE_MIXER_CONTEXT (object)); - G_OBJECT_CLASS (mate_mixer_control_parent_class)->dispose (object); + G_OBJECT_CLASS (mate_mixer_context_parent_class)->dispose (object); } static void -mate_mixer_control_finalize (GObject *object) +mate_mixer_context_finalize (GObject *object) { - MateMixerControl *control; + MateMixerContext *context; - control = MATE_MIXER_CONTROL (object); + context = MATE_MIXER_CONTEXT (object); - g_free (control->priv->backend_data.app_name); - g_free (control->priv->backend_data.app_id); - g_free (control->priv->backend_data.app_version); - g_free (control->priv->backend_data.app_icon); - g_free (control->priv->backend_data.server_address); + g_free (context->priv->backend_data.app_name); + g_free (context->priv->backend_data.app_id); + g_free (context->priv->backend_data.app_version); + g_free (context->priv->backend_data.app_icon); + g_free (context->priv->backend_data.server_address); - G_OBJECT_CLASS (mate_mixer_control_parent_class)->finalize (object); + G_OBJECT_CLASS (mate_mixer_context_parent_class)->finalize (object); } /** - * mate_mixer_control_new: + * mate_mixer_context_new: * - * Creates a new #MateMixerControl instance. + * Creates a new #MateMixerContext instance. * - * Returns: a new #MateMixerControl instance or %NULL if the library has not + * Returns: a new #MateMixerContext instance or %NULL if the library has not * been initialized using mate_mixer_init(). */ -MateMixerControl * -mate_mixer_control_new (void) +MateMixerContext * +mate_mixer_context_new (void) { if (mate_mixer_is_initialized () == FALSE) { g_critical ("The library has not been initialized"); return NULL; } - return g_object_new (MATE_MIXER_TYPE_CONTROL, NULL); + return g_object_new (MATE_MIXER_TYPE_CONTEXT, NULL); } /** - * mate_mixer_control_set_backend_type: - * @control: a #MateMixerControl + * mate_mixer_context_set_backend_type: + * @context: a #MateMixerContext * @backend_type: the sound system backend to use * - * Makes the #MateMixerControl use the given #MateMixerBackendType. + * Makes the #MateMixerContext use the given #MateMixerBackendType. * * By default the backend type is determined automatically. This function can - * be used before mate_mixer_control_open() to alter this behavior and make the - * @control use the given backend. + * be used before mate_mixer_context_open() to alter this behavior and make the + * @context use the given backend. * * This function will fail if support for the backend is not installed in * the system or if the current state is either %MATE_MIXER_STATE_CONNECTING or @@ -499,27 +491,27 @@ mate_mixer_control_new (void) * Returns: %TRUE on success or %FALSE on failure. */ gboolean -mate_mixer_control_set_backend_type (MateMixerControl *control, +mate_mixer_context_set_backend_type (MateMixerContext *context, MateMixerBackendType backend_type) { MateMixerBackendModule *module; const GList *modules; const MateMixerBackendInfo *info; - g_return_val_if_fail (MATE_MIXER_IS_CONTROL (control), FALSE); + g_return_val_if_fail (MATE_MIXER_IS_CONTEXT (context), FALSE); - if (control->priv->state == MATE_MIXER_STATE_CONNECTING || - control->priv->state == MATE_MIXER_STATE_READY) + if (context->priv->state == MATE_MIXER_STATE_CONNECTING || + context->priv->state == MATE_MIXER_STATE_READY) return FALSE; - modules = mate_mixer_get_modules (); + modules = _mate_mixer_get_modules (); while (modules != NULL) { module = MATE_MIXER_BACKEND_MODULE (modules->data); info = mate_mixer_backend_module_get_info (module); if (info->backend_type == backend_type) { - control->priv->backend_type = backend_type; + context->priv->backend_type = backend_type; return TRUE; } modules = modules->next; @@ -528,8 +520,8 @@ mate_mixer_control_set_backend_type (MateMixerControl *control, } /** - * mate_mixer_control_set_app_name: - * @control: a #MateMixerControl + * mate_mixer_context_set_app_name: + * @context: a #MateMixerContext * @app_name: the name of your application, or %NULL to unset * * Sets the name of the application. This feature is only supported in the @@ -542,27 +534,27 @@ mate_mixer_control_set_backend_type (MateMixerControl *control, * Returns: %TRUE on success or %FALSE on failure. */ gboolean -mate_mixer_control_set_app_name (MateMixerControl *control, const gchar *app_name) +mate_mixer_context_set_app_name (MateMixerContext *context, const gchar *app_name) { - g_return_val_if_fail (MATE_MIXER_IS_CONTROL (control), FALSE); + g_return_val_if_fail (MATE_MIXER_IS_CONTEXT (context), FALSE); - if (control->priv->state == MATE_MIXER_STATE_CONNECTING || - control->priv->state == MATE_MIXER_STATE_READY) + if (context->priv->state == MATE_MIXER_STATE_CONNECTING || + context->priv->state == MATE_MIXER_STATE_READY) return FALSE; - if (g_strcmp0 (control->priv->backend_data.app_name, app_name) != 0) { - g_free (control->priv->backend_data.app_name); + if (g_strcmp0 (context->priv->backend_data.app_name, app_name) != 0) { + g_free (context->priv->backend_data.app_name); - control->priv->backend_data.app_name = g_strdup (app_name); + context->priv->backend_data.app_name = g_strdup (app_name); - g_object_notify_by_pspec (G_OBJECT (control), properties[PROP_APP_NAME]); + g_object_notify_by_pspec (G_OBJECT (context), properties[PROP_APP_NAME]); } return TRUE; } /** - * mate_mixer_control_set_app_id: - * @control: a #MateMixerControl + * mate_mixer_context_set_app_id: + * @context: a #MateMixerContext * @app_id: the identifier of your application, or %NULL to unset * * Sets the identifier of the application (e.g. org.example.app). This feature @@ -575,27 +567,27 @@ mate_mixer_control_set_app_name (MateMixerControl *control, const gchar *app_nam * Returns: %TRUE on success or %FALSE on failure. */ gboolean -mate_mixer_control_set_app_id (MateMixerControl *control, const gchar *app_id) +mate_mixer_context_set_app_id (MateMixerContext *context, const gchar *app_id) { - g_return_val_if_fail (MATE_MIXER_IS_CONTROL (control), FALSE); + g_return_val_if_fail (MATE_MIXER_IS_CONTEXT (context), FALSE); - if (control->priv->state == MATE_MIXER_STATE_CONNECTING || - control->priv->state == MATE_MIXER_STATE_READY) + if (context->priv->state == MATE_MIXER_STATE_CONNECTING || + context->priv->state == MATE_MIXER_STATE_READY) return FALSE; - if (g_strcmp0 (control->priv->backend_data.app_id, app_id) != 0) { - g_free (control->priv->backend_data.app_id); + if (g_strcmp0 (context->priv->backend_data.app_id, app_id) != 0) { + g_free (context->priv->backend_data.app_id); - control->priv->backend_data.app_id = g_strdup (app_id); + context->priv->backend_data.app_id = g_strdup (app_id); - g_object_notify_by_pspec (G_OBJECT (control), properties[PROP_APP_ID]); + g_object_notify_by_pspec (G_OBJECT (context), properties[PROP_APP_ID]); } return TRUE; } /** - * mate_mixer_control_set_app_version: - * @control: a #MateMixerControl + * mate_mixer_context_set_app_version: + * @context: a #MateMixerContext * @app_version: the version of your application, or %NULL to unset * * Sets the version of the application. This feature is only supported in the @@ -608,27 +600,27 @@ mate_mixer_control_set_app_id (MateMixerControl *control, const gchar *app_id) * Returns: %TRUE on success or %FALSE on failure. */ gboolean -mate_mixer_control_set_app_version (MateMixerControl *control, const gchar *app_version) +mate_mixer_context_set_app_version (MateMixerContext *context, const gchar *app_version) { - g_return_val_if_fail (MATE_MIXER_IS_CONTROL (control), FALSE); + g_return_val_if_fail (MATE_MIXER_IS_CONTEXT (context), FALSE); - if (control->priv->state == MATE_MIXER_STATE_CONNECTING || - control->priv->state == MATE_MIXER_STATE_READY) + if (context->priv->state == MATE_MIXER_STATE_CONNECTING || + context->priv->state == MATE_MIXER_STATE_READY) return FALSE; - if (g_strcmp0 (control->priv->backend_data.app_version, app_version) != 0) { - g_free (control->priv->backend_data.app_version); + if (g_strcmp0 (context->priv->backend_data.app_version, app_version) != 0) { + g_free (context->priv->backend_data.app_version); - control->priv->backend_data.app_version = g_strdup (app_version); + context->priv->backend_data.app_version = g_strdup (app_version); - g_object_notify_by_pspec (G_OBJECT (control), properties[PROP_APP_VERSION]); + g_object_notify_by_pspec (G_OBJECT (context), properties[PROP_APP_VERSION]); } return TRUE; } /** - * mate_mixer_control_set_app_icon: - * @control: a #MateMixerControl + * mate_mixer_context_set_app_icon: + * @context: a #MateMixerContext * @app_icon: the XDG icon name of your application, or %NULL to unset * * Sets the XDG icon name of the application. This feature is only supported in @@ -641,27 +633,27 @@ mate_mixer_control_set_app_version (MateMixerControl *control, const gchar *app_ * Returns: %TRUE on success or %FALSE on failure. */ gboolean -mate_mixer_control_set_app_icon (MateMixerControl *control, const gchar *app_icon) +mate_mixer_context_set_app_icon (MateMixerContext *context, const gchar *app_icon) { - g_return_val_if_fail (MATE_MIXER_IS_CONTROL (control), FALSE); + g_return_val_if_fail (MATE_MIXER_IS_CONTEXT (context), FALSE); - if (control->priv->state == MATE_MIXER_STATE_CONNECTING || - control->priv->state == MATE_MIXER_STATE_READY) + if (context->priv->state == MATE_MIXER_STATE_CONNECTING || + context->priv->state == MATE_MIXER_STATE_READY) return FALSE; - if (g_strcmp0 (control->priv->backend_data.app_icon, app_icon) != 0) { - g_free (control->priv->backend_data.app_icon); + if (g_strcmp0 (context->priv->backend_data.app_icon, app_icon) != 0) { + g_free (context->priv->backend_data.app_icon); - control->priv->backend_data.app_icon = g_strdup (app_icon); + context->priv->backend_data.app_icon = g_strdup (app_icon); - g_object_notify_by_pspec (G_OBJECT (control), properties[PROP_APP_ICON]); + g_object_notify_by_pspec (G_OBJECT (context), properties[PROP_APP_ICON]); } return TRUE; } /** - * mate_mixer_control_set_server_address: - * @control: a #MateMixerControl + * mate_mixer_context_set_server_address: + * @context: a #MateMixerContext * @address: the address of the sound server to connect to or %NULL * * Sets the address of the sound server. This feature is only supported in the @@ -675,27 +667,27 @@ mate_mixer_control_set_app_icon (MateMixerControl *control, const gchar *app_ico * Returns: %TRUE on success or %FALSE on failure. */ gboolean -mate_mixer_control_set_server_address (MateMixerControl *control, const gchar *address) +mate_mixer_context_set_server_address (MateMixerContext *context, const gchar *address) { - g_return_val_if_fail (MATE_MIXER_IS_CONTROL (control), FALSE); + g_return_val_if_fail (MATE_MIXER_IS_CONTEXT (context), FALSE); - if (control->priv->state == MATE_MIXER_STATE_CONNECTING || - control->priv->state == MATE_MIXER_STATE_READY) + if (context->priv->state == MATE_MIXER_STATE_CONNECTING || + context->priv->state == MATE_MIXER_STATE_READY) return FALSE; - if (g_strcmp0 (control->priv->backend_data.server_address, address) != 0) { - g_free (control->priv->backend_data.server_address); + if (g_strcmp0 (context->priv->backend_data.server_address, address) != 0) { + g_free (context->priv->backend_data.server_address); - control->priv->backend_data.server_address = g_strdup (address); + context->priv->backend_data.server_address = g_strdup (address); - g_object_notify_by_pspec (G_OBJECT (control), properties[PROP_SERVER_ADDRESS]); + g_object_notify_by_pspec (G_OBJECT (context), properties[PROP_SERVER_ADDRESS]); } return TRUE; } /** - * mate_mixer_control_open: - * @control: a #MateMixerControl + * mate_mixer_context_open: + * @context: a #MateMixerContext * * Opens connection to a sound system. Unless the backend type was given * beforehand, the library will find a working sound system automatically. @@ -706,12 +698,12 @@ mate_mixer_control_set_server_address (MateMixerControl *control, const gchar *a * asynchronously. * * In case this function returns %TRUE, you should check the current state of - * the connection using mate_mixer_control_get_state(). If the current state + * the connection using mate_mixer_context_get_state(). If the current state * is %MATE_MIXER_STATE_READY, the connection has been established successfully. * Otherwise the state will be set to %MATE_MIXER_STATE_CONNECTING and the * result of the operation will be determined asynchronously. You should wait * for the state transition by connecting to the notification signal of the - * #MateMixerControl:state property. + * #MateMixerContext:state property. * * In case this function returns %FALSE, it is not possible to use the selected * backend and the state will be set to %MATE_MIXER_STATE_FAILED. @@ -720,31 +712,31 @@ mate_mixer_control_set_server_address (MateMixerControl *control, const gchar *a * or %FALSE on failure. */ gboolean -mate_mixer_control_open (MateMixerControl *control) +mate_mixer_context_open (MateMixerContext *context) { MateMixerBackendModule *module = NULL; MateMixerState state; const GList *modules; const MateMixerBackendInfo *info = NULL; - g_return_val_if_fail (MATE_MIXER_IS_CONTROL (control), FALSE); + g_return_val_if_fail (MATE_MIXER_IS_CONTEXT (context), FALSE); - if (control->priv->state == MATE_MIXER_STATE_CONNECTING || - control->priv->state == MATE_MIXER_STATE_READY) + if (context->priv->state == MATE_MIXER_STATE_CONNECTING || + context->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 application or the one with the highest priority */ - modules = mate_mixer_get_modules (); + modules = _mate_mixer_get_modules (); - if (control->priv->backend_type != MATE_MIXER_BACKEND_UNKNOWN) { + if (context->priv->backend_type != MATE_MIXER_BACKEND_UNKNOWN) { while (modules != NULL) { const MateMixerBackendInfo *info; module = MATE_MIXER_BACKEND_MODULE (modules->data); info = mate_mixer_backend_module_get_info (module); - if (info->backend_type == control->priv->backend_type) + if (info->backend_type == context->priv->backend_type) break; module = NULL; @@ -763,105 +755,105 @@ mate_mixer_control_open (MateMixerControl *control) if (info == NULL) info = mate_mixer_backend_module_get_info (module); - control->priv->module = g_object_ref (module); - control->priv->backend = g_object_new (info->g_type, NULL); + context->priv->module = g_object_ref (module); + context->priv->backend = g_object_new (info->g_type, NULL); - mate_mixer_backend_set_data (control->priv->backend, &control->priv->backend_data); + mate_mixer_backend_set_data (context->priv->backend, &context->priv->backend_data); g_debug ("Trying to open backend %s", info->name); /* This transitional state is always present, it will change to MATE_MIXER_STATE_READY * or MATE_MIXER_STATE_FAILED either instantly or asynchronously */ - change_state (control, MATE_MIXER_STATE_CONNECTING); + change_state (context, MATE_MIXER_STATE_CONNECTING); /* The backend initialization might fail in case it is known right now that * the backend is unusable */ - if (mate_mixer_backend_open (control->priv->backend) == FALSE) { - if (control->priv->backend_type == MATE_MIXER_BACKEND_UNKNOWN) { + if (mate_mixer_backend_open (context->priv->backend) == FALSE) { + if (context->priv->backend_type == MATE_MIXER_BACKEND_UNKNOWN) { /* User didn't request a specific backend, so try another one */ - return try_next_backend (control); + return try_next_backend (context); } /* User requested a specific backend and it failed */ - close_control (control); - change_state (control, MATE_MIXER_STATE_FAILED); + close_context (context); + change_state (context, MATE_MIXER_STATE_FAILED); return FALSE; } - state = mate_mixer_backend_get_state (control->priv->backend); + state = mate_mixer_backend_get_state (context->priv->backend); if (G_UNLIKELY (state != MATE_MIXER_STATE_READY && state != MATE_MIXER_STATE_CONNECTING)) { /* This would be a backend bug */ g_warn_if_reached (); - if (control->priv->backend_type == MATE_MIXER_BACKEND_UNKNOWN) - return try_next_backend (control); + if (context->priv->backend_type == MATE_MIXER_BACKEND_UNKNOWN) + return try_next_backend (context); - close_control (control); - change_state (control, MATE_MIXER_STATE_FAILED); + close_context (context); + change_state (context, MATE_MIXER_STATE_FAILED); return FALSE; } - g_signal_connect (G_OBJECT (control->priv->backend), + g_signal_connect (G_OBJECT (context->priv->backend), "notify::state", G_CALLBACK (on_backend_state_notify), - control); + context); - change_state (control, state); + change_state (context, state); return TRUE; } /** - * mate_mixer_control_close: - * @control: a #MateMixerControl + * mate_mixer_context_close: + * @context: a #MateMixerContext * * 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) +mate_mixer_context_close (MateMixerContext *context) { - g_return_if_fail (MATE_MIXER_IS_CONTROL (control)); + g_return_if_fail (MATE_MIXER_IS_CONTEXT (context)); - close_control (control); - change_state (control, MATE_MIXER_STATE_IDLE); + close_context (context); + change_state (context, MATE_MIXER_STATE_IDLE); } /** - * mate_mixer_control_get_state: - * @control: a #MateMixerControl + * mate_mixer_context_get_state: + * @context: a #MateMixerContext * - * Gets the current backend connection state of the #MateMixerControl. + * Gets the current backend connection state of the #MateMixerContext. * * Returns: The current connection state. */ MateMixerState -mate_mixer_control_get_state (MateMixerControl *control) +mate_mixer_context_get_state (MateMixerContext *context) { - g_return_val_if_fail (MATE_MIXER_IS_CONTROL (control), MATE_MIXER_STATE_UNKNOWN); + g_return_val_if_fail (MATE_MIXER_IS_CONTEXT (context), MATE_MIXER_STATE_UNKNOWN); - return control->priv->state; + return context->priv->state; } /** - * mate_mixer_control_get_device: - * @control: a #MateMixerControl + * mate_mixer_context_get_device: + * @context: a #MateMixerContext * @name: a device name * - * Gets the devices with the given name. + * Gets the device with the given name. * * Returns: a #MateMixerDevice or %NULL if there is no such device. */ MateMixerDevice * -mate_mixer_control_get_device (MateMixerControl *control, const gchar *name) +mate_mixer_context_get_device (MateMixerContext *context, const gchar *name) { - const GList *list; + GList *list; - g_return_val_if_fail (MATE_MIXER_IS_CONTROL (control), NULL); + g_return_val_if_fail (MATE_MIXER_IS_CONTEXT (context), NULL); g_return_val_if_fail (name != NULL, NULL); - list = mate_mixer_control_list_devices (control); + list = (GList *) mate_mixer_context_list_devices (context); while (list != NULL) { MateMixerDevice *device = MATE_MIXER_DEVICE (list->data); @@ -874,8 +866,8 @@ mate_mixer_control_get_device (MateMixerControl *control, const gchar *name) } /** - * mate_mixer_control_get_stream: - * @control: a #MateMixerControl + * mate_mixer_context_get_stream: + * @context: a #MateMixerContext * @name: a stream name * * Gets the stream with the given name. @@ -883,14 +875,14 @@ mate_mixer_control_get_device (MateMixerControl *control, const gchar *name) * Returns: a #MateMixerStream or %NULL if there is no such stream. */ MateMixerStream * -mate_mixer_control_get_stream (MateMixerControl *control, const gchar *name) +mate_mixer_context_get_stream (MateMixerContext *context, const gchar *name) { - const GList *list; + GList *list; - g_return_val_if_fail (MATE_MIXER_IS_CONTROL (control), NULL); + g_return_val_if_fail (MATE_MIXER_IS_CONTEXT (context), NULL); g_return_val_if_fail (name != NULL, NULL); - list = mate_mixer_control_list_streams (control); + list = (GList *) mate_mixer_context_list_streams (context); while (list != NULL) { MateMixerStream *stream = MATE_MIXER_STREAM (list->data); @@ -903,21 +895,24 @@ mate_mixer_control_get_stream (MateMixerControl *control, const gchar *name) } /** - * mate_mixer_control_get_cached_stream: - * @control: a #MateMixerControl + * mate_mixer_context_get_stored_stream: + * @context: a #MateMixerContext * @name: a stream name * + * Gets the stream with the given name. + * + * Returns: a #MateMixerStream or %NULL if there is no such stream. */ MateMixerStream * -mate_mixer_control_get_cached_stream (MateMixerControl *control, const gchar *name) +mate_mixer_context_get_stored_stream (MateMixerContext *context, const gchar *name) { - const GList *list; + GList *list; - g_return_val_if_fail (MATE_MIXER_IS_CONTROL (control), NULL); + g_return_val_if_fail (MATE_MIXER_IS_CONTEXT (context), NULL); g_return_val_if_fail (name != NULL, NULL); - list = mate_mixer_control_list_cached_streams (control); - while (list) { + list = (GList *) mate_mixer_context_list_stored_streams (context); + while (list != NULL) { MateMixerStream *stream = MATE_MIXER_STREAM (list->data); if (strcmp (name, mate_mixer_stream_get_name (stream)) == 0) @@ -929,90 +924,72 @@ mate_mixer_control_get_cached_stream (MateMixerControl *control, const gchar *na } /** - * mate_mixer_control_list_devices: - * @control: a #MateMixerControl + * mate_mixer_context_list_devices: + * @context: a #MateMixerContext * * Gets a list of devices. Each list item is a #MateMixerDevice representing a * hardware or software sound device in the system. * - * The returned #GList is owned by the #MateMixerControl and may be invalidated + * The returned #GList is owned by the #MateMixerContext and may be invalidated * at any time. * * Returns: a #GList of all devices in the system or %NULL if there are none or * you are not connected to a sound system. */ const GList * -mate_mixer_control_list_devices (MateMixerControl *control) +mate_mixer_context_list_devices (MateMixerContext *context) { - g_return_val_if_fail (MATE_MIXER_IS_CONTROL (control), NULL); + g_return_val_if_fail (MATE_MIXER_IS_CONTEXT (context), NULL); - if (control->priv->state != MATE_MIXER_STATE_READY) + if (context->priv->state != MATE_MIXER_STATE_READY) return NULL; - /* This list is cached here and invalidated when the backend notifies us - * about a change */ - if (control->priv->devices == NULL) - control->priv->devices = - mate_mixer_backend_list_devices (MATE_MIXER_BACKEND (control->priv->backend)); - - return (const GList *) control->priv->devices; + return mate_mixer_backend_list_devices (MATE_MIXER_BACKEND (context->priv->backend)); } /** - * mate_mixer_control_list_streams: - * @control: a #MateMixerControl + * mate_mixer_context_list_streams: + * @context: a #MateMixerContext * * Gets a list of streams. Each list item is a #MateMixerStream representing an * input or output of a sound device. * - * The returned #GList is owned by the #MateMixerControl and may be invalidated + * The returned #GList is owned by the #MateMixerContext and may be invalidated * at any time. * * Returns: a #GList of all streams in the system or %NULL if there are none or * you are not connected to a sound system. */ const GList * -mate_mixer_control_list_streams (MateMixerControl *control) +mate_mixer_context_list_streams (MateMixerContext *context) { - g_return_val_if_fail (MATE_MIXER_IS_CONTROL (control), NULL); + g_return_val_if_fail (MATE_MIXER_IS_CONTEXT (context), NULL); - if (control->priv->state != MATE_MIXER_STATE_READY) + if (context->priv->state != MATE_MIXER_STATE_READY) return NULL; - /* This list is cached here and invalidated when the backend notifies us - * about a change */ - if (control->priv->streams == NULL) - control->priv->streams = - mate_mixer_backend_list_streams (MATE_MIXER_BACKEND (control->priv->backend)); - - return (const GList *) control->priv->streams; + return mate_mixer_backend_list_streams (MATE_MIXER_BACKEND (context->priv->backend)); } /** - * mate_mixer_control_list_cached_streams: - * @control: a #MateMixerControl + * mate_mixer_context_list_stored_streams: + * @context: a #MateMixerContext * */ const GList * -mate_mixer_control_list_cached_streams (MateMixerControl *control) +mate_mixer_context_list_stored_streams (MateMixerContext *context) { - g_return_val_if_fail (MATE_MIXER_IS_CONTROL (control), NULL); + g_return_val_if_fail (MATE_MIXER_IS_CONTEXT (context), NULL); - if (control->priv->state != MATE_MIXER_STATE_READY) + if (context->priv->state != MATE_MIXER_STATE_READY) return NULL; - /* This list is cached here and invalidated when the backend notifies us - * about a change */ - if (control->priv->cached_streams == NULL) - control->priv->cached_streams = - mate_mixer_backend_list_cached_streams (MATE_MIXER_BACKEND (control->priv->backend)); - - return (const GList *) control->priv->cached_streams; + return mate_mixer_backend_list_stored_streams (MATE_MIXER_BACKEND (context->priv->backend)); } /** - * mate_mixer_control_get_default_input_stream: - * @control: a #MateMixerControl + * mate_mixer_context_get_default_input_stream: + * @context: a #MateMixerContext * * Gets the default input stream. The returned stream is where sound input is * directed to by default. @@ -1021,19 +998,19 @@ mate_mixer_control_list_cached_streams (MateMixerControl *control) * the system. */ MateMixerStream * -mate_mixer_control_get_default_input_stream (MateMixerControl *control) +mate_mixer_context_get_default_input_stream (MateMixerContext *context) { - g_return_val_if_fail (MATE_MIXER_IS_CONTROL (control), NULL); + g_return_val_if_fail (MATE_MIXER_IS_CONTEXT (context), NULL); - if (control->priv->state != MATE_MIXER_STATE_READY) + if (context->priv->state != MATE_MIXER_STATE_READY) return NULL; - return mate_mixer_backend_get_default_input_stream (control->priv->backend); + return mate_mixer_backend_get_default_input_stream (context->priv->backend); } /** - * mate_mixer_control_set_default_input_stream: - * @control: a #MateMixerControl + * mate_mixer_context_set_default_input_stream: + * @context: a #MateMixerContext * @stream: a #MateMixerStream to set as the default input stream * * Changes the default input stream in the system. The @stream must be an @@ -1042,13 +1019,13 @@ mate_mixer_control_get_default_input_stream (MateMixerControl *control) * Returns: %TRUE on success or %FALSE on failure. */ gboolean -mate_mixer_control_set_default_input_stream (MateMixerControl *control, +mate_mixer_context_set_default_input_stream (MateMixerContext *context, MateMixerStream *stream) { - g_return_val_if_fail (MATE_MIXER_IS_CONTROL (control), FALSE); + g_return_val_if_fail (MATE_MIXER_IS_CONTEXT (context), FALSE); g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), FALSE); - if (control->priv->state != MATE_MIXER_STATE_READY) + if (context->priv->state != MATE_MIXER_STATE_READY) return FALSE; if (MATE_MIXER_IS_CLIENT_STREAM (stream)) { @@ -1060,12 +1037,12 @@ mate_mixer_control_set_default_input_stream (MateMixerControl *control, return FALSE; } - return mate_mixer_backend_set_default_input_stream (control->priv->backend, stream); + return mate_mixer_backend_set_default_input_stream (context->priv->backend, stream); } /** - * mate_mixer_control_get_default_output_stream: - * @control: a #MateMixerControl + * mate_mixer_context_get_default_output_stream: + * @context: a #MateMixerContext * * Gets the default output stream. The returned stream is where sound output is * directed to by default. @@ -1074,19 +1051,19 @@ mate_mixer_control_set_default_input_stream (MateMixerControl *control, * the system. */ MateMixerStream * -mate_mixer_control_get_default_output_stream (MateMixerControl *control) +mate_mixer_context_get_default_output_stream (MateMixerContext *context) { - g_return_val_if_fail (MATE_MIXER_IS_CONTROL (control), NULL); + g_return_val_if_fail (MATE_MIXER_IS_CONTEXT (context), NULL); - if (control->priv->state != MATE_MIXER_STATE_READY) + if (context->priv->state != MATE_MIXER_STATE_READY) return NULL; - return mate_mixer_backend_get_default_output_stream (control->priv->backend); + return mate_mixer_backend_get_default_output_stream (context->priv->backend); } /** - * mate_mixer_control_set_default_output_stream: - * @control: a #MateMixerControl + * mate_mixer_context_set_default_output_stream: + * @context: a #MateMixerContext * @stream: a #MateMixerStream to set as the default output stream * * Changes the default output stream in the system. The @stream must be an @@ -1095,13 +1072,13 @@ mate_mixer_control_get_default_output_stream (MateMixerControl *control) * Returns: %TRUE on success or %FALSE on failure. */ gboolean -mate_mixer_control_set_default_output_stream (MateMixerControl *control, - MateMixerStream *stream) +mate_mixer_context_set_default_output_stream (MateMixerContext *context, + MateMixerStream *stream) { - g_return_val_if_fail (MATE_MIXER_IS_CONTROL (control), FALSE); + g_return_val_if_fail (MATE_MIXER_IS_CONTEXT (context), FALSE); g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), FALSE); - if (control->priv->state != MATE_MIXER_STATE_READY) + if (context->priv->state != MATE_MIXER_STATE_READY) return FALSE; if (MATE_MIXER_IS_CLIENT_STREAM (stream)) { @@ -1113,12 +1090,12 @@ mate_mixer_control_set_default_output_stream (MateMixerControl *control, return FALSE; } - return mate_mixer_backend_set_default_output_stream (control->priv->backend, stream); + return mate_mixer_backend_set_default_output_stream (context->priv->backend, stream); } /** - * mate_mixer_control_get_backend_name: - * @control: a #MateMixerControl + * mate_mixer_context_get_backend_name: + * @context: a #MateMixerContext * * Gets the name of the currently used backend. This function will not * work until connected to a sound system. @@ -1126,19 +1103,19 @@ mate_mixer_control_set_default_output_stream (MateMixerControl *control, * Returns: the name or %NULL on error. */ const gchar * -mate_mixer_control_get_backend_name (MateMixerControl *control) +mate_mixer_context_get_backend_name (MateMixerContext *context) { - g_return_val_if_fail (MATE_MIXER_IS_CONTROL (control), NULL); + g_return_val_if_fail (MATE_MIXER_IS_CONTEXT (context), NULL); - if (control->priv->backend_chosen == FALSE) + if (context->priv->backend_chosen == FALSE) return NULL; - return mate_mixer_backend_module_get_info (control->priv->module)->name; + return mate_mixer_backend_module_get_info (context->priv->module)->name; } /** - * mate_mixer_control_get_backend_type: - * @control: a #MateMixerControl + * mate_mixer_context_get_backend_type: + * @context: a #MateMixerContext * * Gets the type of the currently used backend. This function will not * work until connected to a sound system. @@ -1146,55 +1123,61 @@ mate_mixer_control_get_backend_name (MateMixerControl *control) * Returns: the backend type or %MATE_MIXER_BACKEND_UNKNOWN on error. */ MateMixerBackendType -mate_mixer_control_get_backend_type (MateMixerControl *control) +mate_mixer_context_get_backend_type (MateMixerContext *context) { - g_return_val_if_fail (MATE_MIXER_IS_CONTROL (control), MATE_MIXER_BACKEND_UNKNOWN); + g_return_val_if_fail (MATE_MIXER_IS_CONTEXT (context), MATE_MIXER_BACKEND_UNKNOWN); - if (control->priv->backend_chosen == FALSE) + if (context->priv->backend_chosen == FALSE) return MATE_MIXER_BACKEND_UNKNOWN; - return mate_mixer_backend_module_get_info (control->priv->module)->backend_type; + return mate_mixer_backend_module_get_info (context->priv->module)->backend_type; +} + +/** + * mate_mixer_context_get_backend_flags: + * @context: a #MateMixerContext + */ +MateMixerBackendFlags +mate_mixer_context_get_backend_flags (MateMixerContext *context) +{ + g_return_val_if_fail (MATE_MIXER_IS_CONTEXT (context), MATE_MIXER_BACKEND_NO_FLAGS); + + return mate_mixer_backend_get_flags (context->priv->backend); } static void on_backend_state_notify (MateMixerBackend *backend, GParamSpec *pspec, - MateMixerControl *control) + MateMixerContext *context) { 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); + mate_mixer_backend_module_get_info (context->priv->module)->name); - if (control->priv->backend_chosen == TRUE) { - /* Invalidate cached data when reconnecting */ - free_devices (control); - free_streams (control); - free_cached_streams (control); - } - change_state (control, state); + change_state (context, 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); + mate_mixer_backend_module_get_info (context->priv->module)->name); - change_state (control, state); + change_state (context, 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); + mate_mixer_backend_module_get_info (context->priv->module)->name); - if (control->priv->backend_type == MATE_MIXER_BACKEND_UNKNOWN) { + if (context->priv->backend_type == MATE_MIXER_BACKEND_UNKNOWN) { /* User didn't request a specific backend, so try another one */ - try_next_backend (control); + try_next_backend (context); } else { /* User requested a specific backend and it failed */ - close_control (control); - change_state (control, state); + close_context (context); + change_state (context, state); } break; @@ -1206,11 +1189,9 @@ on_backend_state_notify (MateMixerBackend *backend, static void on_backend_device_added (MateMixerBackend *backend, const gchar *name, - MateMixerControl *control) + MateMixerContext *context) { - free_devices (control); - - g_signal_emit (G_OBJECT (control), + g_signal_emit (G_OBJECT (context), signals[DEVICE_ADDED], 0, name); @@ -1219,11 +1200,9 @@ on_backend_device_added (MateMixerBackend *backend, static void on_backend_device_removed (MateMixerBackend *backend, const gchar *name, - MateMixerControl *control) + MateMixerContext *context) { - free_devices (control); - - g_signal_emit (G_OBJECT (control), + g_signal_emit (G_OBJECT (context), signals[DEVICE_REMOVED], 0, name); @@ -1232,11 +1211,9 @@ on_backend_device_removed (MateMixerBackend *backend, static void on_backend_stream_added (MateMixerBackend *backend, const gchar *name, - MateMixerControl *control) + MateMixerContext *context) { - free_streams (control); - - g_signal_emit (G_OBJECT (control), + g_signal_emit (G_OBJECT (context), signals[STREAM_ADDED], 0, name); @@ -1245,70 +1222,64 @@ on_backend_stream_added (MateMixerBackend *backend, static void on_backend_stream_removed (MateMixerBackend *backend, const gchar *name, - MateMixerControl *control) + MateMixerContext *context) { - free_streams (control); - - g_signal_emit (G_OBJECT (control), + g_signal_emit (G_OBJECT (context), signals[STREAM_REMOVED], 0, name); } static void -on_backend_cached_stream_added (MateMixerBackend *backend, +on_backend_stored_stream_added (MateMixerBackend *backend, const gchar *name, - MateMixerControl *control) + MateMixerContext *context) { - free_cached_streams (control); - - g_signal_emit (G_OBJECT (control), - signals[CACHED_STREAM_ADDED], + g_signal_emit (G_OBJECT (context), + signals[STORED_STREAM_ADDED], 0, name); } static void -on_backend_cached_stream_removed (MateMixerBackend *backend, +on_backend_stored_stream_removed (MateMixerBackend *backend, const gchar *name, - MateMixerControl *control) + MateMixerContext *context) { - free_cached_streams (control); - - g_signal_emit (G_OBJECT (control), - signals[CACHED_STREAM_REMOVED], + g_signal_emit (G_OBJECT (context), + signals[STORED_STREAM_REMOVED], 0, name); } static void -on_backend_default_input_notify (MateMixerBackend *backend, - GParamSpec *pspec, - MateMixerControl *control) +on_backend_default_input_stream_notify (MateMixerBackend *backend, + GParamSpec *pspec, + MateMixerContext *context) { - g_object_notify_by_pspec (G_OBJECT (control), properties[PROP_DEFAULT_INPUT]); + g_object_notify_by_pspec (G_OBJECT (context), properties[PROP_DEFAULT_INPUT_STREAM]); } static void -on_backend_default_output_notify (MateMixerBackend *backend, - GParamSpec *pspec, - MateMixerControl *control) +on_backend_default_output_stream_notify (MateMixerBackend *backend, + GParamSpec *pspec, + MateMixerContext *context) { - g_object_notify_by_pspec (G_OBJECT (control), properties[PROP_DEFAULT_OUTPUT]); + g_object_notify_by_pspec (G_OBJECT (context), properties[PROP_DEFAULT_OUTPUT_STREAM]); } static gboolean -try_next_backend (MateMixerControl *control) +try_next_backend (MateMixerContext *context) { MateMixerBackendModule *module = NULL; MateMixerState state; const GList *modules; const MateMixerBackendInfo *info = NULL; - modules = mate_mixer_get_modules (); + modules = _mate_mixer_get_modules (); while (modules != NULL) { - if (control->priv->module == modules->data) { + if (context->priv->module == modules->data) { /* Found the last tested backend, try to use the next one with a lower * priority unless we have reached the end of the list */ if (modules->next != NULL) @@ -1317,11 +1288,11 @@ try_next_backend (MateMixerControl *control) } modules = modules->next; } - close_control (control); + close_context (context); if (module == NULL) { /* We have tried all the modules and all of them failed */ - change_state (control, MATE_MIXER_STATE_FAILED); + change_state (context, MATE_MIXER_STATE_FAILED); return FALSE; } @@ -1330,143 +1301,99 @@ try_next_backend (MateMixerControl *control) control->priv->module = g_object_ref (module); control->priv->backend = g_object_new (info->g_type, NULL); - mate_mixer_backend_set_data (control->priv->backend, &control->priv->backend_data); + mate_mixer_backend_set_data (context->priv->backend, &context->priv->backend_data); g_debug ("Trying to open backend %s", info->name); /* Try to open this backend and in case of failure keep trying until we find * one that works or reach the end of the list */ - if (mate_mixer_backend_open (control->priv->backend) == FALSE) - return try_next_backend (control); + if (mate_mixer_backend_open (context->priv->backend) == FALSE) + return try_next_backend (context); - state = mate_mixer_backend_get_state (control->priv->backend); + state = mate_mixer_backend_get_state (context->priv->backend); if (G_UNLIKELY (state != MATE_MIXER_STATE_READY && state != MATE_MIXER_STATE_CONNECTING)) { /* This would be a backend bug */ g_warn_if_reached (); - return try_next_backend (control); + return try_next_backend (context); } - g_signal_connect (G_OBJECT (control->priv->backend), + g_signal_connect (G_OBJECT (context->priv->backend), "notify::state", G_CALLBACK (on_backend_state_notify), - control); + context); - change_state (control, state); + change_state (context, state); return TRUE; } static void -change_state (MateMixerControl *control, MateMixerState state) +change_state (MateMixerContext *context, MateMixerState state) { - if (control->priv->state == state) + if (context->priv->state == state) return; - control->priv->state = state; + context->priv->state = state; - if (state == MATE_MIXER_STATE_READY && control->priv->backend_chosen == FALSE) { + if (state == MATE_MIXER_STATE_READY && context->priv->backend_chosen == FALSE) { /* 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; * 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 (G_OBJECT (control->priv->backend), + g_signal_connect (G_OBJECT (context->priv->backend), "device-added", G_CALLBACK (on_backend_device_added), - control); - g_signal_connect (G_OBJECT (control->priv->backend), + context); + g_signal_connect (G_OBJECT (context->priv->backend), "device-removed", G_CALLBACK (on_backend_device_removed), - control); - g_signal_connect (G_OBJECT (control->priv->backend), + context); + g_signal_connect (G_OBJECT (context->priv->backend), "stream-added", G_CALLBACK (on_backend_stream_added), - control); - g_signal_connect (G_OBJECT (control->priv->backend), + context); + g_signal_connect (G_OBJECT (context->priv->backend), "stream-removed", G_CALLBACK (on_backend_stream_removed), - control); - g_signal_connect (G_OBJECT (control->priv->backend), - "cached-stream-added", - G_CALLBACK (on_backend_cached_stream_added), - control); - g_signal_connect (G_OBJECT (control->priv->backend), - "cached-stream-removed", - G_CALLBACK (on_backend_cached_stream_removed), - control); - - g_signal_connect (G_OBJECT (control->priv->backend), + context); + g_signal_connect (G_OBJECT (context->priv->backend), + "stored-stream-added", + G_CALLBACK (on_backend_stored_stream_added), + context); + g_signal_connect (G_OBJECT (context->priv->backend), + "stored-stream-removed", + G_CALLBACK (on_backend_stored_stream_removed), + context); + + g_signal_connect (G_OBJECT (context->priv->backend), "notify::default-input", - G_CALLBACK (on_backend_default_input_notify), - control); - g_signal_connect (G_OBJECT (control->priv->backend), + G_CALLBACK (on_backend_default_input_stream_notify), + context); + g_signal_connect (G_OBJECT (context->priv->backend), "notify::default-output", - G_CALLBACK (on_backend_default_output_notify), - control); + G_CALLBACK (on_backend_default_output_stream_notify), + context); - control->priv->backend_chosen = TRUE; + context->priv->backend_chosen = TRUE; } - g_object_notify_by_pspec (G_OBJECT (control), properties[PROP_STATE]); -} - -static void -close_control (MateMixerControl *control) -{ - free_backend (control); - free_devices (control); - free_streams (control); - free_cached_streams (control); - - g_clear_object (&control->priv->module); - - control->priv->backend_chosen = FALSE; -} - -static void -free_backend (MateMixerControl *control) -{ - if (control->priv->backend == NULL) - return; - - g_signal_handlers_disconnect_by_data (G_OBJECT (control->priv->backend), - control); - - mate_mixer_backend_close (control->priv->backend); - - g_clear_object (&control->priv->backend); + g_object_notify_by_pspec (G_OBJECT (context), properties[PROP_STATE]); } static void -free_devices (MateMixerControl *control) +close_context (MateMixerContext *context) { - if (control->priv->devices == NULL) - return; - - g_list_free_full (control->priv->devices, g_object_unref); + if (context->priv->backend != NULL) { + g_signal_handlers_disconnect_by_data (G_OBJECT (context->priv->backend), + context); - control->priv->devices = NULL; -} - -static void -free_streams (MateMixerControl *control) -{ - if (control->priv->streams == NULL) - return; - - g_list_free_full (control->priv->streams, g_object_unref); - - control->priv->streams = NULL; -} - -static void -free_cached_streams (MateMixerControl *control) -{ - if (control->priv->cached_streams == NULL) - return; + mate_mixer_backend_close (context->priv->backend); + g_clear_object (&context->priv->backend); + } - g_list_free_full (control->priv->cached_streams, g_object_unref); + g_clear_object (&context->priv->module); - control->priv->cached_streams = NULL; + context->priv->backend_chosen = FALSE; } diff --git a/libmatemixer/matemixer-context.h b/libmatemixer/matemixer-context.h new file mode 100644 index 0000000..3370570 --- /dev/null +++ b/libmatemixer/matemixer-context.h @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2014 Michal Ratajsky <[email protected]> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the licence, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef MATEMIXER_CONTEXT_H +#define MATEMIXER_CONTEXT_H + +#include <glib.h> +#include <glib-object.h> + +#include <libmatemixer/matemixer-enums.h> +#include <libmatemixer/matemixer-types.h> + +G_BEGIN_DECLS + +#define MATE_MIXER_TYPE_CONTEXT \ + (mate_mixer_context_get_type ()) +#define MATE_MIXER_CONTEXT(o) \ + (G_TYPE_CHECK_INSTANCE_CAST ((o), MATE_MIXER_TYPE_CONTEXT, MateMixerContext)) +#define MATE_MIXER_IS_CONTEXT(o) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((o), MATE_MIXER_TYPE_CONTEXT)) +#define MATE_MIXER_CONTEXT_CLASS(k) \ + (G_TYPE_CHECK_CLASS_CAST ((k), MATE_MIXER_TYPE_CONTEXT, MateMixerContextClass)) +#define MATE_MIXER_IS_CONTEXT_CLASS(k) \ + (G_TYPE_CHECK_CLASS_TYPE ((k), MATE_MIXER_TYPE_CONTEXT)) +#define MATE_MIXER_CONTEXT_GET_CLASS(o) \ + (G_TYPE_INSTANCE_GET_CLASS ((o), MATE_MIXER_TYPE_CONTEXT, MateMixerContextClass)) + +typedef struct _MateMixerContextClass MateMixerContextClass; +typedef struct _MateMixerContextPrivate MateMixerContextPrivate; + +/** + * MateMixerContext: + * + * The #MateMixerContext structure contains only private data and should only + * be accessed using the provided API. + */ +struct _MateMixerContext +{ + GObject parent; + + /*< private >*/ + MateMixerContextPrivate *priv; +}; + +/** + * MateMixerContextClass: + * + * The class structure of #MateMixerContext. + */ +struct _MateMixerContextClass +{ + GObjectClass parent_class; + + /*< private >*/ + void (*device_added) (MateMixerContext *context, + const gchar *name); + void (*device_removed) (MateMixerContext *context, + const gchar *name); + void (*stream_added) (MateMixerContext *context, + const gchar *name); + void (*stream_removed) (MateMixerContext *context, + const gchar *name); + void (*stored_stream_added) (MateMixerContext *context, + const gchar *name); + void (*stored_stream_removed) (MateMixerContext *context, + const gchar *name); +}; + +GType mate_mixer_context_get_type (void) G_GNUC_CONST; + +MateMixerContext * mate_mixer_context_new (void); + +gboolean mate_mixer_context_set_backend_type (MateMixerContext *context, + MateMixerBackendType backend_type); +gboolean mate_mixer_context_set_app_name (MateMixerContext *context, + const gchar *app_name); +gboolean mate_mixer_context_set_app_id (MateMixerContext *context, + const gchar *app_id); +gboolean mate_mixer_context_set_app_version (MateMixerContext *context, + const gchar *app_version); +gboolean mate_mixer_context_set_app_icon (MateMixerContext *context, + const gchar *app_icon); +gboolean mate_mixer_context_set_server_address (MateMixerContext *context, + const gchar *address); + +gboolean mate_mixer_context_open (MateMixerContext *context); +void mate_mixer_context_close (MateMixerContext *context); + +MateMixerState mate_mixer_context_get_state (MateMixerContext *context); + +MateMixerDevice * mate_mixer_context_get_device (MateMixerContext *context, + const gchar *name); +MateMixerStream * mate_mixer_context_get_stream (MateMixerContext *context, + const gchar *name); +MateMixerStream * mate_mixer_context_get_stored_stream (MateMixerContext *context, + const gchar *name); + +const GList * mate_mixer_context_list_devices (MateMixerContext *context); +const GList * mate_mixer_context_list_streams (MateMixerContext *context); +const GList * mate_mixer_context_list_stored_streams (MateMixerContext *context); + +MateMixerStream * mate_mixer_context_get_default_input_stream (MateMixerContext *context); +gboolean mate_mixer_context_set_default_input_stream (MateMixerContext *context, + MateMixerStream *stream); + +MateMixerStream * mate_mixer_context_get_default_output_stream (MateMixerContext *context); +gboolean mate_mixer_context_set_default_output_stream (MateMixerContext *context, + MateMixerStream *stream); + +const gchar * mate_mixer_context_get_backend_name (MateMixerContext *context); +MateMixerBackendType mate_mixer_context_get_backend_type (MateMixerContext *context); +MateMixerBackendFlags mate_mixer_context_get_backend_flags (MateMixerContext *context); + +G_END_DECLS + +#endif /* MATEMIXER_CONTEXT_H */ diff --git a/libmatemixer/matemixer-control.h b/libmatemixer/matemixer-control.h deleted file mode 100644 index e6d3afa..0000000 --- a/libmatemixer/matemixer-control.h +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright (C) 2014 Michal Ratajsky <[email protected]> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the licence, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef MATEMIXER_CONTROL_H -#define MATEMIXER_CONTROL_H - -#include <glib.h> -#include <glib-object.h> - -#include <libmatemixer/matemixer-device.h> -#include <libmatemixer/matemixer-enums.h> -#include <libmatemixer/matemixer-stream.h> - -G_BEGIN_DECLS - -#define MATE_MIXER_TYPE_CONTROL \ - (mate_mixer_control_get_type ()) -#define MATE_MIXER_CONTROL(o) \ - (G_TYPE_CHECK_INSTANCE_CAST ((o), MATE_MIXER_TYPE_CONTROL, MateMixerControl)) -#define MATE_MIXER_IS_CONTROL(o) \ - (G_TYPE_CHECK_INSTANCE_TYPE ((o), MATE_MIXER_TYPE_CONTROL)) -#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_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)) - -typedef struct _MateMixerControl MateMixerControl; -typedef struct _MateMixerControlClass MateMixerControlClass; -typedef struct _MateMixerControlPrivate MateMixerControlPrivate; - -/** - * MateMixerControl: - * - * The #MateMixerControl structure contains only private data and should only - * be accessed using the provided API. - */ -struct _MateMixerControl -{ - GObject parent; - - /*< private >*/ - MateMixerControlPrivate *priv; -}; - -/** - * MateMixerControlClass: - * - * The class structure of #MateMixerControl. - */ -struct _MateMixerControlClass -{ - GObjectClass parent_class; - - /*< private >*/ - /* Signals */ - void (*device_added) (MateMixerControl *control, - const gchar *name); - void (*device_changed) (MateMixerControl *control, - const gchar *name); - void (*device_removed) (MateMixerControl *control, - const gchar *name); - void (*stream_added) (MateMixerControl *control, - const gchar *name); - void (*stream_changed) (MateMixerControl *control, - const gchar *name); - void (*stream_removed) (MateMixerControl *control, - const gchar *name); - void (*cached_stream_added) (MateMixerControl *control, - const gchar *name); - void (*cached_stream_changed) (MateMixerControl *control, - const gchar *name); - void (*cached_stream_removed) (MateMixerControl *control, - const gchar *name); -}; - -GType mate_mixer_control_get_type (void) G_GNUC_CONST; - -MateMixerControl * mate_mixer_control_new (void); - -gboolean mate_mixer_control_set_backend_type (MateMixerControl *control, - MateMixerBackendType backend_type); -gboolean mate_mixer_control_set_app_name (MateMixerControl *control, - const gchar *app_name); -gboolean mate_mixer_control_set_app_id (MateMixerControl *control, - const gchar *app_id); -gboolean mate_mixer_control_set_app_version (MateMixerControl *control, - const gchar *app_version); -gboolean mate_mixer_control_set_app_icon (MateMixerControl *control, - const gchar *app_icon); -gboolean mate_mixer_control_set_server_address (MateMixerControl *control, - const gchar *address); - -gboolean mate_mixer_control_open (MateMixerControl *control); -void mate_mixer_control_close (MateMixerControl *control); - -MateMixerState mate_mixer_control_get_state (MateMixerControl *control); - -MateMixerDevice * mate_mixer_control_get_device (MateMixerControl *control, - const gchar *name); -MateMixerStream * mate_mixer_control_get_stream (MateMixerControl *control, - const gchar *name); -MateMixerStream * mate_mixer_control_get_cached_stream (MateMixerControl *control, - const gchar *name); - -const GList * mate_mixer_control_list_devices (MateMixerControl *control); -const GList * mate_mixer_control_list_streams (MateMixerControl *control); -const GList * mate_mixer_control_list_cached_streams (MateMixerControl *control); - -MateMixerStream * mate_mixer_control_get_default_input_stream (MateMixerControl *control); -gboolean mate_mixer_control_set_default_input_stream (MateMixerControl *control, - MateMixerStream *stream); - -MateMixerStream * mate_mixer_control_get_default_output_stream (MateMixerControl *control); -gboolean mate_mixer_control_set_default_output_stream (MateMixerControl *control, - MateMixerStream *stream); - -const gchar * mate_mixer_control_get_backend_name (MateMixerControl *control); -MateMixerBackendType mate_mixer_control_get_backend_type (MateMixerControl *control); - -G_END_DECLS - -#endif /* MATEMIXER_CONTROL_H */ diff --git a/libmatemixer/matemixer-device-profile-private.h b/libmatemixer/matemixer-device-profile-private.h index 403c7d7..44f2853 100644 --- a/libmatemixer/matemixer-device-profile-private.h +++ b/libmatemixer/matemixer-device-profile-private.h @@ -24,20 +24,20 @@ G_BEGIN_DECLS -MateMixerDeviceProfile *_mate_mixer_device_profile_new (const gchar *name, - const gchar *description, - guint priority, - guint input_streams, - guint output_streams); - -gboolean _mate_mixer_device_profile_update_description (MateMixerDeviceProfile *profile, - const gchar *description); -gboolean _mate_mixer_device_profile_update_priority (MateMixerDeviceProfile *profile, - guint priority); -gboolean _mate_mixer_device_profile_update_num_input_streams (MateMixerDeviceProfile *profile, - guint num); -gboolean _mate_mixer_device_profile_update_num_output_streams (MateMixerDeviceProfile *profile, - guint num); +MateMixerDeviceProfile *_mate_mixer_device_profile_new (const gchar *name, + const gchar *description, + guint priority, + guint input_streams, + guint output_streams); + +gboolean _mate_mixer_device_profile_set_label (MateMixerDeviceProfile *profile, + const gchar *label); +gboolean _mate_mixer_device_profile_set_priority (MateMixerDeviceProfile *profile, + guint priority); +gboolean _mate_mixer_device_profile_set_num_input_streams (MateMixerDeviceProfile *profile, + guint num); +gboolean _mate_mixer_device_profile_set_num_output_streams (MateMixerDeviceProfile *profile, + guint num); G_END_DECLS diff --git a/libmatemixer/matemixer-device-profile.c b/libmatemixer/matemixer-device-profile.c index 0485740..d841ff2 100644 --- a/libmatemixer/matemixer-device-profile.c +++ b/libmatemixer/matemixer-device-profile.c @@ -30,7 +30,7 @@ struct _MateMixerDeviceProfilePrivate { gchar *name; - gchar *description; + gchar *label; guint priority; guint num_input_streams; guint num_output_streams; @@ -39,7 +39,7 @@ struct _MateMixerDeviceProfilePrivate enum { PROP_0, PROP_NAME, - PROP_DESCRIPTION, + PROP_LABEL, PROP_PRIORITY, PROP_NUM_INPUT_STREAMS, PROP_NUM_OUTPUT_STREAMS, @@ -83,10 +83,10 @@ mate_mixer_device_profile_class_init (MateMixerDeviceProfileClass *klass) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - properties[PROP_DESCRIPTION] = - g_param_spec_string ("description", - "Description", - "Description of the profile", + properties[PROP_LABEL] = + g_param_spec_string ("label", + "Label", + "Label of the profile", NULL, G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | @@ -144,18 +144,23 @@ mate_mixer_device_profile_get_property (GObject *object, case PROP_NAME: g_value_set_string (value, profile->priv->name); break; - case PROP_DESCRIPTION: - g_value_set_string (value, profile->priv->description); + + case PROP_LABEL: + g_value_set_string (value, profile->priv->label); break; + case PROP_PRIORITY: g_value_set_uint (value, profile->priv->priority); break; + case PROP_NUM_INPUT_STREAMS: g_value_set_uint (value, profile->priv->num_input_streams); break; + case PROP_NUM_OUTPUT_STREAMS: g_value_set_uint (value, profile->priv->num_output_streams); break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); break; @@ -177,19 +182,24 @@ mate_mixer_device_profile_set_property (GObject *object, /* Construct-only string */ profile->priv->name = g_strdup (g_value_get_string (value)); break; - case PROP_DESCRIPTION: + + case PROP_LABEL: /* Construct-only string */ - profile->priv->description = g_strdup (g_value_get_string (value)); + profile->priv->label = g_strdup (g_value_get_string (value)); break; + case PROP_PRIORITY: profile->priv->priority = g_value_get_uint (value); break; + case PROP_NUM_INPUT_STREAMS: profile->priv->num_input_streams = g_value_get_uint (value); break; + case PROP_NUM_OUTPUT_STREAMS: profile->priv->num_output_streams = g_value_get_uint (value); break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); break; @@ -212,7 +222,7 @@ mate_mixer_device_profile_finalize (GObject *object) profile = MATE_MIXER_DEVICE_PROFILE (object); g_free (profile->priv->name); - g_free (profile->priv->description); + g_free (profile->priv->label); G_OBJECT_CLASS (mate_mixer_device_profile_parent_class)->finalize (object); } @@ -230,15 +240,15 @@ mate_mixer_device_profile_get_name (MateMixerDeviceProfile *profile) } /** - * mate_mixer_device_profile_get_description: + * mate_mixer_device_profile_get_label: * @profile: a #MateMixerDeviceProfile */ const gchar * -mate_mixer_device_profile_get_description (MateMixerDeviceProfile *profile) +mate_mixer_device_profile_get_label (MateMixerDeviceProfile *profile) { g_return_val_if_fail (MATE_MIXER_IS_DEVICE_PROFILE (profile), NULL); - return profile->priv->description; + return profile->priv->label; } /** @@ -279,14 +289,14 @@ mate_mixer_device_profile_get_num_output_streams (MateMixerDeviceProfile *profil MateMixerDeviceProfile * _mate_mixer_device_profile_new (const gchar *name, - const gchar *description, + const gchar *label, guint priority, guint input_streams, guint output_streams) { return g_object_new (MATE_MIXER_TYPE_DEVICE_PROFILE, "name", name, - "description", description, + "label", label, "priority", priority, "num-input-streams", input_streams, "num-output-streams", output_streams, @@ -294,17 +304,17 @@ _mate_mixer_device_profile_new (const gchar *name, } gboolean -_mate_mixer_device_profile_update_description (MateMixerDeviceProfile *profile, - const gchar *description) +_mate_mixer_device_profile_set_label (MateMixerDeviceProfile *profile, + const gchar *label) { g_return_val_if_fail (MATE_MIXER_IS_DEVICE_PROFILE (profile), FALSE); - if (g_strcmp0 (profile->priv->description, description) != 0) { - g_free (profile->priv->description); + if (g_strcmp0 (profile->priv->label, label) != 0) { + g_free (profile->priv->label); - profile->priv->description = g_strdup (description); + profile->priv->label = g_strdup (label); - g_object_notify_by_pspec (G_OBJECT (profile), properties[PROP_DESCRIPTION]); + g_object_notify_by_pspec (G_OBJECT (profile), properties[PROP_LABEL]); return TRUE; } @@ -312,8 +322,8 @@ _mate_mixer_device_profile_update_description (MateMixerDeviceProfile *profile, } gboolean -_mate_mixer_device_profile_update_priority (MateMixerDeviceProfile *profile, - guint priority) +_mate_mixer_device_profile_set_priority (MateMixerDeviceProfile *profile, + guint priority) { g_return_val_if_fail (MATE_MIXER_IS_DEVICE_PROFILE (profile), FALSE); @@ -328,8 +338,8 @@ _mate_mixer_device_profile_update_priority (MateMixerDeviceProfile *profile, } gboolean -_mate_mixer_device_profile_update_num_input_streams (MateMixerDeviceProfile *profile, - guint num) +_mate_mixer_device_profile_set_num_input_streams (MateMixerDeviceProfile *profile, + guint num) { g_return_val_if_fail (MATE_MIXER_IS_DEVICE_PROFILE (profile), FALSE); @@ -344,8 +354,8 @@ _mate_mixer_device_profile_update_num_input_streams (MateMixerDeviceProfile *pro } gboolean -_mate_mixer_device_profile_update_num_output_streams (MateMixerDeviceProfile *profile, - guint num) +_mate_mixer_device_profile_set_num_output_streams (MateMixerDeviceProfile *profile, + guint num) { g_return_val_if_fail (MATE_MIXER_IS_DEVICE_PROFILE (profile), FALSE); diff --git a/libmatemixer/matemixer-device-profile.h b/libmatemixer/matemixer-device-profile.h index e8fae19..8e4221a 100644 --- a/libmatemixer/matemixer-device-profile.h +++ b/libmatemixer/matemixer-device-profile.h @@ -20,6 +20,7 @@ #include <glib.h> #include <glib-object.h> +#include <libmatemixer/matemixer-types.h> G_BEGIN_DECLS @@ -36,7 +37,6 @@ G_BEGIN_DECLS #define MATE_MIXER_DEVICE_PROFILE_GET_CLASS(o) \ (G_TYPE_INSTANCE_GET_CLASS ((o), MATE_MIXER_TYPE_DEVICE_PROFILE, MateMixerDeviceProfileClass)) -typedef struct _MateMixerDeviceProfile MateMixerDeviceProfile; typedef struct _MateMixerDeviceProfileClass MateMixerDeviceProfileClass; typedef struct _MateMixerDeviceProfilePrivate MateMixerDeviceProfilePrivate; @@ -56,8 +56,9 @@ struct _MateMixerDeviceProfileClass GType mate_mixer_device_profile_get_type (void) G_GNUC_CONST; const gchar *mate_mixer_device_profile_get_name (MateMixerDeviceProfile *profile); -const gchar *mate_mixer_device_profile_get_description (MateMixerDeviceProfile *profile); +const gchar *mate_mixer_device_profile_get_label (MateMixerDeviceProfile *profile); guint mate_mixer_device_profile_get_priority (MateMixerDeviceProfile *profile); + guint mate_mixer_device_profile_get_num_input_streams (MateMixerDeviceProfile *profile); guint mate_mixer_device_profile_get_num_output_streams (MateMixerDeviceProfile *profile); diff --git a/libmatemixer/matemixer-device.c b/libmatemixer/matemixer-device.c index 0406709..229110f 100644 --- a/libmatemixer/matemixer-device.c +++ b/libmatemixer/matemixer-device.c @@ -15,12 +15,14 @@ * License along with this library; if not, see <http://www.gnu.org/licenses/>. */ +#include <string.h> #include <glib.h> #include <glib-object.h> #include "matemixer-device.h" #include "matemixer-device-profile.h" -#include "matemixer-port.h" +#include "matemixer-stream.h" +#include "matemixer-switch.h" /** * SECTION:matemixer-device @@ -28,42 +30,270 @@ * @include: libmatemixer/matemixer.h */ -G_DEFINE_INTERFACE (MateMixerDevice, mate_mixer_device, G_TYPE_OBJECT) +struct _MateMixerDevicePrivate +{ + gchar *name; + gchar *label; + gchar *icon; + GList *streams; + GList *switches; + GList *profiles; + MateMixerDeviceProfile *profile; +}; + +enum { + PROP_0, + PROP_NAME, + PROP_LABEL, + PROP_ICON, + PROP_ACTIVE_PROFILE, + N_PROPERTIES +}; + +static GParamSpec *properties[N_PROPERTIES] = { NULL, }; + +enum { + STREAM_ADDED, + STREAM_REMOVED, + SWITCH_ADDED, + SWITCH_REMOVED, + N_SIGNALS +}; + +static guint signals[N_SIGNALS] = { 0, }; + +static void mate_mixer_device_class_init (MateMixerDeviceClass *klass); + +static void mate_mixer_device_get_property (GObject *object, + guint param_id, + GValue *value, + GParamSpec *pspec); +static void mate_mixer_device_set_property (GObject *object, + guint param_id, + const GValue *value, + GParamSpec *pspec); + +static void mate_mixer_device_init (MateMixerDevice *device); +static void mate_mixer_device_dispose (GObject *object); +static void mate_mixer_device_finalize (GObject *object); + +G_DEFINE_ABSTRACT_TYPE (MateMixerDevice, mate_mixer_device, G_TYPE_OBJECT) + +static MateMixerStream * mate_mixer_device_real_get_stream (MateMixerDevice *device, + const gchar *name); +static MateMixerSwitch * mate_mixer_device_real_get_switch (MateMixerDevice *device, + const gchar *name); +static MateMixerDeviceProfile *mate_mixer_device_real_get_profile (MateMixerDevice *device, + const gchar *name); + +static void +mate_mixer_device_class_init (MateMixerDeviceClass *klass) +{ + GObjectClass *object_class; + + klass->get_stream = mate_mixer_device_real_get_stream; + klass->get_switch = mate_mixer_device_real_get_switch; + klass->get_profile = mate_mixer_device_real_get_profile; + + object_class = G_OBJECT_CLASS (klass); + object_class->dispose = mate_mixer_device_dispose; + object_class->finalize = mate_mixer_device_finalize; + object_class->get_property = mate_mixer_device_get_property; + object_class->set_property = mate_mixer_device_set_property; + + properties[PROP_NAME] = + g_param_spec_string ("name", + "Name", + "Name of the device", + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + + properties[PROP_LABEL] = + g_param_spec_string ("label", + "Label", + "Label of the device", + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + + properties[PROP_ICON] = + g_param_spec_string ("icon", + "Icon", + "Name of the sound device icon", + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + + properties[PROP_ACTIVE_PROFILE] = + g_param_spec_object ("active-profile", + "Active profile", + "The currently active profile of the device", + MATE_MIXER_TYPE_DEVICE_PROFILE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties (object_class, N_PROPERTIES, properties); + + signals[STREAM_ADDED] = + g_signal_new ("stream-added", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (MateMixerDeviceClass, stream_added), + 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 (MateMixerDeviceClass, stream_removed), + NULL, + NULL, + g_cclosure_marshal_VOID__STRING, + G_TYPE_NONE, + 1, + G_TYPE_STRING); + + signals[SWITCH_ADDED] = + g_signal_new ("switch-added", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (MateMixerDeviceClass, switch_added), + NULL, + NULL, + g_cclosure_marshal_VOID__STRING, + G_TYPE_NONE, + 1, + G_TYPE_STRING); + + signals[SWITCH_REMOVED] = + g_signal_new ("switch-removed", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (MateMixerDeviceClass, switch_removed), + NULL, + NULL, + g_cclosure_marshal_VOID__STRING, + G_TYPE_NONE, + 1, + G_TYPE_STRING); + + g_type_class_add_private (object_class, sizeof (MateMixerDevicePrivate)); +} + +static void +mate_mixer_device_get_property (GObject *object, + guint param_id, + GValue *value, + GParamSpec *pspec) +{ + MateMixerDevice *device; + + device = MATE_MIXER_DEVICE (object); + + switch (param_id) { + case PROP_NAME: + g_value_set_string (value, device->priv->name); + break; + case PROP_LABEL: + g_value_set_string (value, device->priv->label); + break; + case PROP_ICON: + g_value_set_string (value, device->priv->icon); + break; + case PROP_ACTIVE_PROFILE: + g_value_set_object (value, device->priv->profile); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); + break; + } +} + +static void +mate_mixer_device_set_property (GObject *object, + guint param_id, + const GValue *value, + GParamSpec *pspec) +{ + MateMixerDevice *device; + + device = MATE_MIXER_DEVICE (object); + + switch (param_id) { + case PROP_NAME: + /* Construct-only string */ + device->priv->name = g_strdup (g_value_get_string (value)); + break; + case PROP_LABEL: + /* Construct-only string */ + device->priv->label = g_strdup (g_value_get_string (value)); + break; + case PROP_ICON: + /* Construct-only string */ + device->priv->icon = g_strdup (g_value_get_string (value)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); + break; + } +} static void -mate_mixer_device_default_init (MateMixerDeviceInterface *iface) -{ - g_object_interface_install_property (iface, - g_param_spec_string ("name", - "Name", - "Name of the device", - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); - - g_object_interface_install_property (iface, - g_param_spec_string ("description", - "Description", - "Description of the device", - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); - - g_object_interface_install_property (iface, - g_param_spec_string ("icon", - "Icon", - "Name of the sound device icon", - NULL, - G_PARAM_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 device", - MATE_MIXER_TYPE_DEVICE_PROFILE, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); +mate_mixer_device_init (MateMixerDevice *device) +{ + device->priv = G_TYPE_INSTANCE_GET_PRIVATE (device, + MATE_MIXER_TYPE_DEVICE, + MateMixerDevicePrivate); +} + +static void +mate_mixer_device_dispose (GObject *object) +{ + MateMixerDevice *device; + + device = MATE_MIXER_DEVICE (object); + + if (device->priv->streams != NULL) { + g_list_free_full (device->priv->streams, g_object_unref); + device->priv->streams = NULL; + } + if (device->priv->switches != NULL) { + g_list_free_full (device->priv->switches, g_object_unref); + device->priv->switches = NULL; + } + if (device->priv->profiles != NULL) { + g_list_free_full (device->priv->profiles, g_object_unref); + device->priv->profiles = NULL; + } + + g_clear_object (&device->priv->profile); + + G_OBJECT_CLASS (mate_mixer_device_parent_class)->dispose (object); +} + +static void +mate_mixer_device_finalize (GObject *object) +{ + MateMixerDevice *device; + + device = MATE_MIXER_DEVICE (object); + + g_free (device->priv->name); + g_free (device->priv->label); + g_free (device->priv->icon); + + G_OBJECT_CLASS (mate_mixer_device_parent_class)->finalize (object); } /** @@ -75,8 +305,7 @@ mate_mixer_device_get_name (MateMixerDevice *device) { g_return_val_if_fail (MATE_MIXER_IS_DEVICE (device), NULL); - /* Implementation required */ - return MATE_MIXER_DEVICE_GET_INTERFACE (device)->get_name (device); + return device->priv->name; } /** @@ -84,18 +313,11 @@ mate_mixer_device_get_name (MateMixerDevice *device) * @device: a #MateMixerDevice */ const gchar * -mate_mixer_device_get_description (MateMixerDevice *device) +mate_mixer_device_get_label (MateMixerDevice *device) { - MateMixerDeviceInterface *iface; - g_return_val_if_fail (MATE_MIXER_IS_DEVICE (device), NULL); - iface = MATE_MIXER_DEVICE_GET_INTERFACE (device); - - if (iface->get_description) - return iface->get_description (device); - - return NULL; + return device->priv->label; } /** @@ -105,77 +327,80 @@ mate_mixer_device_get_description (MateMixerDevice *device) const gchar * mate_mixer_device_get_icon (MateMixerDevice *device) { - MateMixerDeviceInterface *iface; - g_return_val_if_fail (MATE_MIXER_IS_DEVICE (device), NULL); - iface = MATE_MIXER_DEVICE_GET_INTERFACE (device); - - if (iface->get_icon) - return iface->get_icon (device); - - return NULL; + return device->priv->icon; } /** - * mate_mixer_device_get_port: + * mate_mixer_device_get_profile: * @device: a #MateMixerDevice - * @name: a port name + * @name: a profile name */ -MateMixerPort * -mate_mixer_device_get_port (MateMixerDevice *device, const gchar *name) +MateMixerDeviceProfile * +mate_mixer_device_get_profile (MateMixerDevice *device, const gchar *name) { - MateMixerDeviceInterface *iface; - - g_return_val_if_fail (MATE_MIXER_IS_DEVICE (device), NULL); - g_return_val_if_fail (name != NULL, NULL); - - iface = MATE_MIXER_DEVICE_GET_INTERFACE (device); - - if (iface->get_port) - return iface->get_port (device, name); + return MATE_MIXER_DEVICE_GET_CLASS (device)->get_profile (device, name); +} - return NULL; +/** + * mate_mixer_device_get_stream: + * @device: a #MateMixerDevice + * @name: a profile name + */ +MateMixerStream * +mate_mixer_device_get_stream (MateMixerDevice *device, const gchar *name) +{ + return MATE_MIXER_DEVICE_GET_CLASS (device)->get_stream (device, name); } /** - * mate_mixer_device_get_profile: + * mate_mixer_device_get_switch: * @device: a #MateMixerDevice * @name: a profile name */ -MateMixerDeviceProfile * -mate_mixer_device_get_profile (MateMixerDevice *device, const gchar *name) +MateMixerSwitch * +mate_mixer_device_get_switch (MateMixerDevice *device, const gchar *name) { - MateMixerDeviceInterface *iface; + return MATE_MIXER_DEVICE_GET_CLASS (device)->get_switch (device, name); +} +/** + * mate_mixer_device_list_streams: + * @device: a #MateMixerDevice + */ +const GList * +mate_mixer_device_list_streams (MateMixerDevice *device) +{ g_return_val_if_fail (MATE_MIXER_IS_DEVICE (device), NULL); - g_return_val_if_fail (name != NULL, NULL); - iface = MATE_MIXER_DEVICE_GET_INTERFACE (device); + if (device->priv->streams == NULL) { + MateMixerDeviceClass *klass = MATE_MIXER_DEVICE_GET_CLASS (device); - if (iface->get_profile) - return iface->get_profile (device, name); + if (klass->list_streams != NULL) + device->priv->streams = klass->list_streams (device); + } - return NULL; + return (const GList *) device->priv->streams; } /** - * mate_mixer_device_list_ports: + * mate_mixer_device_list_switches: * @device: a #MateMixerDevice */ const GList * -mate_mixer_device_list_ports (MateMixerDevice *device) +mate_mixer_device_list_switches (MateMixerDevice *device) { - MateMixerDeviceInterface *iface; - g_return_val_if_fail (MATE_MIXER_IS_DEVICE (device), NULL); - iface = MATE_MIXER_DEVICE_GET_INTERFACE (device); + if (device->priv->switches == NULL) { + MateMixerDeviceClass *klass = MATE_MIXER_DEVICE_GET_CLASS (device); - if (iface->list_ports) - return iface->list_ports (device); + if (klass->list_switches != NULL) + device->priv->switches = klass->list_switches (device); + } - return NULL; + return (const GList *) device->priv->switches; } /** @@ -185,16 +410,16 @@ mate_mixer_device_list_ports (MateMixerDevice *device) const GList * mate_mixer_device_list_profiles (MateMixerDevice *device) { - MateMixerDeviceInterface *iface; - g_return_val_if_fail (MATE_MIXER_IS_DEVICE (device), NULL); - iface = MATE_MIXER_DEVICE_GET_INTERFACE (device); + if (device->priv->profiles == NULL) { + MateMixerDeviceClass *klass = MATE_MIXER_DEVICE_GET_CLASS (device); - if (iface->list_profiles) - return iface->list_profiles (device); + if (klass->list_profiles != NULL) + device->priv->profiles = klass->list_profiles (device); + } - return NULL; + return (const GList *) device->priv->profiles; } /** @@ -204,16 +429,9 @@ mate_mixer_device_list_profiles (MateMixerDevice *device) MateMixerDeviceProfile * mate_mixer_device_get_active_profile (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_active_profile) - return iface->get_active_profile (device); - - return NULL; + return device->priv->profile; } /** @@ -225,15 +443,83 @@ gboolean mate_mixer_device_set_active_profile (MateMixerDevice *device, MateMixerDeviceProfile *profile) { - MateMixerDeviceInterface *iface; - g_return_val_if_fail (MATE_MIXER_IS_DEVICE (device), FALSE); g_return_val_if_fail (MATE_MIXER_IS_DEVICE_PROFILE (profile), FALSE); - iface = MATE_MIXER_DEVICE_GET_INTERFACE (device); + if (profile != device->priv->profile) { + MateMixerDeviceClass *klass; + + klass = MATE_MIXER_DEVICE_GET_CLASS (device); + + if (klass->set_active_profile == NULL || + klass->set_active_profile (device, profile) == FALSE) + return FALSE; - if (iface->set_active_profile) - return iface->set_active_profile (device, profile); + if (G_LIKELY (device->priv->profile != NULL)) + g_object_unref (device->priv->profile); - return FALSE; + device->priv->profile = g_object_ref (profile); + } + + return TRUE; +} + +static MateMixerStream * +mate_mixer_device_real_get_stream (MateMixerDevice *device, const gchar *name) +{ + const GList *list; + + g_return_val_if_fail (MATE_MIXER_IS_DEVICE (device), NULL); + g_return_val_if_fail (name != NULL, NULL); + + list = mate_mixer_device_list_streams (device); + while (list != NULL) { + MateMixerStream *stream = MATE_MIXER_STREAM (list->data); + + if (strcmp (name, mate_mixer_stream_get_name (stream)) == 0) + return stream; + + list = list->next; + } + return NULL; +} + +static MateMixerSwitch * +mate_mixer_device_real_get_switch (MateMixerDevice *device, const gchar *name) +{ + const GList *list; + + g_return_val_if_fail (MATE_MIXER_IS_DEVICE (device), NULL); + g_return_val_if_fail (name != NULL, NULL); + + list = mate_mixer_device_list_switches (device); + while (list != NULL) { + MateMixerSwitch *swtch = MATE_MIXER_SWITCH (list->data); + + if (strcmp (name, mate_mixer_switch_get_name (swtch)) == 0) + return swtch; + + list = list->next; + } + return NULL; +} + +static MateMixerDeviceProfile * +mate_mixer_device_real_get_profile (MateMixerDevice *device, const gchar *name) +{ + const GList *list; + + g_return_val_if_fail (MATE_MIXER_IS_DEVICE (device), NULL); + g_return_val_if_fail (name != NULL, NULL); + + list = mate_mixer_device_list_profiles (device); + while (list != NULL) { + MateMixerDeviceProfile *profile = MATE_MIXER_DEVICE_PROFILE (list->data); + + if (strcmp (name, mate_mixer_device_profile_get_name (profile)) == 0) + return profile; + + list = list->next; + } + return NULL; } diff --git a/libmatemixer/matemixer-device.h b/libmatemixer/matemixer-device.h index 340496b..885460c 100644 --- a/libmatemixer/matemixer-device.h +++ b/libmatemixer/matemixer-device.h @@ -21,8 +21,7 @@ #include <glib.h> #include <glib-object.h> -#include <libmatemixer/matemixer-device-profile.h> -#include <libmatemixer/matemixer-port.h> +#include "matemixer-types.h" G_BEGIN_DECLS @@ -32,48 +31,72 @@ G_BEGIN_DECLS (G_TYPE_CHECK_INSTANCE_CAST ((o), MATE_MIXER_TYPE_DEVICE, MateMixerDevice)) #define MATE_MIXER_IS_DEVICE(o) \ (G_TYPE_CHECK_INSTANCE_TYPE ((o), MATE_MIXER_TYPE_DEVICE)) -#define MATE_MIXER_DEVICE_GET_INTERFACE(o) \ - (G_TYPE_INSTANCE_GET_INTERFACE ((o), MATE_MIXER_TYPE_DEVICE, MateMixerDeviceInterface)) +#define MATE_MIXER_DEVICE_CLASS(k) \ + (G_TYPE_CHECK_CLASS_CAST ((k), MATE_MIXER_TYPE_DEVICE, MateMixerDeviceClass)) +#define MATE_MIXER_IS_DEVICE_CLASS(k) \ + (G_TYPE_CHECK_CLASS_TYPE ((k), MATE_MIXER_TYPE_DEVICE)) +#define MATE_MIXER_DEVICE_GET_CLASS(o) \ + (G_TYPE_INSTANCE_GET_CLASS ((o), MATE_MIXER_TYPE_DEVICE, MateMixerDeviceClass)) -typedef struct _MateMixerDevice MateMixerDevice; /* dummy object */ -typedef struct _MateMixerDeviceInterface MateMixerDeviceInterface; +typedef struct _MateMixerDeviceClass MateMixerDeviceClass; +typedef struct _MateMixerDevicePrivate MateMixerDevicePrivate; -struct _MateMixerDeviceInterface +struct _MateMixerDevice { - GTypeInterface parent_iface; + GObject object; + + /*< private >*/ + MateMixerDevicePrivate *priv; +}; + +struct _MateMixerDeviceClass +{ + GObjectClass parent_class; /*< private >*/ - /* Virtual table */ - const gchar *(*get_name) (MateMixerDevice *device); - const gchar *(*get_description) (MateMixerDevice *device); - const gchar *(*get_icon) (MateMixerDevice *device); - MateMixerPort *(*get_port) (MateMixerDevice *device, + MateMixerStream *(*get_stream) (MateMixerDevice *device, + const gchar *name); + MateMixerSwitch *(*get_switch) (MateMixerDevice *device, const gchar *name); MateMixerDeviceProfile *(*get_profile) (MateMixerDevice *device, const gchar *name); - const GList *(*list_streams) (MateMixerDevice *device); - const GList *(*list_ports) (MateMixerDevice *device); - const GList *(*list_profiles) (MateMixerDevice *device); + GList *(*list_streams) (MateMixerDevice *device); + GList *(*list_switches) (MateMixerDevice *device); + GList *(*list_profiles) (MateMixerDevice *device); - MateMixerDeviceProfile *(*get_active_profile) (MateMixerDevice *device); gboolean (*set_active_profile) (MateMixerDevice *device, MateMixerDeviceProfile *profile); + + /* Signals */ + void (*stream_added) (MateMixerDevice *device, + const gchar *name); + void (*stream_removed) (MateMixerDevice *device, + const gchar *name); + void (*switch_added) (MateMixerDevice *device, + const gchar *name); + void (*switch_removed) (MateMixerDevice *device, + const gchar *name); }; 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_label (MateMixerDevice *device); const gchar * mate_mixer_device_get_icon (MateMixerDevice *device); -MateMixerPort * mate_mixer_device_get_port (MateMixerDevice *device, +MateMixerStream * mate_mixer_device_get_stream (MateMixerDevice *device, const gchar *name); + +MateMixerSwitch * mate_mixer_device_get_switch (MateMixerDevice *device, + const gchar *name); + MateMixerDeviceProfile *mate_mixer_device_get_profile (MateMixerDevice *device, const gchar *name); -const GList * mate_mixer_device_list_ports (MateMixerDevice *device); +const GList * mate_mixer_device_list_streams (MateMixerDevice *device); +const GList * mate_mixer_device_list_switches (MateMixerDevice *device); const GList * mate_mixer_device_list_profiles (MateMixerDevice *device); MateMixerDeviceProfile *mate_mixer_device_get_active_profile (MateMixerDevice *device); diff --git a/libmatemixer/matemixer-enum-types.c b/libmatemixer/matemixer-enum-types.c index 339b673..035be3d 100644 --- a/libmatemixer/matemixer-enum-types.c +++ b/libmatemixer/matemixer-enum-types.c @@ -94,14 +94,7 @@ mate_mixer_stream_flags_get_type (void) { MATE_MIXER_STREAM_INPUT, "MATE_MIXER_STREAM_INPUT", "input" }, { MATE_MIXER_STREAM_OUTPUT, "MATE_MIXER_STREAM_OUTPUT", "output" }, { MATE_MIXER_STREAM_CLIENT, "MATE_MIXER_STREAM_CLIENT", "client" }, - { MATE_MIXER_STREAM_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_SET_VOLUME, "MATE_MIXER_STREAM_CAN_SET_VOLUME", "can-set-volume" }, - { MATE_MIXER_STREAM_CAN_BALANCE, "MATE_MIXER_STREAM_CAN_BALANCE", "can-balance" }, - { MATE_MIXER_STREAM_CAN_FADE, "MATE_MIXER_STREAM_CAN_FADE", "can-fade" }, { MATE_MIXER_STREAM_CAN_SUSPEND, "MATE_MIXER_STREAM_CAN_SUSPEND", "can-suspend" }, { 0, NULL, NULL } }; @@ -133,6 +126,54 @@ mate_mixer_stream_state_get_type (void) } GType +mate_mixer_stream_control_flags_get_type (void) +{ + static GType etype = 0; + + if (etype == 0) { + static const GFlagsValue values[] = { + { MATE_MIXER_STREAM_CONTROL_NO_FLAGS, "MATE_MIXER_STREAM_CONTROL_NO_FLAGS", "no-flags" }, + { MATE_MIXER_STREAM_CONTROL_HAS_MUTE, "MATE_MIXER_STREAM_CONTROL_HAS_MUTE", "has-mute" }, + { MATE_MIXER_STREAM_CONTROL_HAS_VOLUME, "MATE_MIXER_STREAM_CONTROL_HAS_VOLUME", "has-volume" }, + { MATE_MIXER_STREAM_CONTROL_HAS_DECIBEL, "MATE_MIXER_STREAM_CONTROL_HAS_DECIBEL", "has-decibel" }, + { MATE_MIXER_STREAM_CONTROL_HAS_FLAT_VOLUME, "MATE_MIXER_STREAM_CONTROL_HAS_FLAT_VOLUME", "has-flat-volume" }, + { MATE_MIXER_STREAM_CONTROL_CAN_SET_VOLUME, "MATE_MIXER_STREAM_CONTROL_CAN_SET_VOLUME", "can-set-volume" }, + { MATE_MIXER_STREAM_CONTROL_CAN_BALANCE, "MATE_MIXER_STREAM_CONTROL_CAN_BALANCE", "can-balance" }, + { MATE_MIXER_STREAM_CONTROL_CAN_FADE, "MATE_MIXER_STREAM_CONTROL_CAN_FADE", "can-fade" }, + { 0, NULL, NULL } + }; + etype = g_flags_register_static ( + g_intern_static_string ("MateMixerStreamControlFlags"), + values); + } + return etype; +} + +GType +mate_mixer_stream_control_role_get_type (void) +{ + static GType etype = 0; + + if (etype == 0) { + static const GEnumValue values[] = { + { MATE_MIXER_STREAM_CONTROL_ROLE_UNKNOWN, "MATE_MIXER_STREAM_CONTROL_ROLE_UNKNOWN", "unknown" }, + { MATE_MIXER_STREAM_CONTROL_ROLE_MASTER, "MATE_MIXER_STREAM_CONTROL_ROLE_MASTER", "master" }, + { MATE_MIXER_STREAM_CONTROL_ROLE_PORT, "MATE_MIXER_STREAM_CONTROL_ROLE_PORT", "port" }, + { MATE_MIXER_STREAM_CONTROL_ROLE_PCM, "MATE_MIXER_STREAM_CONTROL_ROLE_PCM", "pcm" }, + { MATE_MIXER_STREAM_CONTROL_ROLE_BASS, "MATE_MIXER_STREAM_CONTROL_ROLE_BASS", "bass" }, + { MATE_MIXER_STREAM_CONTROL_ROLE_TREBLE, "MATE_MIXER_STREAM_CONTROL_ROLE_TREBLE", "treble" }, + { MATE_MIXER_STREAM_CONTROL_ROLE_CD, "MATE_MIXER_STREAM_CONTROL_ROLE_CD", "cd" }, + { MATE_MIXER_STREAM_CONTROL_ROLE_SPEAKER, "MATE_MIXER_STREAM_CONTROL_ROLE_SPEAKER", "speaker" }, + { 0, NULL, NULL } + }; + etype = g_enum_register_static ( + g_intern_static_string ("MateMixerStreamControlRole"), + values); + } + return etype; +} + +GType mate_mixer_client_stream_flags_get_type (void) { static GType etype = 0; diff --git a/libmatemixer/matemixer-enum-types.h b/libmatemixer/matemixer-enum-types.h index 03c1297..f2193be 100644 --- a/libmatemixer/matemixer-enum-types.h +++ b/libmatemixer/matemixer-enum-types.h @@ -43,6 +43,12 @@ GType mate_mixer_stream_flags_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_STREAM_CONTROL_FLAGS (mate_mixer_stream_control_flags_get_type ()) +GType mate_mixer_stream_control_flags_get_type (void) G_GNUC_CONST; + +#define MATE_MIXER_TYPE_STREAM_CONTROL_ROLE (mate_mixer_stream_control_role_get_type ()) +GType mate_mixer_stream_control_role_get_type (void); + #define MATE_MIXER_TYPE_CLIENT_STREAM_FLAGS (mate_mixer_client_stream_flags_get_type ()) GType mate_mixer_client_stream_flags_get_type (void) G_GNUC_CONST; diff --git a/libmatemixer/matemixer-enums.h b/libmatemixer/matemixer-enums.h index a6326ce..8a88b1c 100644 --- a/libmatemixer/matemixer-enums.h +++ b/libmatemixer/matemixer-enums.h @@ -47,6 +47,8 @@ typedef enum { * 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_ALSA: + * @MATE_MIXER_BACKEND_OSS: * @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 @@ -56,9 +58,17 @@ typedef enum { typedef enum { MATE_MIXER_BACKEND_UNKNOWN, MATE_MIXER_BACKEND_PULSEAUDIO, + MATE_MIXER_BACKEND_ALSA, + MATE_MIXER_BACKEND_OSS, MATE_MIXER_BACKEND_NULL } MateMixerBackendType; +typedef enum { /*< flags >*/ + MATE_MIXER_BACKEND_NO_FLAGS = 0, + MATE_MIXER_BACKEND_CAN_SET_DEFAULT_INPUT_STREAM, + MATE_MIXER_BACKEND_CAN_SET_DEFAULT_OUTPUT_STREAM +} MateMixerBackendFlags; + /** * MateMixerPortFlags: * @MATE_MIXER_PORT_NO_FLAGS: @@ -79,14 +89,7 @@ typedef enum { /*< flags >*/ * @MATE_MIXER_STREAM_INPUT: * @MATE_MIXER_STREAM_OUTPUT: * @MATE_MIXER_STREAM_CLIENT: - * @MATE_MIXER_STREAM_HAS_MUTE: - * @MATE_MIXER_STREAM_HAS_VOLUME: - * @MATE_MIXER_STREAM_HAS_DECIBEL_VOLUME: - * @MATE_MIXER_STREAM_HAS_FLAT_VOLUME: * @MATE_MIXER_STREAM_HAS_MONITOR: - * @MATE_MIXER_STREAM_CAN_SET_VOLUME: - * @MATE_MIXER_STREAM_CAN_BALANCE: - * @MATE_MIXER_STREAM_CAN_FADE: * @MATE_MIXER_STREAM_CAN_SUSPEND: */ typedef enum { /*< flags >*/ @@ -94,15 +97,10 @@ typedef enum { /*< flags >*/ MATE_MIXER_STREAM_INPUT = 1 << 0, MATE_MIXER_STREAM_OUTPUT = 1 << 1, MATE_MIXER_STREAM_CLIENT = 1 << 2, - MATE_MIXER_STREAM_HAS_MUTE = 1 << 3, - MATE_MIXER_STREAM_HAS_VOLUME = 1 << 4, - MATE_MIXER_STREAM_HAS_DECIBEL_VOLUME = 1 << 5, - MATE_MIXER_STREAM_HAS_FLAT_VOLUME = 1 << 6, - MATE_MIXER_STREAM_HAS_MONITOR = 1 << 7, - MATE_MIXER_STREAM_CAN_SET_VOLUME = 1 << 8, - MATE_MIXER_STREAM_CAN_BALANCE = 1 << 9, - MATE_MIXER_STREAM_CAN_FADE = 1 << 10, - MATE_MIXER_STREAM_CAN_SUSPEND = 1 << 11 + MATE_MIXER_STREAM_HAS_MONITOR = 1 << 3, + MATE_MIXER_STREAM_CAN_SUSPEND = 1 << 4, + MATE_MIXER_STREAM_PORTS_FIXED = 1 << 5, + MATE_MIXER_STREAM_PORTS_EXCLUSIVE = 1 << 6, } MateMixerStreamFlags; /** @@ -120,6 +118,40 @@ typedef enum { } MateMixerStreamState; /** + * MateMixerStreamControlFlags: + * @MATE_MIXER_STREAM_CONTROL_NO_FLAGS: + * @MATE_MIXER_STREAM_CONTROL_HAS_MUTE: + * @MATE_MIXER_STREAM_CONTROL_HAS_VOLUME: + * @MATE_MIXER_STREAM_CONTROL_HAS_DECIBEL: + * @MATE_MIXER_STREAM_CONTROL_HAS_FLAT_VOLUME: + * @MATE_MIXER_STREAM_CONTROL_CAN_SET_VOLUME: + * @MATE_MIXER_STREAM_CONTROL_CAN_BALANCE: + * @MATE_MIXER_STREAM_CONTROL_CAN_FADE: + */ +typedef enum { + MATE_MIXER_STREAM_CONTROL_NO_FLAGS = 0, + MATE_MIXER_STREAM_CONTROL_HAS_MUTE = 1 << 0, + MATE_MIXER_STREAM_CONTROL_HAS_VOLUME = 1 << 1, + MATE_MIXER_STREAM_CONTROL_HAS_DECIBEL = 1 << 2, + MATE_MIXER_STREAM_CONTROL_HAS_FLAT_VOLUME = 1 << 3, + MATE_MIXER_STREAM_CONTROL_CAN_SET_MUTE = 1 << 4, + MATE_MIXER_STREAM_CONTROL_CAN_SET_VOLUME = 1 << 5, + MATE_MIXER_STREAM_CONTROL_CAN_BALANCE = 1 << 6, + MATE_MIXER_STREAM_CONTROL_CAN_FADE = 1 << 7 +} MateMixerStreamControlFlags; + +typedef enum { + MATE_MIXER_STREAM_CONTROL_ROLE_UNKNOWN, + MATE_MIXER_STREAM_CONTROL_ROLE_MASTER, + MATE_MIXER_STREAM_CONTROL_ROLE_PORT, + MATE_MIXER_STREAM_CONTROL_ROLE_PCM, + MATE_MIXER_STREAM_CONTROL_ROLE_BASS, + MATE_MIXER_STREAM_CONTROL_ROLE_TREBLE, + MATE_MIXER_STREAM_CONTROL_ROLE_CD, + MATE_MIXER_STREAM_CONTROL_ROLE_SPEAKER, +} MateMixerStreamControlRole; + +/** * MateMixerClientStreamFlags: * @MATE_MIXER_CLIENT_STREAM_NO_FLAGS: * @MATE_MIXER_CLIENT_STREAM_APPLICATION: @@ -185,7 +217,7 @@ typedef enum { * @MATE_MIXER_CHANNEL_TOP_BACK_CENTER: */ typedef enum { - MATE_MIXER_CHANNEL_UNKNOWN, + MATE_MIXER_CHANNEL_UNKNOWN = 0, MATE_MIXER_CHANNEL_MONO, MATE_MIXER_CHANNEL_FRONT_LEFT, MATE_MIXER_CHANNEL_FRONT_RIGHT, @@ -204,7 +236,8 @@ typedef enum { MATE_MIXER_CHANNEL_TOP_CENTER, MATE_MIXER_CHANNEL_TOP_BACK_LEFT, MATE_MIXER_CHANNEL_TOP_BACK_RIGHT, - MATE_MIXER_CHANNEL_TOP_BACK_CENTER + MATE_MIXER_CHANNEL_TOP_BACK_CENTER, + MATE_MIXER_CHANNEL_MAX } MateMixerChannelPosition; #endif /* MATEMIXER_ENUMS_H */ diff --git a/libmatemixer/matemixer-port-private.h b/libmatemixer/matemixer-port-private.h deleted file mode 100644 index a696d27..0000000 --- a/libmatemixer/matemixer-port-private.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2014 Michal Ratajsky <[email protected]> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the licence, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef MATEMIXER_PORT_PRIVATE_H -#define MATEMIXER_PORT_PRIVATE_H - -#include <glib.h> - -#include "matemixer-enums.h" -#include "matemixer-port.h" - -G_BEGIN_DECLS - -MateMixerPort *_mate_mixer_port_new (const gchar *name, - const gchar *description, - const gchar *icon, - guint priority, - MateMixerPortFlags flags); - -gboolean _mate_mixer_port_update_description (MateMixerPort *port, - const gchar *description); -gboolean _mate_mixer_port_update_icon (MateMixerPort *port, - const gchar *icon); -gboolean _mate_mixer_port_update_priority (MateMixerPort *port, - guint priority); -gboolean _mate_mixer_port_update_flags (MateMixerPort *port, - MateMixerPortFlags flags); - -G_END_DECLS - -#endif /* MATEMIXER_PORT_PRIVATE_H */ diff --git a/libmatemixer/matemixer-port.c b/libmatemixer/matemixer-port.c deleted file mode 100644 index f89a8bb..0000000 --- a/libmatemixer/matemixer-port.c +++ /dev/null @@ -1,358 +0,0 @@ -/* - * Copyright (C) 2014 Michal Ratajsky <[email protected]> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the licence, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - */ - -#include <glib.h> -#include <glib-object.h> - -#include "matemixer-enums.h" -#include "matemixer-enum-types.h" -#include "matemixer-port.h" -#include "matemixer-port-private.h" - -/** - * SECTION:matemixer-port - * @include: libmatemixer/matemixer.h - */ - -struct _MateMixerPortPrivate -{ - gchar *name; - gchar *description; - gchar *icon; - guint priority; - MateMixerPortFlags flags; -}; - -enum { - PROP_0, - PROP_NAME, - PROP_DESCRIPTION, - PROP_ICON, - PROP_PRIORITY, - PROP_FLAGS, - N_PROPERTIES -}; - -static GParamSpec *properties[N_PROPERTIES] = { NULL, }; - -static void mate_mixer_port_class_init (MateMixerPortClass *klass); - -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_uint ("priority", - "Priority", - "Priority of the port", - 0, - G_MAXUINT, - 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, - GParamSpec *pspec) -{ - MateMixerPort *port; - - port = MATE_MIXER_PORT (object); - - switch (param_id) { - case PROP_NAME: - g_value_set_string (value, port->priv->name); - break; - case PROP_DESCRIPTION: - g_value_set_string (value, port->priv->description); - break; - case PROP_ICON: - g_value_set_string (value, port->priv->icon); - break; - case PROP_PRIORITY: - g_value_set_uint (value, port->priv->priority); - break; - case PROP_FLAGS: - g_value_set_flags (value, port->priv->flags); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); - break; - } -} - -static void -mate_mixer_port_set_property (GObject *object, - guint param_id, - const GValue *value, - GParamSpec *pspec) -{ - MateMixerPort *port; - - port = MATE_MIXER_PORT (object); - - switch (param_id) { - case PROP_NAME: - /* 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_uint (value); - break; - case PROP_FLAGS: - port->priv->flags = g_value_get_flags (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); - break; - } -} - -static void -mate_mixer_port_init (MateMixerPort *port) -{ - port->priv = G_TYPE_INSTANCE_GET_PRIVATE (port, - MATE_MIXER_TYPE_PORT, - MateMixerPortPrivate); -} - -static void -mate_mixer_port_finalize (GObject *object) -{ - MateMixerPort *port; - - port = MATE_MIXER_PORT (object); - - g_free (port->priv->name); - g_free (port->priv->description); - g_free (port->priv->icon); - - G_OBJECT_CLASS (mate_mixer_port_parent_class)->finalize (object); -} - -/** - * mate_mixer_port_get_name: - * @port: a #MateMixerPort - */ -const gchar * -mate_mixer_port_get_name (MateMixerPort *port) -{ - g_return_val_if_fail (MATE_MIXER_IS_PORT (port), NULL); - - return port->priv->name; -} - -/** - * mate_mixer_port_get_description: - * @port: a #MateMixerPort - */ -const gchar * -mate_mixer_port_get_description (MateMixerPort *port) -{ - g_return_val_if_fail (MATE_MIXER_IS_PORT (port), NULL); - - return port->priv->description; -} - -/** - * mate_mixer_port_get_icon: - * @port: a #MateMixerPort - */ -const gchar * -mate_mixer_port_get_icon (MateMixerPort *port) -{ - g_return_val_if_fail (MATE_MIXER_IS_PORT (port), NULL); - - return port->priv->icon; -} - -/** - * mate_mixer_port_get_priority: - * @port: a #MateMixerPort - */ -guint -mate_mixer_port_get_priority (MateMixerPort *port) -{ - g_return_val_if_fail (MATE_MIXER_IS_PORT (port), 0); - - return port->priv->priority; -} - -/** - * mate_mixer_port_get_flags: - * @port: a #MateMixerPort - */ -MateMixerPortFlags -mate_mixer_port_get_flags (MateMixerPort *port) -{ - g_return_val_if_fail (MATE_MIXER_IS_PORT (port), MATE_MIXER_PORT_NO_FLAGS); - - return port->priv->flags; -} - -MateMixerPort * -_mate_mixer_port_new (const gchar *name, - const gchar *description, - const gchar *icon, - guint priority, - MateMixerPortFlags flags) -{ - return g_object_new (MATE_MIXER_TYPE_PORT, - "name", name, - "description", description, - "icon", icon, - "priority", priority, - "flags", flags, - NULL); -} - -gboolean -_mate_mixer_port_update_description (MateMixerPort *port, const gchar *description) -{ - g_return_val_if_fail (MATE_MIXER_IS_PORT (port), FALSE); - - if (g_strcmp0 (port->priv->description, description) != 0) { - g_free (port->priv->description); - - port->priv->description = g_strdup (description); - - g_object_notify_by_pspec (G_OBJECT (port), properties[PROP_DESCRIPTION]); - return TRUE; - } - - return FALSE; -} - -gboolean -_mate_mixer_port_update_icon (MateMixerPort *port, const gchar *icon) -{ - g_return_val_if_fail (MATE_MIXER_IS_PORT (port), FALSE); - - if (g_strcmp0 (port->priv->icon, icon) != 0) { - g_free (port->priv->icon); - - port->priv->icon = g_strdup (icon); - - g_object_notify_by_pspec (G_OBJECT (port), properties[PROP_ICON]); - return TRUE; - } - - return FALSE; -} - -gboolean -_mate_mixer_port_update_priority (MateMixerPort *port, guint priority) -{ - g_return_val_if_fail (MATE_MIXER_IS_PORT (port), FALSE); - - if (port->priv->priority != priority) { - port->priv->priority = priority; - - g_object_notify_by_pspec (G_OBJECT (port), properties[PROP_PRIORITY]); - return TRUE; - } - - return FALSE; -} - -gboolean -_mate_mixer_port_update_flags (MateMixerPort *port, MateMixerPortFlags flags) -{ - g_return_val_if_fail (MATE_MIXER_IS_PORT (port), FALSE); - - if (port->priv->flags != flags) { - port->priv->flags = flags; - - g_object_notify_by_pspec (G_OBJECT (port), properties[PROP_FLAGS]); - return TRUE; - } - - return FALSE; -} diff --git a/libmatemixer/matemixer-port.h b/libmatemixer/matemixer-port.h deleted file mode 100644 index 61f16f5..0000000 --- a/libmatemixer/matemixer-port.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (C) 2014 Michal Ratajsky <[email protected]> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the licence, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef MATEMIXER_PORT_H -#define MATEMIXER_PORT_H - -#include <glib.h> -#include <glib-object.h> - -#include <libmatemixer/matemixer-enums.h> - -G_BEGIN_DECLS - -#define MATE_MIXER_TYPE_PORT \ - (mate_mixer_port_get_type ()) -#define MATE_MIXER_PORT(o) \ - (G_TYPE_CHECK_INSTANCE_CAST ((o), MATE_MIXER_TYPE_PORT, MateMixerPort)) -#define MATE_MIXER_IS_PORT(o) \ - (G_TYPE_CHECK_INSTANCE_TYPE ((o), MATE_MIXER_TYPE_PORT)) -#define MATE_MIXER_PORT_CLASS(k) \ - (G_TYPE_CHECK_CLASS_CAST ((k), MATE_MIXER_TYPE_PORT, MateMixerPortClass)) -#define MATE_MIXER_IS_PORT_CLASS(k) \ - (G_TYPE_CHECK_CLASS_TYPE ((k), MATE_MIXER_TYPE_PORT)) -#define MATE_MIXER_PORT_GET_CLASS(o) \ - (G_TYPE_INSTANCE_GET_CLASS ((o), MATE_MIXER_TYPE_PORT, MateMixerPortClass)) - -typedef struct _MateMixerPort MateMixerPort; -typedef struct _MateMixerPortClass MateMixerPortClass; -typedef struct _MateMixerPortPrivate MateMixerPortPrivate; - -struct _MateMixerPort -{ - GObject parent; - - /*< private >*/ - MateMixerPortPrivate *priv; -}; - -struct _MateMixerPortClass -{ - GObjectClass parent_class; -}; - -GType mate_mixer_port_get_type (void) G_GNUC_CONST; - -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); -guint mate_mixer_port_get_priority (MateMixerPort *port); -MateMixerPortFlags mate_mixer_port_get_flags (MateMixerPort *port); - -G_END_DECLS - -#endif /* MATEMIXER_PORT_H */ diff --git a/libmatemixer/matemixer-private.h b/libmatemixer/matemixer-private.h index 4dde496..4229000 100644 --- a/libmatemixer/matemixer-private.h +++ b/libmatemixer/matemixer-private.h @@ -20,9 +20,91 @@ #include <glib.h> +#include "matemixer-backend-module.h" +#include "matemixer-backend-private.h" +#include "matemixer-device-profile-private.h" +#include "matemixer-stream-control-private.h" +#include "matemixer-switch-option-private.h" +#include "matemixer-switch-private.h" + G_BEGIN_DECLS -const GList *mate_mixer_get_modules (void); +#define MATE_MIXER_IS_LEFT_CHANNEL(c) \ + ((c) == MATE_MIXER_CHANNEL_FRONT_LEFT || \ + (c) == MATE_MIXER_CHANNEL_BACK_LEFT || \ + (c) == MATE_MIXER_CHANNEL_FRONT_LEFT_CENTER || \ + (c) == MATE_MIXER_CHANNEL_SIDE_LEFT || \ + (c) == MATE_MIXER_CHANNEL_TOP_FRONT_LEFT || \ + (c) == MATE_MIXER_CHANNEL_TOP_BACK_LEFT) + +#define MATE_MIXER_IS_RIGHT_CHANNEL(c) \ + ((c) == MATE_MIXER_CHANNEL_FRONT_RIGHT || \ + (c) == MATE_MIXER_CHANNEL_BACK_RIGHT || \ + (c) == MATE_MIXER_CHANNEL_FRONT_RIGHT_CENTER || \ + (c) == MATE_MIXER_CHANNEL_SIDE_RIGHT || \ + (c) == MATE_MIXER_CHANNEL_TOP_FRONT_RIGHT || \ + (c) == MATE_MIXER_CHANNEL_TOP_BACK_RIGHT) + +#define MATE_MIXER_IS_FRONT_CHANNEL(c) \ + ((c) == MATE_MIXER_CHANNEL_FRONT_LEFT || \ + (c) == MATE_MIXER_CHANNEL_FRONT_RIGHT || \ + (c) == MATE_MIXER_CHANNEL_FRONT_CENTER || \ + (c) == MATE_MIXER_CHANNEL_FRONT_LEFT_CENTER || \ + (c) == MATE_MIXER_CHANNEL_FRONT_RIGHT_CENTER || \ + (c) == MATE_MIXER_CHANNEL_TOP_FRONT_LEFT || \ + (c) == MATE_MIXER_CHANNEL_TOP_FRONT_RIGHT || \ + (c) == MATE_MIXER_CHANNEL_TOP_FRONT_CENTER) + +#define MATE_MIXER_IS_BACK_CHANNEL(c) \ + ((c) == MATE_MIXER_CHANNEL_BACK_LEFT || \ + (c) == MATE_MIXER_CHANNEL_BACK_RIGHT || \ + (c) == MATE_MIXER_CHANNEL_BACK_CENTER || \ + (c) == MATE_MIXER_CHANNEL_TOP_BACK_LEFT || \ + (c) == MATE_MIXER_CHANNEL_TOP_BACK_RIGHT || \ + (c) == MATE_MIXER_CHANNEL_TOP_BACK_CENTER) + +#define MATE_MIXER_CHANNEL_MASK_LEFT \ + ((1 << MATE_MIXER_CHANNEL_FRONT_LEFT) | \ + (1 << MATE_MIXER_CHANNEL_BACK_LEFT) | \ + (1 << MATE_MIXER_CHANNEL_FRONT_LEFT_CENTER) | \ + (1 << MATE_MIXER_CHANNEL_SIDE_LEFT) | \ + (1 << MATE_MIXER_CHANNEL_TOP_FRONT_LEFT) | \ + (1 << MATE_MIXER_CHANNEL_TOP_BACK_LEFT)) + +#define MATE_MIXER_CHANNEL_MASK_RIGHT \ + ((1 << MATE_MIXER_CHANNEL_FRONT_RIGHT) | \ + (1 << MATE_MIXER_CHANNEL_BACK_RIGHT) | \ + (1 << MATE_MIXER_CHANNEL_FRONT_RIGHT_CENTER) | \ + (1 << MATE_MIXER_CHANNEL_SIDE_RIGHT) | \ + (1 << MATE_MIXER_CHANNEL_TOP_FRONT_RIGHT) | \ + (1 << MATE_MIXER_CHANNEL_TOP_BACK_RIGHT)) + +#define MATE_MIXER_CHANNEL_MASK_FRONT \ + ((1 << MATE_MIXER_CHANNEL_FRONT_LEFT) | \ + (1 << MATE_MIXER_CHANNEL_FRONT_RIGHT) | \ + (1 << MATE_MIXER_CHANNEL_FRONT_CENTER) | \ + (1 << MATE_MIXER_CHANNEL_FRONT_LEFT_CENTER) | \ + (1 << MATE_MIXER_CHANNEL_FRONT_RIGHT_CENTER) | \ + (1 << MATE_MIXER_CHANNEL_TOP_FRONT_LEFT) | \ + (1 << MATE_MIXER_CHANNEL_TOP_FRONT_RIGHT) | \ + (1 << MATE_MIXER_CHANNEL_TOP_FRONT_CENTER)) + +#define MATE_MIXER_CHANNEL_MASK_BACK \ + ((1 << MATE_MIXER_CHANNEL_BACK_LEFT) | \ + (1 << MATE_MIXER_CHANNEL_BACK_RIGHT) | \ + (1 << MATE_MIXER_CHANNEL_BACK_CENTER) | \ + (1 << MATE_MIXER_CHANNEL_TOP_BACK_LEFT) | \ + (1 << MATE_MIXER_CHANNEL_TOP_BACK_RIGHT) | \ + (1 << MATE_MIXER_CHANNEL_TOP_BACK_CENTER)) + +#define MATE_MIXER_CHANNEL_MASK_HAS_CHANNEL(m,c) ((m) & (1 << (c))) +#define MATE_MIXER_CHANNEL_MASK_HAS_LEFT(m) ((m) & MATE_MIXER_CHANNEL_MASK_LEFT) +#define MATE_MIXER_CHANNEL_MASK_HAS_RIGHT(m) ((m) & MATE_MIXER_CHANNEL_MASK_RIGHT) +#define MATE_MIXER_CHANNEL_MASK_HAS_FRONT(m) ((m) & MATE_MIXER_CHANNEL_MASK_FRONT) +#define MATE_MIXER_CHANNEL_MASK_HAS_BACK(m) ((m) & MATE_MIXER_CHANNEL_MASK_BACK) + +const GList *_mate_mixer_get_modules (void); +guint32 _mate_mixer_create_channel_mask (MateMixerChannelPosition *positions, guint n); G_END_DECLS diff --git a/libmatemixer/matemixer-stream-control-private.h b/libmatemixer/matemixer-stream-control-private.h new file mode 100644 index 0000000..49454b3 --- /dev/null +++ b/libmatemixer/matemixer-stream-control-private.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2014 Michal Ratajsky <[email protected]> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the licence, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef MATEMIXER_STREAM_CONTROL_PRIVATE_H +#define MATEMIXER_STREAM_CONTROL_PRIVATE_H + +#include <glib.h> +#include "matemixer-enums.h" +#include "matemixer-types.h" + +G_BEGIN_DECLS + +void _mate_mixer_stream_control_set_flags (MateMixerStreamControl *control, + MateMixerStreamControlFlags flags); + +void _mate_mixer_stream_control_set_mute (MateMixerStreamControl *control, + gboolean mute); + +void _mate_mixer_stream_control_set_balance (MateMixerStreamControl *control, + gfloat balance); + +void _mate_mixer_stream_control_set_fade (MateMixerStreamControl *control, + gfloat fade); + +G_END_DECLS + +#endif /* MATEMIXER_STREAM_CONTROL_PRIVATE_H */ diff --git a/libmatemixer/matemixer-stream-control.c b/libmatemixer/matemixer-stream-control.c new file mode 100644 index 0000000..ace584a --- /dev/null +++ b/libmatemixer/matemixer-stream-control.c @@ -0,0 +1,627 @@ +/* + * Copyright (C) 2014 Michal Ratajsky <[email protected]> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the licence, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see <http://www.gnu.org/licenses/>. + */ + +#include <glib.h> +#include <glib-object.h> + +#include "matemixer-enums.h" +#include "matemixer-enum-types.h" +#include "matemixer-stream-control.h" +#include "matemixer-stream-control-private.h" + +/** + * SECTION:matemixer-stream-control + * @include: libmatemixer/matemixer.h + */ + +struct _MateMixerStreamControlPrivate +{ + gchar *name; + gchar *label; + gboolean mute; + gfloat balance; + gfloat fade; + MateMixerStreamControlFlags flags; + MateMixerStreamControlRole role; +}; + +enum { + PROP_0, + PROP_NAME, + PROP_LABEL, + PROP_FLAGS, + PROP_ROLE, + PROP_MUTE, + PROP_VOLUME, + PROP_BALANCE, + PROP_FADE, + N_PROPERTIES +}; + +static GParamSpec *properties[N_PROPERTIES] = { NULL, }; + +static void mate_mixer_stream_control_class_init (MateMixerStreamControlClass *klass); + +static void mate_mixer_stream_control_get_property (GObject *object, + guint param_id, + GValue *value, + GParamSpec *pspec); +static void mate_mixer_stream_control_set_property (GObject *object, + guint param_id, + const GValue *value, + GParamSpec *pspec); + +static void mate_mixer_stream_control_init (MateMixerStreamControl *control); +static void mate_mixer_stream_control_finalize (GObject *object); + +G_DEFINE_ABSTRACT_TYPE (MateMixerStreamControl, mate_mixer_stream_control, G_TYPE_OBJECT) + +static void +mate_mixer_stream_control_class_init (MateMixerStreamControlClass *klass) +{ + GObjectClass *object_class; + + object_class = G_OBJECT_CLASS (klass); + object_class->finalize = mate_mixer_stream_control_finalize; + object_class->get_property = mate_mixer_stream_control_get_property; + object_class->set_property = mate_mixer_stream_control_set_property; + + properties[PROP_NAME] = + g_param_spec_string ("name", + "Name", + "Name of the stream control", + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + + properties[PROP_LABEL] = + g_param_spec_string ("label", + "Label", + "Label of the stream control", + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + + properties[PROP_FLAGS] = + g_param_spec_flags ("flags", + "Flags", + "Capability flags of the stream control", + MATE_MIXER_TYPE_STREAM_CONTROL_FLAGS, + MATE_MIXER_STREAM_CONTROL_NO_FLAGS, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + + properties[PROP_ROLE] = + g_param_spec_enum ("role", + "Role", + "Role of the stream control", + MATE_MIXER_TYPE_STREAM_CONTROL_ROLE, + MATE_MIXER_STREAM_CONTROL_ROLE_UNKNOWN, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + + properties[PROP_MUTE] = + g_param_spec_boolean ("mute", + "Mute", + "Mute state of the stream control", + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); + + properties[PROP_VOLUME] = + g_param_spec_uint ("volume", + "Volume", + "Volume of the stream control", + 0, + G_MAXUINT, + 0, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); + + properties[PROP_BALANCE] = + g_param_spec_float ("balance", + "Balance", + "Balance value of the stream control", + -1.0f, + 1.0f, + 0.0f, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); + + properties[PROP_FADE] = + g_param_spec_float ("fade", + "Fade", + "Fade value of the stream control", + -1.0f, + 1.0f, + 0.0f, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties (object_class, N_PROPERTIES, properties); + + g_type_class_add_private (object_class, sizeof (MateMixerStreamControlPrivate)); +} + +static void +mate_mixer_stream_control_get_property (GObject *object, + guint param_id, + GValue *value, + GParamSpec *pspec) +{ + MateMixerStreamControl *control; + + control = MATE_MIXER_STREAM_CONTROL (object); + + switch (param_id) { + case PROP_NAME: + g_value_set_string (value, control->priv->name); + break; + case PROP_LABEL: + g_value_set_string (value, control->priv->label); + break; + case PROP_FLAGS: + g_value_set_flags (value, control->priv->flags); + break; + case PROP_ROLE: + g_value_set_enum (value, control->priv->role); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); + break; + } +} + +static void +mate_mixer_stream_control_set_property (GObject *object, + guint param_id, + const GValue *value, + GParamSpec *pspec) +{ + MateMixerStreamControl *control; + + control = MATE_MIXER_STREAM_CONTROL (object); + + switch (param_id) { + case PROP_NAME: + /* Construct-only string */ + control->priv->name = g_value_dup_string (value); + break; + case PROP_LABEL: + /* Construct-only string */ + control->priv->label = g_value_dup_string (value); + break; + case PROP_FLAGS: + control->priv->flags = g_value_get_flags (value); + break; + case PROP_ROLE: + control->priv->role = g_value_get_enum (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); + break; + } +} + +static void +mate_mixer_stream_control_init (MateMixerStreamControl *control) +{ + control->priv = G_TYPE_INSTANCE_GET_PRIVATE (control, + MATE_MIXER_TYPE_STREAM_CONTROL, + MateMixerStreamControlPrivate); +} + +static void +mate_mixer_stream_control_finalize (GObject *object) +{ + MateMixerStreamControl *control; + + control = MATE_MIXER_STREAM_CONTROL (object); + + g_free (control->priv->name); + g_free (control->priv->label); + + G_OBJECT_CLASS (mate_mixer_stream_control_parent_class)->finalize (object); +} + +const gchar * +mate_mixer_stream_control_get_name (MateMixerStreamControl *control) +{ + g_return_val_if_fail (MATE_MIXER_IS_STREAM_CONTROL (control), NULL); + + return control->priv->name; +} + +const gchar * +mate_mixer_stream_control_get_label (MateMixerStreamControl *control) +{ + g_return_val_if_fail (MATE_MIXER_IS_STREAM_CONTROL (control), NULL); + + return control->priv->label; +} + +MateMixerStreamControlFlags +mate_mixer_stream_control_get_flags (MateMixerStreamControl *control) +{ + g_return_val_if_fail (MATE_MIXER_IS_STREAM_CONTROL (control), MATE_MIXER_STREAM_CONTROL_NO_FLAGS); + + return control->priv->flags; +} + +MateMixerStreamControlRole +mate_mixer_stream_control_get_role (MateMixerStreamControl *control) +{ + g_return_val_if_fail (MATE_MIXER_IS_STREAM_CONTROL (control), MATE_MIXER_STREAM_CONTROL_ROLE_UNKNOWN); + + return control->priv->role; +} + +gboolean +mate_mixer_stream_control_get_mute (MateMixerStreamControl *control) +{ + g_return_val_if_fail (MATE_MIXER_IS_STREAM_CONTROL (control), FALSE); + + return control->priv->mute; +} + +gboolean +mate_mixer_stream_control_set_mute (MateMixerStreamControl *control, gboolean mute) +{ + g_return_val_if_fail (MATE_MIXER_IS_STREAM_CONTROL (control), FALSE); + + if (control->priv->mute == mute) + return TRUE; + + if (control->priv->flags & MATE_MIXER_STREAM_CONTROL_HAS_MUTE) { + MateMixerStreamControlClass *klass; + + klass = MATE_MIXER_STREAM_CONTROL_GET_CLASS (control); + + if (G_LIKELY (klass->set_mute != NULL)) + return klass->set_mute (control, mute); + } + return FALSE; +} + +guint +mate_mixer_stream_control_get_num_channels (MateMixerStreamControl *control) +{ + MateMixerStreamControlClass *klass; + + g_return_val_if_fail (MATE_MIXER_IS_STREAM_CONTROL (control), 0); + + klass = MATE_MIXER_STREAM_CONTROL_GET_CLASS (control); + + if (klass->get_num_channels != NULL) + return klass->get_num_channels (control); + + return 0; +} + +guint +mate_mixer_stream_control_get_volume (MateMixerStreamControl *control) +{ + g_return_val_if_fail (MATE_MIXER_IS_STREAM_CONTROL (control), 0); + + if (control->priv->flags & MATE_MIXER_STREAM_CONTROL_HAS_VOLUME) { + MateMixerStreamControlClass *klass; + + klass = MATE_MIXER_STREAM_CONTROL_GET_CLASS (control); + + if G_LIKELY (klass->get_volume != NULL) + return klass->get_volume (control); + } + return 0; +} + +gboolean +mate_mixer_stream_control_set_volume (MateMixerStreamControl *control, guint volume) +{ + g_return_val_if_fail (MATE_MIXER_IS_STREAM_CONTROL (control), FALSE); + + if (control->priv->flags & MATE_MIXER_STREAM_CONTROL_HAS_VOLUME) { + MateMixerStreamControlClass *klass; + + klass = MATE_MIXER_STREAM_CONTROL_GET_CLASS (control); + + if (G_LIKELY (klass->set_volume != NULL)) + return klass->set_volume (control, volume); + } + return FALSE; +} + +gdouble +mate_mixer_stream_control_get_decibel (MateMixerStreamControl *control) +{ + g_return_val_if_fail (MATE_MIXER_IS_STREAM_CONTROL (control), -MATE_MIXER_INFINITY); + + if (control->priv->flags & MATE_MIXER_STREAM_CONTROL_HAS_DECIBEL) { + MateMixerStreamControlClass *klass; + + klass = MATE_MIXER_STREAM_CONTROL_GET_CLASS (control); + + if (G_LIKELY (klass->get_decibel != NULL)) + return klass->get_decibel (control); + } + return -MATE_MIXER_INFINITY; +} + +gboolean +mate_mixer_stream_control_set_decibel (MateMixerStreamControl *control, gdouble decibel) +{ + g_return_val_if_fail (MATE_MIXER_IS_STREAM_CONTROL (control), FALSE); + + if (control->priv->flags & MATE_MIXER_STREAM_CONTROL_HAS_DECIBEL) { + MateMixerStreamControlClass *klass; + + klass = MATE_MIXER_STREAM_CONTROL_GET_CLASS (control); + + if (G_LIKELY (klass->set_decibel != NULL)) + return klass->set_decibel (control, decibel); + } + return FALSE; +} + +MateMixerChannelPosition +mate_mixer_stream_control_get_channel_position (MateMixerStreamControl *control, guint channel) +{ + MateMixerStreamControlClass *klass; + + g_return_val_if_fail (MATE_MIXER_IS_STREAM_CONTROL (control), MATE_MIXER_CHANNEL_UNKNOWN); + + klass = MATE_MIXER_STREAM_CONTROL_GET_CLASS (control); + + if (klass->get_channel_position != NULL) + return klass->get_channel_position (control, channel); + + return MATE_MIXER_CHANNEL_UNKNOWN; +} + +guint +mate_mixer_stream_control_get_channel_volume (MateMixerStreamControl *control, guint channel) +{ + g_return_val_if_fail (MATE_MIXER_IS_STREAM_CONTROL (control), 0); + + if (control->priv->flags & MATE_MIXER_STREAM_CONTROL_HAS_VOLUME) { + MateMixerStreamControlClass *klass; + + klass = MATE_MIXER_STREAM_CONTROL_GET_CLASS (control); + + if (G_LIKELY (klass->get_channel_volume != NULL)) + return klass->get_channel_volume (control, channel); + } + return 0; +} + +gboolean +mate_mixer_stream_control_set_channel_volume (MateMixerStreamControl *control, + guint channel, + guint volume) +{ + g_return_val_if_fail (MATE_MIXER_IS_STREAM_CONTROL (control), FALSE); + + if (control->priv->flags & MATE_MIXER_STREAM_CONTROL_HAS_VOLUME) { + MateMixerStreamControlClass *klass; + + klass = MATE_MIXER_STREAM_CONTROL_GET_CLASS (control); + + if (G_LIKELY (klass->set_channel_volume != NULL)) + return klass->set_channel_volume (control, channel, volume); + } + return FALSE; +} + +gdouble +mate_mixer_stream_control_get_channel_decibel (MateMixerStreamControl *control, guint channel) +{ + g_return_val_if_fail (MATE_MIXER_IS_STREAM_CONTROL (control), -MATE_MIXER_INFINITY); + + if (control->priv->flags & MATE_MIXER_STREAM_CONTROL_HAS_DECIBEL) { + MateMixerStreamControlClass *klass; + + klass = MATE_MIXER_STREAM_CONTROL_GET_CLASS (control); + + if (G_LIKELY (klass->get_channel_decibel != NULL)) + return klass->get_channel_decibel (control, channel); + } + return -MATE_MIXER_INFINITY; +} + +gboolean +mate_mixer_stream_control_set_channel_decibel (MateMixerStreamControl *control, + guint channel, + gdouble decibel) +{ + g_return_val_if_fail (MATE_MIXER_IS_STREAM_CONTROL (control), FALSE); + + if (control->priv->flags & MATE_MIXER_STREAM_CONTROL_HAS_DECIBEL) { + MateMixerStreamControlClass *klass; + + klass = MATE_MIXER_STREAM_CONTROL_GET_CLASS (control); + + if (G_LIKELY (klass->set_channel_decibel != NULL)) + return klass->set_channel_decibel (control, channel, decibel); + } + return FALSE; +} + +gboolean +mate_mixer_stream_control_has_channel_position (MateMixerStreamControl *control, + MateMixerChannelPosition position) +{ + MateMixerStreamControlClass *klass; + + g_return_val_if_fail (MATE_MIXER_IS_STREAM_CONTROL (control), FALSE); + + klass = MATE_MIXER_STREAM_CONTROL_GET_CLASS (control); + + if (klass->has_channel_position != NULL) + return klass->has_channel_position (control, position); + + return FALSE; +} + +gfloat +mate_mixer_stream_control_get_balance (MateMixerStreamControl *control) +{ + g_return_val_if_fail (MATE_MIXER_IS_STREAM_CONTROL (control), 0.0f); + + if (control->priv->flags & MATE_MIXER_STREAM_CONTROL_CAN_BALANCE) + return control->priv->balance; + else + return 0.0f; +} + +gboolean +mate_mixer_stream_control_set_balance (MateMixerStreamControl *control, gfloat balance) +{ + g_return_val_if_fail (MATE_MIXER_IS_STREAM_CONTROL (control), FALSE); + + if (control->priv->flags & MATE_MIXER_STREAM_CONTROL_CAN_BALANCE) { + MateMixerStreamControlClass *klass; + + if (balance < -1.0f || balance > 1.0f) + return FALSE; + + klass = MATE_MIXER_STREAM_CONTROL_GET_CLASS (control); + + if (G_LIKELY (klass->set_balance != NULL)) + return klass->set_balance (control, balance); + } + return FALSE; +} + +gfloat +mate_mixer_stream_control_get_fade (MateMixerStreamControl *control) +{ + g_return_val_if_fail (MATE_MIXER_IS_STREAM_CONTROL (control), 0.0f); + + if (control->priv->flags & MATE_MIXER_STREAM_CONTROL_CAN_FADE) + return control->priv->fade; + else + return 0.0f; +} + +gboolean +mate_mixer_stream_control_set_fade (MateMixerStreamControl *control, gfloat fade) +{ + g_return_val_if_fail (MATE_MIXER_IS_STREAM_CONTROL (control), FALSE); + + if (control->priv->flags & MATE_MIXER_STREAM_CONTROL_CAN_FADE) { + MateMixerStreamControlClass *klass; + + if (fade < -1.0f || fade > 1.0f) + return FALSE; + + klass = MATE_MIXER_STREAM_CONTROL_GET_CLASS (control); + + if (G_LIKELY (klass->set_fade != NULL)) + return klass->set_fade (control, fade); + } + return FALSE; +} + +guint +mate_mixer_stream_control_get_min_volume (MateMixerStreamControl *control) +{ + MateMixerStreamControlClass *klass; + + g_return_val_if_fail (MATE_MIXER_IS_STREAM_CONTROL (control), 0); + + klass = MATE_MIXER_STREAM_CONTROL_GET_CLASS (control); + + if (klass->get_min_volume != NULL) + return klass->get_min_volume (control); + + return 0; +} + +guint +mate_mixer_stream_control_get_max_volume (MateMixerStreamControl *control) +{ + MateMixerStreamControlClass *klass; + + g_return_val_if_fail (MATE_MIXER_IS_STREAM_CONTROL (control), 0); + + klass = MATE_MIXER_STREAM_CONTROL_GET_CLASS (control); + + if (klass->get_max_volume != NULL) + return klass->get_max_volume (control); + + return 0; +} + +guint +mate_mixer_stream_control_get_normal_volume (MateMixerStreamControl *control) +{ + MateMixerStreamControlClass *klass; + + g_return_val_if_fail (MATE_MIXER_IS_STREAM_CONTROL (control), 0); + + klass = MATE_MIXER_STREAM_CONTROL_GET_CLASS (control); + + if (klass->get_normal_volume != NULL) + return klass->get_normal_volume (control); + + return 0; +} + +guint +mate_mixer_stream_control_get_base_volume (MateMixerStreamControl *control) +{ + MateMixerStreamControlClass *klass; + + g_return_val_if_fail (MATE_MIXER_IS_STREAM_CONTROL (control), 0); + + klass = MATE_MIXER_STREAM_CONTROL_GET_CLASS (control); + + if (klass->get_base_volume != NULL) + return klass->get_base_volume (control); + + return 0; +} + +void +_mate_mixer_stream_control_set_flags (MateMixerStreamControl *control, + MateMixerStreamControlFlags flags) +{ + control->priv->flags = flags; +} + +void +_mate_mixer_stream_control_set_mute (MateMixerStreamControl *control, gboolean mute) +{ + control->priv->mute = mute; +} + +void +_mate_mixer_stream_control_set_balance (MateMixerStreamControl *control, gfloat balance) +{ + control->priv->balance = balance; +} + +void +_mate_mixer_stream_control_set_fade (MateMixerStreamControl *control, gfloat fade) +{ + control->priv->fade = fade; +} diff --git a/libmatemixer/matemixer-stream-control.h b/libmatemixer/matemixer-stream-control.h new file mode 100644 index 0000000..51d7f95 --- /dev/null +++ b/libmatemixer/matemixer-stream-control.h @@ -0,0 +1,160 @@ +/* + * Copyright (C) 2014 Michal Ratajsky <[email protected]> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the licence, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef MATEMIXER_STREAM_CONTROL_H +#define MATEMIXER_STREAM_CONTROL_H + +#include <math.h> +#include <glib.h> +#include <glib-object.h> + +#include <libmatemixer/matemixer-enums.h> +#include <libmatemixer/matemixer-types.h> + +G_BEGIN_DECLS + +#ifdef INFINITY +# define MATE_MIXER_INFINITY INFINITY +#else +# define MATE_MIXER_INFINITY G_MAXDOUBLE +#endif + +#define MATE_MIXER_TYPE_STREAM_CONTROL \ + (mate_mixer_stream_control_get_type ()) +#define MATE_MIXER_STREAM_CONTROL(o) \ + (G_TYPE_CHECK_INSTANCE_CAST ((o), MATE_MIXER_TYPE_STREAM_CONTROL, MateMixerStreamControl)) +#define MATE_MIXER_IS_STREAM_CONTROL(o) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((o), MATE_MIXER_TYPE_STREAM_CONTROL)) +#define MATE_MIXER_STREAM_CONTROL_CLASS(k) \ + (G_TYPE_CHECK_CLASS_CAST ((k), MATE_MIXER_TYPE_STREAM_CONTROL, MateMixerStreamControlClass)) +#define MATE_MIXER_IS_STREAM_CONTROL_CLASS(k) \ + (G_TYPE_CHECK_CLASS_TYPE ((k), MATE_MIXER_TYPE_STREAM_CONTROL)) +#define MATE_MIXER_STREAM_CONTROL_GET_CLASS(o) \ + (G_TYPE_INSTANCE_GET_CLASS ((o), MATE_MIXER_TYPE_STREAM_CONTROL, MateMixerStreamControlClass)) + +typedef struct _MateMixerStreamControlClass MateMixerStreamControlClass; +typedef struct _MateMixerStreamControlPrivate MateMixerStreamControlPrivate; + +struct _MateMixerStreamControl +{ + GObject object; + + /*< private >*/ + MateMixerStreamControlPrivate *priv; +}; + +struct _MateMixerStreamControlClass +{ + GObjectClass parent_class; + + /*< private >*/ + gboolean (*set_mute) (MateMixerStreamControl *control, + gboolean mute); + + guint (*get_num_channels) (MateMixerStreamControl *control); + + guint (*get_volume) (MateMixerStreamControl *control); + gboolean (*set_volume) (MateMixerStreamControl *control, + guint volume); + + gdouble (*get_decibel) (MateMixerStreamControl *control); + gboolean (*set_decibel) (MateMixerStreamControl *control, + gdouble decibel); + + gboolean (*has_channel_position) (MateMixerStreamControl *control, + MateMixerChannelPosition position); + MateMixerChannelPosition (*get_channel_position) (MateMixerStreamControl *control, + guint channel); + + guint (*get_channel_volume) (MateMixerStreamControl *control, + guint channel); + gboolean (*set_channel_volume) (MateMixerStreamControl *control, + guint channel, + guint volume); + + gdouble (*get_channel_decibel) (MateMixerStreamControl *control, + guint channel); + gboolean (*set_channel_decibel) (MateMixerStreamControl *control, + guint channel, + gdouble decibel); + + gboolean (*set_balance) (MateMixerStreamControl *control, + gfloat balance); + + gboolean (*set_fade) (MateMixerStreamControl *control, + gfloat fade); + + guint (*get_min_volume) (MateMixerStreamControl *control); + guint (*get_max_volume) (MateMixerStreamControl *control); + guint (*get_normal_volume) (MateMixerStreamControl *control); + guint (*get_base_volume) (MateMixerStreamControl *control); +}; + +GType mate_mixer_stream_control_get_type (void) G_GNUC_CONST; + +const gchar * mate_mixer_stream_control_get_name (MateMixerStreamControl *control); +const gchar * mate_mixer_stream_control_get_label (MateMixerStreamControl *control); +MateMixerStreamControlFlags mate_mixer_stream_control_get_flags (MateMixerStreamControl *control); +MateMixerStreamControlRole mate_mixer_stream_control_get_role (MateMixerStreamControl *control); + +gboolean mate_mixer_stream_control_get_mute (MateMixerStreamControl *control); +gboolean mate_mixer_stream_control_set_mute (MateMixerStreamControl *control, + gboolean mute); + +guint mate_mixer_stream_control_get_num_channels (MateMixerStreamControl *control); + +guint mate_mixer_stream_control_get_volume (MateMixerStreamControl *control); +gboolean mate_mixer_stream_control_set_volume (MateMixerStreamControl *control, + guint volume); + +gdouble mate_mixer_stream_control_get_decibel (MateMixerStreamControl *control); +gboolean mate_mixer_stream_control_set_decibel (MateMixerStreamControl *control, + gdouble decibel); + +gboolean mate_mixer_stream_control_has_channel_position (MateMixerStreamControl *control, + MateMixerChannelPosition position); +MateMixerChannelPosition mate_mixer_stream_control_get_channel_position (MateMixerStreamControl *control, + guint channel); + +guint mate_mixer_stream_control_get_channel_volume (MateMixerStreamControl *control, + guint channel); +gboolean mate_mixer_stream_control_set_channel_volume (MateMixerStreamControl *control, + guint channel, + guint volume); + +gdouble mate_mixer_stream_control_get_channel_decibel (MateMixerStreamControl *control, + guint channel); +gboolean mate_mixer_stream_control_set_channel_decibel (MateMixerStreamControl *control, + guint channel, + gdouble decibel); + +gfloat mate_mixer_stream_control_get_balance (MateMixerStreamControl *control); +gboolean mate_mixer_stream_control_set_balance (MateMixerStreamControl *control, + gfloat balance); + +gfloat mate_mixer_stream_control_get_fade (MateMixerStreamControl *control); +gboolean mate_mixer_stream_control_set_fade (MateMixerStreamControl *control, + gfloat fade); + +guint mate_mixer_stream_control_get_min_volume (MateMixerStreamControl *control); +guint mate_mixer_stream_control_get_max_volume (MateMixerStreamControl *control); +guint mate_mixer_stream_control_get_normal_volume (MateMixerStreamControl *control); +guint mate_mixer_stream_control_get_base_volume (MateMixerStreamControl *control); + +G_END_DECLS + +#endif /* MATEMIXER_STREAM_CONTROL_H */ diff --git a/libmatemixer/matemixer-stream.c b/libmatemixer/matemixer-stream.c index 6bec2be..1902de3 100644 --- a/libmatemixer/matemixer-stream.c +++ b/libmatemixer/matemixer-stream.c @@ -15,20 +15,44 @@ * License along with this library; if not, see <http://www.gnu.org/licenses/>. */ +#include <string.h> #include <glib.h> #include <glib-object.h> #include "matemixer-device.h" #include "matemixer-enums.h" #include "matemixer-enum-types.h" -#include "matemixer-port.h" #include "matemixer-stream.h" +#include "matemixer-stream-control.h" +#include "matemixer-switch.h" /** * SECTION:matemixer-stream * @include: libmatemixer/matemixer.h */ +struct _MateMixerStreamPrivate +{ + gchar *name; + GList *controls; + GList *switches; + gboolean monitor_enabled; + MateMixerDevice *device; + MateMixerStreamFlags flags; + MateMixerStreamState state; +}; + +enum { + PROP_0, + PROP_NAME, + PROP_DEVICE, + PROP_FLAGS, + PROP_STATE, + N_PROPERTIES +}; + +static GParamSpec *properties[N_PROPERTIES] = { NULL, }; + enum { MONITOR_VALUE, N_SIGNALS @@ -36,449 +60,285 @@ enum { static guint signals[N_SIGNALS] = { 0, }; -G_DEFINE_INTERFACE (MateMixerStream, mate_mixer_stream, G_TYPE_OBJECT) +static void mate_mixer_stream_class_init (MateMixerStreamClass *klass); + +static void mate_mixer_stream_get_property (GObject *object, + guint param_id, + GValue *value, + GParamSpec *pspec); +static void mate_mixer_stream_set_property (GObject *object, + guint param_id, + const GValue *value, + GParamSpec *pspec); + +static void mate_mixer_stream_init (MateMixerStream *stream); +static void mate_mixer_stream_dispose (GObject *object); +static void mate_mixer_stream_finalize (GObject *object); + +G_DEFINE_ABSTRACT_TYPE (MateMixerStream, mate_mixer_stream, G_TYPE_OBJECT) + +static MateMixerStreamControl *mate_mixer_stream_real_get_control (MateMixerStream *stream, + const gchar *name); +static MateMixerSwitch * mate_mixer_stream_real_get_switch (MateMixerStream *stream, + const gchar *name); static void -mate_mixer_stream_default_init (MateMixerStreamInterface *iface) -{ - g_object_interface_install_property (iface, - g_param_spec_string ("name", - "Name", - "Name of the stream", - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); - - g_object_interface_install_property (iface, - g_param_spec_string ("description", - "Description", - "Description of the stream", - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); - - g_object_interface_install_property (iface, - g_param_spec_object ("device", - "Device", - "Device the stream belongs to", - MATE_MIXER_TYPE_DEVICE, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); - - g_object_interface_install_property (iface, - g_param_spec_flags ("flags", - "Flags", - "Capability flags of the stream", - MATE_MIXER_TYPE_STREAM_FLAGS, - MATE_MIXER_STREAM_NO_FLAGS, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); - - g_object_interface_install_property (iface, - g_param_spec_enum ("state", - "State", - "Current state of the stream", - MATE_MIXER_TYPE_STREAM_STATE, - MATE_MIXER_STREAM_STATE_UNKNOWN, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); - - g_object_interface_install_property (iface, - g_param_spec_boolean ("mute", - "Mute", - "Mute state of the stream", - FALSE, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); - - g_object_interface_install_property (iface, - g_param_spec_uint ("volume", - "Volume", - "Volume of the stream", - 0, - G_MAXUINT, - 0, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); - - g_object_interface_install_property (iface, - g_param_spec_float ("balance", - "Balance", - "Balance value of the stream", - -1.0f, - 1.0f, - 0.0f, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); - - g_object_interface_install_property (iface, - g_param_spec_float ("fade", - "Fade", - "Fade value of the stream", - -1.0f, - 1.0f, - 0.0f, - 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_READABLE | - G_PARAM_STATIC_STRINGS)); +mate_mixer_stream_class_init (MateMixerStreamClass *klass) +{ + GObjectClass *object_class; + + klass->get_control = mate_mixer_stream_real_get_control; + klass->get_switch = mate_mixer_stream_real_get_switch; + + object_class = G_OBJECT_CLASS (klass); + object_class->dispose = mate_mixer_stream_dispose; + object_class->finalize = mate_mixer_stream_finalize; + object_class->get_property = mate_mixer_stream_get_property; + object_class->set_property = mate_mixer_stream_set_property; + + properties[PROP_NAME] = + g_param_spec_string ("name", + "Name", + "Name of the stream", + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + + properties[PROP_DEVICE] = + g_param_spec_object ("device", + "Device", + "Device the stream belongs to", + MATE_MIXER_TYPE_DEVICE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + + properties[PROP_FLAGS] = + g_param_spec_flags ("flags", + "Flags", + "Capability flags of the stream", + MATE_MIXER_TYPE_STREAM_FLAGS, + MATE_MIXER_STREAM_NO_FLAGS, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + + properties[PROP_STATE] = + g_param_spec_enum ("state", + "State", + "Current state of the stream", + MATE_MIXER_TYPE_STREAM_STATE, + MATE_MIXER_STREAM_STATE_UNKNOWN, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties (object_class, N_PROPERTIES, properties); signals[MONITOR_VALUE] = g_signal_new ("monitor-value", - G_TYPE_FROM_INTERFACE (iface), + G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (MateMixerStreamInterface, monitor_value), + G_STRUCT_OFFSET (MateMixerStreamClass, 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) -{ - return MATE_MIXER_STREAM_GET_INTERFACE (stream)->get_name (stream); -} - -const gchar * -mate_mixer_stream_get_description (MateMixerStream *stream) -{ - MateMixerStreamInterface *iface; - - g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), NULL); - - iface = MATE_MIXER_STREAM_GET_INTERFACE (stream); - - if (iface->get_description) - return iface->get_description (stream); - - return NULL; -} - -MateMixerDevice * -mate_mixer_stream_get_device (MateMixerStream *stream) -{ - MateMixerStreamInterface *iface; - - g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), NULL); - - iface = MATE_MIXER_STREAM_GET_INTERFACE (stream); - - if (iface->get_device) - return iface->get_device (stream); - - return NULL; -} - -MateMixerStreamFlags -mate_mixer_stream_get_flags (MateMixerStream *stream) -{ - MateMixerStreamInterface *iface; - - 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_flags) - return iface->get_flags (stream); - - return MATE_MIXER_STREAM_NO_FLAGS; -} - -MateMixerStreamState -mate_mixer_stream_get_state (MateMixerStream *stream) -{ - MateMixerStreamInterface *iface; - - g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), MATE_MIXER_STREAM_STATE_UNKNOWN); - - iface = MATE_MIXER_STREAM_GET_INTERFACE (stream); - - if (iface->get_state) - return iface->get_state (stream); - - return MATE_MIXER_STREAM_STATE_UNKNOWN; -} - -gboolean -mate_mixer_stream_get_mute (MateMixerStream *stream) -{ - MateMixerStreamInterface *iface; - - g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), FALSE); - - iface = MATE_MIXER_STREAM_GET_INTERFACE (stream); - - if (iface->get_mute) - return iface->get_mute (stream); - return FALSE; + g_type_class_add_private (object_class, sizeof (MateMixerStreamPrivate)); } -gboolean -mate_mixer_stream_set_mute (MateMixerStream *stream, gboolean mute) -{ - MateMixerStreamInterface *iface; - - g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), FALSE); - - iface = MATE_MIXER_STREAM_GET_INTERFACE (stream); - - if (iface->set_mute) - return iface->set_mute (stream, mute); - - return FALSE; -} - -guint -mate_mixer_stream_get_volume (MateMixerStream *stream) -{ - MateMixerStreamInterface *iface; - - g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), 0); - - iface = MATE_MIXER_STREAM_GET_INTERFACE (stream); - - if (iface->get_volume) - return iface->get_volume (stream); - - return 0; -} - -gboolean -mate_mixer_stream_set_volume (MateMixerStream *stream, guint volume) -{ - MateMixerStreamInterface *iface; - - g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), FALSE); - - iface = MATE_MIXER_STREAM_GET_INTERFACE (stream); - - if (iface->set_volume) - return iface->set_volume (stream, volume); - - return FALSE; +static void +mate_mixer_stream_get_property (GObject *object, + guint param_id, + GValue *value, + GParamSpec *pspec) +{ + MateMixerStream *stream; + + stream = MATE_MIXER_STREAM (object); + + switch (param_id) { + case PROP_NAME: + g_value_set_string (value, stream->priv->name); + break; + case PROP_DEVICE: + g_value_set_object (value, stream->priv->device); + break; + case PROP_FLAGS: + g_value_set_flags (value, stream->priv->flags); + break; + case PROP_STATE: + g_value_set_enum (value, stream->priv->state); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); + break; + } } -gdouble -mate_mixer_stream_get_decibel (MateMixerStream *stream) -{ - MateMixerStreamInterface *iface; - - g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), -MATE_MIXER_INFINITY); - - iface = MATE_MIXER_STREAM_GET_INTERFACE (stream); - - if (iface->get_decibel) - return iface->get_decibel (stream); - - return -MATE_MIXER_INFINITY; +static void +mate_mixer_stream_set_property (GObject *object, + guint param_id, + const GValue *value, + GParamSpec *pspec) +{ + MateMixerStream *stream; + + stream = MATE_MIXER_STREAM (object); + + switch (param_id) { + case PROP_NAME: + /* Construct-only string */ + stream->priv->name = g_value_dup_string (value); + break; + case PROP_DEVICE: + /* Construct-only object */ + stream->priv->device = g_value_dup_object (value); + break; + case PROP_FLAGS: + stream->priv->flags = g_value_get_flags (value); + break; + case PROP_STATE: + stream->priv->state = g_value_get_enum (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); + break; + } } -gboolean -mate_mixer_stream_set_decibel (MateMixerStream *stream, gdouble decibel) +static void +mate_mixer_stream_init (MateMixerStream *stream) { - MateMixerStreamInterface *iface; - - g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), FALSE); - - iface = MATE_MIXER_STREAM_GET_INTERFACE (stream); - - if (iface->set_decibel) - return iface->set_decibel (stream, decibel); - - return FALSE; + stream->priv = G_TYPE_INSTANCE_GET_PRIVATE (stream, + MATE_MIXER_TYPE_STREAM, + MateMixerStreamPrivate); } -guint -mate_mixer_stream_get_num_channels (MateMixerStream *stream) +static void +mate_mixer_stream_dispose (GObject *object) { - MateMixerStreamInterface *iface; - - g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), 0); + MateMixerStream *stream; - iface = MATE_MIXER_STREAM_GET_INTERFACE (stream); + stream = MATE_MIXER_STREAM (object); - if (iface->get_num_channels) - return iface->get_num_channels (stream); + g_clear_object (&stream->priv->device); - return 0; + G_OBJECT_CLASS (mate_mixer_stream_parent_class)->dispose (object); } -MateMixerChannelPosition -mate_mixer_stream_get_channel_position (MateMixerStream *stream, guint channel) +static void +mate_mixer_stream_finalize (GObject *object) { - MateMixerStreamInterface *iface; - - g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), MATE_MIXER_CHANNEL_UNKNOWN); + MateMixerStream *stream; - iface = MATE_MIXER_STREAM_GET_INTERFACE (stream); + stream = MATE_MIXER_STREAM (object); - if (iface->get_channel_position) - return iface->get_channel_position (stream, channel); + g_free (stream->priv->name); - return MATE_MIXER_CHANNEL_UNKNOWN; + G_OBJECT_CLASS (mate_mixer_stream_parent_class)->finalize (object); } -guint -mate_mixer_stream_get_channel_volume (MateMixerStream *stream, guint channel) +const gchar * +mate_mixer_stream_get_name (MateMixerStream *stream) { - MateMixerStreamInterface *iface; - - g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), 0); - - iface = MATE_MIXER_STREAM_GET_INTERFACE (stream); - - if (iface->get_channel_volume) - return iface->get_channel_volume (stream, channel); + g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), NULL); - return 0; + return stream->priv->name; } -gboolean -mate_mixer_stream_set_channel_volume (MateMixerStream *stream, - guint channel, - guint volume) +MateMixerDevice * +mate_mixer_stream_get_device (MateMixerStream *stream) { - MateMixerStreamInterface *iface; - - g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), FALSE); - - iface = MATE_MIXER_STREAM_GET_INTERFACE (stream); - - if (iface->set_channel_volume) - return iface->set_channel_volume (stream, channel, volume); + g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), NULL); - return FALSE; + return stream->priv->device; } -gdouble -mate_mixer_stream_get_channel_decibel (MateMixerStream *stream, guint channel) +MateMixerStreamFlags +mate_mixer_stream_get_flags (MateMixerStream *stream) { - MateMixerStreamInterface *iface; - - g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), -MATE_MIXER_INFINITY); - - iface = MATE_MIXER_STREAM_GET_INTERFACE (stream); - - if (iface->get_channel_decibel) - return iface->get_channel_decibel (stream, channel); + g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), MATE_MIXER_STREAM_NO_FLAGS); - return -MATE_MIXER_INFINITY; + return stream->priv->flags; } -gboolean -mate_mixer_stream_set_channel_decibel (MateMixerStream *stream, - guint channel, - gdouble decibel) +MateMixerStreamState +mate_mixer_stream_get_state (MateMixerStream *stream) { - MateMixerStreamInterface *iface; - - g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), FALSE); - - iface = MATE_MIXER_STREAM_GET_INTERFACE (stream); - - if (iface->set_channel_decibel) - return iface->set_channel_decibel (stream, channel, decibel); + g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), MATE_MIXER_STREAM_STATE_UNKNOWN); - return FALSE; + return stream->priv->state; } -gboolean -mate_mixer_stream_has_channel_position (MateMixerStream *stream, - MateMixerChannelPosition position) +MateMixerStreamControl * +mate_mixer_stream_get_control (MateMixerStream *stream, const gchar *name) { - MateMixerStreamInterface *iface; - - g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), FALSE); - - iface = MATE_MIXER_STREAM_GET_INTERFACE (stream); - - if (iface->has_channel_position) - return iface->has_channel_position (stream, position); + g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), NULL); + g_return_val_if_fail (name != NULL, NULL); - return FALSE; + return MATE_MIXER_STREAM_GET_CLASS (stream)->get_control (stream, name); } -gfloat -mate_mixer_stream_get_balance (MateMixerStream *stream) +MateMixerSwitch * +mate_mixer_stream_get_switch (MateMixerStream *stream, const gchar *name) { - MateMixerStreamInterface *iface; - - g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), 0.0f); - - iface = MATE_MIXER_STREAM_GET_INTERFACE (stream); - - if (iface->get_balance) - return iface->get_balance (stream); + g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), NULL); + g_return_val_if_fail (name != NULL, NULL); - return 0.0f; + return MATE_MIXER_STREAM_GET_CLASS (stream)->get_switch (stream, name); } -gboolean -mate_mixer_stream_set_balance (MateMixerStream *stream, gfloat balance) +MateMixerStreamControl * +mate_mixer_stream_get_default_control (MateMixerStream *stream) { - MateMixerStreamInterface *iface; - - g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), FALSE); - - iface = MATE_MIXER_STREAM_GET_INTERFACE (stream); - - if (iface->set_balance) - return iface->set_balance (stream, balance); + g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), NULL); - return FALSE; + return MATE_MIXER_STREAM_GET_CLASS (stream)->get_default_control (stream); } -gfloat -mate_mixer_stream_get_fade (MateMixerStream *stream) +const GList * +mate_mixer_stream_list_controls (MateMixerStream *stream) { - MateMixerStreamInterface *iface; - - g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), 0.0f); - - iface = MATE_MIXER_STREAM_GET_INTERFACE (stream); + g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), NULL); - if (iface->get_fade) - return iface->get_fade (stream); + if (stream->priv->controls == NULL) + stream->priv->controls = MATE_MIXER_STREAM_GET_CLASS (stream)->list_controls (stream); - return 0.0f; + return (const GList *) stream->priv->controls; } -gboolean -mate_mixer_stream_set_fade (MateMixerStream *stream, gfloat fade) +const GList * +mate_mixer_stream_list_switches (MateMixerStream *stream) { - MateMixerStreamInterface *iface; - - g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), FALSE); + g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), NULL); - iface = MATE_MIXER_STREAM_GET_INTERFACE (stream); + if (stream->priv->switches == NULL) { + MateMixerStreamClass *klass = MATE_MIXER_STREAM_GET_CLASS (stream); - if (iface->set_fade) - return iface->set_fade (stream, fade); + if (klass->list_switches != NULL) + stream->priv->switches = klass->list_switches (stream); + } - return FALSE; + return (const GList *) stream->priv->switches; } gboolean mate_mixer_stream_suspend (MateMixerStream *stream) { - MateMixerStreamInterface *iface; - g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), FALSE); - iface = MATE_MIXER_STREAM_GET_INTERFACE (stream); + if (stream->priv->state == MATE_MIXER_STREAM_STATE_SUSPENDED) + return TRUE; - if (iface->suspend) - return iface->suspend (stream); + if (stream->priv->flags & MATE_MIXER_STREAM_CAN_SUSPEND) + return MATE_MIXER_STREAM_GET_CLASS (stream)->suspend (stream); return FALSE; } @@ -486,178 +346,79 @@ mate_mixer_stream_suspend (MateMixerStream *stream) gboolean mate_mixer_stream_resume (MateMixerStream *stream) { - MateMixerStreamInterface *iface; - g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), FALSE); - iface = MATE_MIXER_STREAM_GET_INTERFACE (stream); + if (stream->priv->state != MATE_MIXER_STREAM_STATE_SUSPENDED) + return TRUE; - if (iface->resume) - return iface->resume (stream); + if (stream->priv->flags & MATE_MIXER_STREAM_CAN_SUSPEND) + return MATE_MIXER_STREAM_GET_CLASS (stream)->resume (stream); return FALSE; } gboolean -mate_mixer_stream_monitor_start (MateMixerStream *stream) +mate_mixer_stream_monitor_get_enabled (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); + return stream->priv->monitor_enabled; } gboolean -mate_mixer_stream_monitor_is_running (MateMixerStream *stream) +mate_mixer_stream_monitor_set_enabled (MateMixerStream *stream, gboolean enabled) { - MateMixerStreamInterface *iface; - g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), FALSE); - iface = MATE_MIXER_STREAM_GET_INTERFACE (stream); + if (stream->priv->monitor_enabled == enabled) + return TRUE; - if (iface->monitor_is_running) - return iface->monitor_is_running (stream); + if (stream->priv->flags & MATE_MIXER_STREAM_HAS_MONITOR) { + if (enabled) + return MATE_MIXER_STREAM_GET_CLASS (stream)->monitor_start (stream); + else + return MATE_MIXER_STREAM_GET_CLASS (stream)->monitor_stop (stream); + } return FALSE; } -gboolean -mate_mixer_stream_monitor_set_name (MateMixerStream *stream, const gchar *name) +static MateMixerStreamControl * +mate_mixer_stream_real_get_control (MateMixerStream *stream, const gchar *name) { - MateMixerStreamInterface *iface; - - g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), FALSE); - - iface = MATE_MIXER_STREAM_GET_INTERFACE (stream); - - if (iface->monitor_set_name) - return iface->monitor_set_name (stream, name); - - return FALSE; -} - -const GList * -mate_mixer_stream_list_ports (MateMixerStream *stream) -{ - MateMixerStreamInterface *iface; + const GList *list; g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), NULL); + g_return_val_if_fail (name != NULL, NULL); - iface = MATE_MIXER_STREAM_GET_INTERFACE (stream); + list = mate_mixer_stream_list_controls (stream); + while (list != NULL) { + MateMixerStreamControl *control = MATE_MIXER_STREAM_CONTROL (list->data); - if (iface->list_ports) - return iface->list_ports (stream); + if (strcmp (name, mate_mixer_stream_control_get_name (control)) == 0) + return control; + list = list->next; + } return NULL; } -MateMixerPort * -mate_mixer_stream_get_active_port (MateMixerStream *stream) +static MateMixerSwitch * +mate_mixer_stream_real_get_switch (MateMixerStream *stream, const gchar *name) { - MateMixerStreamInterface *iface; + const GList *list; g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), NULL); + g_return_val_if_fail (name != NULL, NULL); - iface = MATE_MIXER_STREAM_GET_INTERFACE (stream); + list = mate_mixer_stream_list_switches (stream); + while (list != NULL) { + MateMixerSwitch *swtch = MATE_MIXER_SWITCH (list->data); - if (iface->get_active_port) - return iface->get_active_port (stream); + if (strcmp (name, mate_mixer_switch_get_name (swtch)) == 0) + return swtch; + list = list->next; + } return NULL; } - -gboolean -mate_mixer_stream_set_active_port (MateMixerStream *stream, MateMixerPort *port) -{ - MateMixerStreamInterface *iface; - - g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), FALSE); - g_return_val_if_fail (MATE_MIXER_IS_PORT (port), FALSE); - - iface = MATE_MIXER_STREAM_GET_INTERFACE (stream); - - if (iface->set_active_port) - return iface->set_active_port (stream, port); - - return FALSE; -} - -guint -mate_mixer_stream_get_min_volume (MateMixerStream *stream) -{ - MateMixerStreamInterface *iface; - - g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), 0); - - iface = MATE_MIXER_STREAM_GET_INTERFACE (stream); - - if (iface->get_min_volume) - return iface->get_min_volume (stream); - - return 0; -} - -guint -mate_mixer_stream_get_max_volume (MateMixerStream *stream) -{ - MateMixerStreamInterface *iface; - - g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), 0); - - iface = MATE_MIXER_STREAM_GET_INTERFACE (stream); - - if (iface->get_max_volume) - return iface->get_max_volume (stream); - - return 0; -} - -guint -mate_mixer_stream_get_normal_volume (MateMixerStream *stream) -{ - MateMixerStreamInterface *iface; - - g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), 0); - - iface = MATE_MIXER_STREAM_GET_INTERFACE (stream); - - if (iface->get_normal_volume) - return iface->get_normal_volume (stream); - - return 0; -} - -guint -mate_mixer_stream_get_base_volume (MateMixerStream *stream) -{ - MateMixerStreamInterface *iface; - - g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), 0); - - iface = MATE_MIXER_STREAM_GET_INTERFACE (stream); - - if (iface->get_base_volume) - return iface->get_base_volume (stream); - - return 0; -} diff --git a/libmatemixer/matemixer-stream.h b/libmatemixer/matemixer-stream.h index e91a2a5..e73579e 100644 --- a/libmatemixer/matemixer-stream.h +++ b/libmatemixer/matemixer-stream.h @@ -18,164 +18,87 @@ #ifndef MATEMIXER_STREAM_H #define MATEMIXER_STREAM_H -#include <math.h> #include <glib.h> #include <glib-object.h> -#include <libmatemixer/matemixer-device.h> #include <libmatemixer/matemixer-enums.h> -#include <libmatemixer/matemixer-port.h> +#include <libmatemixer/matemixer-types.h> G_BEGIN_DECLS -#ifdef INFINITY -#define MATE_MIXER_INFINITY INFINITY -#else -#define MATE_MIXER_INFINITY G_MAXDOUBLE -#endif - #define MATE_MIXER_TYPE_STREAM \ (mate_mixer_stream_get_type ()) #define MATE_MIXER_STREAM(o) \ (G_TYPE_CHECK_INSTANCE_CAST ((o), MATE_MIXER_TYPE_STREAM, MateMixerStream)) #define MATE_MIXER_IS_STREAM(o) \ (G_TYPE_CHECK_INSTANCE_TYPE ((o), MATE_MIXER_TYPE_STREAM)) -#define MATE_MIXER_STREAM_GET_INTERFACE(o) \ - (G_TYPE_INSTANCE_GET_INTERFACE ((o), MATE_MIXER_TYPE_STREAM, MateMixerStreamInterface)) +#define MATE_MIXER_STREAM_CLASS(k) \ + (G_TYPE_CHECK_CLASS_CAST ((k), MATE_MIXER_TYPE_STREAM, MateMixerStreamClass)) +#define MATE_MIXER_IS_STREAM_CLASS(k) \ + (G_TYPE_CHECK_CLASS_TYPE ((k), MATE_MIXER_TYPE_STREAM)) +#define MATE_MIXER_STREAM_GET_CLASS(o) \ + (G_TYPE_INSTANCE_GET_CLASS ((o), MATE_MIXER_TYPE_STREAM, MateMixerStreamClass)) -typedef struct _MateMixerStream MateMixerStream; /* dummy object */ -typedef struct _MateMixerStreamInterface MateMixerStreamInterface; +typedef struct _MateMixerStreamClass MateMixerStreamClass; +typedef struct _MateMixerStreamPrivate MateMixerStreamPrivate; -struct _MateMixerStreamInterface +struct _MateMixerStream { - GTypeInterface parent_iface; + GObject object; /*< private >*/ - /* Virtual table */ - const gchar * (*get_name) (MateMixerStream *stream); - const gchar * (*get_description) (MateMixerStream *stream); - MateMixerDevice * (*get_device) (MateMixerStream *stream); - MateMixerStreamFlags (*get_flags) (MateMixerStream *stream); - MateMixerStreamState (*get_state) (MateMixerStream *stream); - gboolean (*get_mute) (MateMixerStream *stream); - gboolean (*set_mute) (MateMixerStream *stream, - gboolean mute); - guint (*get_num_channels) (MateMixerStream *stream); - guint (*get_volume) (MateMixerStream *stream); - gboolean (*set_volume) (MateMixerStream *stream, - guint volume); - gdouble (*get_decibel) (MateMixerStream *stream); - gboolean (*set_decibel) (MateMixerStream *stream, - gdouble decibel); - MateMixerChannelPosition (*get_channel_position) (MateMixerStream *stream, - guint channel); - guint (*get_channel_volume) (MateMixerStream *stream, - guint channel); - gboolean (*set_channel_volume) (MateMixerStream *stream, - guint channel, - guint volume); - gdouble (*get_channel_decibel) (MateMixerStream *stream, - guint channel); - gboolean (*set_channel_decibel) (MateMixerStream *stream, - guint channel, - gdouble decibel); - gboolean (*has_channel_position) (MateMixerStream *stream, - MateMixerChannelPosition position); - gfloat (*get_balance) (MateMixerStream *stream); - gboolean (*set_balance) (MateMixerStream *stream, - gfloat balance); - gfloat (*get_fade) (MateMixerStream *stream); - gboolean (*set_fade) (MateMixerStream *stream, - gfloat 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); - gboolean (*monitor_set_name) (MateMixerStream *stream, - const gchar *name); - const GList * (*list_ports) (MateMixerStream *stream); - MateMixerPort * (*get_active_port) (MateMixerStream *stream); - gboolean (*set_active_port) (MateMixerStream *stream, - MateMixerPort *port); - guint (*get_min_volume) (MateMixerStream *stream); - guint (*get_max_volume) (MateMixerStream *stream); - guint (*get_normal_volume) (MateMixerStream *stream); - guint (*get_base_volume) (MateMixerStream *stream); - - /* Signals */ - void (*monitor_value) (MateMixerStream *stream, - gdouble value); + MateMixerStreamPrivate *priv; }; -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); -MateMixerDevice * mate_mixer_stream_get_device (MateMixerStream *stream); -MateMixerStreamFlags mate_mixer_stream_get_flags (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, - gboolean mute); - -guint mate_mixer_stream_get_num_channels (MateMixerStream *stream); +struct _MateMixerStreamClass +{ + GObjectClass parent_class; -guint mate_mixer_stream_get_volume (MateMixerStream *stream); -gboolean mate_mixer_stream_set_volume (MateMixerStream *stream, - guint volume); + /*< private >*/ + MateMixerStreamControl *(*get_control) (MateMixerStream *stream, + const gchar *name); -gdouble mate_mixer_stream_get_decibel (MateMixerStream *stream); -gboolean mate_mixer_stream_set_decibel (MateMixerStream *stream, - gdouble decibel); + MateMixerStreamControl *(*get_default_control) (MateMixerStream *stream); -MateMixerChannelPosition mate_mixer_stream_get_channel_position (MateMixerStream *stream, - guint channel); + MateMixerSwitch *(*get_switch) (MateMixerStream *stream, + const gchar *name); -guint mate_mixer_stream_get_channel_volume (MateMixerStream *stream, - guint channel); -gboolean mate_mixer_stream_set_channel_volume (MateMixerStream *stream, - guint channel, - guint volume); + GList *(*list_controls) (MateMixerStream *stream); + GList *(*list_switches) (MateMixerStream *stream); -gdouble mate_mixer_stream_get_channel_decibel (MateMixerStream *stream, - guint channel); -gboolean mate_mixer_stream_set_channel_decibel (MateMixerStream *stream, - guint channel, - gdouble decibel); + gboolean (*suspend) (MateMixerStream *stream); + gboolean (*resume) (MateMixerStream *stream); -gboolean mate_mixer_stream_has_channel_position (MateMixerStream *stream, - MateMixerChannelPosition position); + gboolean (*monitor_start) (MateMixerStream *stream); + gboolean (*monitor_stop) (MateMixerStream *stream); -gfloat mate_mixer_stream_get_balance (MateMixerStream *stream); -gboolean mate_mixer_stream_set_balance (MateMixerStream *stream, - gfloat balance); + /* Signals */ + void (*monitor_value) (MateMixerStream *stream, gdouble value); +}; -gfloat mate_mixer_stream_get_fade (MateMixerStream *stream); -gboolean mate_mixer_stream_set_fade (MateMixerStream *stream, - gfloat fade); +GType mate_mixer_stream_get_type (void) G_GNUC_CONST; -gboolean mate_mixer_stream_suspend (MateMixerStream *stream); -gboolean mate_mixer_stream_resume (MateMixerStream *stream); +const gchar * mate_mixer_stream_get_name (MateMixerStream *stream); +MateMixerDevice * mate_mixer_stream_get_device (MateMixerStream *stream); +MateMixerStreamFlags mate_mixer_stream_get_flags (MateMixerStream *stream); +MateMixerStreamState mate_mixer_stream_get_state (MateMixerStream *stream); -gboolean mate_mixer_stream_monitor_start (MateMixerStream *stream); -void mate_mixer_stream_monitor_stop (MateMixerStream *stream); +MateMixerStreamControl *mate_mixer_stream_get_control (MateMixerStream *stream, + const gchar *name); +MateMixerSwitch * mate_mixer_stream_get_switch (MateMixerStream *stream, + const gchar *name); -gboolean mate_mixer_stream_monitor_is_running (MateMixerStream *stream); -gboolean mate_mixer_stream_monitor_set_name (MateMixerStream *stream, - const gchar *name); +MateMixerStreamControl *mate_mixer_stream_get_default_control (MateMixerStream *stream); -const GList * mate_mixer_stream_list_ports (MateMixerStream *stream); +const GList * mate_mixer_stream_list_controls (MateMixerStream *stream); +const GList * mate_mixer_stream_list_switches (MateMixerStream *stream); -MateMixerPort * mate_mixer_stream_get_active_port (MateMixerStream *stream); -gboolean mate_mixer_stream_set_active_port (MateMixerStream *stream, - MateMixerPort *port); +gboolean mate_mixer_stream_suspend (MateMixerStream *stream); +gboolean mate_mixer_stream_resume (MateMixerStream *stream); -guint mate_mixer_stream_get_min_volume (MateMixerStream *stream); -guint mate_mixer_stream_get_max_volume (MateMixerStream *stream); -guint mate_mixer_stream_get_normal_volume (MateMixerStream *stream); -guint mate_mixer_stream_get_base_volume (MateMixerStream *stream); +gboolean mate_mixer_stream_monitor_get_enabled (MateMixerStream *stream); +gboolean mate_mixer_stream_monitor_set_enabled (MateMixerStream *stream, + gboolean enabled); G_END_DECLS diff --git a/libmatemixer/matemixer-switch-option-private.h b/libmatemixer/matemixer-switch-option-private.h new file mode 100644 index 0000000..dea7583 --- /dev/null +++ b/libmatemixer/matemixer-switch-option-private.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2014 Michal Ratajsky <[email protected]> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the licence, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef MATEMIXER_SWITCH_OPTION_PRIVATE_H +#define MATEMIXER_SWITCH_OPTION_PRIVATE_H + +#include <glib.h> + +#include "matemixer-switch-option.h" + +G_BEGIN_DECLS + +MateMixerSwitchOption *_mate_mixer_switch_option_new (const gchar *name, + const gchar *label, + const gchar *icon); + +G_END_DECLS + +#endif /* MATEMIXER_SWITCH_OPTION_PRIVATE_H */ diff --git a/libmatemixer/matemixer-switch-option.c b/libmatemixer/matemixer-switch-option.c new file mode 100644 index 0000000..e924b46 --- /dev/null +++ b/libmatemixer/matemixer-switch-option.c @@ -0,0 +1,224 @@ +/* + * Copyright (C) 2014 Michal Ratajsky <[email protected]> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the licence, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see <http://www.gnu.org/licenses/>. + */ + +#include <glib.h> +#include <glib-object.h> + +#include "matemixer-switch-option.h" +#include "matemixer-switch-option-private.h" + +/** + * SECTION:matemixer-stream-switch-option + * @include: libmatemixer/matemixer.h + */ + +struct _MateMixerSwitchOptionPrivate +{ + gchar *name; + gchar *label; + gchar *icon; +}; + +enum { + PROP_0, + PROP_NAME, + PROP_LABEL, + PROP_ICON, + N_PROPERTIES +}; + +static GParamSpec *properties[N_PROPERTIES] = { NULL, }; + +static void mate_mixer_switch_option_class_init (MateMixerSwitchOptionClass *klass); + +static void mate_mixer_switch_option_get_property (GObject *object, + guint param_id, + GValue *value, + GParamSpec *pspec); +static void mate_mixer_switch_option_set_property (GObject *object, + guint param_id, + const GValue *value, + GParamSpec *pspec); + +static void mate_mixer_switch_option_init (MateMixerSwitchOption *option); +static void mate_mixer_switch_option_finalize (GObject *object); + +G_DEFINE_TYPE (MateMixerSwitchOption, mate_mixer_switch_option, G_TYPE_OBJECT) + +static void +mate_mixer_switch_option_class_init (MateMixerSwitchOptionClass *klass) +{ + GObjectClass *object_class; + + object_class = G_OBJECT_CLASS (klass); + object_class->finalize = mate_mixer_switch_option_finalize; + object_class->get_property = mate_mixer_switch_option_get_property; + object_class->set_property = mate_mixer_switch_option_set_property; + + properties[PROP_NAME] = + g_param_spec_string ("name", + "Name", + "Name of the switch option", + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + + properties[PROP_LABEL] = + g_param_spec_string ("label", + "Label", + "Label of the switch option", + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + + properties[PROP_ICON] = + g_param_spec_string ("icon", + "Icon", + "Icon of the switch option", + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties (object_class, N_PROPERTIES, properties); + + g_type_class_add_private (object_class, sizeof (MateMixerSwitchOptionPrivate)); +} + +static void +mate_mixer_switch_option_get_property (GObject *object, + guint param_id, + GValue *value, + GParamSpec *pspec) +{ + MateMixerSwitchOption *option; + + option = MATE_MIXER_SWITCH_OPTION (object); + + switch (param_id) { + case PROP_NAME: + g_value_set_string (value, option->priv->name); + break; + case PROP_LABEL: + g_value_set_string (value, option->priv->label); + break; + case PROP_ICON: + g_value_set_string (value, option->priv->icon); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); + break; + } +} + +static void +mate_mixer_switch_option_set_property (GObject *object, + guint param_id, + const GValue *value, + GParamSpec *pspec) +{ + MateMixerSwitchOption *option; + + option = MATE_MIXER_SWITCH_OPTION (object); + + switch (param_id) { + case PROP_NAME: + /* Construct-only string */ + option->priv->name = g_value_dup_string (value); + break; + case PROP_LABEL: + /* Construct-only string */ + option->priv->label = g_value_dup_string (value); + break; + case PROP_ICON: + /* Construct-only string */ + option->priv->icon = g_value_dup_string (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); + break; + } +} + +static void +mate_mixer_switch_option_init (MateMixerSwitchOption *option) +{ + option->priv = G_TYPE_INSTANCE_GET_PRIVATE (option, + MATE_MIXER_TYPE_SWITCH_OPTION, + MateMixerSwitchOptionPrivate); +} + +static void +mate_mixer_switch_option_finalize (GObject *object) +{ + MateMixerSwitchOption *option; + + option = MATE_MIXER_SWITCH_OPTION (object); + + g_free (option->priv->name); + g_free (option->priv->label); + g_free (option->priv->icon); + + G_OBJECT_CLASS (mate_mixer_switch_option_parent_class)->finalize (object); +} + +/** + * mate_mixer_switch_option_get_name: + */ +const gchar * +mate_mixer_switch_option_get_name (MateMixerSwitchOption *option) +{ + g_return_val_if_fail (MATE_MIXER_IS_SWITCH_OPTION (option), NULL); + + return option->priv->name; +} + +/** + * mate_mixer_switch_option_get_label: + */ +const gchar * +mate_mixer_switch_option_get_label (MateMixerSwitchOption *option) +{ + g_return_val_if_fail (MATE_MIXER_IS_SWITCH_OPTION (option), NULL); + + return option->priv->label; +} + +/** + * mate_mixer_switch_option_get_icon: + */ +const gchar * +mate_mixer_switch_option_get_icon (MateMixerSwitchOption *option) +{ + g_return_val_if_fail (MATE_MIXER_IS_SWITCH_OPTION (option), NULL); + + return option->priv->icon; +} + +MateMixerSwitchOption * +_mate_mixer_switch_option_new (const gchar *name, + const gchar *label, + const gchar *icon) +{ + return g_object_new (MATE_MIXER_TYPE_SWITCH_OPTION, + "name", name, + "label", label, + "icon", icon, + NULL); +} diff --git a/libmatemixer/matemixer-switch-option.h b/libmatemixer/matemixer-switch-option.h new file mode 100644 index 0000000..b02c42c --- /dev/null +++ b/libmatemixer/matemixer-switch-option.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2014 Michal Ratajsky <[email protected]> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the licence, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef MATEMIXER_SWITCH_OPTION_H +#define MATEMIXER_SWITCH_OPTION_H + +#include <glib.h> +#include <glib-object.h> +#include <libmatemixer/matemixer-types.h> + +G_BEGIN_DECLS + +#define MATE_MIXER_TYPE_SWITCH_OPTION \ + (mate_mixer_switch_option_get_type ()) +#define MATE_MIXER_SWITCH_OPTION(o) \ + (G_TYPE_CHECK_INSTANCE_CAST ((o), MATE_MIXER_TYPE_SWITCH_OPTION, MateMixerSwitchOption)) +#define MATE_MIXER_IS_SWITCH_OPTION(o) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((o), MATE_MIXER_TYPE_SWITCH_OPTION)) +#define MATE_MIXER_SWITCH_OPTION_CLASS(k) \ + (G_TYPE_CHECK_CLASS_CAST ((k), MATE_MIXER_TYPE_SWITCH_OPTION, MateMixerSwitchOptionClass)) +#define MATE_MIXER_IS_SWITCH_OPTION_CLASS(k) \ + (G_TYPE_CHECK_CLASS_TYPE ((k), MATE_MIXER_TYPE_SWITCH_OPTION)) +#define MATE_MIXER_SWITCH_OPTION_GET_CLASS(o) \ + (G_TYPE_INSTANCE_GET_CLASS ((o), MATE_MIXER_TYPE_SWITCH_OPTION, MateMixerSwitchOptionClass)) + +typedef struct _MateMixerSwitchOptionClass MateMixerSwitchOptionClass; +typedef struct _MateMixerSwitchOptionPrivate MateMixerSwitchOptionPrivate; + +struct _MateMixerSwitchOption +{ + GObject parent; + + /*< private >*/ + MateMixerSwitchOptionPrivate *priv; +}; + +struct _MateMixerSwitchOptionClass +{ + GObjectClass parent_class; +}; + +GType mate_mixer_switch_option_get_type (void) G_GNUC_CONST; + +const gchar *mate_mixer_switch_option_get_name (MateMixerSwitchOption *option); +const gchar *mate_mixer_switch_option_get_label (MateMixerSwitchOption *option); +const gchar *mate_mixer_switch_option_get_icon (MateMixerSwitchOption *option); + +G_END_DECLS + +#endif /* MATEMIXER_SWITCH_OPTION_H */ diff --git a/libmatemixer/matemixer-switch-private.h b/libmatemixer/matemixer-switch-private.h new file mode 100644 index 0000000..42390a9 --- /dev/null +++ b/libmatemixer/matemixer-switch-private.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2014 Michal Ratajsky <[email protected]> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the licence, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef MATEMIXER_SWITCH_PRIVATE_H +#define MATEMIXER_SWITCH_PRIVATE_H + +#include <glib.h> +#include "matemixer-types.h" + +G_BEGIN_DECLS + +void _mate_mixer_switch_set_active_option (MateMixerSwitch *sw, + MateMixerSwitchOption *option); + +G_END_DECLS + +#endif /* MATEMIXER_SWITCH_PRIVATE_H */ diff --git a/libmatemixer/matemixer-switch.c b/libmatemixer/matemixer-switch.c new file mode 100644 index 0000000..b30e405 --- /dev/null +++ b/libmatemixer/matemixer-switch.c @@ -0,0 +1,283 @@ +/* + * Copyright (C) 2014 Michal Ratajsky <[email protected]> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the licence, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see <http://www.gnu.org/licenses/>. + */ + +#include <string.h> +#include <glib.h> +#include <glib-object.h> + +#include "matemixer-enums.h" +#include "matemixer-enum-types.h" +#include "matemixer-switch.h" +#include "matemixer-switch-private.h" +#include "matemixer-switch-option.h" + +/** + * SECTION:matemixer-switch + * @include: libmatemixer/matemixer.h + */ + +struct _MateMixerSwitchPrivate +{ + gchar *name; + gchar *label; + GList *options; + MateMixerSwitchOption *active; +}; + +enum { + PROP_0, + PROP_NAME, + PROP_LABEL, + PROP_ACTIVE_OPTION, + N_PROPERTIES +}; + +static GParamSpec *properties[N_PROPERTIES] = { NULL, }; + +static void mate_mixer_switch_class_init (MateMixerSwitchClass *klass); + +static void mate_mixer_switch_get_property (GObject *object, + guint param_id, + GValue *value, + GParamSpec *pspec); +static void mate_mixer_switch_set_property (GObject *object, + guint param_id, + const GValue *value, + GParamSpec *pspec); + +static void mate_mixer_switch_init (MateMixerSwitch *swtch); +static void mate_mixer_switch_finalize (GObject *object); + +G_DEFINE_ABSTRACT_TYPE (MateMixerSwitch, mate_mixer_switch, G_TYPE_OBJECT) + +static MateMixerSwitchOption *mate_mixer_switch_real_get_option (MateMixerSwitch *swtch, + const gchar *name); + +static void +mate_mixer_switch_class_init (MateMixerSwitchClass *klass) +{ + GObjectClass *object_class; + + klass->get_option = mate_mixer_switch_real_get_option; + + object_class = G_OBJECT_CLASS (klass); + object_class->finalize = mate_mixer_switch_finalize; + object_class->get_property = mate_mixer_switch_get_property; + object_class->set_property = mate_mixer_switch_set_property; + + properties[PROP_NAME] = + g_param_spec_string ("name", + "Name", + "Name of the switch", + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + + properties[PROP_LABEL] = + g_param_spec_string ("label", + "Label", + "Label of the switch", + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + + properties[PROP_ACTIVE_OPTION] = + g_param_spec_object ("active-option", + "Active option", + "Active option of the switch", + MATE_MIXER_TYPE_SWITCH_OPTION, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties (object_class, N_PROPERTIES, properties); + + g_type_class_add_private (object_class, sizeof (MateMixerSwitchPrivate)); +} + +static void +mate_mixer_switch_get_property (GObject *object, + guint param_id, + GValue *value, + GParamSpec *pspec) +{ + MateMixerSwitch *swtch; + + swtch = MATE_MIXER_SWITCH (object); + + switch (param_id) { + case PROP_NAME: + g_value_set_string (value, swtch->priv->name); + break; + case PROP_LABEL: + g_value_set_string (value, swtch->priv->label); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); + break; + } +} + +static void +mate_mixer_switch_set_property (GObject *object, + guint param_id, + const GValue *value, + GParamSpec *pspec) +{ + MateMixerSwitch *swtch; + + swtch = MATE_MIXER_SWITCH (object); + + switch (param_id) { + case PROP_NAME: + /* Construct-only string */ + swtch->priv->name = g_value_dup_string (value); + break; + case PROP_LABEL: + /* Construct-only string */ + swtch->priv->label = g_value_dup_string (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); + break; + } +} + +static void +mate_mixer_switch_init (MateMixerSwitch *swtch) +{ + swtch->priv = G_TYPE_INSTANCE_GET_PRIVATE (swtch, + MATE_MIXER_TYPE_SWITCH, + MateMixerSwitchPrivate); +} + +static void +mate_mixer_switch_finalize (GObject *object) +{ + MateMixerSwitch *swtch; + + swtch = MATE_MIXER_SWITCH (object); + + g_free (swtch->priv->name); + g_free (swtch->priv->label); + + G_OBJECT_CLASS (mate_mixer_switch_parent_class)->finalize (object); +} + +const gchar * +mate_mixer_switch_get_name (MateMixerSwitch *swtch) +{ + g_return_val_if_fail (MATE_MIXER_IS_SWITCH (swtch), NULL); + + return swtch->priv->name; +} + +const gchar * +mate_mixer_switch_get_label (MateMixerSwitch *swtch) +{ + g_return_val_if_fail (MATE_MIXER_IS_SWITCH (swtch), NULL); + + return swtch->priv->label; +} + +MateMixerSwitchOption * +mate_mixer_switch_get_option (MateMixerSwitch *swtch, const gchar *name) +{ + g_return_val_if_fail (MATE_MIXER_IS_SWITCH (swtch), NULL); + + return MATE_MIXER_SWITCH_GET_CLASS (swtch)->get_option (swtch, name); +} + +MateMixerSwitchOption * +mate_mixer_switch_get_active_option (MateMixerSwitch *swtch) +{ + g_return_val_if_fail (MATE_MIXER_IS_SWITCH (swtch), NULL); + + return swtch->priv->active; +} + +gboolean +mate_mixer_switch_set_active_option (MateMixerSwitch *swtch, + MateMixerSwitchOption *option) +{ + MateMixerSwitchClass *klass; + + g_return_val_if_fail (MATE_MIXER_IS_SWITCH (swtch), FALSE); + + klass = MATE_MIXER_SWITCH_GET_CLASS (swtch); + if (klass->set_active_option != NULL) { + if (klass->set_active_option (swtch, option) == FALSE) + return FALSE; + + _mate_mixer_switch_set_active_option (swtch, option); + return TRUE; + } + return FALSE; +} + +const GList * +mate_mixer_switch_list_options (MateMixerSwitch *swtch) +{ + g_return_val_if_fail (MATE_MIXER_IS_SWITCH (swtch), NULL); + + if (swtch->priv->options == NULL) { + MateMixerSwitchClass *klass = MATE_MIXER_SWITCH_GET_CLASS (swtch); + + if (klass->list_options != NULL) + swtch->priv->options = klass->list_options (swtch); + } + return (const GList *) swtch->priv->options; +} + +void +_mate_mixer_switch_set_active_option (MateMixerSwitch *swtch, + MateMixerSwitchOption *option) +{ + g_return_if_fail (MATE_MIXER_IS_SWITCH (swtch)); + g_return_if_fail (MATE_MIXER_IS_SWITCH_OPTION (option)); + + if (swtch->priv->active == option) + return; + + if (swtch->priv->active != NULL) + g_object_unref (swtch->priv->active); + + swtch->priv->active = g_object_ref (option); + + g_object_notify_by_pspec (G_OBJECT (swtch), properties[PROP_ACTIVE_OPTION]); +} + +static MateMixerSwitchOption * +mate_mixer_switch_real_get_option (MateMixerSwitch *swtch, const gchar *name) +{ + const GList *list; + + g_return_val_if_fail (MATE_MIXER_IS_SWITCH (swtch), NULL); + g_return_val_if_fail (name != NULL, NULL); + + list = mate_mixer_switch_list_options (swtch); + while (list != NULL) { + MateMixerSwitchOption *option = MATE_MIXER_SWITCH_OPTION (list->data); + + if (strcmp (name, mate_mixer_switch_option_get_name (option)) == 0) + return option; + + list = list->next; + } + return NULL; +} diff --git a/libmatemixer/matemixer-switch.h b/libmatemixer/matemixer-switch.h new file mode 100644 index 0000000..3035607 --- /dev/null +++ b/libmatemixer/matemixer-switch.h @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2014 Michal Ratajsky <[email protected]> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the licence, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef MATEMIXER_SWITCH_H +#define MATEMIXER_SWITCH_H + +#include <glib.h> +#include <glib-object.h> + +#include <libmatemixer/matemixer-types.h> + +G_BEGIN_DECLS + +#define MATE_MIXER_TYPE_SWITCH \ + (mate_mixer_switch_get_type ()) +#define MATE_MIXER_SWITCH(o) \ + (G_TYPE_CHECK_INSTANCE_CAST ((o), MATE_MIXER_TYPE_SWITCH, MateMixerSwitch)) +#define MATE_MIXER_IS_SWITCH(o) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((o), MATE_MIXER_TYPE_SWITCH)) +#define MATE_MIXER_SWITCH_CLASS(k) \ + (G_TYPE_CHECK_CLASS_CAST ((k), MATE_MIXER_TYPE_SWITCH, MateMixerSwitchClass)) +#define MATE_MIXER_IS_SWITCH_CLASS(k) \ + (G_TYPE_CHECK_CLASS_TYPE ((k), MATE_MIXER_TYPE_SWITCH)) +#define MATE_MIXER_SWITCH_GET_CLASS(o) \ + (G_TYPE_INSTANCE_GET_CLASS ((o), MATE_MIXER_TYPE_SWITCH, MateMixerSwitchClass)) + +typedef struct _MateMixerSwitchClass MateMixerSwitchClass; +typedef struct _MateMixerSwitchPrivate MateMixerSwitchPrivate; + +struct _MateMixerSwitch +{ + GObject object; + + /*< private >*/ + MateMixerSwitchPrivate *priv; +}; + +struct _MateMixerSwitchClass +{ + GObjectClass parent_class; + + /*< private >*/ + MateMixerSwitchOption *(*get_option) (MateMixerSwitch *swtch, + const gchar *name); + + gboolean (*set_active_option) (MateMixerSwitch *swtch, + MateMixerSwitchOption *option); + + GList *(*list_options) (MateMixerSwitch *swtch); +}; + +GType mate_mixer_switch_get_type (void) G_GNUC_CONST; + +const gchar * mate_mixer_switch_get_name (MateMixerSwitch *swtch); +const gchar * mate_mixer_switch_get_label (MateMixerSwitch *swtch); + +MateMixerSwitchOption *mate_mixer_switch_get_option (MateMixerSwitch *swtch, + const gchar *name); + +MateMixerSwitchOption *mate_mixer_switch_get_active_option (MateMixerSwitch *swtch); +gboolean mate_mixer_switch_set_active_option (MateMixerSwitch *swtch, + MateMixerSwitchOption *option); + +const GList * mate_mixer_switch_list_options (MateMixerSwitch *swtch); + +G_END_DECLS + +#endif /* MATEMIXER_SWITCH_H */ diff --git a/libmatemixer/matemixer-toggle.c b/libmatemixer/matemixer-toggle.c new file mode 100644 index 0000000..2eea599 --- /dev/null +++ b/libmatemixer/matemixer-toggle.c @@ -0,0 +1,254 @@ +/* + * Copyright (C) 2014 Michal Ratajsky <[email protected]> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the licence, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see <http://www.gnu.org/licenses/>. + */ + +#include <string.h> +#include <glib.h> +#include <glib-object.h> + +#include "matemixer-switch.h" +#include "matemixer-switch-option.h" +#include "matemixer-toggle.h" + +/** + * SECTION:matemixer-toggle + * @include: libmatemixer/matemixer.h + */ + +struct _MateMixerTogglePrivate +{ + MateMixerSwitchOption *on; + MateMixerSwitchOption *off; +}; + +enum { + PROP_0, + PROP_STATE, + PROP_STATE_OPTION_ON, + PROP_STATE_OPTION_OFF, + N_PROPERTIES +}; + +static GParamSpec *properties[N_PROPERTIES] = { NULL, }; + +static void mate_mixer_toggle_class_init (MateMixerToggleClass *klass); + +static void mate_mixer_toggle_get_property (GObject *object, + guint param_id, + GValue *value, + GParamSpec *pspec); +static void mate_mixer_toggle_set_property (GObject *object, + guint param_id, + const GValue *value, + GParamSpec *pspec); + +static void mate_mixer_toggle_init (MateMixerToggle *toggle); +static void mate_mixer_toggle_dispose (GObject *object); + +G_DEFINE_ABSTRACT_TYPE (MateMixerToggle, mate_mixer_toggle, MATE_MIXER_TYPE_SWITCH) + +static MateMixerSwitchOption *mate_mixer_toggle_get_option (MateMixerSwitch *swtch, + const gchar *name); + +static GList * mate_mixer_toggle_list_options (MateMixerSwitch *swtch); + +static void +mate_mixer_toggle_class_init (MateMixerToggleClass *klass) +{ + GObjectClass *object_class; + MateMixerSwitchClass *switch_class; + + object_class = G_OBJECT_CLASS (klass); + object_class->dispose = mate_mixer_toggle_dispose; + object_class->get_property = mate_mixer_toggle_get_property; + object_class->set_property = mate_mixer_toggle_set_property; + + switch_class = MATE_MIXER_SWITCH_CLASS (klass); + switch_class->get_option = mate_mixer_toggle_get_option; + switch_class->list_options = mate_mixer_toggle_list_options; + + properties[PROP_STATE] = + g_param_spec_boolean ("state", + "State", + "Current state", + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); + + properties[PROP_STATE_OPTION_ON] = + g_param_spec_object ("state-option-on", + "State option for on", + "Option corresponding to the 'on' value of the toggle", + MATE_MIXER_TYPE_SWITCH_OPTION, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + + properties[PROP_STATE_OPTION_OFF] = + g_param_spec_object ("state-option-off", + "State option for off", + "Option corresponding to the 'off' value of the toggle", + MATE_MIXER_TYPE_SWITCH_OPTION, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties (object_class, N_PROPERTIES, properties); + + g_type_class_add_private (object_class, sizeof (MateMixerTogglePrivate)); +} + +static void +mate_mixer_toggle_get_property (GObject *object, + guint param_id, + GValue *value, + GParamSpec *pspec) +{ + MateMixerToggle *toggle; + + toggle = MATE_MIXER_TOGGLE (object); + + switch (param_id) { + case PROP_STATE: + g_value_set_boolean (value, mate_mixer_toggle_get_state (toggle)); + break; + case PROP_STATE_OPTION_ON: + g_value_set_object (value, toggle->priv->on); + break; + case PROP_STATE_OPTION_OFF: + g_value_set_object (value, toggle->priv->off); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); + break; + } +} + +static void +mate_mixer_toggle_set_property (GObject *object, + guint param_id, + const GValue *value, + GParamSpec *pspec) +{ + MateMixerToggle *toggle; + + toggle = MATE_MIXER_TOGGLE (object); + + switch (param_id) { + case PROP_STATE_OPTION_ON: + /* Construct-only object */ + toggle->priv->on = g_value_dup_object (value); + break; + case PROP_STATE_OPTION_OFF: + /* Construct-only object */ + toggle->priv->off = g_value_dup_object (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); + break; + } +} + +static void +mate_mixer_toggle_init (MateMixerToggle *toggle) +{ + toggle->priv = G_TYPE_INSTANCE_GET_PRIVATE (toggle, + MATE_MIXER_TYPE_TOGGLE, + MateMixerTogglePrivate); +} + +static void +mate_mixer_toggle_dispose (GObject *object) +{ + MateMixerToggle *toggle; + + toggle = MATE_MIXER_TOGGLE (object); + + g_clear_object (&toggle->priv->on); + g_clear_object (&toggle->priv->off); + + G_OBJECT_CLASS (mate_mixer_toggle_parent_class)->dispose (object); +} + +gboolean +mate_mixer_toggle_get_state (MateMixerToggle *toggle) +{ + MateMixerSwitchOption *active; + + g_return_val_if_fail (MATE_MIXER_IS_TOGGLE (toggle), FALSE); + + active = mate_mixer_switch_get_active_option (MATE_MIXER_SWITCH (toggle)); + if (active == toggle->priv->on) + return TRUE; + else + return FALSE; +} + +MateMixerSwitchOption * +mate_mixer_toggle_get_state_option (MateMixerToggle *toggle, gboolean state) +{ + g_return_val_if_fail (MATE_MIXER_IS_TOGGLE (toggle), NULL); + + if (state == TRUE) + return toggle->priv->on; + else + return toggle->priv->off; +} + +gboolean +mate_mixer_toggle_set_state (MateMixerToggle *toggle, gboolean state) +{ + MateMixerSwitchOption *active; + + g_return_val_if_fail (MATE_MIXER_IS_TOGGLE (toggle), FALSE); + + if (state == TRUE) + active = toggle->priv->on; + else + active = toggle->priv->off; + + return mate_mixer_switch_set_active_option (MATE_MIXER_SWITCH (toggle), active); +} + +static MateMixerSwitchOption * +mate_mixer_toggle_get_option (MateMixerSwitch *swtch, const gchar *name) +{ + MateMixerToggle *toggle; + + g_return_val_if_fail (MATE_MIXER_IS_TOGGLE (swtch), NULL); + + toggle = MATE_MIXER_TOGGLE (swtch); + + if (strcmp (name, mate_mixer_switch_option_get_name (toggle->priv->on)) == 0) + return toggle->priv->on; + if (strcmp (name, mate_mixer_switch_option_get_name (toggle->priv->off)) == 0) + return toggle->priv->off; + + return NULL; +} + +static GList * +mate_mixer_toggle_list_options (MateMixerSwitch *swtch) +{ + GList *list = NULL; + + g_return_val_if_fail (MATE_MIXER_IS_TOGGLE (swtch), NULL); + + list = g_list_prepend (list, MATE_MIXER_TOGGLE (swtch)->priv->off); + list = g_list_prepend (list, MATE_MIXER_TOGGLE (swtch)->priv->on); + + return list; +} diff --git a/libmatemixer/matemixer-toggle.h b/libmatemixer/matemixer-toggle.h new file mode 100644 index 0000000..1cedfc5 --- /dev/null +++ b/libmatemixer/matemixer-toggle.h @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2014 Michal Ratajsky <[email protected]> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the licence, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef MATEMIXER_TOGGLE_H +#define MATEMIXER_TOGGLE_H + +#include <glib.h> +#include <glib-object.h> + +#include <libmatemixer/matemixer-types.h> + +G_BEGIN_DECLS + +#define MATE_MIXER_TYPE_TOGGLE \ + (mate_mixer_toggle_get_type ()) +#define MATE_MIXER_TOGGLE(o) \ + (G_TYPE_CHECK_INSTANCE_CAST ((o), MATE_MIXER_TYPE_TOGGLE, MateMixerToggle)) +#define MATE_MIXER_IS_TOGGLE(o) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((o), MATE_MIXER_TYPE_TOGGLE)) +#define MATE_MIXER_TOGGLE_CLASS(k) \ + (G_TYPE_CHECK_CLASS_CAST ((k), MATE_MIXER_TYPE_TOGGLE, MateMixerToggleClass)) +#define MATE_MIXER_IS_TOGGLE_CLASS(k) \ + (G_TYPE_CHECK_CLASS_TYPE ((k), MATE_MIXER_TYPE_TOGGLE)) +#define MATE_MIXER_TOGGLE_GET_CLASS(o) \ + (G_TYPE_INSTANCE_GET_CLASS ((o), MATE_MIXER_TYPE_TOGGLE, MateMixerToggleClass)) + +typedef struct _MateMixerToggleClass MateMixerToggleClass; +typedef struct _MateMixerTogglePrivate MateMixerTogglePrivate; + +struct _MateMixerToggle +{ + MateMixerSwitch object; + + /*< private >*/ + MateMixerTogglePrivate *priv; +}; + +struct _MateMixerToggleClass +{ + MateMixerSwitchClass parent_class; +}; + +GType mate_mixer_toggle_get_type (void) G_GNUC_CONST; + +gboolean mate_mixer_toggle_get_state (MateMixerToggle *toggle); +gboolean mate_mixer_toggle_set_state (MateMixerToggle *toggle, + gboolean state); + +MateMixerSwitchOption *mate_mixer_toggle_get_state_option (MateMixerToggle *toggle, + gboolean state); + +G_END_DECLS + +#endif /* MATEMIXER_TOGGLE_H */ diff --git a/libmatemixer/matemixer-types.h b/libmatemixer/matemixer-types.h new file mode 100644 index 0000000..6601a95 --- /dev/null +++ b/libmatemixer/matemixer-types.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2014 Michal Ratajsky <[email protected]> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the licence, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef MATEMIXER_TYPES_H +#define MATEMIXER_TYPES_H + +G_BEGIN_DECLS + +typedef struct _MateMixerDevice MateMixerDevice; +typedef struct _MateMixerClientStream MateMixerClientStream; +typedef struct _MateMixerContext MateMixerContext; +typedef struct _MateMixerDeviceProfile MateMixerDeviceProfile; +typedef struct _MateMixerStream MateMixerStream; +typedef struct _MateMixerStreamControl MateMixerStreamControl; +typedef struct _MateMixerSwitch MateMixerSwitch; +typedef struct _MateMixerSwitchOption MateMixerSwitchOption; +typedef struct _MateMixerToggle MateMixerToggle; + +G_END_DECLS + +#endif /* MATEMIXER_TYPES_H */ diff --git a/libmatemixer/matemixer.c b/libmatemixer/matemixer.c index 0ca09b9..fa83e3f 100644 --- a/libmatemixer/matemixer.c +++ b/libmatemixer/matemixer.c @@ -54,6 +54,10 @@ mate_mixer_init (void) if (initialized == TRUE) return TRUE; +#if !GLIB_CHECK_VERSION (2, 36, 0) + g_type_init (); +#endif + load_modules (); if (modules != NULL) { @@ -96,33 +100,25 @@ mate_mixer_is_initialized (void) return initialized; } -/** - * mate_mixer_deinit: - * - * Deinitializes the library. You should call this function when you are done - * using the library. - */ -void -mate_mixer_deinit (void) +/* Return a list of loaded backend modules */ +const GList * +_mate_mixer_get_modules (void) { - GList *list; - - if (initialized == FALSE) - return; - - list = modules; - while (list != NULL) { - g_type_module_unuse (G_TYPE_MODULE (list->data)); - list = list->next; - } - initialized = FALSE; + return (const GList *) modules; } -/* Internal function: return a list of loaded backend modules */ -const GList * -mate_mixer_get_modules (void) +guint32 +_mate_mixer_create_channel_mask (MateMixerChannelPosition *positions, guint n) { - return (const GList *) modules; + guint32 mask = 0; + guint i = 0; + + for (i = 0; i < n; i++) { + if (positions[i] > MATE_MIXER_CHANNEL_UNKNOWN && + positions[i] < MATE_MIXER_CHANNEL_MAX) + mask |= 1 << positions[i]; + } + return mask; } static void @@ -150,7 +146,8 @@ load_modules (void) continue; file = g_build_filename (LIBMATEMIXER_BACKEND_DIR, name, NULL); - modules = g_list_prepend (modules, mate_mixer_backend_module_new (file)); + modules = g_list_prepend (modules, + mate_mixer_backend_module_new (file)); g_free (file); } diff --git a/libmatemixer/matemixer.h b/libmatemixer/matemixer.h index 36a3d39..a6eac79 100644 --- a/libmatemixer/matemixer.h +++ b/libmatemixer/matemixer.h @@ -22,19 +22,21 @@ #include <glib-object.h> #include <libmatemixer/matemixer-client-stream.h> -#include <libmatemixer/matemixer-control.h> +#include <libmatemixer/matemixer-context.h> #include <libmatemixer/matemixer-device.h> #include <libmatemixer/matemixer-device-profile.h> #include <libmatemixer/matemixer-enums.h> -#include <libmatemixer/matemixer-port.h> #include <libmatemixer/matemixer-stream.h> +#include <libmatemixer/matemixer-stream-control.h> +#include <libmatemixer/matemixer-switch.h> +#include <libmatemixer/matemixer-switch-option.h> +#include <libmatemixer/matemixer-toggle.h> #include <libmatemixer/matemixer-version.h> G_BEGIN_DECLS gboolean mate_mixer_init (void); gboolean mate_mixer_is_initialized (void); -void mate_mixer_deinit (void); G_END_DECLS |