diff options
46 files changed, 2006 insertions, 861 deletions
@@ -0,0 +1,36 @@ +libmatemixer +============ + +libmatemixer is a mixer library for MATE desktop. + +It provides an abstract API allowing access to mixer functionality available +in the PulseAudio, ALSA and OSS sound systems. + +Documentation for the API is provided with gtk-doc. + +Installation and packaging +========================== + +See the INSTALL file for general instructions about the build process. + +The library includes dynamically loaded modules which provide access to each +of the supported sound systems. + +By default configure auto-detects whether support for PulseAudio and ALSA +is available in the system. Make sure to install the appropriate development +packages to allow the modules to be built. + +Building the OSS module is only advised on non-Linux systems as OSS support +in Linux is only provided as an ALSA emulation layer. To build the OSS module, +you will need to pass --enable-oss=yes to configure. + +As the modules are loaded dynamically each time an application utilizes the +library, it is possible to provide the modules in separate distribution +packages. + +How to report bugs +================== + +Bugs should be reported to the MATE bug tracking system on GitHub: + + https://github.com/mate-desktop/libmatemixer/issues/ diff --git a/backends/alsa/alsa-backend.c b/backends/alsa/alsa-backend.c index 6bac691..0b7895e 100644 --- a/backends/alsa/alsa-backend.c +++ b/backends/alsa/alsa-backend.c @@ -28,6 +28,7 @@ #define BACKEND_NAME "ALSA" #define BACKEND_PRIORITY 20 +#define BACKEND_FLAGS MATE_MIXER_BACKEND_NO_FLAGS #define ALSA_DEVICE_GET_ID(d) \ (g_object_get_data (G_OBJECT (d), "__matemixer_alsa_device_id")) @@ -97,10 +98,11 @@ backend_module_init (GTypeModule *module) { alsa_backend_register_type (module); - info.name = BACKEND_NAME; - info.priority = BACKEND_PRIORITY; - info.g_type = ALSA_TYPE_BACKEND; - info.backend_type = MATE_MIXER_BACKEND_ALSA; + info.name = BACKEND_NAME; + info.priority = BACKEND_PRIORITY; + info.g_type = ALSA_TYPE_BACKEND; + info.backend_flags = BACKEND_FLAGS; + info.backend_type = MATE_MIXER_BACKEND_ALSA; } const MateMixerBackendInfo *backend_module_get_info (void) @@ -363,10 +365,12 @@ read_device (AlsaBackend *alsa, const gchar *card) static void add_device (AlsaBackend *alsa, AlsaDevice *device) { - alsa->priv->devices = g_list_insert_sorted_with_data (alsa->priv->devices, - device, - (GCompareDataFunc) compare_devices, - NULL); + /* Takes reference of device */ + alsa->priv->devices = + g_list_insert_sorted_with_data (alsa->priv->devices, + device, + (GCompareDataFunc) compare_devices, + NULL); /* Keep track of device identifiers */ g_hash_table_add (alsa->priv->devices_ids, g_strdup (ALSA_DEVICE_GET_ID (device))); diff --git a/backends/alsa/alsa-device.c b/backends/alsa/alsa-device.c index f7f705e..03dd7c0 100644 --- a/backends/alsa/alsa-device.c +++ b/backends/alsa/alsa-device.c @@ -230,7 +230,7 @@ alsa_device_finalize (GObject *object) close_mixer (device); - G_OBJECT_CLASS (alsa_device_parent_class)->dispose (object); + G_OBJECT_CLASS (alsa_device_parent_class)->finalize (object); } AlsaDevice * diff --git a/backends/alsa/alsa-stream-control.c b/backends/alsa/alsa-stream-control.c index 97a0f8b..b5500d1 100644 --- a/backends/alsa/alsa-stream-control.c +++ b/backends/alsa/alsa-stream-control.c @@ -291,8 +291,6 @@ alsa_stream_control_set_mute (MateMixerStreamControl *mmsc, gboolean mute) for (i = 0; i < control->priv->data.channels; i++) control->priv->data.m[i] = mute; - - _mate_mixer_stream_control_set_mute (mmsc, mute); } return TRUE; } diff --git a/backends/alsa/alsa-toggle.c b/backends/alsa/alsa-toggle.c index a7958c9..c843985 100644 --- a/backends/alsa/alsa-toggle.c +++ b/backends/alsa/alsa-toggle.c @@ -92,8 +92,8 @@ alsa_toggle_new (const gchar *name, "label", label, "flags", MATE_MIXER_SWITCH_TOGGLE, "role", role, - "state-option-on", on, - "state-option-off", off, + "on-state-option", on, + "off-state-option", off, NULL); toggle->priv->type = type; diff --git a/backends/null/null-backend.c b/backends/null/null-backend.c index ee0ad2e..a061428 100644 --- a/backends/null/null-backend.c +++ b/backends/null/null-backend.c @@ -24,6 +24,7 @@ #define BACKEND_NAME "Null" #define BACKEND_PRIORITY 0 +#define BACKEND_FLAGS MATE_MIXER_BACKEND_NO_FLAGS static void null_backend_class_init (NullBackendClass *klass); static void null_backend_class_finalize (NullBackendClass *klass); @@ -43,10 +44,11 @@ backend_module_init (GTypeModule *module) { null_backend_register_type (module); - info.name = BACKEND_NAME; - info.priority = BACKEND_PRIORITY; - info.g_type = NULL_TYPE_BACKEND; - info.backend_type = MATE_MIXER_BACKEND_NULL; + info.name = BACKEND_NAME; + info.priority = BACKEND_PRIORITY; + info.g_type = NULL_TYPE_BACKEND; + info.backend_flags = BACKEND_FLAGS; + info.backend_type = MATE_MIXER_BACKEND_NULL; } const MateMixerBackendInfo *backend_module_get_info (void) diff --git a/backends/oss/oss-backend.c b/backends/oss/oss-backend.c index 23d265b..78ed69b 100644 --- a/backends/oss/oss-backend.c +++ b/backends/oss/oss-backend.c @@ -33,6 +33,7 @@ #define BACKEND_NAME "OSS" #define BACKEND_PRIORITY 10 +#define BACKEND_FLAGS MATE_MIXER_BACKEND_NO_FLAGS #if !defined(__linux__) && !defined(__NetBSD__) && !defined(__OpenBSD__) /* At least on systems based on FreeBSD we will need to read device names @@ -114,10 +115,11 @@ backend_module_init (GTypeModule *module) { oss_backend_register_type (module); - info.name = BACKEND_NAME; - info.priority = BACKEND_PRIORITY; - info.g_type = OSS_TYPE_BACKEND; - info.backend_type = MATE_MIXER_BACKEND_OSS; + info.name = BACKEND_NAME; + info.priority = BACKEND_PRIORITY; + info.g_type = OSS_TYPE_BACKEND; + info.backend_flags = BACKEND_FLAGS; + info.backend_type = MATE_MIXER_BACKEND_OSS; } const MateMixerBackendInfo *backend_module_get_info (void) @@ -461,6 +463,7 @@ read_device_label_sndstat (OssBackend *oss, static void add_device (OssBackend *oss, OssDevice *device) { + /* Takes reference of device */ oss->priv->devices = g_list_insert_sorted_with_data (oss->priv->devices, device, diff --git a/backends/pulse/pulse-backend.c b/backends/pulse/pulse-backend.c index e1b7ed5..4c0697a 100644 --- a/backends/pulse/pulse-backend.c +++ b/backends/pulse/pulse-backend.c @@ -38,6 +38,10 @@ #define BACKEND_NAME "PulseAudio" #define BACKEND_PRIORITY 100 +#define BACKEND_FLAGS (MATE_MIXER_BACKEND_HAS_APPLICATION_CONTROLS | \ + MATE_MIXER_BACKEND_HAS_STORED_CONTROLS | \ + MATE_MIXER_BACKEND_CAN_SET_DEFAULT_INPUT_STREAM | \ + MATE_MIXER_BACKEND_CAN_SET_DEFAULT_OUTPUT_STREAM) struct _PulseBackendPrivate { @@ -99,8 +103,7 @@ struct _PulseBackendPrivate NULL)) #define PULSE_GET_HANGING(o) \ - ((gboolean) g_object_get_data (G_OBJECT (o), \ - "__matemixer_pulse_hanging")) + ((gboolean) GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (o), "__matemixer_pulse_hanging"))) #define PULSE_SET_HANGING(o) \ (g_object_set_data (G_OBJECT (o), \ @@ -210,10 +213,11 @@ backend_module_init (GTypeModule *module) { pulse_backend_register_type (module); - info.name = BACKEND_NAME; - info.priority = BACKEND_PRIORITY; - info.g_type = PULSE_TYPE_BACKEND; - info.backend_type = MATE_MIXER_BACKEND_PULSEAUDIO; + info.name = BACKEND_NAME; + info.priority = BACKEND_PRIORITY; + info.g_type = PULSE_TYPE_BACKEND; + info.backend_flags = BACKEND_FLAGS; + info.backend_type = MATE_MIXER_BACKEND_PULSEAUDIO; } const MateMixerBackendInfo *backend_module_get_info (void) @@ -433,11 +437,6 @@ pulse_backend_open (MateMixerBackend *backend) return FALSE; } - _mate_mixer_backend_set_flags (backend, - MATE_MIXER_BACKEND_HAS_APPLICATION_CONTROLS | - MATE_MIXER_BACKEND_CAN_SET_DEFAULT_INPUT_STREAM | - MATE_MIXER_BACKEND_CAN_SET_DEFAULT_OUTPUT_STREAM); - pulse->priv->connection = connection; return TRUE; } @@ -762,7 +761,7 @@ on_connection_card_info (PulseConnection *connection, g_hash_table_insert (pulse->priv->devices, GUINT_TO_POINTER (info->index), - device); + g_object_ref (device)); free_list_devices (pulse); g_signal_emit_by_name (G_OBJECT (pulse), @@ -814,7 +813,7 @@ on_connection_sink_info (PulseConnection *connection, free_list_streams (pulse); g_hash_table_insert (pulse->priv->sinks, GUINT_TO_POINTER (info->index), - stream); + g_object_ref (stream)); if (device != NULL) { pulse_device_add_stream (device, stream); @@ -932,7 +931,7 @@ on_connection_source_info (PulseConnection *connection, free_list_streams (pulse); g_hash_table_insert (pulse->priv->sources, GUINT_TO_POINTER (info->index), - stream); + g_object_ref (stream)); if (device != NULL) { pulse_device_add_stream (device, stream); @@ -1051,7 +1050,7 @@ on_connection_ext_stream_info (PulseConnection *connection, free_list_ext_streams (pulse); g_hash_table_insert (pulse->priv->ext_streams, g_strdup (info->name), - ext); + g_object_ref (ext)); g_signal_emit_by_name (G_OBJECT (pulse), "stored-control-added", @@ -1091,7 +1090,7 @@ on_connection_ext_stream_loaded (PulseConnection *connection, PulseBackend *puls continue; free_list_ext_streams (pulse); - g_hash_table_remove (pulse->priv->ext_streams, (gconstpointer) name); + g_hash_table_iter_remove (&iter); g_signal_emit_by_name (G_OBJECT (pulse), "stored-control-removed", diff --git a/backends/pulse/pulse-device.c b/backends/pulse/pulse-device.c index 5403712..9f33132 100644 --- a/backends/pulse/pulse-device.c +++ b/backends/pulse/pulse-device.c @@ -281,7 +281,10 @@ pulse_device_add_stream (PulseDevice *device, PulseStream *stream) free_list_streams (device); - g_hash_table_insert (device->priv->streams, g_strdup (name), stream); + g_hash_table_insert (device->priv->streams, + g_strdup (name), + g_object_ref (stream)); + g_signal_emit_by_name (G_OBJECT (device), "stream-added", name); @@ -382,7 +385,9 @@ pulse_device_load (PulseDevice *device, const pa_card_info *info) icon, info->ports[i]->priority); - g_hash_table_insert (device->priv->ports, g_strdup (name), port); + g_hash_table_insert (device->priv->ports, + g_strdup (name), + g_object_ref (port)); } #endif diff --git a/backends/pulse/pulse-ext-stream.c b/backends/pulse/pulse-ext-stream.c index 3e7490a..48b11d1 100644 --- a/backends/pulse/pulse-ext-stream.c +++ b/backends/pulse/pulse-ext-stream.c @@ -33,16 +33,20 @@ struct _PulseExtStreamPrivate { - MateMixerAppInfo *app_info; - MateMixerDirection direction; + guint volume; + pa_cvolume cvolume; + pa_channel_map channel_map; + MateMixerAppInfo *app_info; + PulseConnection *connection; }; enum { PROP_0, - PROP_DIRECTION + PROP_CONNECTION, + N_PROPERTIES }; -static void mate_mixer_stored_control_interface_init (MateMixerStoredControlInterface *iface); +static GParamSpec *properties[N_PROPERTIES] = { NULL, }; static void pulse_ext_stream_class_init (PulseExtStreamClass *klass); @@ -56,52 +60,95 @@ static void pulse_ext_stream_set_property (GObject *object, GParamSpec *pspec); static void pulse_ext_stream_init (PulseExtStream *ext); +static void pulse_ext_stream_dispose (GObject *object); +static void pulse_ext_stream_finalize (GObject *object); -G_DEFINE_TYPE_WITH_CODE (PulseExtStream, pulse_ext_stream, PULSE_TYPE_STREAM_CONTROL, - G_IMPLEMENT_INTERFACE (MATE_MIXER_TYPE_STORED_CONTROL, - mate_mixer_stored_control_interface_init)) +G_DEFINE_TYPE (PulseExtStream, pulse_ext_stream, MATE_MIXER_TYPE_STORED_CONTROL) -static MateMixerDirection pulse_ext_stream_get_direction (MateMixerStoredControl *mmsc); +static MateMixerAppInfo * pulse_ext_stream_get_app_info (MateMixerStreamControl *mmsc); -static MateMixerAppInfo * pulse_ext_stream_get_app_info (MateMixerStreamControl *mmsc); +static gboolean pulse_ext_stream_set_stream (MateMixerStreamControl *mmsc, + MateMixerStream *mms); -static gboolean pulse_ext_stream_set_stream (MateMixerStreamControl *mmsc, - MateMixerStream *mms); +static gboolean pulse_ext_stream_set_mute (MateMixerStreamControl *mmsc, + gboolean mute); -static gboolean pulse_ext_stream_set_mute (PulseStreamControl *control, - gboolean mute); -static gboolean pulse_ext_stream_set_volume (PulseStreamControl *control, - pa_cvolume *cvolume); +static guint pulse_ext_stream_get_num_channels (MateMixerStreamControl *mmsc); -static void fill_ext_stream_restore_info (PulseStreamControl *control, - pa_ext_stream_restore_info *info); +static guint pulse_ext_stream_get_volume (MateMixerStreamControl *mmsc); +static gboolean pulse_ext_stream_set_volume (MateMixerStreamControl *mmsc, + guint volume); -static void -mate_mixer_stored_control_interface_init (MateMixerStoredControlInterface *iface) -{ - iface->get_direction = pulse_ext_stream_get_direction; -} +static guint pulse_ext_stream_get_channel_volume (MateMixerStreamControl *mmsc, + guint channel); +static gboolean pulse_ext_stream_set_channel_volume (MateMixerStreamControl *mmsc, + guint channel, + guint volume); + +static MateMixerChannelPosition pulse_ext_stream_get_channel_position (MateMixerStreamControl *mmsc, + guint channel); +static gboolean pulse_ext_stream_has_channel_position (MateMixerStreamControl *mmsc, + MateMixerChannelPosition position); + +static gboolean pulse_ext_stream_set_balance (MateMixerStreamControl *mmsc, + gfloat balance); + +static gboolean pulse_ext_stream_set_fade (MateMixerStreamControl *mmsc, + gfloat fade); + +static guint pulse_ext_stream_get_min_volume (MateMixerStreamControl *mmsc); +static guint pulse_ext_stream_get_max_volume (MateMixerStreamControl *mmsc); +static guint pulse_ext_stream_get_normal_volume (MateMixerStreamControl *mmsc); +static guint pulse_ext_stream_get_base_volume (MateMixerStreamControl *mmsc); + +static void fill_ext_stream_restore_info (PulseExtStream *ext, + pa_ext_stream_restore_info *info); + +static gboolean write_cvolume (PulseExtStream *ext, + const pa_cvolume *cvolume); +static void store_cvolume (PulseExtStream *ext, + const pa_cvolume *cvolume); static void pulse_ext_stream_class_init (PulseExtStreamClass *klass) { GObjectClass *object_class; MateMixerStreamControlClass *control_class; - PulseStreamControlClass *pulse_class; object_class = G_OBJECT_CLASS (klass); + object_class->dispose = pulse_ext_stream_dispose; + object_class->finalize = pulse_ext_stream_finalize; object_class->get_property = pulse_ext_stream_get_property; object_class->set_property = pulse_ext_stream_set_property; control_class = MATE_MIXER_STREAM_CONTROL_CLASS (klass); - control_class->get_app_info = pulse_ext_stream_get_app_info; - control_class->set_stream = pulse_ext_stream_set_stream; - - pulse_class = PULSE_STREAM_CONTROL_CLASS (klass); - pulse_class->set_mute = pulse_ext_stream_set_mute; - pulse_class->set_volume = pulse_ext_stream_set_volume; - - g_object_class_override_property (object_class, PROP_DIRECTION, "direction"); + control_class->get_app_info = pulse_ext_stream_get_app_info; + control_class->set_stream = pulse_ext_stream_set_stream; + control_class->set_mute = pulse_ext_stream_set_mute; + control_class->get_num_channels = pulse_ext_stream_get_num_channels; + control_class->get_volume = pulse_ext_stream_get_volume; + control_class->set_volume = pulse_ext_stream_set_volume; + control_class->get_channel_volume = pulse_ext_stream_get_channel_volume; + control_class->set_channel_volume = pulse_ext_stream_set_channel_volume; + control_class->get_channel_position = pulse_ext_stream_get_channel_position; + control_class->has_channel_position = pulse_ext_stream_has_channel_position; + control_class->set_balance = pulse_ext_stream_set_balance; + control_class->set_fade = pulse_ext_stream_set_fade; + control_class->get_min_volume = pulse_ext_stream_get_min_volume; + control_class->get_max_volume = pulse_ext_stream_get_max_volume; + control_class->get_normal_volume = pulse_ext_stream_get_normal_volume; + control_class->get_base_volume = pulse_ext_stream_get_base_volume; + + properties[PROP_CONNECTION] = + g_param_spec_object ("connection", + "Connection", + "PulseAudio connection", + PULSE_TYPE_CONNECTION, + 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 (PulseExtStreamPrivate)); } @@ -117,8 +164,8 @@ pulse_ext_stream_get_property (GObject *object, ext = PULSE_EXT_STREAM (object); switch (param_id) { - case PROP_DIRECTION: - g_value_set_enum (value, ext->priv->direction); + case PROP_CONNECTION: + g_value_set_object (value, ext->priv->connection); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); @@ -137,8 +184,9 @@ pulse_ext_stream_set_property (GObject *object, ext = PULSE_EXT_STREAM (object); switch (param_id) { - case PROP_DIRECTION: - ext->priv->direction = g_value_get_enum (value); + case PROP_CONNECTION: + /* Construct-only object */ + ext->priv->connection = g_value_dup_object (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); @@ -154,26 +202,61 @@ pulse_ext_stream_init (PulseExtStream *ext) PulseExtStreamPrivate); } +static void +pulse_ext_stream_dispose (GObject *object) +{ + PulseExtStream *ext; + + ext = PULSE_EXT_STREAM (object); + + g_clear_object (&ext->priv->connection); + + G_OBJECT_CLASS (pulse_ext_stream_parent_class)->dispose (object); +} + +static void +pulse_ext_stream_finalize (GObject *object) +{ + PulseExtStream *ext; + + ext = PULSE_EXT_STREAM (object); + + if (ext->priv->app_info != NULL) + _mate_mixer_app_info_free (ext->priv->app_info); + + G_OBJECT_CLASS (pulse_ext_stream_parent_class)->finalize (object); +} + PulseExtStream * pulse_ext_stream_new (PulseConnection *connection, const pa_ext_stream_restore_info *info, PulseStream *parent) { - PulseExtStream *ext; - gchar *suffix; - MateMixerDirection direction; - MateMixerStreamControlFlags flags = MATE_MIXER_STREAM_CONTROL_VOLUME_READABLE | - MATE_MIXER_STREAM_CONTROL_VOLUME_WRITABLE | - MATE_MIXER_STREAM_CONTROL_MUTE_READABLE | - MATE_MIXER_STREAM_CONTROL_MUTE_WRITABLE; - MateMixerStreamControlRole role = MATE_MIXER_STREAM_CONTROL_ROLE_UNKNOWN; - MateMixerAppInfo *app_info; - - MateMixerStreamControlMediaRole media_role = MATE_MIXER_STREAM_CONTROL_MEDIA_ROLE_UNKNOWN; + PulseExtStream *ext; + gchar *suffix; + MateMixerAppInfo *app_info = NULL; + MateMixerDirection direction; + MateMixerStreamControlFlags flags = MATE_MIXER_STREAM_CONTROL_MUTE_READABLE | + MATE_MIXER_STREAM_CONTROL_MUTE_WRITABLE | + MATE_MIXER_STREAM_CONTROL_MOVABLE | + MATE_MIXER_STREAM_CONTROL_STORED; + MateMixerStreamControlRole role = MATE_MIXER_STREAM_CONTROL_ROLE_UNKNOWN; + MateMixerStreamControlMediaRole media_role = + MATE_MIXER_STREAM_CONTROL_MEDIA_ROLE_UNKNOWN; g_return_val_if_fail (PULSE_IS_CONNECTION (connection), NULL); g_return_val_if_fail (info != NULL, NULL); + /* The name of an ext-stream is in one of the following formats: + * sink-input-by-media-role: ... + * sink-input-by-application-name: ... + * sink-input-by-application-id: ... + * sink-input-by-media-name: ... + * source-output-by-media-role: ... + * source-output-by-application-name: ... + * source-output-by-application-id: ... + * source-output-by-media-name: ... + */ if (g_str_has_prefix (info->name, "sink-input")) direction = MATE_MIXER_DIRECTION_OUTPUT; else if (g_str_has_prefix (info->name, "source-output")) @@ -181,26 +264,36 @@ pulse_ext_stream_new (PulseConnection *connection, else direction = MATE_MIXER_DIRECTION_UNKNOWN; - app_info = _mate_mixer_app_info_new (); - suffix = strchr (info->name, ':'); if (suffix != NULL) suffix++; if (strstr (info->name, "-by-media-role:")) { - if (G_LIKELY (suffix != NULL)) + if G_LIKELY (suffix != NULL) media_role = pulse_convert_media_role_name (suffix); } else if (strstr (info->name, "-by-application-name:")) { role = MATE_MIXER_STREAM_CONTROL_ROLE_APPLICATION; - if (G_LIKELY (suffix != NULL)) + /* Make sure an application ext-stream always has a MateMixerAppInfo + * structure available, even in the case no application info is + * available */ + if (app_info == NULL) + app_info = _mate_mixer_app_info_new (); + + if G_LIKELY (suffix != NULL) _mate_mixer_app_info_set_name (app_info, suffix); } else if (strstr (info->name, "-by-application-id:")) { role = MATE_MIXER_STREAM_CONTROL_ROLE_APPLICATION; - if (G_LIKELY (suffix != NULL)) + /* Make sure an application ext-stream always has a MateMixerAppInfo + * structure available, even in the case no application info is + * available */ + if (app_info == NULL) + app_info = _mate_mixer_app_info_new (); + + if G_LIKELY (suffix != NULL) _mate_mixer_app_info_set_id (app_info, suffix); } @@ -214,12 +307,12 @@ pulse_ext_stream_new (PulseConnection *connection, "stream", parent, NULL); - if (role == MATE_MIXER_STREAM_CONTROL_ROLE_APPLICATION) - ext->priv->app_info = app_info; - else - _mate_mixer_app_info_free (app_info); + // XXX property? + ext->priv->app_info = app_info; + /* Store values which are expected to be changed */ pulse_ext_stream_update (ext, info, parent); + return ext; } @@ -228,6 +321,9 @@ pulse_ext_stream_update (PulseExtStream *ext, const pa_ext_stream_restore_info *info, PulseStream *parent) { + MateMixerStreamControlFlags flags; + gboolean volume_changed = FALSE; + g_return_if_fail (PULSE_IS_EXT_STREAM (ext)); g_return_if_fail (info != NULL); @@ -237,27 +333,54 @@ pulse_ext_stream_update (PulseExtStream *ext, _mate_mixer_stream_control_set_mute (MATE_MIXER_STREAM_CONTROL (ext), info->mute ? TRUE : FALSE); - pulse_stream_control_set_channel_map (PULSE_STREAM_CONTROL (ext), - &info->channel_map); + flags = mate_mixer_stream_control_get_flags (MATE_MIXER_STREAM_CONTROL (ext)); + + if (pa_channel_map_valid (&info->channel_map) != 0) { + if (pa_channel_map_can_balance (&info->channel_map) != 0) + flags |= MATE_MIXER_STREAM_CONTROL_CAN_BALANCE; + else + flags &= ~MATE_MIXER_STREAM_CONTROL_CAN_BALANCE; + + if (pa_channel_map_can_fade (&info->channel_map) != 0) + flags |= MATE_MIXER_STREAM_CONTROL_CAN_FADE; + else + flags &= ~MATE_MIXER_STREAM_CONTROL_CAN_FADE; + + ext->priv->channel_map = info->channel_map; + } else { + flags &= ~(MATE_MIXER_STREAM_CONTROL_CAN_BALANCE | MATE_MIXER_STREAM_CONTROL_CAN_FADE); + + /* If the channel map is not valid, create an empty channel map, which + * also won't validate, but at least we know what it is */ + pa_channel_map_init (&ext->priv->channel_map); + } - pulse_stream_control_set_cvolume (PULSE_STREAM_CONTROL (ext), - &info->volume, - 0); + if (pa_cvolume_valid (&info->volume) != 0) { + flags |= MATE_MIXER_STREAM_CONTROL_VOLUME_READABLE | + MATE_MIXER_STREAM_CONTROL_VOLUME_WRITABLE; + if (pa_cvolume_equal (&ext->priv->cvolume, &info->volume) == 0) + volume_changed = TRUE; + } else { + flags &= ~(MATE_MIXER_STREAM_CONTROL_VOLUME_READABLE | + MATE_MIXER_STREAM_CONTROL_VOLUME_WRITABLE); + + if (ext->priv->volume != (guint) PA_VOLUME_MUTED) + volume_changed = TRUE; + } + + if (volume_changed == TRUE) + store_cvolume (ext, &info->volume); + + _mate_mixer_stream_control_set_flags (MATE_MIXER_STREAM_CONTROL (ext), flags); + + /* Also set initially, but may change at any time */ _mate_mixer_stream_control_set_stream (MATE_MIXER_STREAM_CONTROL (ext), MATE_MIXER_STREAM (parent)); g_object_thaw_notify (G_OBJECT (ext)); } -static MateMixerDirection -pulse_ext_stream_get_direction (MateMixerStoredControl *mmsc) -{ - g_return_val_if_fail (PULSE_IS_EXT_STREAM (mmsc), MATE_MIXER_DIRECTION_UNKNOWN); - - return PULSE_EXT_STREAM (mmsc)->priv->direction; -} - static MateMixerAppInfo * pulse_ext_stream_get_app_info (MateMixerStreamControl *mmsc) { @@ -269,76 +392,277 @@ pulse_ext_stream_get_app_info (MateMixerStreamControl *mmsc) static gboolean pulse_ext_stream_set_stream (MateMixerStreamControl *mmsc, MateMixerStream *mms) { + PulseExtStream *ext; pa_ext_stream_restore_info info; g_return_val_if_fail (PULSE_IS_EXT_STREAM (mmsc), FALSE); g_return_val_if_fail (mms == NULL || PULSE_IS_STREAM (mms), FALSE); - fill_ext_stream_restore_info (PULSE_STREAM_CONTROL (mms), &info); + ext = PULSE_EXT_STREAM (mmsc); + fill_ext_stream_restore_info (ext, &info); if (mms != NULL) info.device = mate_mixer_stream_get_name (mms); else info.device = NULL; - return pulse_connection_write_ext_stream (pulse_stream_control_get_connection (PULSE_STREAM_CONTROL (mmsc)), - &info); + return pulse_connection_write_ext_stream (ext->priv->connection, &info); } static gboolean -pulse_ext_stream_set_mute (PulseStreamControl *control, gboolean mute) +pulse_ext_stream_set_mute (MateMixerStreamControl *mmsc, gboolean mute) { + PulseExtStream *ext; pa_ext_stream_restore_info info; - g_return_val_if_fail (PULSE_IS_EXT_STREAM (control), FALSE); + g_return_val_if_fail (PULSE_IS_EXT_STREAM (mmsc), FALSE); - fill_ext_stream_restore_info (control, &info); + ext = PULSE_EXT_STREAM (mmsc); + fill_ext_stream_restore_info (ext, &info); info.mute = mute; - return pulse_connection_write_ext_stream (pulse_stream_control_get_connection (control), - &info); + return pulse_connection_write_ext_stream (ext->priv->connection, &info); +} + +static guint +pulse_ext_stream_get_num_channels (MateMixerStreamControl *mmsc) +{ + g_return_val_if_fail (PULSE_IS_EXT_STREAM (mmsc), 0); + + return PULSE_EXT_STREAM (mmsc)->priv->channel_map.channels; +} + +static guint +pulse_ext_stream_get_volume (MateMixerStreamControl *mmsc) +{ + g_return_val_if_fail (PULSE_IS_EXT_STREAM (mmsc), (guint) PA_VOLUME_MUTED); + + return PULSE_EXT_STREAM (mmsc)->priv->volume; } static gboolean -pulse_ext_stream_set_volume (PulseStreamControl *control, pa_cvolume *cvolume) +pulse_ext_stream_set_volume (MateMixerStreamControl *mmsc, guint volume) { - pa_ext_stream_restore_info info; + PulseExtStream *ext; + pa_cvolume cvolume; - g_return_val_if_fail (PULSE_IS_EXT_STREAM (control), FALSE); - g_return_val_if_fail (cvolume != NULL, FALSE); + g_return_val_if_fail (PULSE_IS_EXT_STREAM (mmsc), FALSE); - fill_ext_stream_restore_info (control, &info); + ext = PULSE_EXT_STREAM (mmsc); + cvolume = ext->priv->cvolume; - info.volume = *cvolume; + /* Modify a temporary cvolume structure as the change may be irreversible */ + if (pa_cvolume_scale (&cvolume, (pa_volume_t) volume) == NULL) + return FALSE; + + return write_cvolume (ext, &cvolume); +} + +static guint +pulse_ext_stream_get_channel_volume (MateMixerStreamControl *mmsc, guint channel) +{ + PulseExtStream *ext; + + g_return_val_if_fail (PULSE_IS_EXT_STREAM (mmsc), (guint) PA_VOLUME_MUTED); + + ext = PULSE_EXT_STREAM (mmsc); + + if (channel >= ext->priv->cvolume.channels) + return (guint) PA_VOLUME_MUTED; + + return (guint) ext->priv->cvolume.values[channel]; +} + +static gboolean +pulse_ext_stream_set_channel_volume (MateMixerStreamControl *mmsc, guint channel, guint volume) +{ + PulseExtStream *ext; + pa_cvolume cvolume; + + g_return_val_if_fail (PULSE_IS_EXT_STREAM (mmsc), FALSE); + + ext = PULSE_EXT_STREAM (mmsc); - return pulse_connection_write_ext_stream (pulse_stream_control_get_connection (control), - &info); + if (channel >= ext->priv->cvolume.channels) + return FALSE; + + /* Modify a temporary cvolume structure as the change may be irreversible */ + cvolume = ext->priv->cvolume; + cvolume.values[channel] = (pa_volume_t) volume; + + return write_cvolume (ext, &cvolume); +} + +static MateMixerChannelPosition +pulse_ext_stream_get_channel_position (MateMixerStreamControl *mmsc, guint channel) +{ + PulseExtStream *ext; + + g_return_val_if_fail (PULSE_IS_EXT_STREAM (mmsc), MATE_MIXER_CHANNEL_UNKNOWN); + + ext = PULSE_EXT_STREAM (mmsc); + + if (channel >= ext->priv->channel_map.channels) + return MATE_MIXER_CHANNEL_UNKNOWN; + + return pulse_convert_position_from_pulse (ext->priv->channel_map.map[channel]); +} + +static gboolean +pulse_ext_stream_has_channel_position (MateMixerStreamControl *mmsc, + MateMixerChannelPosition position) +{ + PulseExtStream *ext; + pa_channel_position_t p; + + g_return_val_if_fail (PULSE_IS_EXT_STREAM (mmsc), FALSE); + + ext = PULSE_EXT_STREAM (mmsc); + + /* Handle invalid position as a special case, otherwise this function would + * return TRUE for e.g. unknown index in a default channel map */ + p = pulse_convert_position_to_pulse (position); + + if (p == PA_CHANNEL_POSITION_INVALID) + return FALSE; + + if (pa_channel_map_has_position (&ext->priv->channel_map, p) != 0) + return TRUE; + else + return FALSE; +} + +static gboolean +pulse_ext_stream_set_balance (MateMixerStreamControl *mmsc, gfloat balance) +{ + PulseExtStream *ext; + pa_cvolume cvolume; + + g_return_val_if_fail (PULSE_IS_EXT_STREAM (mmsc), FALSE); + + ext = PULSE_EXT_STREAM (mmsc); + cvolume = ext->priv->cvolume; + + /* Modify a temporary cvolume structure as the change may be irreversible */ + if (pa_cvolume_set_balance (&cvolume, &ext->priv->channel_map, balance) == NULL) + return FALSE; + + return write_cvolume (ext, &cvolume); +} + +static gboolean +pulse_ext_stream_set_fade (MateMixerStreamControl *mmsc, gfloat fade) +{ + PulseExtStream *ext; + pa_cvolume cvolume; + + g_return_val_if_fail (PULSE_IS_EXT_STREAM (mmsc), FALSE); + + ext = PULSE_EXT_STREAM (mmsc); + cvolume = ext->priv->cvolume; + + /* Modify a temporary cvolume structure as the change may be irreversible */ + if (pa_cvolume_set_fade (&cvolume, &ext->priv->channel_map, fade) == NULL) + return FALSE; + + return write_cvolume (ext, &cvolume); +} + +static guint +pulse_ext_stream_get_min_volume (MateMixerStreamControl *mmsc) +{ + return (guint) PA_VOLUME_MUTED; +} + +static guint +pulse_ext_stream_get_max_volume (MateMixerStreamControl *mmsc) +{ + g_return_val_if_fail (PULSE_IS_EXT_STREAM (mmsc), (guint) PA_VOLUME_MUTED); + + return (guint) PA_VOLUME_UI_MAX; +} + +static guint +pulse_ext_stream_get_normal_volume (MateMixerStreamControl *mmsc) +{ + g_return_val_if_fail (PULSE_IS_EXT_STREAM (mmsc), (guint) PA_VOLUME_MUTED); + + return (guint) PA_VOLUME_NORM; +} + +static guint +pulse_ext_stream_get_base_volume (MateMixerStreamControl *mmsc) +{ + g_return_val_if_fail (PULSE_IS_EXT_STREAM (mmsc), (guint) PA_VOLUME_MUTED); + + /* Base volume is not supported/used in ext-streams */ + return (guint) PA_VOLUME_NORM; } static void -fill_ext_stream_restore_info (PulseStreamControl *control, +fill_ext_stream_restore_info (PulseExtStream *ext, pa_ext_stream_restore_info *info) { - MateMixerStream *stream; + MateMixerStream *mms; MateMixerStreamControl *mmsc; - const pa_channel_map *map; - const pa_cvolume *cvolume; - mmsc = MATE_MIXER_STREAM_CONTROL (control); + mmsc = MATE_MIXER_STREAM_CONTROL (ext); info->name = mate_mixer_stream_control_get_name (mmsc); info->mute = mate_mixer_stream_control_get_mute (mmsc); + info->volume = ext->priv->cvolume; + info->channel_map = ext->priv->channel_map; - map = pulse_stream_control_get_channel_map (control); - info->channel_map = *map; - - cvolume = pulse_stream_control_get_cvolume (control); - info->volume = *cvolume; - - stream = mate_mixer_stream_control_get_stream (mmsc); - if (stream != NULL) - info->device = mate_mixer_stream_get_name (stream); + mms = mate_mixer_stream_control_get_stream (mmsc); + if (mms != NULL) + info->device = mate_mixer_stream_get_name (mms); else info->device = NULL; } + +static gboolean +write_cvolume (PulseExtStream *ext, const pa_cvolume *cvolume) +{ + pa_ext_stream_restore_info info; + + /* Make sure to only store a valid and modified volume */ + if (pa_cvolume_valid (cvolume) == 0) + return FALSE; + if (pa_cvolume_equal (cvolume, &ext->priv->cvolume) != 0) + return TRUE; + + fill_ext_stream_restore_info (ext, &info); + info.volume = *cvolume; + + if (pulse_connection_write_ext_stream (ext->priv->connection, &info) == FALSE) + return FALSE; + + store_cvolume (ext, cvolume); + return TRUE; +} + +static void +store_cvolume (PulseExtStream *ext, const pa_cvolume *cvolume) +{ + gfloat value; + + /* Avoid validating whether the volume has changed, it should be done by + * the caller */ + ext->priv->cvolume = *cvolume; + ext->priv->volume = (guint) pa_cvolume_max (cvolume); + + g_object_notify (G_OBJECT (ext), "volume"); + + /* PulseAudio returns the default 0.0f value on error, so skip checking validity + * of the channel map and cvolume */ + value = pa_cvolume_get_balance (&ext->priv->cvolume, + &ext->priv->channel_map); + + _mate_mixer_stream_control_set_balance (MATE_MIXER_STREAM_CONTROL (ext), value); + + value = pa_cvolume_get_fade (&ext->priv->cvolume, + &ext->priv->channel_map); + + _mate_mixer_stream_control_set_fade (MATE_MIXER_STREAM_CONTROL (ext), value); +} diff --git a/backends/pulse/pulse-ext-stream.h b/backends/pulse/pulse-ext-stream.h index b667dc7..af3d75f 100644 --- a/backends/pulse/pulse-ext-stream.h +++ b/backends/pulse/pulse-ext-stream.h @@ -47,7 +47,7 @@ typedef struct _PulseExtStreamPrivate PulseExtStreamPrivate; struct _PulseExtStream { - PulseStreamControl parent; + MateMixerStoredControl parent; /*< private >*/ PulseExtStreamPrivate *priv; @@ -55,7 +55,7 @@ struct _PulseExtStream struct _PulseExtStreamClass { - PulseStreamControlClass parent_class; + MateMixerStoredControlClass parent_class; }; GType pulse_ext_stream_get_type (void) G_GNUC_CONST; diff --git a/backends/pulse/pulse-port-switch.c b/backends/pulse/pulse-port-switch.c index 08f1543..db06a7c 100644 --- a/backends/pulse/pulse-port-switch.c +++ b/backends/pulse/pulse-port-switch.c @@ -53,7 +53,6 @@ static void pulse_port_switch_set_property (GObject *object, GParamSpec *pspec); static void pulse_port_switch_init (PulsePortSwitch *swtch); -static void pulse_port_switch_dispose (GObject *object); G_DEFINE_ABSTRACT_TYPE (PulsePortSwitch, pulse_port_switch, MATE_MIXER_TYPE_SWITCH) @@ -74,7 +73,6 @@ pulse_port_switch_class_init (PulsePortSwitchClass *klass) MateMixerSwitchClass *switch_class; object_class = G_OBJECT_CLASS (klass); - object_class->dispose = pulse_port_switch_dispose; object_class->get_property = pulse_port_switch_get_property; object_class->set_property = pulse_port_switch_set_property; @@ -129,7 +127,11 @@ pulse_port_switch_set_property (GObject *object, switch (param_id) { case PROP_STREAM: /* Construct-only object */ - swtch->priv->stream = g_value_dup_object (value); + swtch->priv->stream = g_value_get_object (value); + + if (swtch->priv->stream != NULL) + g_object_add_weak_pointer (G_OBJECT (swtch->priv->stream), + (gpointer *) &swtch->priv->stream); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); @@ -145,18 +147,6 @@ pulse_port_switch_init (PulsePortSwitch *swtch) PulsePortSwitchPrivate); } -static void -pulse_port_switch_dispose (GObject *object) -{ - PulsePortSwitch *swtch; - - swtch = PULSE_PORT_SWITCH (object); - - g_clear_object (&swtch->priv->stream); - - G_OBJECT_CLASS (pulse_port_switch_parent_class)->dispose (object); -} - PulseStream * pulse_port_switch_get_stream (PulsePortSwitch *swtch) { diff --git a/backends/pulse/pulse-sink.c b/backends/pulse/pulse-sink.c index d2f0280..aedd5c8 100644 --- a/backends/pulse/pulse-sink.c +++ b/backends/pulse/pulse-sink.c @@ -188,7 +188,7 @@ pulse_sink_add_input (PulseSink *sink, const pa_sink_input_info *info) input = pulse_sink_input_new (sink, info); g_hash_table_insert (sink->priv->inputs, GINT_TO_POINTER (info->index), - input); + g_object_ref (input)); name = mate_mixer_stream_control_get_name (MATE_MIXER_STREAM_CONTROL (input)); g_signal_emit_by_name (G_OBJECT (sink), diff --git a/backends/pulse/pulse-source.c b/backends/pulse/pulse-source.c index 0d095a7..99c7432 100644 --- a/backends/pulse/pulse-source.c +++ b/backends/pulse/pulse-source.c @@ -183,7 +183,7 @@ pulse_source_add_output (PulseSource *source, const pa_source_output_info *info) output = pulse_source_output_new (source, info); g_hash_table_insert (source->priv->outputs, GINT_TO_POINTER (info->index), - output); + g_object_ref (output)); name = mate_mixer_stream_control_get_name (MATE_MIXER_STREAM_CONTROL (output)); g_signal_emit_by_name (G_OBJECT (source), diff --git a/backends/pulse/pulse-stream-control.c b/backends/pulse/pulse-stream-control.c index fa17e6b..f61a616 100644 --- a/backends/pulse/pulse-stream-control.c +++ b/backends/pulse/pulse-stream-control.c @@ -550,7 +550,7 @@ pulse_stream_control_get_channel_position (MateMixerStreamControl *mmsc, guint c if (channel >= control->priv->channel_map.channels) return MATE_MIXER_CHANNEL_UNKNOWN; - return pulse_convert_position_to_pulse (control->priv->channel_map.map[channel]); + return pulse_convert_position_from_pulse (control->priv->channel_map.map[channel]); } static gboolean diff --git a/backends/pulse/pulse-stream.c b/backends/pulse/pulse-stream.c index 752c3e6..9856c98 100644 --- a/backends/pulse/pulse-stream.c +++ b/backends/pulse/pulse-stream.c @@ -63,16 +63,13 @@ G_DEFINE_ABSTRACT_TYPE (PulseStream, pulse_stream, MATE_MIXER_TYPE_STREAM) static void pulse_stream_class_init (PulseStreamClass *klass) { - GObjectClass *object_class; - MateMixerStreamClass *stream_class; + GObjectClass *object_class; object_class = G_OBJECT_CLASS (klass); object_class->dispose = pulse_stream_dispose; object_class->get_property = pulse_stream_get_property; object_class->set_property = pulse_stream_set_property; - stream_class = MATE_MIXER_STREAM_CLASS (klass); - properties[PROP_INDEX] = g_param_spec_uint ("index", "Index", diff --git a/docs/reference/Makefile.am b/docs/reference/Makefile.am index 9c58b70..fb3db04 100644 --- a/docs/reference/Makefile.am +++ b/docs/reference/Makefile.am @@ -53,11 +53,14 @@ EXTRA_HFILES= # Header files or dirs to ignore when scanning. Use base file/dir names # e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h private_code IGNORE_HFILES= \ + matemixer-app-info-private.h \ matemixer-backend.h \ matemixer-backend-module.h \ - matemixer-device-profile-private.h \ matemixer-enum-types.h \ - matemixer-port-private.h \ + matemixer-stream-control-private.h \ + matemixer-stream-private.h \ + matemixer-switch-option-private.h \ + matemixer-switch-private.h \ matemixer-private.h # Images to copy into HTML directory. diff --git a/docs/reference/libmatemixer-docs.xml b/docs/reference/libmatemixer-docs.xml index 708ca6e..16c1a1f 100644 --- a/docs/reference/libmatemixer-docs.xml +++ b/docs/reference/libmatemixer-docs.xml @@ -16,12 +16,15 @@ <chapter> <title>API Reference</title> <xi:include href="xml/matemixer.xml"/> - <xi:include href="xml/matemixer-client-stream.xml"/> - <xi:include href="xml/matemixer-control.xml"/> + <xi:include href="xml/matemixer-app-info.xml"/> + <xi:include href="xml/matemixer-context.xml"/> <xi:include href="xml/matemixer-device.xml"/> - <xi:include href="xml/matemixer-device-profile.xml"/> - <xi:include href="xml/matemixer-port.xml"/> <xi:include href="xml/matemixer-stream.xml"/> + <xi:include href="xml/matemixer-stream-control.xml"/> + <xi:include href="xml/matemixer-stored-control.xml"/> + <xi:include href="xml/matemixer-switch.xml"/> + <xi:include href="xml/matemixer-switch-option.xml"/> + <xi:include href="xml/matemixer-toggle.xml"/> </chapter> <index id="api-index-full"> <title>API Index</title> diff --git a/docs/reference/libmatemixer-sections.txt b/docs/reference/libmatemixer-sections.txt index 5807f76..911d43d 100644 --- a/docs/reference/libmatemixer-sections.txt +++ b/docs/reference/libmatemixer-sections.txt @@ -1,191 +1,254 @@ <SECTION> <FILE>matemixer</FILE> +<TITLE>MateMixer</TITLE> mate_mixer_init -mate_mixer_deinit mate_mixer_is_initialized LIBMATEMIXER_CHECK_VERSION </SECTION> <SECTION> -<FILE>matemixer-client-stream</FILE> -<TITLE>MateMixerClientStream</TITLE> -MateMixerClientStreamFlags -MateMixerClientStreamRole -MateMixerClientStream -MateMixerClientStreamInterface -mate_mixer_client_stream_get_flags -mate_mixer_client_stream_get_role -mate_mixer_client_stream_get_parent -mate_mixer_client_stream_set_parent -mate_mixer_client_stream_remove -mate_mixer_client_stream_get_app_name -mate_mixer_client_stream_get_app_id -mate_mixer_client_stream_get_app_version -mate_mixer_client_stream_get_app_icon +<FILE>matemixer-app-info</FILE> +<TITLE>MateMixerAppInfo</TITLE> +MateMixerAppInfo +mate_mixer_app_info_get_name +mate_mixer_app_info_get_id +mate_mixer_app_info_get_version +mate_mixer_app_info_get_icon <SUBSECTION Standard> -MATE_MIXER_CLIENT_STREAM -MATE_MIXER_CLIENT_STREAM_GET_INTERFACE -MATE_MIXER_IS_CLIENT_STREAM -MATE_MIXER_TYPE_CLIENT_STREAM -mate_mixer_client_stream_get_type +MATE_MIXER_APP_INFO +MATE_MIXER_TYPE_APP_INFO +<SUBSECTION Private> +mate_mixer_app_info_get_type </SECTION> <SECTION> -<FILE>matemixer-control</FILE> -<TITLE>MateMixerControl</TITLE> +<FILE>matemixer-context</FILE> +<TITLE>MateMixerContext</TITLE> MateMixerState MateMixerBackendType -MateMixerControl -mate_mixer_control_new -mate_mixer_control_set_backend_type -mate_mixer_control_set_app_name -mate_mixer_control_set_app_id -mate_mixer_control_set_app_version -mate_mixer_control_set_app_icon -mate_mixer_control_set_server_address -mate_mixer_control_open -mate_mixer_control_close -mate_mixer_control_get_state -mate_mixer_control_get_device -mate_mixer_control_get_stream -mate_mixer_control_get_cached_stream -mate_mixer_control_list_devices -mate_mixer_control_list_streams -mate_mixer_control_list_cached_streams -mate_mixer_control_get_default_input_stream -mate_mixer_control_set_default_input_stream -mate_mixer_control_get_default_output_stream -mate_mixer_control_set_default_output_stream -mate_mixer_control_get_backend_name -mate_mixer_control_get_backend_type +MateMixerBackendFlags +MateMixerContext +MateMixerContextClass +mate_mixer_context_new +mate_mixer_context_set_backend_type +mate_mixer_context_set_app_name +mate_mixer_context_set_app_id +mate_mixer_context_set_app_version +mate_mixer_context_set_app_icon +mate_mixer_context_set_server_address +mate_mixer_context_open +mate_mixer_context_close +mate_mixer_context_get_state +mate_mixer_context_get_device +mate_mixer_context_get_stream +mate_mixer_context_get_stored_control +mate_mixer_context_list_devices +mate_mixer_context_list_streams +mate_mixer_context_list_stored_controls +mate_mixer_context_get_default_input_stream +mate_mixer_context_set_default_input_stream +mate_mixer_context_get_default_output_stream +mate_mixer_context_set_default_output_stream +mate_mixer_context_get_backend_name +mate_mixer_context_get_backend_type +mate_mixer_context_get_backend_flags <SUBSECTION Standard> -MateMixerControlClass -MATE_MIXER_CONTROL -MATE_MIXER_CONTROL_CLASS -MATE_MIXER_CONTROL_GET_CLASS -MATE_MIXER_IS_CONTROL -MATE_MIXER_IS_CONTROL_CLASS -MATE_MIXER_TYPE_CONTROL -mate_mixer_control_get_type +MATE_MIXER_CONTEXT +MATE_MIXER_CONTEXT_CLASS +MATE_MIXER_CONTEXT_GET_CLASS +MATE_MIXER_IS_CONTEXT +MATE_MIXER_IS_CONTEXT_CLASS +MATE_MIXER_TYPE_CONTEXT <SUBSECTION Private> -MateMixerControlPrivate +MateMixerContextPrivate +mate_mixer_context_get_type </SECTION> <SECTION> <FILE>matemixer-device</FILE> <TITLE>MateMixerDevice</TITLE> MateMixerDevice -MateMixerDeviceInterface +MateMixerDeviceClass mate_mixer_device_get_name -mate_mixer_device_get_description +mate_mixer_device_get_label mate_mixer_device_get_icon -mate_mixer_device_get_port -mate_mixer_device_get_profile -mate_mixer_device_list_ports -mate_mixer_device_list_profiles -mate_mixer_device_get_active_profile -mate_mixer_device_set_active_profile +mate_mixer_device_get_stream +mate_mixer_device_get_switch +mate_mixer_device_list_streams +mate_mixer_device_list_switches <SUBSECTION Standard> MATE_MIXER_DEVICE -MATE_MIXER_DEVICE_GET_INTERFACE +MATE_MIXER_DEVICE_CLASS +MATE_MIXER_DEVICE_GET_CLASS MATE_MIXER_IS_DEVICE +MATE_MIXER_IS_DEVICE_CLASS MATE_MIXER_TYPE_DEVICE -mate_mixer_device_get_type -</SECTION> - -<SECTION> -<FILE>matemixer-device-profile</FILE> -<TITLE>MateMixerDeviceProfile</TITLE> -MateMixerDeviceProfile -mate_mixer_device_profile_get_name -mate_mixer_device_profile_get_description -mate_mixer_device_profile_get_priority -mate_mixer_device_profile_get_num_input_streams -mate_mixer_device_profile_get_num_output_streams -<SUBSECTION Standard> -MateMixerDeviceProfileClass -MATE_MIXER_IS_DEVICE_PROFILE -MATE_MIXER_IS_DEVICE_PROFILE_CLASS -MATE_MIXER_DEVICE_PROFILE -MATE_MIXER_DEVICE_PROFILE_CLASS -MATE_MIXER_DEVICE_PROFILE_GET_CLASS -MATE_MIXER_TYPE_DEVICE_PROFILE -mate_mixer_device_profile_get_type <SUBSECTION Private> -MateMixerDeviceProfilePrivate +MateMixerDevicePrivate +mate_mixer_device_get_type </SECTION> <SECTION> -<FILE>matemixer-port</FILE> -<TITLE>MateMixerPort</TITLE> -MateMixerPortFlags -MateMixerPort -mate_mixer_port_get_name -mate_mixer_port_get_description -mate_mixer_port_get_icon -mate_mixer_port_get_priority -mate_mixer_port_get_flags +<FILE>matemixer-stored-control</FILE> +<TITLE>MateMixerStoredControl</TITLE> +MateMixerStoredControl +MateMixerStoredControlClass +mate_mixer_stored_control_get_direction <SUBSECTION Standard> -MateMixerPortClass -MATE_MIXER_IS_PORT -MATE_MIXER_IS_PORT_CLASS -MATE_MIXER_PORT -MATE_MIXER_PORT_CLASS -MATE_MIXER_PORT_GET_CLASS -MATE_MIXER_TYPE_PORT -mate_mixer_port_get_type +MATE_MIXER_STORED_CONTROL +MATE_MIXER_STORED_CONTROL_CLASS +MATE_MIXER_STORED_CONTROL_GET_CLASS +MATE_MIXER_IS_STORED_CONTROL +MATE_MIXER_IS_STORED_CONTROL_CLASS +MATE_MIXER_TYPE_STORED_CONTROL <SUBSECTION Private> -MateMixerPortPrivate +MateMixerStoredControlPrivate +mate_mixer_stored_control_get_type </SECTION> <SECTION> <FILE>matemixer-stream</FILE> <TITLE>MateMixerStream</TITLE> -MateMixerChannelPosition -MateMixerStreamFlags -MateMixerStreamState +MateMixerDirection MateMixerStream -MateMixerStreamInterface -MATE_MIXER_INFINITY +MateMixerStreamClass mate_mixer_stream_get_name -mate_mixer_stream_get_description +mate_mixer_stream_get_label +mate_mixer_stream_get_direction mate_mixer_stream_get_device -mate_mixer_stream_get_flags -mate_mixer_stream_get_state -mate_mixer_stream_get_mute -mate_mixer_stream_set_mute -mate_mixer_stream_get_num_channels -mate_mixer_stream_get_volume -mate_mixer_stream_set_volume -mate_mixer_stream_get_decibel -mate_mixer_stream_set_decibel -mate_mixer_stream_get_channel_position -mate_mixer_stream_get_channel_volume -mate_mixer_stream_set_channel_volume -mate_mixer_stream_get_channel_decibel -mate_mixer_stream_set_channel_decibel -mate_mixer_stream_has_channel_position -mate_mixer_stream_get_balance -mate_mixer_stream_set_balance -mate_mixer_stream_get_fade -mate_mixer_stream_set_fade -mate_mixer_stream_suspend -mate_mixer_stream_resume -mate_mixer_stream_monitor_start -mate_mixer_stream_monitor_stop -mate_mixer_stream_monitor_is_running -mate_mixer_stream_monitor_set_name -mate_mixer_stream_list_ports -mate_mixer_stream_get_active_port -mate_mixer_stream_set_active_port -mate_mixer_stream_get_min_volume -mate_mixer_stream_get_max_volume -mate_mixer_stream_get_normal_volume -mate_mixer_stream_get_base_volume +mate_mixer_stream_get_control +mate_mixer_stream_get_switch +mate_mixer_stream_get_default_control +mate_mixer_stream_list_controls +mate_mixer_stream_list_switches <SUBSECTION Standard> MATE_MIXER_IS_STREAM +MATE_MIXER_IS_STREAM_CLASS MATE_MIXER_STREAM -MATE_MIXER_STREAM_GET_INTERFACE +MATE_MIXER_STREAM_CLASS +MATE_MIXER_STREAM_GET_CLASS MATE_MIXER_TYPE_STREAM +<SUBSECTION Private> +MateMixerStreamPrivate mate_mixer_stream_get_type </SECTION> + +<SECTION> +<FILE>matemixer-stream-control</FILE> +<TITLE>MateMixerStreamControl</TITLE> +MATE_MIXER_INFINITY +MateMixerStreamControlFlags +MateMixerStreamControlRole +MateMixerStreamControlMediaRole +MateMixerChannelPosition +MateMixerStreamControl +MateMixerStreamControlClass +mate_mixer_stream_control_get_name +mate_mixer_stream_control_get_label +mate_mixer_stream_control_get_flags +mate_mixer_stream_control_get_role +mate_mixer_stream_control_get_media_role +mate_mixer_stream_control_get_app_info +mate_mixer_stream_control_get_stream +mate_mixer_stream_control_set_stream +mate_mixer_stream_control_get_mute +mate_mixer_stream_control_set_mute +mate_mixer_stream_control_get_num_channels +mate_mixer_stream_control_get_volume +mate_mixer_stream_control_set_volume +mate_mixer_stream_control_get_decibel +mate_mixer_stream_control_set_decibel +mate_mixer_stream_control_has_channel_position +mate_mixer_stream_control_get_channel_position +mate_mixer_stream_control_get_channel_volume +mate_mixer_stream_control_set_channel_volume +mate_mixer_stream_control_get_channel_decibel +mate_mixer_stream_control_set_channel_decibel +mate_mixer_stream_control_get_balance +mate_mixer_stream_control_set_balance +mate_mixer_stream_control_get_fade +mate_mixer_stream_control_set_fade +mate_mixer_stream_control_get_monitor_enabled +mate_mixer_stream_control_set_monitor_enabled +mate_mixer_stream_control_get_min_volume +mate_mixer_stream_control_get_max_volume +mate_mixer_stream_control_get_normal_volume +mate_mixer_stream_control_get_base_volume +<SUBSECTION Standard> +MATE_MIXER_IS_STREAM_CONTROL +MATE_MIXER_IS_STREAM_CONTROL_CLASS +MATE_MIXER_STREAM_CONTROL +MATE_MIXER_STREAM_CONTROL_CLASS +MATE_MIXER_STREAM_CONTROL_GET_CLASS +MATE_MIXER_TYPE_STREAM_CONTROL +<SUBSECTION Private> +MateMixerStreamControlPrivate +mate_mixer_stream_control_get_type +</SECTION> + +<SECTION> +<FILE>matemixer-switch</FILE> +<TITLE>MateMixerSwitch</TITLE> +MateMixerSwitchFlags +MateMixerSwitchRole +MateMixerSwitch +MateMixerSwitchClass +mate_mixer_switch_get_name +mate_mixer_switch_get_label +mate_mixer_switch_get_flags +mate_mixer_switch_get_role +mate_mixer_switch_get_option +mate_mixer_switch_list_options +mate_mixer_switch_get_active_option +mate_mixer_switch_set_active_option +<SUBSECTION Standard> +MATE_MIXER_IS_SWITCH +MATE_MIXER_IS_SWITCH_CLASS +MATE_MIXER_SWITCH +MATE_MIXER_SWITCH_CLASS +MATE_MIXER_SWITCH_GET_CLASS +MATE_MIXER_TYPE_SWITCH +<SUBSECTION Private> +MateMixerSwitchPrivate +mate_mixer_switch_get_type +</SECTION> + +<SECTION> +<FILE>matemixer-switch-option</FILE> +<TITLE>MateMixerSwitchOption</TITLE> +MateMixerSwitchOption +MateMixerSwitchOptionClass +mate_mixer_switch_option_get_name +mate_mixer_switch_option_get_label +mate_mixer_switch_option_get_icon +<SUBSECTION Standard> +MATE_MIXER_IS_SWITCH_OPTION +MATE_MIXER_IS_SWITCH_OPTION_CLASS +MATE_MIXER_SWITCH_OPTION +MATE_MIXER_SWITCH_OPTION_CLASS +MATE_MIXER_SWITCH_OPTION_GET_CLASS +MATE_MIXER_TYPE_SWITCH_OPTION +<SUBSECTION Private> +MateMixerSwitchOptionPrivate +mate_mixer_switch_option_get_type +</SECTION> + +<SECTION> +<FILE>matemixer-toggle</FILE> +<TITLE>MateMixerToggle</TITLE> +MateMixerToggle +MateMixerToggleClass +mate_mixer_toggle_get_state +mate_mixer_toggle_set_state +mate_mixer_toggle_get_state_option +<SUBSECTION Standard> +MATE_MIXER_IS_TOGGLE +MATE_MIXER_IS_TOGGLE_CLASS +MATE_MIXER_TOGGLE +MATE_MIXER_TOGGLE_CLASS +MATE_MIXER_TOGGLE_GET_CLASS +MATE_MIXER_TYPE_TOGGLE +<SUBSECTION Private> +MateMixerTogglePrivate +mate_mixer_toggle_get_type +</SECTION> diff --git a/libmatemixer/matemixer-app-info.c b/libmatemixer/matemixer-app-info.c index 369f148..1be6610 100644 --- a/libmatemixer/matemixer-app-info.c +++ b/libmatemixer/matemixer-app-info.c @@ -18,13 +18,35 @@ #include "matemixer-app-info.h" #include "matemixer-app-info-private.h" +/** + * SECTION:matemixer-app-info + * @short_description: Application information + * @include: libmatemixer/matemixer.h + * @see_also: #MateMixerStreamControl + * + * The #MateMixerAppInfo structure describes application properties. + * + * See #MateMixerStreamControl and the mate_mixer_stream_control_get_app_info() + * function for more information. + */ + +/** + * MateMixerAppInfo: + * + * The #MateMixerAppInfo structure contains only private data and should only + * be accessed using the provided API. + */ G_DEFINE_BOXED_TYPE (MateMixerAppInfo, mate_mixer_app_info, _mate_mixer_app_info_copy, _mate_mixer_app_info_free) /** * mate_mixer_app_info_get_name: - * @device: a #MateMixerAppInfo + * @info: a #MateMixerAppInfo + * + * Gets the name of the application described by @info. + * + * Returns: name of the application or %NULL if it is unknown. */ const gchar * mate_mixer_app_info_get_name (MateMixerAppInfo *info) @@ -36,7 +58,12 @@ mate_mixer_app_info_get_name (MateMixerAppInfo *info) /** * mate_mixer_app_info_get_id: - * @device: a #MateMixerAppInfo + * @info: a #MateMixerAppInfo + * + * Gets the identifier of the application described by @info + * (e.g. org.example.app). + * + * Returns: identifier of the application or %NULL if it is unknown. */ const gchar * mate_mixer_app_info_get_id (MateMixerAppInfo *info) @@ -48,7 +75,11 @@ mate_mixer_app_info_get_id (MateMixerAppInfo *info) /** * mate_mixer_app_info_get_version: - * @device: a #MateMixerAppInfo + * @info: a #MateMixerAppInfo + * + * Gets the version of the application described by @info. + * + * Returns: version of the application or %NULL if it is unknown. */ const gchar * mate_mixer_app_info_get_version (MateMixerAppInfo *info) @@ -60,7 +91,11 @@ mate_mixer_app_info_get_version (MateMixerAppInfo *info) /** * mate_mixer_app_info_get_icon: - * @device: a #MateMixerAppInfo + * @info: a #MateMixerAppInfo + * + * Gets the XDG icon name of the application described by @info. + * + * Returns: icon name of the application or %NULL if it is unknown. */ const gchar * mate_mixer_app_info_get_icon (MateMixerAppInfo *info) @@ -70,12 +105,26 @@ mate_mixer_app_info_get_icon (MateMixerAppInfo *info) return info->icon; } +/** + * _mate_mixer_app_info_new: + * + * Creates a new empty #MateMixerAppInfo structure. + * + * Returns: a new #MateMixerAppInfo. + */ MateMixerAppInfo * _mate_mixer_app_info_new (void) { return g_slice_new0 (MateMixerAppInfo); } +/** + * _mate_mixer_app_info_set_name: + * @info: a #MateMixerAppInfo + * @name: the application name to set + * + * Sets the name of the application described by @info. + */ void _mate_mixer_app_info_set_name (MateMixerAppInfo *info, const gchar *name) { @@ -86,6 +135,13 @@ _mate_mixer_app_info_set_name (MateMixerAppInfo *info, const gchar *name) info->name = g_strdup (name); } +/** + * _mate_mixer_app_info_set_id: + * @info: a #MateMixerAppInfo + * @id: the application identifier to set + * + * Sets the identifier of the application described by @info. + */ void _mate_mixer_app_info_set_id (MateMixerAppInfo *info, const gchar *id) { @@ -96,6 +152,13 @@ _mate_mixer_app_info_set_id (MateMixerAppInfo *info, const gchar *id) info->id = g_strdup (id); } +/** + * _mate_mixer_app_info_set_version: + * @info: a #MateMixerAppInfo + * @version: the application version to set + * + * Sets the version of the application described by @info. + */ void _mate_mixer_app_info_set_version (MateMixerAppInfo *info, const gchar *version) { @@ -106,6 +169,13 @@ _mate_mixer_app_info_set_version (MateMixerAppInfo *info, const gchar *version) info->version = g_strdup (version); } +/** + * _mate_mixer_app_info_set_version: + * @info: a #MateMixerAppInfo + * @icon: the application icon name to set + * + * Sets the XDG icon name of the application described by @info. + */ void _mate_mixer_app_info_set_icon (MateMixerAppInfo *info, const gchar *icon) { @@ -116,11 +186,21 @@ _mate_mixer_app_info_set_icon (MateMixerAppInfo *info, const gchar *icon) info->icon = g_strdup (icon); } +/** + * _mate_mixer_app_info_copy: + * @info: a #MateMixerAppInfo + * + * Creates a copy of the #MateMixerAppInfo. + * + * Returns: a copy of the given @info. + */ MateMixerAppInfo * _mate_mixer_app_info_copy (MateMixerAppInfo *info) { MateMixerAppInfo *info2; + g_return_val_if_fail (info != NULL, NULL); + info2 = _mate_mixer_app_info_new (); info2->name = g_strdup (info->name); info2->id = g_strdup (info->id); @@ -130,9 +210,17 @@ _mate_mixer_app_info_copy (MateMixerAppInfo *info) return info2; } +/** + * _mate_mixer_app_info_free: + * @info: a #MateMixerAppInfo + * + * Frees the #MateMixerAppInfo. + */ void _mate_mixer_app_info_free (MateMixerAppInfo *info) { + g_return_if_fail (info != NULL); + g_free (info->name); g_free (info->id); g_free (info->version); diff --git a/libmatemixer/matemixer-app-info.h b/libmatemixer/matemixer-app-info.h index eedc1c7..69aa6f9 100644 --- a/libmatemixer/matemixer-app-info.h +++ b/libmatemixer/matemixer-app-info.h @@ -26,7 +26,6 @@ G_BEGIN_DECLS #define MATE_MIXER_TYPE_APP_INFO (mate_mixer_app_info_get_type ()) -#define MATE_MIXER_APP_INFO(o) ((MateMixerAppInfo *) o) GType mate_mixer_app_info_get_type (void) G_GNUC_CONST; diff --git a/libmatemixer/matemixer-backend-module.c b/libmatemixer/matemixer-backend-module.c index bd71de0..f5f7994 100644 --- a/libmatemixer/matemixer-backend-module.c +++ b/libmatemixer/matemixer-backend-module.c @@ -124,7 +124,7 @@ mate_mixer_backend_module_set_property (GObject *object, switch (param_id) { case PROP_PATH: /* Construct-only string */ - module->priv->path = g_strdup (g_value_get_string (value)); + module->priv->path = g_value_dup_string (value); g_type_module_set_name (G_TYPE_MODULE (object), module->priv->path); break; @@ -213,7 +213,7 @@ mate_mixer_backend_module_get_info (MateMixerBackendModule *module) * * Gets file path to the backend module. * - * Returns: string containing the path. + * Returns: the file path. */ const gchar * mate_mixer_backend_module_get_path (MateMixerBackendModule *module) @@ -234,7 +234,8 @@ backend_module_load (GTypeModule *type_module) return TRUE; module->priv->gmodule = g_module_open (module->priv->path, - G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL); + 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, @@ -263,7 +264,7 @@ backend_module_load (GTypeModule *type_module) /* 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)) { + if G_UNLIKELY (module->priv->get_info () == NULL) { g_critical ("Backend module %s does not provide module information", module->priv->path); diff --git a/libmatemixer/matemixer-backend-module.h b/libmatemixer/matemixer-backend-module.h index dc95633..be2f7d1 100644 --- a/libmatemixer/matemixer-backend-module.h +++ b/libmatemixer/matemixer-backend-module.h @@ -61,6 +61,7 @@ struct _MateMixerBackendInfo gchar *name; guint priority; GType g_type; + MateMixerBackendFlags backend_flags; MateMixerBackendType backend_type; }; diff --git a/libmatemixer/matemixer-backend.c b/libmatemixer/matemixer-backend.c index b8177e3..56efd94 100644 --- a/libmatemixer/matemixer-backend.c +++ b/libmatemixer/matemixer-backend.c @@ -356,14 +356,6 @@ mate_mixer_backend_get_state (MateMixerBackend *backend) return backend->priv->state; } -MateMixerBackendFlags -mate_mixer_backend_get_flags (MateMixerBackend *backend) -{ - g_return_val_if_fail (MATE_MIXER_IS_BACKEND (backend), MATE_MIXER_BACKEND_NO_FLAGS); - - return backend->priv->flags; -} - MateMixerDevice * mate_mixer_backend_get_device (MateMixerBackend *backend, const gchar *name) { @@ -433,7 +425,7 @@ mate_mixer_backend_list_devices (MateMixerBackend *backend) klass = MATE_MIXER_BACKEND_GET_CLASS (backend); - if G_LIKELY (klass->list_devices != NULL) + if (klass->list_devices != NULL) return klass->list_devices (backend); return NULL; @@ -448,7 +440,7 @@ mate_mixer_backend_list_streams (MateMixerBackend *backend) klass = MATE_MIXER_BACKEND_GET_CLASS (backend); - if G_LIKELY (klass->list_streams != NULL) + if (klass->list_streams != NULL) return klass->list_streams (backend); return NULL; @@ -481,21 +473,26 @@ gboolean mate_mixer_backend_set_default_input_stream (MateMixerBackend *backend, MateMixerStream *stream) { + MateMixerBackendClass *klass; + 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_input_stream == NULL) + return FALSE; - klass = MATE_MIXER_BACKEND_GET_CLASS (backend); + if (backend->priv->default_input != stream) { + if (mate_mixer_stream_get_direction (stream) != MATE_MIXER_DIRECTION_INPUT) { + g_warning ("Unable to set non-input stream as the default input stream"); + return FALSE; + } - if (klass->set_default_input_stream == NULL || - klass->set_default_input_stream (backend, stream) == FALSE) + if (klass->set_default_input_stream (backend, stream) == FALSE) return FALSE; _mate_mixer_backend_set_default_input_stream (backend, stream); } - return TRUE; } @@ -511,21 +508,26 @@ gboolean mate_mixer_backend_set_default_output_stream (MateMixerBackend *backend, MateMixerStream *stream) { + MateMixerBackendClass *klass; + 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) + return FALSE; - klass = MATE_MIXER_BACKEND_GET_CLASS (backend); + if (backend->priv->default_input != stream) { + if (mate_mixer_stream_get_direction (stream) != MATE_MIXER_DIRECTION_OUTPUT) { + g_warning ("Unable to set non-output stream as the default output stream"); + return FALSE; + } - if (klass->set_default_output_stream == NULL || - klass->set_default_output_stream (backend, stream) == FALSE) + if (klass->set_default_output_stream (backend, stream) == FALSE) return FALSE; _mate_mixer_backend_set_default_output_stream (backend, stream); } - return TRUE; } @@ -612,14 +614,6 @@ _mate_mixer_backend_set_state (MateMixerBackend *backend, MateMixerState state) } void -_mate_mixer_backend_set_flags (MateMixerBackend *backend, MateMixerBackendFlags flags) -{ - g_return_if_fail (MATE_MIXER_IS_BACKEND (backend)); - - backend->priv->flags = flags; -} - -void _mate_mixer_backend_set_default_input_stream (MateMixerBackend *backend, MateMixerStream *stream) { diff --git a/libmatemixer/matemixer-backend.h b/libmatemixer/matemixer-backend.h index 41ffb40..08dc92c 100644 --- a/libmatemixer/matemixer-backend.h +++ b/libmatemixer/matemixer-backend.h @@ -90,47 +90,44 @@ struct _MateMixerBackendClass GType mate_mixer_backend_get_type (void) G_GNUC_CONST; -void mate_mixer_backend_set_app_info (MateMixerBackend *backend, - MateMixerAppInfo *info); -void mate_mixer_backend_set_server_address (MateMixerBackend *backend, - const gchar *address); +void mate_mixer_backend_set_app_info (MateMixerBackend *backend, + MateMixerAppInfo *info); +void mate_mixer_backend_set_server_address (MateMixerBackend *backend, + const gchar *address); -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); -MateMixerBackendFlags mate_mixer_backend_get_flags (MateMixerBackend *backend); +MateMixerState mate_mixer_backend_get_state (MateMixerBackend *backend); -MateMixerDevice * mate_mixer_backend_get_device (MateMixerBackend *backend, - const gchar *name); -MateMixerStream * mate_mixer_backend_get_stream (MateMixerBackend *backend, - const gchar *name); -MateMixerStoredControl *mate_mixer_backend_get_stored_control (MateMixerBackend *backend, - const gchar *name); +MateMixerDevice * mate_mixer_backend_get_device (MateMixerBackend *backend, + const gchar *name); +MateMixerStream * mate_mixer_backend_get_stream (MateMixerBackend *backend, + const gchar *name); +MateMixerStoredControl *mate_mixer_backend_get_stored_control (MateMixerBackend *backend, + const gchar *name); -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_controls (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_controls (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); /* Protected functions */ -void _mate_mixer_backend_set_state (MateMixerBackend *backend, - MateMixerState state); -void _mate_mixer_backend_set_flags (MateMixerBackend *backend, - MateMixerBackendFlags flags); +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_input_stream (MateMixerBackend *backend, + MateMixerStream *stream); -void _mate_mixer_backend_set_default_output_stream (MateMixerBackend *backend, - MateMixerStream *stream); +void _mate_mixer_backend_set_default_output_stream (MateMixerBackend *backend, + MateMixerStream *stream); G_END_DECLS diff --git a/libmatemixer/matemixer-context.c b/libmatemixer/matemixer-context.c index bb28b18..dacbc9a 100644 --- a/libmatemixer/matemixer-context.c +++ b/libmatemixer/matemixer-context.c @@ -15,7 +15,6 @@ * License along with this library; if not, see <http://www.gnu.org/licenses/>. */ -#include <string.h> #include <glib.h> #include <glib-object.h> @@ -32,6 +31,43 @@ * SECTION:matemixer-context * @short_description:The main class for interfacing with the library * @include: libmatemixer/matemixer.h + * + * After the library is initialized, a context should be created to gain + * access to a sound system. + * + * To create a new context, use the mate_mixer_context_new() function. + * + * The mate_mixer_context_set_backend_type() function can be used to associate + * the context with a particular type of sound system. Using this function is + * not necessary, by default the context will select a working sound system + * backend automatically. + * + * To connect to a sound system, use mate_mixer_context_open(). + * + * When the connection is established, it is possible to query a list of sound + * devices with mate_mixer_context_list_devices() and streams with + * mate_mixer_context_list_streams(). + * + * A device represents a hardware or software sound device in the system, + * typically a sound card. + * + * A stream is an input or output channel that may exist either as a part of a + * sound device, or independently. Streams essentially serve as containers for + * volume controls and switches, for example a sound card with microphone and + * line-in connectors may have an input stream containing volume controls for + * each of these connectors and possibly a switch allowing to change the active + * connector. + * + * Streams may also exist independently as the sound system may for example + * allow audio streaming over a network. + * + * For a more thorough description of devices and streams, see #MateMixerDevice + * and #MateMixerStream. + * + * Devices and streams (as almost all other elements in the library) may appear + * and disappear at any time, for example when external sound cards are plugged + * and unplugged. The application should connect to the appropriate signals to + * handle these events. */ struct _MateMixerContextPrivate @@ -178,12 +214,12 @@ mate_mixer_context_class_init (MateMixerContextClass *klass) /** * MateMixerContext:app-icon: * - * An XDG icon name for the application. + * The XDG icon name of the application. */ properties[PROP_APP_ICON] = g_param_spec_string ("app-icon", "App icon", - "Application icon name", + "Application XDG icon name", NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); @@ -192,8 +228,9 @@ mate_mixer_context_class_init (MateMixerContextClass *klass) * * Address of the sound server to connect to. * - * This feature is only supported in the PulseAudio backend. There is - * no need to specify an address in order to connect to the local daemon. + * This feature is only supported by the PulseAudio sound system. + * There is no need to specify an address in order to connect to the + * local PulseAudio daemon. */ properties[PROP_SERVER_ADDRESS] = g_param_spec_string ("server-address", @@ -202,6 +239,11 @@ mate_mixer_context_class_init (MateMixerContextClass *klass) NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + /** + * MateMixerContext:state: + * + * The current state of the connection to a sound system. + */ properties[PROP_STATE] = g_param_spec_enum ("state", "State", @@ -210,6 +252,14 @@ mate_mixer_context_class_init (MateMixerContextClass *klass) MATE_MIXER_STATE_IDLE, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + /** + * MateMixerContext:default-input-stream: + * + * The stream sound input most likely comes from by default. + * + * See mate_mixer_context_set_default_input_stream() for more information + * about changing the default input stream. + */ properties[PROP_DEFAULT_INPUT_STREAM] = g_param_spec_object ("default-input-stream", "Default input stream", @@ -217,6 +267,14 @@ mate_mixer_context_class_init (MateMixerContextClass *klass) MATE_MIXER_TYPE_STREAM, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + /** + * MateMixerContext:default-output-stream: + * + * The stream sound output is most likely directed to by default. + * + * See mate_mixer_context_set_default_output_stream() for more information + * about changing the default output stream. + */ properties[PROP_DEFAULT_OUTPUT_STREAM] = g_param_spec_object ("default-output-stream", "Default output stream", @@ -232,11 +290,16 @@ mate_mixer_context_class_init (MateMixerContextClass *klass) * @name: name of the added device * * The signal is emitted each time a device is added to the system. + * + * Use mate_mixer_context_get_device() to get the #MateMixerDevice. + * + * Note that at the time this signal is emitted, the streams and switches + * of the device may not yet be known. */ signals[DEVICE_ADDED] = g_signal_new ("device-added", G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, + G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (MateMixerContextClass, device_added), NULL, NULL, @@ -251,11 +314,16 @@ mate_mixer_context_class_init (MateMixerContextClass *klass) * @name: name of the removed device * * The signal is emitted each time a device is removed from the system. + * + * When this signal is emitted, the device is no longer known to the library, + * it will not be included in the device list provided by the + * mate_mixer_context_list_devices() function and it is not possible to get + * the device with mate_mixer_context_get_device(). */ signals[DEVICE_REMOVED] = g_signal_new ("device-removed", G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, + G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (MateMixerContextClass, device_removed), NULL, NULL, @@ -269,12 +337,19 @@ mate_mixer_context_class_init (MateMixerContextClass *klass) * @context: a #MateMixerContext * @name: name of the added stream * - * The signal is emitted each time a stream is created. + * The signal is emitted each time a stream is added. + * + * This signal is emitted for streams which belong to devices as well as + * streams which do not. If you are only interested in streams of a + * specific device, the signal is also available in #MateMixerDevice. + * + * Note that at the time this signal is emitted, the controls and switches + * of the stream may not yet be known. */ signals[STREAM_ADDED] = g_signal_new ("stream-added", G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, + G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (MateMixerContextClass, stream_added), NULL, NULL, @@ -289,11 +364,20 @@ mate_mixer_context_class_init (MateMixerContextClass *klass) * @name: name of the removed stream * * The signal is emitted each time a stream is removed. + * + * When this signal is emitted, the stream is no longer known to the library, + * it will not be included in the stream list provided by the + * mate_mixer_context_list_streams() function and it is not possible to get + * the stream with mate_mixer_context_get_stream(). + * + * This signal is emitted for streams which belong to devices as well as + * streams which do not. If you are only interested in streams of a + * specific device, the signal is also available in #MateMixerDevice. */ signals[STREAM_REMOVED] = g_signal_new ("stream-removed", G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, + G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (MateMixerContextClass, stream_removed), NULL, NULL, @@ -307,12 +391,14 @@ mate_mixer_context_class_init (MateMixerContextClass *klass) * @context: a #MateMixerContext * @name: name of the added stored control * - * The signal is emitted each time a stored control is created. + * The signal is emitted each time a stored control is added. + * + * Use mate_mixer_context_get_stored_control() to get the #MateMixerStoredControl. */ signals[STORED_CONTROL_ADDED] = g_signal_new ("stored-control-added", G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, + G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (MateMixerContextClass, stored_control_added), NULL, NULL, @@ -324,14 +410,19 @@ mate_mixer_context_class_init (MateMixerContextClass *klass) /** * MateMixerContext::stored-control-removed: * @context: a #MateMixerContext - * @name: name of the removed control + * @name: name of the removed stored control + * + * The signal is emitted each time a stored control is removed. * - * The signal is emitted each time a control is removed. + * When this signal is emitted, the stored control is no longer known to the + * library, it will not be included in the stream list provided by the + * mate_mixer_context_list_stored_controls() function and it is not possible to + * get the stored control with mate_mixer_context_get_stored_control(). */ signals[STORED_CONTROL_REMOVED] = g_signal_new ("stored-control-removed", G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, + G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (MateMixerContextClass, stored_control_removed), NULL, NULL, @@ -466,7 +557,7 @@ mate_mixer_context_finalize (GObject *object) * Creates a new #MateMixerContext instance. * * Returns: a new #MateMixerContext instance or %NULL if the library has not - * been initialized using mate_mixer_init(). + * been initialized with mate_mixer_init(). */ MateMixerContext * mate_mixer_context_new (void) @@ -487,18 +578,23 @@ mate_mixer_context_new (void) * Makes the #MateMixerContext use the given #MateMixerBackendType. * * By default the backend type is determined automatically. This function can - * be used before mate_mixer_context_open() to alter this behavior and make the - * @context use the given backend. + * be used to alter this behavior and make the @context use the selected sound + * system. + * + * Setting the backend type only succeeds if the selected backend module is + * available in the target system. * - * 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 - * %MATE_MIXER_STATE_READY. + * If you have used this function before and want restore the default automatic + * backend type discovery, set the backend type to %MATE_MIXER_BACKEND_UNKNOWN. + * + * This function must be used before opening a connection to a sound system with + * mate_mixer_context_open(), otherwise it will fail. * * Returns: %TRUE on success or %FALSE on failure. */ gboolean -mate_mixer_context_set_backend_type (MateMixerContext *context, - MateMixerBackendType backend_type) +mate_mixer_context_set_backend_type (MateMixerContext *context, + MateMixerBackendType backend_type) { MateMixerBackendModule *module; const GList *modules; @@ -510,8 +606,13 @@ mate_mixer_context_set_backend_type (MateMixerContext *context, context->priv->state == MATE_MIXER_STATE_READY) return FALSE; - modules = _mate_mixer_list_modules (); + /* Allow setting the backend to unknown to restore the auto-detection */ + if (backend_type == MATE_MIXER_BACKEND_UNKNOWN) { + context->priv->backend_type = backend_type; + return TRUE; + } + modules = _mate_mixer_list_modules (); while (modules != NULL) { module = MATE_MIXER_BACKEND_MODULE (modules->data); info = mate_mixer_backend_module_get_info (module); @@ -530,12 +631,11 @@ mate_mixer_context_set_backend_type (MateMixerContext *context, * @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 - * PulseAudio backend. + * Sets the name of your application. This information may be used when + * registering with the sound system. * - * This function will fail if the current state is either - * %MATE_MIXER_STATE_CONNECTING or %MATE_MIXER_STATE_READY, therefore you should - * use it before opening a connection to the sound system. + * This function must be used before opening a connection to a sound system with + * mate_mixer_context_open(), otherwise it will fail. * * Returns: %TRUE on success or %FALSE on failure. */ @@ -550,9 +650,7 @@ mate_mixer_context_set_app_name (MateMixerContext *context, const gchar *app_nam _mate_mixer_app_info_set_name (context->priv->app_info, app_name); - g_object_notify_by_pspec (G_OBJECT (context), - properties[PROP_APP_NAME]); - + g_object_notify_by_pspec (G_OBJECT (context), properties[PROP_APP_NAME]); return TRUE; } @@ -561,12 +659,11 @@ mate_mixer_context_set_app_name (MateMixerContext *context, const gchar *app_nam * @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 - * is only supported in the PulseAudio backend. + * Sets the identifier of your application (e.g. org.example.app). This + * information may be used when registering with the sound system. * - * This function will fail if the current state is either - * %MATE_MIXER_STATE_CONNECTING or %MATE_MIXER_STATE_READY, therefore you should - * use it before opening a connection to the sound system. + * This function must be used before opening a connection to a sound system with + * mate_mixer_context_open(), otherwise it will fail. * * Returns: %TRUE on success or %FALSE on failure. */ @@ -581,9 +678,7 @@ mate_mixer_context_set_app_id (MateMixerContext *context, const gchar *app_id) _mate_mixer_app_info_set_id (context->priv->app_info, app_id); - g_object_notify_by_pspec (G_OBJECT (context), - properties[PROP_APP_ID]); - + g_object_notify_by_pspec (G_OBJECT (context), properties[PROP_APP_ID]); return TRUE; } @@ -592,12 +687,11 @@ mate_mixer_context_set_app_id (MateMixerContext *context, const gchar *app_id) * @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 - * PulseAudio backend. + * Sets the version of your application. This information may be used when + * registering with the sound system. * - * This function will fail if the current state is either - * %MATE_MIXER_STATE_CONNECTING or %MATE_MIXER_STATE_READY, therefore you should - * use it before opening a connection to the sound system. + * This function must be used before opening a connection to a sound system with + * mate_mixer_context_open(), otherwise it will fail. * * Returns: %TRUE on success or %FALSE on failure. */ @@ -612,9 +706,7 @@ mate_mixer_context_set_app_version (MateMixerContext *context, const gchar *app_ _mate_mixer_app_info_set_version (context->priv->app_info, app_version); - g_object_notify_by_pspec (G_OBJECT (context), - properties[PROP_APP_VERSION]); - + g_object_notify_by_pspec (G_OBJECT (context), properties[PROP_APP_VERSION]); return TRUE; } @@ -623,12 +715,11 @@ mate_mixer_context_set_app_version (MateMixerContext *context, const gchar *app_ * @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 - * the PulseAudio backend. + * Sets the XDG icon name of your application. This information may be used when + * registering with the sound system. * - * This function will fail if the current state is either - * %MATE_MIXER_STATE_CONNECTING or %MATE_MIXER_STATE_READY, therefore you should - * use it before opening a connection to the sound system. + * This function must be used before opening a connection to a sound system with + * mate_mixer_context_open(), otherwise it will fail. * * Returns: %TRUE on success or %FALSE on failure. */ @@ -643,9 +734,7 @@ mate_mixer_context_set_app_icon (MateMixerContext *context, const gchar *app_ico _mate_mixer_app_info_set_icon (context->priv->app_info, app_icon); - g_object_notify_by_pspec (G_OBJECT (context), - properties[PROP_APP_ICON]); - + g_object_notify_by_pspec (G_OBJECT (context), properties[PROP_APP_ICON]); return TRUE; } @@ -658,9 +747,8 @@ mate_mixer_context_set_app_icon (MateMixerContext *context, const gchar *app_ico * PulseAudio backend. If the address is not set, the default PulseAudio sound * server will be used, which is normally the local daemon. * - * This function will fail if the current state is either - * %MATE_MIXER_STATE_CONNECTING or %MATE_MIXER_STATE_READY, therefore you should - * use it before opening a connection to the sound system. + * This function must be used before opening a connection to a sound system with + * mate_mixer_context_open(), otherwise it will fail. * * Returns: %TRUE on success or %FALSE on failure. */ @@ -677,9 +765,7 @@ mate_mixer_context_set_server_address (MateMixerContext *context, const gchar *a context->priv->server_address = g_strdup (address); - g_object_notify_by_pspec (G_OBJECT (context), - properties[PROP_SERVER_ADDRESS]); - + g_object_notify_by_pspec (G_OBJECT (context), properties[PROP_SERVER_ADDRESS]); return TRUE; } @@ -687,24 +773,30 @@ mate_mixer_context_set_server_address (MateMixerContext *context, const gchar *a * 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. - * If the automatic discovery fails to find a working sound system, it will - * use the "Null" backend, which provides no functionality. + * Opens connection to a sound system. Unless the sound system backend type + * was chosen manually with mate_mixer_context_set_backend_type(), the library + * will find a working sound system automatically. * * This function can complete the operation either synchronously or - * asynchronously. + * asynchronously and it may go through a series of connection + * #MateMixerContext:state transitions. + * + * If this function returns %TRUE, the connection has either been established, or + * it hasn't been established yet and the result will be determined asynchronously. + * You can differentiate between these two possibilities by checking the connection + * #MateMixerContext:state after this function returns. * - * In case this function returns %TRUE, you should check the current state of - * 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 - * #MateMixerContext:state property. + * The %MATE_MIXER_STATE_READY state indicates that the connection has been + * established successfully. * - * 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. + * The %MATE_MIXER_STATE_CONNECTING state is reached when the connection has not been + * established yet and you should wait for the state to change to either + * %MATE_MIXER_STATE_READY or %MATE_MIXER_STATE_FAILED. It is required to have a main + * loop running to allow an asynchronous connection to proceed. The library will use + * the thread's default main context for this purpose. + * + * If this function returns %FALSE, it was not possible to connect to a sound system + * and the #MateMixerContext:state will be set to %MATE_MIXER_STATE_FAILED. * * Returns: %TRUE on success or if the result will be determined asynchronously, * or %FALSE on failure. @@ -724,7 +816,7 @@ mate_mixer_context_open (MateMixerContext *context) 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 */ + * selected by the application or the one with the highest priority */ modules = _mate_mixer_list_modules (); if (context->priv->backend_type != MATE_MIXER_BACKEND_UNKNOWN) { @@ -781,8 +873,8 @@ mate_mixer_context_open (MateMixerContext *context) state = mate_mixer_backend_get_state (context->priv->backend); - if (G_UNLIKELY (state != MATE_MIXER_STATE_READY && - state != MATE_MIXER_STATE_CONNECTING)) { + if G_UNLIKELY (state != MATE_MIXER_STATE_READY && + state != MATE_MIXER_STATE_CONNECTING) { /* This would be a backend bug */ g_warn_if_reached (); @@ -807,8 +899,8 @@ mate_mixer_context_open (MateMixerContext *context) * 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. + * Closes an open connection to the sound system. The #MateMixerContext:state + * will be set to %MATE_MIXER_STATE_IDLE. */ void mate_mixer_context_close (MateMixerContext *context) @@ -823,9 +915,9 @@ mate_mixer_context_close (MateMixerContext *context) * mate_mixer_context_get_state: * @context: a #MateMixerContext * - * Gets the current backend connection state of the #MateMixerContext. + * Gets the state of the @context's connection to a sound system. * - * Returns: The current connection state. + * Returns: the connection state. */ MateMixerState mate_mixer_context_get_state (MateMixerContext *context) @@ -884,7 +976,7 @@ mate_mixer_context_get_stream (MateMixerContext *context, const gchar *name) * * Gets the stored control with the given name. * - * Returns: a #MateMixerStoredControl or %NULL if there is no such control. + * Returns: a #MateMixerStoredControl or %NULL if there is no such stored control. */ MateMixerStoredControl * mate_mixer_context_get_stored_control (MateMixerContext *context, const gchar *name) @@ -902,11 +994,10 @@ mate_mixer_context_get_stored_control (MateMixerContext *context, const gchar *n * 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. + * Gets a list of devices. Each item in the list is a #MateMixerDevice representing + * a sound device in the system. * - * The returned #GList is owned by the #MateMixerContext and may be invalidated - * at any time. + * The returned #GList is owned by the library 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. @@ -926,11 +1017,14 @@ mate_mixer_context_list_devices (MateMixerContext *context) * 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. + * Gets a list of streams. Each item in the list is a #MateMixerStream representing + * an input or output stream. + * + * Note that the list will contain streams which belong to devices as well + * as streams which do not. If you are only interested in streams of a specific + * device, use mate_mixer_device_list_streams(). * - * The returned #GList is owned by the #MateMixerContext and may be invalidated - * at any time. + * The returned #GList is owned by the library 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. @@ -950,6 +1044,12 @@ mate_mixer_context_list_streams (MateMixerContext *context) * mate_mixer_context_list_stored_controls: * @context: a #MateMixerContext * + * Gets a list of stored controls. Each item in the list is a #MateMixerStoredControl. + * + * The returned #GList is owned by the library and may be invalidated at any time. + * + * Returns: a #GList of stored controls or %NULL if there are none or you are not + * connected to a sound system. */ const GList * mate_mixer_context_list_stored_controls (MateMixerContext *context) @@ -966,11 +1066,10 @@ mate_mixer_context_list_stored_controls (MateMixerContext *context) * 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. + * Gets the default input stream. The returned stream is where sound input + * most likely comes from by default. * - * Returns: a #MateMixerStream or %NULL if there are no input streams in - * the system. + * Returns: a #MateMixerStream or %NULL if there is no default input stream. */ MateMixerStream * mate_mixer_context_get_default_input_stream (MateMixerContext *context) @@ -988,8 +1087,10 @@ mate_mixer_context_get_default_input_stream (MateMixerContext *context) * @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 - * input non-client stream. + * Changes the default input stream. The given @stream must be an input stream. + * + * Changing the default input stream may not be supported by the sound system. + * Use mate_mixer_context_get_backend_flags() to find out. * * Returns: %TRUE on success or %FALSE on failure. */ @@ -1003,11 +1104,6 @@ mate_mixer_context_set_default_input_stream (MateMixerContext *context, if (context->priv->state != MATE_MIXER_STATE_READY) return FALSE; - if (mate_mixer_stream_get_direction (stream) != MATE_MIXER_DIRECTION_INPUT) { - g_warning ("Unable to set non-input stream as the default input stream"); - return FALSE; - } - return mate_mixer_backend_set_default_input_stream (context->priv->backend, stream); } @@ -1016,7 +1112,7 @@ mate_mixer_context_set_default_input_stream (MateMixerContext *context, * @context: a #MateMixerContext * * Gets the default output stream. The returned stream is where sound output is - * directed to by default. + * most likely directed to by default. * * Returns: a #MateMixerStream or %NULL if there are no output streams in * the system. @@ -1037,8 +1133,10 @@ mate_mixer_context_get_default_output_stream (MateMixerContext *context) * @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 - * output non-client stream. + * Changes the default output stream. The given @stream must be an output stream. + * + * Changing the default output stream may not be supported by the sound system. + * Use mate_mixer_context_get_backend_flags() to find out. * * Returns: %TRUE on success or %FALSE on failure. */ @@ -1052,11 +1150,6 @@ mate_mixer_context_set_default_output_stream (MateMixerContext *context, if (context->priv->state != MATE_MIXER_STATE_READY) return FALSE; - if (mate_mixer_stream_get_direction (stream) != MATE_MIXER_DIRECTION_OUTPUT) { - g_warning ("Unable to set non-output stream as the default output stream"); - return FALSE; - } - return mate_mixer_backend_set_default_output_stream (context->priv->backend, stream); } @@ -1064,8 +1157,9 @@ mate_mixer_context_set_default_output_stream (MateMixerContext *context, * 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. + * Gets the name of the currently used sound system backend. + * + * This function will not work until the @context is connected to a sound system. * * Returns: the name or %NULL on error. */ @@ -1084,8 +1178,9 @@ mate_mixer_context_get_backend_name (MateMixerContext *context) * 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. + * Gets the type of the currently used sound system backend. + * + * This function will not work until the @context is connected to a sound system. * * Returns: the backend type or %MATE_MIXER_BACKEND_UNKNOWN on error. */ @@ -1103,13 +1198,22 @@ mate_mixer_context_get_backend_type (MateMixerContext *context) /** * mate_mixer_context_get_backend_flags: * @context: a #MateMixerContext + * + * Gets the capability flags of the currently used sound system backend. + * + * This function will not work until the @context is connected to a sound system. + * + * Returns: the capability flags. */ 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); + if (context->priv->backend_chosen == FALSE) + return MATE_MIXER_BACKEND_NO_FLAGS; + + return mate_mixer_backend_module_get_info (context->priv->module)->backend_flags; } static void @@ -1280,8 +1384,8 @@ try_next_backend (MateMixerContext *context) state = mate_mixer_backend_get_state (context->priv->backend); - if (G_UNLIKELY (state != MATE_MIXER_STATE_READY && - state != MATE_MIXER_STATE_CONNECTING)) { + if G_UNLIKELY (state != MATE_MIXER_STATE_READY && + state != MATE_MIXER_STATE_CONNECTING) { /* This would be a backend bug */ g_warn_if_reached (); diff --git a/libmatemixer/matemixer-context.h b/libmatemixer/matemixer-context.h index 30d9363..19d153f 100644 --- a/libmatemixer/matemixer-context.h +++ b/libmatemixer/matemixer-context.h @@ -58,8 +58,9 @@ struct _MateMixerContext /** * MateMixerContextClass: + * @parent_class: The parent class. * - * The class structure of #MateMixerContext. + * The class structure for #MateMixerContext. */ struct _MateMixerContextClass { diff --git a/libmatemixer/matemixer-device.c b/libmatemixer/matemixer-device.c index 8144388..f9d368b 100644 --- a/libmatemixer/matemixer-device.c +++ b/libmatemixer/matemixer-device.c @@ -27,6 +27,10 @@ * SECTION:matemixer-device * @short_description: Hardware or software device in the sound system * @include: libmatemixer/matemixer.h + * + * A #MateMixerDevice represents a sound device, most typically a sound card. + * + * Each device may contain an arbitrary number of streams. */ struct _MateMixerDevicePrivate @@ -72,24 +76,30 @@ 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 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 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_stream = mate_mixer_device_real_get_stream; + klass->get_switch = mate_mixer_device_real_get_switch; object_class = G_OBJECT_CLASS (klass); 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; + /** + * MateMixerDevice:name: + * + * The name of the device. The name serves as a unique identifier and + * in most cases it is not in a user-readable form. + */ properties[PROP_NAME] = g_param_spec_string ("name", "Name", @@ -99,6 +109,12 @@ mate_mixer_device_class_init (MateMixerDeviceClass *klass) G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + /** + * MateMixerDevice:label: + * + * The label of the device. This is a potentially translated string + * that should be presented to users in the user interface. + */ properties[PROP_LABEL] = g_param_spec_string ("label", "Label", @@ -108,10 +124,15 @@ mate_mixer_device_class_init (MateMixerDeviceClass *klass) G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + /** + * MateMixerDevice:icon: + * + * The XDG icon name of the device. + */ properties[PROP_ICON] = g_param_spec_string ("icon", "Icon", - "Name of the sound device icon", + "XDG icon name of the device", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | @@ -119,10 +140,20 @@ mate_mixer_device_class_init (MateMixerDeviceClass *klass) g_object_class_install_properties (object_class, N_PROPERTIES, properties); + /** + * MateMixerDevice::stream-added: + * @device: a #MateMixerDevice + * @name: name of the added stream + * + * The signal is emitted each time a device stream is added. + * + * Note that at the time this signal is emitted, the controls and switches + * of the stream may not yet be known. + */ signals[STREAM_ADDED] = g_signal_new ("stream-added", G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, + G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (MateMixerDeviceClass, stream_added), NULL, NULL, @@ -131,10 +162,22 @@ mate_mixer_device_class_init (MateMixerDeviceClass *klass) 1, G_TYPE_STRING); + /** + * MateMixerDevice::stream-removed: + * @device: a #MateMixerDevice + * @name: name of the removed stream + * + * The signal is emitted each time a device stream is removed. + * + * When this signal is emitted, the stream is no longer known to the library, + * it will not be included in the stream list provided by the + * mate_mixer_device_list_streams() function and it is not possible to get + * the stream with mate_mixer_device_get_stream(). + */ signals[STREAM_REMOVED] = g_signal_new ("stream-removed", G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, + G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (MateMixerDeviceClass, stream_removed), NULL, NULL, @@ -143,10 +186,17 @@ mate_mixer_device_class_init (MateMixerDeviceClass *klass) 1, G_TYPE_STRING); + /** + * MateMixerDevice::switch-added: + * @device: a #MateMixerDevice + * @name: name of the added switch + * + * The signal is emitted each time a device switch is added. + */ signals[SWITCH_ADDED] = g_signal_new ("switch-added", G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, + G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (MateMixerDeviceClass, switch_added), NULL, NULL, @@ -155,10 +205,22 @@ mate_mixer_device_class_init (MateMixerDeviceClass *klass) 1, G_TYPE_STRING); + /** + * MateMixerDevice::switch-removed: + * @device: a #MateMixerDevice + * @name: name of the removed switch + * + * The signal is emitted each time a device switch is removed. + * + * When this signal is emitted, the switch is no longer known to the library, + * it will not be included in the switch list provided by the + * mate_mixer_device_list_switches() function and it is not possible to get + * the switch with mate_mixer_device_get_switch(). + */ signals[SWITCH_REMOVED] = g_signal_new ("switch-removed", G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, + G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (MateMixerDeviceClass, switch_removed), NULL, NULL, @@ -190,6 +252,7 @@ mate_mixer_device_get_property (GObject *object, case PROP_ICON: g_value_set_string (value, device->priv->icon); break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); break; @@ -209,15 +272,15 @@ mate_mixer_device_set_property (GObject *object, switch (param_id) { case PROP_NAME: /* Construct-only string */ - device->priv->name = g_strdup (g_value_get_string (value)); + device->priv->name = g_value_dup_string (value); break; case PROP_LABEL: /* Construct-only string */ - device->priv->label = g_strdup (g_value_get_string (value)); + device->priv->label = g_value_dup_string (value); break; case PROP_ICON: /* Construct-only string */ - device->priv->icon = g_strdup (g_value_get_string (value)); + device->priv->icon = g_value_dup_string (value); break; default: @@ -251,6 +314,17 @@ mate_mixer_device_finalize (GObject *object) /** * mate_mixer_device_get_name: * @device: a #MateMixerDevice + * + * Gets the name of the device. + * + * The name serves as a unique identifier and in most cases it is not in a + * user-readable form. + * + * The returned name is guaranteed to be unique across all the known devices + * and may be used to get the #MateMixerDevice using + * mate_mixer_context_get_device(). + * + * Returns: the name of the device. */ const gchar * mate_mixer_device_get_name (MateMixerDevice *device) @@ -263,6 +337,13 @@ mate_mixer_device_get_name (MateMixerDevice *device) /** * mate_mixer_device_get_label: * @device: a #MateMixerDevice + * + * Gets the label of the device. + * + * This is a potentially translated string that should be presented to users + * in the user interface. + * + * Returns: the label of the device. */ const gchar * mate_mixer_device_get_label (MateMixerDevice *device) @@ -275,6 +356,10 @@ mate_mixer_device_get_label (MateMixerDevice *device) /** * mate_mixer_device_get_icon: * @device: a #MateMixerDevice + * + * Gets the XDG icon name of the device. + * + * Returns: the icon name or %NULL. */ const gchar * mate_mixer_device_get_icon (MateMixerDevice *device) @@ -288,6 +373,10 @@ mate_mixer_device_get_icon (MateMixerDevice *device) * mate_mixer_device_get_stream: * @device: a #MateMixerDevice * @name: a stream name + * + * Gets the device stream with the given name. + * + * Returns: a #MateMixerStream or %NULL if there is no such stream. */ MateMixerStream * mate_mixer_device_get_stream (MateMixerDevice *device, const gchar *name) @@ -299,6 +388,17 @@ mate_mixer_device_get_stream (MateMixerDevice *device, const gchar *name) * mate_mixer_device_get_switch: * @device: a #MateMixerDevice * @name: a switch name + * + * Gets the device switch with the given name. + * + * Note that this function will only return a switch that belongs to the device + * and not to a stream of the device. See mate_mixer_device_list_switches() for + * information about the difference between device and stream switches. + * + * To get a stream switch, rather than a device switch, use + * mate_mixer_stream_get_switch(). + * + * Returns: a #MateMixerSwitch or %NULL if there is no such device switch. */ MateMixerSwitch * mate_mixer_device_get_switch (MateMixerDevice *device, const gchar *name) @@ -309,6 +409,14 @@ mate_mixer_device_get_switch (MateMixerDevice *device, const gchar *name) /** * mate_mixer_device_list_streams: * @device: a #MateMixerDevice + * + * Gets the list of streams that belong to the device. + * + * The returned #GList is owned by the #MateMixerDevice and may be invalidated + * at any time. + * + * Returns: a #GList of the device streams or %NULL if the device does not have + * any streams. */ const GList * mate_mixer_device_list_streams (MateMixerDevice *device) @@ -328,6 +436,21 @@ mate_mixer_device_list_streams (MateMixerDevice *device) /** * mate_mixer_device_list_switches: * @device: a #MateMixerDevice + * + * Gets the list of switches the belong to the device. + * + * Note that a switch may belong either to a device, or to a stream. Unlike + * stream switches, device switches returned by this function are not classified + * as input or output (as streams are), but they operate on the whole device. + * + * Use mate_mixer_stream_list_switches() to get a list of switches that belong + * to a stream. + * + * The returned #GList is owned by the #MateMixerDevice and may be invalidated + * at any time. + * + * Returns: a #GList of the device switches or %NULL if the device does not have + * any switches. */ const GList * mate_mixer_device_list_switches (MateMixerDevice *device) diff --git a/libmatemixer/matemixer-device.h b/libmatemixer/matemixer-device.h index 51d2a14..49ac347 100644 --- a/libmatemixer/matemixer-device.h +++ b/libmatemixer/matemixer-device.h @@ -57,8 +57,9 @@ struct _MateMixerDevice /** * MateMixerDeviceClass: + * @parent_class: The parent class. * - * The class structure of #MateMixerDevice. + * The class structure for #MateMixerDevice. */ struct _MateMixerDeviceClass { diff --git a/libmatemixer/matemixer-enum-types.c b/libmatemixer/matemixer-enum-types.c index ea63f50..cbc4ea8 100644 --- a/libmatemixer/matemixer-enum-types.c +++ b/libmatemixer/matemixer-enum-types.c @@ -74,6 +74,7 @@ mate_mixer_backend_flags_get_type (void) static const GFlagsValue values[] = { { MATE_MIXER_BACKEND_NO_FLAGS, "MATE_MIXER_STREAM_NO_FLAGS", "no-flags" }, { MATE_MIXER_BACKEND_HAS_APPLICATION_CONTROLS, "MATE_MIXER_BACKEND_HAS_APPLICATION_CONTROLS", "has-application-controls" }, + { MATE_MIXER_BACKEND_HAS_STORED_CONTROLS, "MATE_MIXER_BACKEND_HAS_STORED_CONTROLS", "has-stored-controls" }, { MATE_MIXER_BACKEND_CAN_SET_DEFAULT_INPUT_STREAM, "MATE_MIXER_BACKEND_CAN_SET_DEFAULT_INPUT_STREAM", "can-set-default-input-stream" }, { MATE_MIXER_BACKEND_CAN_SET_DEFAULT_OUTPUT_STREAM, "MATE_MIXER_BACKEND_CAN_SET_DEFAULT_OUTPUT_STREAM", "can-set-default-output-stream" }, { 0, NULL, NULL } @@ -254,6 +255,7 @@ mate_mixer_channel_position_get_type (void) { MATE_MIXER_CHANNEL_TOP_BACK_LEFT, "MATE_MIXER_CHANNEL_TOP_BACK_LEFT", "top-back-left" }, { MATE_MIXER_CHANNEL_TOP_BACK_RIGHT, "MATE_MIXER_CHANNEL_TOP_BACK_RIGHT", "top-back-right" }, { MATE_MIXER_CHANNEL_TOP_BACK_CENTER, "MATE_MIXER_CHANNEL_TOP_BACK_CENTER", "top-back-center" }, + { MATE_MIXER_CHANNEL_MAX, "MATE_MIXER_CHANNEL_MAX", "max" }, { 0, NULL, NULL } }; etype = g_enum_register_static ( diff --git a/libmatemixer/matemixer-enums.h b/libmatemixer/matemixer-enums.h index 18bbbcf..96176fa 100644 --- a/libmatemixer/matemixer-enums.h +++ b/libmatemixer/matemixer-enums.h @@ -26,10 +26,17 @@ /** * MateMixerState: * @MATE_MIXER_STATE_IDLE: + * Not connected. * @MATE_MIXER_STATE_CONNECTING: + * Connection is in progress. * @MATE_MIXER_STATE_READY: + * Connected. * @MATE_MIXER_STATE_FAILED: + * Connection has failed. * @MATE_MIXER_STATE_UNKNOWN: + * Unknown state. This state is used as an error indicator. + * + * State of a connection to a sound system. */ typedef enum { MATE_MIXER_STATE_IDLE, @@ -42,18 +49,22 @@ typedef enum { /** * MateMixerBackendType: * @MATE_MIXER_BACKEND_UNKNOWN: - * Unknown or undefined backend type. + * Unknown or undefined sound system backend type. * @MATE_MIXER_BACKEND_PULSEAUDIO: * 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. + * will be the first one to try when you call mate_mixer_context_open(), + * unless you select a specific sound system to connect to. * @MATE_MIXER_BACKEND_ALSA: + * The Advanced Linux Sound Architecture sound system. * @MATE_MIXER_BACKEND_OSS: + * The Open Sound System. * @MATE_MIXER_BACKEND_NULL: * Fallback backend which never fails to initialize, but provides no * functionality. This backend has the lowest priority and will be used - * if you do not select a specific backend to connect to and all the - * "real" backends fail to initialize. + * if you do not select a specific backend and it isn't possible to use + * any of the other backends. + * + * Constants identifying a sound system backend. */ typedef enum { MATE_MIXER_BACKEND_UNKNOWN, @@ -65,17 +76,43 @@ typedef enum { /** * MateMixerBackendFlags: + * @MATE_MIXER_BACKEND_NO_FLAGS: + * No flags. + * @MATE_MIXER_BACKEND_HAS_APPLICATION_CONTROLS: + * The sound system backend includes support for application stream controls, + * allowing per-application volume control. + * @MATE_MIXER_BACKEND_HAS_STORED_CONTROLS: + * The sound system backend includes support for stored controls. See the + * #MateMixerStoredControl description for more information. + * The presence of this flag does not guarantee that this feature is enabled + * in the sound system's configuration. + * @MATE_MIXER_BACKEND_CAN_SET_DEFAULT_INPUT_STREAM: + * The sound system backend is able to change the current default input stream + * using the mate_mixer_context_set_default_input_stream() function. + * @MATE_MIXER_BACKEND_CAN_SET_DEFAULT_OUTPUT_STREAM: + * The sound system backend is able to change the current default output stream + * using the mate_mixer_context_set_default_output_stream() function. + * + * Flags describing capabilities of a sound system. */ - typedef enum { /*< flags >*/ - MATE_MIXER_BACKEND_NO_FLAGS = 0, - MATE_MIXER_BACKEND_HAS_APPLICATION_CONTROLS, - MATE_MIXER_BACKEND_CAN_SET_DEFAULT_INPUT_STREAM, - MATE_MIXER_BACKEND_CAN_SET_DEFAULT_OUTPUT_STREAM + MATE_MIXER_BACKEND_NO_FLAGS = 0, + MATE_MIXER_BACKEND_HAS_APPLICATION_CONTROLS = 1 << 0, + MATE_MIXER_BACKEND_HAS_STORED_CONTROLS = 1 << 1, + MATE_MIXER_BACKEND_CAN_SET_DEFAULT_INPUT_STREAM = 1 << 2, + MATE_MIXER_BACKEND_CAN_SET_DEFAULT_OUTPUT_STREAM = 1 << 3 } MateMixerBackendFlags; /** * MateMixerDirection: + * @MATE_MIXER_DIRECTION_UNKNOWN: + * Unknown direction. + * @MATE_MIXER_DIRECTION_INPUT: + * Input direction (recording). + * @MATE_MIXER_DIRECTION_OUTPUT: + * Output direction (playback). + * + * Sound stream direction. */ typedef enum { MATE_MIXER_DIRECTION_UNKNOWN, @@ -86,13 +123,34 @@ typedef enum { /** * 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: + * No flags. + * @MATE_MIXER_STREAM_CONTROL_MUTE_READABLE: + * The stream control includes a mute toggle and allows reading the mute state. + * @MATE_MIXER_STREAM_CONTROL_MUTE_WRITABLE: + * The stream control includes a mute toggle and allows changing the mute state. + * @MATE_MIXER_STREAM_CONTROL_VOLUME_READABLE: + * The stream control includes a volume control and allows reading the volume. + * @MATE_MIXER_STREAM_CONTROL_VOLUME_WRITABLE: + * The stream control includes a volume control and allows changing the volume. * @MATE_MIXER_STREAM_CONTROL_CAN_BALANCE: + * The stream control includes the necessary channel positions to allow left/right + * volume balancing. * @MATE_MIXER_STREAM_CONTROL_CAN_FADE: + * The stream control includes the necessary channel positions to allow front/back + * volume fading. + * @MATE_MIXER_STREAM_CONTROL_MOVABLE: + * It is possible to move the stream control to a different stream using the + * mate_mixer_stream_control_set_stream() function. See the function description + * for details. + * @MATE_MIXER_STREAM_CONTROL_HAS_DECIBEL: + * The stream controls supports decibel values and it is possible to successfully + * use the functions which operate on decibel values. + * @MATE_MIXER_STREAM_CONTROL_HAS_MONITOR: + * The stream control supports peak level monitoring. + * @MATE_MIXER_STREAM_CONTROL_STORED: + * The stream control is a #MateMixerStoredControl. + * + * Flags describing capabilities and properties of a stream control. */ typedef enum { MATE_MIXER_STREAM_CONTROL_NO_FLAGS = 0, @@ -108,6 +166,35 @@ typedef enum { MATE_MIXER_STREAM_CONTROL_STORED = 1 << 9 } MateMixerStreamControlFlags; +/** + * MateMixerStreamControlRole: + * @MATE_MIXER_STREAM_CONTROL_ROLE_UNKNOWN: + * Unknown role. + * @MATE_MIXER_STREAM_CONTROL_ROLE_MASTER: + * Master volume control. + * @MATE_MIXER_STREAM_CONTROL_ROLE_APPLICATION: + * Application volume control. + * @MATE_MIXER_STREAM_CONTROL_ROLE_PCM: + * PCM volume control. + * @MATE_MIXER_STREAM_CONTROL_ROLE_SPEAKER: + * Speaker volume control. + * @MATE_MIXER_STREAM_CONTROL_ROLE_MICROPHONE: + * Microphone volume control. + * @MATE_MIXER_STREAM_CONTROL_ROLE_PORT: + * Volume control for a connector of a sound device. + * @MATE_MIXER_STREAM_CONTROL_ROLE_BOOST: + * Boost control (for example a microphone boost or bass boost). + * @MATE_MIXER_STREAM_CONTROL_ROLE_BASS: + * Bass control. + * @MATE_MIXER_STREAM_CONTROL_ROLE_TREBLE: + * Treble control. + * @MATE_MIXER_STREAM_CONTROL_ROLE_CD: + * CD input volume control. + * @MATE_MIXER_STREAM_CONTROL_ROLE_VIDEO: + * Video volume control. + * @MATE_MIXER_STREAM_CONTROL_ROLE_MUSIC: + * Music volume control. + */ typedef enum { MATE_MIXER_STREAM_CONTROL_ROLE_UNKNOWN, MATE_MIXER_STREAM_CONTROL_ROLE_MASTER, @@ -124,6 +211,38 @@ typedef enum { MATE_MIXER_STREAM_CONTROL_ROLE_MUSIC } MateMixerStreamControlRole; +/** + * MateMixerStreamControlMediaRole: + * @MATE_MIXER_STREAM_CONTROL_MEDIA_ROLE_UNKNOWN: + * Unknown media role. + * @MATE_MIXER_STREAM_CONTROL_MEDIA_ROLE_VIDEO: + * Video role. + * @MATE_MIXER_STREAM_CONTROL_MEDIA_ROLE_MUSIC: + * Music role. + * @MATE_MIXER_STREAM_CONTROL_MEDIA_ROLE_GAME: + * Game role. + * @MATE_MIXER_STREAM_CONTROL_MEDIA_ROLE_EVENT: + * Event sounds. + * @MATE_MIXER_STREAM_CONTROL_MEDIA_ROLE_PHONE: + * @MATE_MIXER_STREAM_CONTROL_MEDIA_ROLE_ANIMATION: + * @MATE_MIXER_STREAM_CONTROL_MEDIA_ROLE_PRODUCTION: + * @MATE_MIXER_STREAM_CONTROL_MEDIA_ROLE_A11Y: + * @MATE_MIXER_STREAM_CONTROL_MEDIA_ROLE_TEST: + * @MATE_MIXER_STREAM_CONTROL_MEDIA_ROLE_ABSTRACT: + * @MATE_MIXER_STREAM_CONTROL_MEDIA_ROLE_FILTER: + * + * Constants describing a media role of a control. These constants are mapped + * to PulseAudio media role property and therefore are only available when using + * the PulseAudio sound system. + * + * Media roles are commonly set by applications to indicate what kind of sound + * input/output they provide and may be the defining property of stored controls + * (for example an event role stored control can be used to provide a volume + * slider for event sounds). + * + * See the PulseAudio documentation for more detailed information about media + * roles. + */ typedef enum { MATE_MIXER_STREAM_CONTROL_MEDIA_ROLE_UNKNOWN, MATE_MIXER_STREAM_CONTROL_MEDIA_ROLE_VIDEO, @@ -139,12 +258,30 @@ typedef enum { MATE_MIXER_STREAM_CONTROL_MEDIA_ROLE_FILTER } MateMixerStreamControlMediaRole; +/** + * MateMixerSwitchFlags: + * @MATE_MIXER_SWITCH_NO_FLAGS: + * No flags. + * @MATE_MIXER_SWITCH_TOGGLE: + * The switch is a #MateMixerToggle. + */ typedef enum { /*< flags >*/ MATE_MIXER_SWITCH_NO_FLAGS = 0, MATE_MIXER_SWITCH_TOGGLE = 1 << 0, MATE_MIXER_SWITCH_ALLOWS_NO_ACTIVE_OPTION = 1 << 1 } MateMixerSwitchFlags; +/** + * MateMixerSwitchRole: + * @MATE_MIXER_SWITCH_ROLE_UNKNOWN: + * Unknown switch role. + * @MATE_MIXER_SWITCH_ROLE_DEVICE_PROFILE: + * The switch changes the active sound device profile. + * @MATE_MIXER_SWITCH_ROLE_PORT: + * The switch changes the active port. + * @MATE_MIXER_SWITCH_ROLE_BOOST: + * The switch changes the boost value. + */ typedef enum { MATE_MIXER_SWITCH_ROLE_UNKNOWN, MATE_MIXER_SWITCH_ROLE_DEVICE_PROFILE, @@ -155,25 +292,45 @@ typedef enum { /** * MateMixerChannelPosition: * @MATE_MIXER_CHANNEL_UNKNOWN: + * Unknown channel position. * @MATE_MIXER_CHANNEL_MONO: + * Mono channel. Only used for single-channel controls. * @MATE_MIXER_CHANNEL_FRONT_LEFT: + * Front left channel. * @MATE_MIXER_CHANNEL_FRONT_RIGHT: + * Front right channel. * @MATE_MIXER_CHANNEL_FRONT_CENTER: + * Front center channel. * @MATE_MIXER_CHANNEL_LFE: + * Low-frequency effects channel (subwoofer). * @MATE_MIXER_CHANNEL_BACK_LEFT: + * Back (rear) left channel. * @MATE_MIXER_CHANNEL_BACK_RIGHT: + * Back (rear) right channel. * @MATE_MIXER_CHANNEL_BACK_CENTER: + * Back (rear) center channel. * @MATE_MIXER_CHANNEL_FRONT_LEFT_CENTER: + * Front left of center channel. * @MATE_MIXER_CHANNEL_FRONT_RIGHT_CENTER: + * Front right of center channel. * @MATE_MIXER_CHANNEL_SIDE_LEFT: + * Side left channel. * @MATE_MIXER_CHANNEL_SIDE_RIGHT: + * Side right channel. * @MATE_MIXER_CHANNEL_TOP_FRONT_LEFT: + * Top front left channel. * @MATE_MIXER_CHANNEL_TOP_FRONT_RIGHT: + * Top front right channel. * @MATE_MIXER_CHANNEL_TOP_FRONT_CENTER: + * Top front center channel. * @MATE_MIXER_CHANNEL_TOP_CENTER: + * Top center channel. * @MATE_MIXER_CHANNEL_TOP_BACK_LEFT: + * Top back (rear) left channel. * @MATE_MIXER_CHANNEL_TOP_BACK_RIGHT: + * Top back (rear) right channel. * @MATE_MIXER_CHANNEL_TOP_BACK_CENTER: + * Top back (rear) center channel. */ typedef enum { MATE_MIXER_CHANNEL_UNKNOWN = 0, @@ -196,6 +353,7 @@ typedef enum { MATE_MIXER_CHANNEL_TOP_BACK_LEFT, MATE_MIXER_CHANNEL_TOP_BACK_RIGHT, MATE_MIXER_CHANNEL_TOP_BACK_CENTER, + /*< private >*/ MATE_MIXER_CHANNEL_MAX } MateMixerChannelPosition; diff --git a/libmatemixer/matemixer-private.h b/libmatemixer/matemixer-private.h index 41cd2e7..37c430d 100644 --- a/libmatemixer/matemixer-private.h +++ b/libmatemixer/matemixer-private.h @@ -106,10 +106,10 @@ G_BEGIN_DECLS #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) -G_GNUC_INTERNAL const GList *_mate_mixer_list_modules (void); -guint32 _mate_mixer_create_channel_mask (MateMixerChannelPosition *positions, guint n); +guint32 _mate_mixer_create_channel_mask (MateMixerChannelPosition *positions, + guint n) G_GNUC_PURE; G_END_DECLS diff --git a/libmatemixer/matemixer-stored-control.c b/libmatemixer/matemixer-stored-control.c index eb2a448..d150490 100644 --- a/libmatemixer/matemixer-stored-control.c +++ b/libmatemixer/matemixer-stored-control.c @@ -23,20 +23,104 @@ #include "matemixer-stream-control.h" #include "matemixer-stored-control.h" -G_DEFINE_INTERFACE (MateMixerStoredControl, mate_mixer_stored_control, MATE_MIXER_TYPE_STREAM_CONTROL) +struct _MateMixerStoredControlPrivate +{ + MateMixerDirection direction; +}; + +enum { + PROP_0, + PROP_DIRECTION, + N_PROPERTIES +}; + +static GParamSpec *properties[N_PROPERTIES] = { NULL, }; + +static void mate_mixer_stored_control_class_init (MateMixerStoredControlClass *klass); + +static void mate_mixer_stored_control_get_property (GObject *object, + guint param_id, + GValue *value, + GParamSpec *pspec); +static void mate_mixer_stored_control_set_property (GObject *object, + guint param_id, + const GValue *value, + GParamSpec *pspec); + +static void mate_mixer_stored_control_init (MateMixerStoredControl *control); + +G_DEFINE_ABSTRACT_TYPE (MateMixerStoredControl, mate_mixer_stored_control, MATE_MIXER_TYPE_STREAM_CONTROL) + +static void +mate_mixer_stored_control_class_init (MateMixerStoredControlClass *klass) +{ + GObjectClass *object_class; + + object_class = G_OBJECT_CLASS (klass); + object_class->get_property = mate_mixer_stored_control_get_property; + object_class->set_property = mate_mixer_stored_control_set_property; + + properties[PROP_DIRECTION] = + g_param_spec_enum ("direction", + "Direction", + "Direction of the stored control", + MATE_MIXER_TYPE_DIRECTION, + MATE_MIXER_DIRECTION_UNKNOWN, + 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 (MateMixerStoredControlPrivate)); +} + +static void +mate_mixer_stored_control_get_property (GObject *object, + guint param_id, + GValue *value, + GParamSpec *pspec) +{ + MateMixerStoredControl *control; + + control = MATE_MIXER_STORED_CONTROL (object); + + switch (param_id) { + case PROP_DIRECTION: + g_value_set_enum (value, control->priv->direction); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); + break; + } +} + +static void +mate_mixer_stored_control_set_property (GObject *object, + guint param_id, + const GValue *value, + GParamSpec *pspec) +{ + MateMixerStoredControl *control; + + control = MATE_MIXER_STORED_CONTROL (object); + + switch (param_id) { + case PROP_DIRECTION: + control->priv->direction = g_value_get_enum (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); + break; + } +} static void -mate_mixer_stored_control_default_init (MateMixerStoredControlInterface *iface) +mate_mixer_stored_control_init (MateMixerStoredControl *control) { - g_object_interface_install_property (iface, - g_param_spec_enum ("direction", - "Direction", - "Direction of the stored control", - MATE_MIXER_TYPE_DIRECTION, - MATE_MIXER_DIRECTION_UNKNOWN, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS)); + control->priv = G_TYPE_INSTANCE_GET_PRIVATE (control, + MATE_MIXER_TYPE_STORED_CONTROL, + MateMixerStoredControlPrivate); } /** @@ -48,5 +132,5 @@ mate_mixer_stored_control_get_direction (MateMixerStoredControl *control) { g_return_val_if_fail (MATE_MIXER_IS_STORED_CONTROL (control), MATE_MIXER_DIRECTION_UNKNOWN); - return MATE_MIXER_STORED_CONTROL_GET_INTERFACE (control)->get_direction (control); + return control->priv->direction; } diff --git a/libmatemixer/matemixer-stored-control.h b/libmatemixer/matemixer-stored-control.h index 0c9c982..d21209e 100644 --- a/libmatemixer/matemixer-stored-control.h +++ b/libmatemixer/matemixer-stored-control.h @@ -22,32 +22,50 @@ #include <glib-object.h> #include <libmatemixer/matemixer-enums.h> +#include <libmatemixer/matemixer-stream-control.h> #include <libmatemixer/matemixer-types.h> G_BEGIN_DECLS -#define MATE_MIXER_TYPE_STORED_CONTROL \ +#define MATE_MIXER_TYPE_STORED_CONTROL \ (mate_mixer_stored_control_get_type ()) -#define MATE_MIXER_STORED_CONTROL(o) \ +#define MATE_MIXER_STORED_CONTROL(o) \ (G_TYPE_CHECK_INSTANCE_CAST ((o), MATE_MIXER_TYPE_STORED_CONTROL, MateMixerStoredControl)) -#define MATE_MIXER_IS_STORED_CONTROL(o) \ +#define MATE_MIXER_IS_STORED_CONTROL(o) \ (G_TYPE_CHECK_INSTANCE_TYPE ((o), MATE_MIXER_TYPE_STORED_CONTROL)) -#define MATE_MIXER_STORED_CONTROL_GET_INTERFACE(o) \ - (G_TYPE_INSTANCE_GET_INTERFACE ((o), MATE_MIXER_TYPE_STORED_CONTROL, MateMixerStoredControlInterface)) +#define MATE_MIXER_STORED_CONTROL_CLASS(k) \ + (G_TYPE_CHECK_CLASS_CAST ((k), MATE_MIXER_TYPE_STORED_CONTROL, MateMixerStoredControlClass)) +#define MATE_MIXER_IS_STORED_CONTROL_CLASS(k) \ + (G_TYPE_CHECK_CLASS_TYPE ((k), MATE_MIXER_TYPE_STORED_CONTROL)) +#define MATE_MIXER_STORED_CONTROL_GET_CLASS(o) \ + (G_TYPE_INSTANCE_GET_CLASS ((o), MATE_MIXER_TYPE_STORED_CONTROL, MateMixerStoredControlClass)) -typedef struct _MateMixerStoredControlInterface MateMixerStoredControlInterface; +typedef struct _MateMixerStoredControlClass MateMixerStoredControlClass; +typedef struct _MateMixerStoredControlPrivate MateMixerStoredControlPrivate; /** - * MateMixerStoredControlInterface: + * MateMixerStoredControl: * - * The interface structure of #MateMixerStoredControl. + * The #MateMixerStoredControl structure contains only private data and should only + * be accessed using the provided API. */ -struct _MateMixerStoredControlInterface +struct _MateMixerStoredControl { - GTypeInterface parent_iface; + MateMixerStreamControl object; /*< private >*/ - MateMixerDirection (*get_direction) (MateMixerStoredControl *control); + MateMixerStoredControlPrivate *priv; +}; + +/** + * MateMixerStoredControlClass: + * @parent_class: The parent class. + * + * The class structure for #MateMixerStoredControl. + */ +struct _MateMixerStoredControlClass +{ + MateMixerStreamControlClass parent_class; }; GType mate_mixer_stored_control_get_type (void) G_GNUC_CONST; diff --git a/libmatemixer/matemixer-stream-control.c b/libmatemixer/matemixer-stream-control.c index b2b2dad..5d97709 100644 --- a/libmatemixer/matemixer-stream-control.c +++ b/libmatemixer/matemixer-stream-control.c @@ -78,7 +78,6 @@ static void mate_mixer_stream_control_set_property (GObject GParamSpec *pspec); static void mate_mixer_stream_control_init (MateMixerStreamControl *control); -static void mate_mixer_stream_control_dispose (GObject *object); static void mate_mixer_stream_control_finalize (GObject *object); G_DEFINE_ABSTRACT_TYPE (MateMixerStreamControl, mate_mixer_stream_control, G_TYPE_OBJECT) @@ -89,7 +88,6 @@ mate_mixer_stream_control_class_init (MateMixerStreamControlClass *klass) GObjectClass *object_class; object_class = G_OBJECT_CLASS (klass); - object_class->dispose = mate_mixer_stream_control_dispose; 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; @@ -274,10 +272,9 @@ mate_mixer_stream_control_set_property (GObject *object, /* Construct-only object */ control->priv->stream = g_value_get_object (value); - if (control->priv->stream != NULL) { + if (control->priv->stream != NULL) g_object_add_weak_pointer (G_OBJECT (control->priv->stream), (gpointer *) &control->priv->stream); - } break; default: @@ -295,18 +292,6 @@ mate_mixer_stream_control_init (MateMixerStreamControl *control) } static void -mate_mixer_stream_control_dispose (GObject *object) -{ - MateMixerStreamControl *control; - - control = MATE_MIXER_STREAM_CONTROL (object); - - g_clear_object (&control->priv->stream); - - G_OBJECT_CLASS (mate_mixer_stream_control_parent_class)->dispose (object); -} - -static void mate_mixer_stream_control_finalize (GObject *object) { MateMixerStreamControl *control; @@ -389,12 +374,11 @@ mate_mixer_stream_control_get_app_info (MateMixerStreamControl *control) g_return_val_if_fail (MATE_MIXER_IS_STREAM_CONTROL (control), NULL); if (control->priv->role == MATE_MIXER_STREAM_CONTROL_ROLE_APPLICATION) { - MateMixerStreamControlClass *klass; - - klass = MATE_MIXER_STREAM_CONTROL_GET_CLASS (control); + MateMixerStreamControlClass *klass = + MATE_MIXER_STREAM_CONTROL_GET_CLASS (control); - if G_LIKELY (klass->get_app_info != NULL) - return klass->get_app_info (control); + /* Implementation required for application role controls */ + return klass->get_app_info (control); } return NULL; } @@ -414,25 +398,27 @@ mate_mixer_stream_control_get_stream (MateMixerStreamControl *control) /** * mate_mixer_stream_control_set_stream: * @control: a #MateMixerStreamControl + * @stream: a #MateMixerStream */ gboolean mate_mixer_stream_control_set_stream (MateMixerStreamControl *control, MateMixerStream *stream) { - g_return_val_if_fail (MATE_MIXER_IS_STREAM_CONTROL (control), 0); + g_return_val_if_fail (MATE_MIXER_IS_STREAM_CONTROL (control), FALSE); - if (control->priv->stream != stream) { - MateMixerStreamControlClass *klass; + if ((control->priv->flags & MATE_MIXER_STREAM_CONTROL_MOVABLE) == 0) + return FALSE; - klass = MATE_MIXER_STREAM_CONTROL_GET_CLASS (control); + if (control->priv->stream != stream) { + MateMixerStreamControlClass *klass = + MATE_MIXER_STREAM_CONTROL_GET_CLASS (control); - if (klass->set_stream == NULL || - klass->set_stream (control, stream) == FALSE) + /* Implementation required when the flag is available */ + if (klass->set_stream (control, stream) == FALSE) return FALSE; _mate_mixer_stream_control_set_stream (control, stream); } - return TRUE; } @@ -451,24 +437,27 @@ mate_mixer_stream_control_get_mute (MateMixerStreamControl *control) /** * mate_mixer_stream_control_set_mute: * @control: a #MateMixerStreamControl + * @mute: the mute toggle state to set */ 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_MUTE_WRITABLE) == 0) + return FALSE; - if (control->priv->flags & MATE_MIXER_STREAM_CONTROL_MUTE_WRITABLE) { - MateMixerStreamControlClass *klass; + if (control->priv->mute != mute) { + MateMixerStreamControlClass *klass = + MATE_MIXER_STREAM_CONTROL_GET_CLASS (control); - klass = MATE_MIXER_STREAM_CONTROL_GET_CLASS (control); + /* Implementation required when the flag is available */ + if (klass->set_mute (control, mute) == FALSE) + return FALSE; - if G_LIKELY (klass->set_mute != NULL) - return klass->set_mute (control, mute); + _mate_mixer_stream_control_set_mute (control, mute); } - return FALSE; + return TRUE; } /** @@ -504,8 +493,8 @@ mate_mixer_stream_control_get_volume (MateMixerStreamControl *control) klass = MATE_MIXER_STREAM_CONTROL_GET_CLASS (control); if (control->priv->flags & MATE_MIXER_STREAM_CONTROL_VOLUME_READABLE) { - if G_LIKELY (klass->get_volume != NULL) - return klass->get_volume (control); + /* Implementation required when the flag is available */ + return klass->get_volume (control); } return klass->get_min_volume (control); } @@ -513,6 +502,7 @@ mate_mixer_stream_control_get_volume (MateMixerStreamControl *control) /** * mate_mixer_stream_control_set_volume: * @control: a #MateMixerStreamControl + * @volume: the volume to set */ gboolean mate_mixer_stream_control_set_volume (MateMixerStreamControl *control, guint volume) @@ -520,12 +510,11 @@ mate_mixer_stream_control_set_volume (MateMixerStreamControl *control, guint vol g_return_val_if_fail (MATE_MIXER_IS_STREAM_CONTROL (control), FALSE); if (control->priv->flags & MATE_MIXER_STREAM_CONTROL_VOLUME_WRITABLE) { - MateMixerStreamControlClass *klass; - - klass = MATE_MIXER_STREAM_CONTROL_GET_CLASS (control); + MateMixerStreamControlClass *klass = + MATE_MIXER_STREAM_CONTROL_GET_CLASS (control); - if G_LIKELY (klass->set_volume != NULL) - return klass->set_volume (control, volume); + /* Implementation required when the flag is available */ + return klass->set_volume (control, volume); } return FALSE; } @@ -539,13 +528,13 @@ 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 (control->priv->flags & MATE_MIXER_STREAM_CONTROL_HAS_DECIBEL && + control->priv->flags & MATE_MIXER_STREAM_CONTROL_VOLUME_READABLE) { + MateMixerStreamControlClass *klass = + MATE_MIXER_STREAM_CONTROL_GET_CLASS (control); - if G_LIKELY (klass->get_decibel != NULL) - return klass->get_decibel (control); + /* Implementation required when the flags are available */ + return klass->get_decibel (control); } return -MATE_MIXER_INFINITY; } @@ -553,6 +542,7 @@ mate_mixer_stream_control_get_decibel (MateMixerStreamControl *control) /** * mate_mixer_stream_control_set_decibel: * @control: a #MateMixerStreamControl + * @decibel: the volume to set in decibels */ gboolean mate_mixer_stream_control_set_decibel (MateMixerStreamControl *control, gdouble decibel) @@ -561,12 +551,11 @@ mate_mixer_stream_control_set_decibel (MateMixerStreamControl *control, gdouble if (control->priv->flags & MATE_MIXER_STREAM_CONTROL_HAS_DECIBEL && control->priv->flags & MATE_MIXER_STREAM_CONTROL_VOLUME_WRITABLE) { - MateMixerStreamControlClass *klass; - - klass = MATE_MIXER_STREAM_CONTROL_GET_CLASS (control); + MateMixerStreamControlClass *klass = + MATE_MIXER_STREAM_CONTROL_GET_CLASS (control); - if G_LIKELY (klass->set_decibel != NULL) - return klass->set_decibel (control, decibel); + /* Implementation required when the flags are available */ + return klass->set_decibel (control, decibel); } return FALSE; } @@ -574,10 +563,11 @@ mate_mixer_stream_control_set_decibel (MateMixerStreamControl *control, gdouble /** * mate_mixer_stream_control_has_channel_position: * @control: a #MateMixerStreamControl + * @position: to channel position to check */ gboolean -mate_mixer_stream_control_has_channel_position (MateMixerStreamControl *control, - MateMixerChannelPosition position) +mate_mixer_stream_control_has_channel_position (MateMixerStreamControl *control, + MateMixerChannelPosition position) { MateMixerStreamControlClass *klass; @@ -594,6 +584,7 @@ mate_mixer_stream_control_has_channel_position (MateMixerStreamControl *contro /** * mate_mixer_stream_control_get_channel_position: * @control: a #MateMixerStreamControl + * @channel: a channel index */ MateMixerChannelPosition mate_mixer_stream_control_get_channel_position (MateMixerStreamControl *control, guint channel) @@ -613,26 +604,29 @@ mate_mixer_stream_control_get_channel_position (MateMixerStreamControl *control, /** * mate_mixer_stream_control_get_channel_volume: * @control: a #MateMixerStreamControl + * @channel: a channel index */ guint mate_mixer_stream_control_get_channel_volume (MateMixerStreamControl *control, guint channel) { - g_return_val_if_fail (MATE_MIXER_IS_STREAM_CONTROL (control), 0); + MateMixerStreamControlClass *klass; - if (control->priv->flags & MATE_MIXER_STREAM_CONTROL_VOLUME_READABLE) { - MateMixerStreamControlClass *klass; + g_return_val_if_fail (MATE_MIXER_IS_STREAM_CONTROL (control), 0); - klass = MATE_MIXER_STREAM_CONTROL_GET_CLASS (control); + klass = MATE_MIXER_STREAM_CONTROL_GET_CLASS (control); - if G_LIKELY (klass->get_channel_volume != NULL) - return klass->get_channel_volume (control, channel); + if (control->priv->flags & MATE_MIXER_STREAM_CONTROL_VOLUME_READABLE) { + /* Implementation required when the flag is available */ + return klass->get_channel_volume (control, channel); } - return 0; + return klass->get_min_volume (control); } /** * mate_mixer_stream_control_set_channel_volume: * @control: a #MateMixerStreamControl + * @channel: a channel index + * @volume: the volume to set */ gboolean mate_mixer_stream_control_set_channel_volume (MateMixerStreamControl *control, @@ -641,13 +635,12 @@ mate_mixer_stream_control_set_channel_volume (MateMixerStreamControl *control, { g_return_val_if_fail (MATE_MIXER_IS_STREAM_CONTROL (control), FALSE); - if (control->priv->flags & MATE_MIXER_STREAM_CONTROL_VOLUME_READABLE) { - MateMixerStreamControlClass *klass; - - klass = MATE_MIXER_STREAM_CONTROL_GET_CLASS (control); + if (control->priv->flags & MATE_MIXER_STREAM_CONTROL_VOLUME_WRITABLE) { + MateMixerStreamControlClass *klass = + MATE_MIXER_STREAM_CONTROL_GET_CLASS (control); - if G_LIKELY (klass->set_channel_volume != NULL) - return klass->set_channel_volume (control, channel, volume); + /* Implementation required when the flag is available */ + return klass->set_channel_volume (control, channel, volume); } return FALSE; } @@ -655,19 +648,20 @@ mate_mixer_stream_control_set_channel_volume (MateMixerStreamControl *control, /** * mate_mixer_stream_control_get_channel_decibel: * @control: a #MateMixerStreamControl + * @channel: a channel index */ 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 (control->priv->flags & MATE_MIXER_STREAM_CONTROL_HAS_DECIBEL && + control->priv->flags & MATE_MIXER_STREAM_CONTROL_VOLUME_READABLE) { + MateMixerStreamControlClass *klass = + MATE_MIXER_STREAM_CONTROL_GET_CLASS (control); - if G_LIKELY (klass->get_channel_decibel != NULL) - return klass->get_channel_decibel (control, channel); + /* Implementation required when the flags are available */ + return klass->get_channel_decibel (control, channel); } return -MATE_MIXER_INFINITY; } @@ -675,6 +669,8 @@ mate_mixer_stream_control_get_channel_decibel (MateMixerStreamControl *control, /** * mate_mixer_stream_control_set_channel_decibel: * @control: a #MateMixerStreamControl + * @channel: a channel index + * @decibel: the volume to set in decibels */ gboolean mate_mixer_stream_control_set_channel_decibel (MateMixerStreamControl *control, @@ -683,13 +679,13 @@ mate_mixer_stream_control_set_channel_decibel (MateMixerStreamControl *control, { 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 (control->priv->flags & MATE_MIXER_STREAM_CONTROL_HAS_DECIBEL && + control->priv->flags & MATE_MIXER_STREAM_CONTROL_VOLUME_WRITABLE) { + MateMixerStreamControlClass *klass = + MATE_MIXER_STREAM_CONTROL_GET_CLASS (control); - if G_LIKELY (klass->set_channel_decibel != NULL) - return klass->set_channel_decibel (control, channel, decibel); + /* Implementation required when the flags are available */ + return klass->set_channel_decibel (control, channel, decibel); } return FALSE; } @@ -712,24 +708,28 @@ mate_mixer_stream_control_get_balance (MateMixerStreamControl *control) /** * mate_mixer_stream_control_set_balance: * @control: a #MateMixerStreamControl + * @balance: the balance value */ gboolean mate_mixer_stream_control_set_balance (MateMixerStreamControl *control, gfloat balance) { g_return_val_if_fail (MATE_MIXER_IS_STREAM_CONTROL (control), FALSE); + g_return_val_if_fail (balance >= -1.0f && balance <= 1.0f, FALSE); - if (control->priv->flags & MATE_MIXER_STREAM_CONTROL_CAN_BALANCE) { - MateMixerStreamControlClass *klass; + if ((control->priv->flags & MATE_MIXER_STREAM_CONTROL_CAN_BALANCE) == 0) + return FALSE; - if (balance < -1.0f || balance > 1.0f) - return FALSE; + if (control->priv->balance != balance) { + MateMixerStreamControlClass *klass = + MATE_MIXER_STREAM_CONTROL_GET_CLASS (control); - klass = MATE_MIXER_STREAM_CONTROL_GET_CLASS (control); + /* Implementation required when the flag is available */ + if (klass->set_balance (control, balance) == FALSE) + return FALSE; - if (G_LIKELY (klass->set_balance != NULL)) - return klass->set_balance (control, balance); + _mate_mixer_stream_control_set_balance (control, balance); } - return FALSE; + return TRUE; } /** @@ -750,24 +750,28 @@ mate_mixer_stream_control_get_fade (MateMixerStreamControl *control) /** * mate_mixer_stream_control_set_fade: * @control: a #MateMixerStreamControl + * @fade: the fade value */ gboolean mate_mixer_stream_control_set_fade (MateMixerStreamControl *control, gfloat fade) { g_return_val_if_fail (MATE_MIXER_IS_STREAM_CONTROL (control), FALSE); + g_return_val_if_fail (fade >= -1.0f && fade <= 1.0f, FALSE); - if (control->priv->flags & MATE_MIXER_STREAM_CONTROL_CAN_FADE) { - MateMixerStreamControlClass *klass; + if ((control->priv->flags & MATE_MIXER_STREAM_CONTROL_CAN_FADE) == 0) + return FALSE; - if (fade < -1.0f || fade > 1.0f) - return FALSE; + if (control->priv->fade != fade) { + MateMixerStreamControlClass *klass = + MATE_MIXER_STREAM_CONTROL_GET_CLASS (control); - klass = MATE_MIXER_STREAM_CONTROL_GET_CLASS (control); + /* Implementation required when the flag is available */ + if (klass->set_fade (control, fade) == FALSE) + return FALSE; - if (klass->set_fade != NULL) - return klass->set_fade (control, fade); + _mate_mixer_stream_control_set_fade (control, fade); } - return FALSE; + return TRUE; } /** @@ -780,37 +784,30 @@ mate_mixer_stream_control_get_monitor_enabled (MateMixerStreamControl *control) g_return_val_if_fail (MATE_MIXER_IS_STREAM_CONTROL (control), FALSE); if (control->priv->flags & MATE_MIXER_STREAM_CONTROL_HAS_MONITOR) { - MateMixerStreamControlClass *klass; + MateMixerStreamControlClass *klass = + MATE_MIXER_STREAM_CONTROL_GET_CLASS (control); - klass = MATE_MIXER_STREAM_CONTROL_GET_CLASS (control); - if (klass->get_monitor_enabled != NULL) - return klass->get_monitor_enabled (control); + /* Implementation required when the flag is available */ + return klass->get_monitor_enabled (control); } - return FALSE; } /** * mate_mixer_stream_control_set_monitor_enabled: * @control: a #MateMixerStreamControl + * @enabled: a boolean value */ gboolean mate_mixer_stream_control_set_monitor_enabled (MateMixerStreamControl *control, gboolean enabled) { g_return_val_if_fail (MATE_MIXER_IS_STREAM_CONTROL (control), FALSE); - if (enabled == mate_mixer_stream_control_get_monitor_enabled (control)) - return TRUE; - - if (control->priv->flags & MATE_MIXER_STREAM_CONTROL_HAS_MONITOR) { - MateMixerStreamControlClass *klass; - - klass = MATE_MIXER_STREAM_CONTROL_GET_CLASS (control); - if (klass->set_monitor_enabled != NULL) - return klass->set_monitor_enabled (control, enabled); - } + if ((control->priv->flags & MATE_MIXER_STREAM_CONTROL_HAS_MONITOR) == 0) + return FALSE; - return FALSE; + /* Implementation required when the flag is available */ + return MATE_MIXER_STREAM_CONTROL_GET_CLASS (control)->set_monitor_enabled (control, enabled); } /** @@ -820,16 +817,10 @@ mate_mixer_stream_control_set_monitor_enabled (MateMixerStreamControl *control, 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; + /* Implementation required */ + return MATE_MIXER_STREAM_CONTROL_GET_CLASS (control)->get_min_volume (control); } /** @@ -839,16 +830,10 @@ mate_mixer_stream_control_get_min_volume (MateMixerStreamControl *control) 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; + /* Implementation required */ + return MATE_MIXER_STREAM_CONTROL_GET_CLASS (control)->get_max_volume (control); } /** @@ -858,16 +843,10 @@ mate_mixer_stream_control_get_max_volume (MateMixerStreamControl *control) 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; + /* Implementation required */ + return MATE_MIXER_STREAM_CONTROL_GET_CLASS (control)->get_normal_volume (control); } /** @@ -877,16 +856,10 @@ mate_mixer_stream_control_get_normal_volume (MateMixerStreamControl *control) 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; + /* Implementation required */ + return MATE_MIXER_STREAM_CONTROL_GET_CLASS (control)->get_base_volume (control); } /* Protected functions */ @@ -904,7 +877,6 @@ _mate_mixer_stream_control_set_flags (MateMixerStreamControl *control, g_object_notify_by_pspec (G_OBJECT (control), properties[PROP_FLAGS]); } -/* Protected functions */ void _mate_mixer_stream_control_set_stream (MateMixerStreamControl *control, MateMixerStream *stream) @@ -915,11 +887,14 @@ _mate_mixer_stream_control_set_stream (MateMixerStreamControl *control, return; if (control->priv->stream != NULL) - g_object_unref (control->priv->stream); - - if (stream != NULL) - control->priv->stream = g_object_ref (stream); - else + g_object_remove_weak_pointer (G_OBJECT (control->priv->stream), + (gpointer *) &control->priv->stream); + + if (stream != NULL) { + control->priv->stream = stream; + g_object_add_weak_pointer (G_OBJECT (control->priv->stream), + (gpointer *) &control->priv->stream); + } else control->priv->stream = NULL; g_object_notify_by_pspec (G_OBJECT (control), properties[PROP_STREAM]); diff --git a/libmatemixer/matemixer-stream-control.h b/libmatemixer/matemixer-stream-control.h index 2adf97f..fe9faca 100644 --- a/libmatemixer/matemixer-stream-control.h +++ b/libmatemixer/matemixer-stream-control.h @@ -65,130 +65,130 @@ struct _MateMixerStreamControl /** * MateMixerStreamControlClass: + * @parent_class: The parent class. * - * The class structure of #MateMixerStreamControl. + * The class structure for #MateMixerStreamControl. */ struct _MateMixerStreamControlClass { GObjectClass parent_class; /*< private >*/ - MateMixerAppInfo * (*get_app_info) (MateMixerStreamControl *control); + MateMixerAppInfo * (*get_app_info) (MateMixerStreamControl *control); - gboolean (*set_stream) (MateMixerStreamControl *control, - MateMixerStream *stream); + gboolean (*set_stream) (MateMixerStreamControl *control, + MateMixerStream *stream); - gboolean (*set_mute) (MateMixerStreamControl *control, - gboolean mute); + gboolean (*set_mute) (MateMixerStreamControl *control, + gboolean mute); - guint (*get_num_channels) (MateMixerStreamControl *control); + guint (*get_num_channels) (MateMixerStreamControl *control); - guint (*get_volume) (MateMixerStreamControl *control); - gboolean (*set_volume) (MateMixerStreamControl *control, - guint volume); + guint (*get_volume) (MateMixerStreamControl *control); + gboolean (*set_volume) (MateMixerStreamControl *control, + guint volume); - gdouble (*get_decibel) (MateMixerStreamControl *control); - gboolean (*set_decibel) (MateMixerStreamControl *control, - gdouble decibel); + 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); + 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); + 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); + 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_balance) (MateMixerStreamControl *control, + gfloat balance); - gboolean (*set_fade) (MateMixerStreamControl *control, - gfloat fade); + gboolean (*set_fade) (MateMixerStreamControl *control, + gfloat fade); - gboolean (*get_monitor_enabled) (MateMixerStreamControl *control); - gboolean (*set_monitor_enabled) (MateMixerStreamControl *control, - gboolean enabled); + gboolean (*get_monitor_enabled) (MateMixerStreamControl *control); + gboolean (*set_monitor_enabled) (MateMixerStreamControl *control, + gboolean enabled); - guint (*get_min_volume) (MateMixerStreamControl *control); - guint (*get_max_volume) (MateMixerStreamControl *control); - guint (*get_normal_volume) (MateMixerStreamControl *control); - guint (*get_base_volume) (MateMixerStreamControl *control); + guint (*get_min_volume) (MateMixerStreamControl *control); + guint (*get_max_volume) (MateMixerStreamControl *control); + guint (*get_normal_volume) (MateMixerStreamControl *control); + guint (*get_base_volume) (MateMixerStreamControl *control); /* Signals */ - void (*monitor_value) (MateMixerStreamControl *control, - gdouble value); + void (*monitor_value) (MateMixerStreamControl *control, gdouble value); }; 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); -MateMixerStreamControlMediaRole mate_mixer_stream_control_get_media_role (MateMixerStreamControl *control); - -MateMixerAppInfo * mate_mixer_stream_control_get_app_info (MateMixerStreamControl *control); - -MateMixerStream * mate_mixer_stream_control_get_stream (MateMixerStreamControl *control); -gboolean mate_mixer_stream_control_set_stream (MateMixerStreamControl *control, - MateMixerStream *stream); - -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); - -gboolean mate_mixer_stream_control_get_monitor_enabled (MateMixerStreamControl *control); -gboolean mate_mixer_stream_control_set_monitor_enabled (MateMixerStreamControl *control, - gboolean enabled); - -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); +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); +MateMixerStreamControlMediaRole mate_mixer_stream_control_get_media_role (MateMixerStreamControl *control); + +MateMixerAppInfo * mate_mixer_stream_control_get_app_info (MateMixerStreamControl *control); + +MateMixerStream * mate_mixer_stream_control_get_stream (MateMixerStreamControl *control); +gboolean mate_mixer_stream_control_set_stream (MateMixerStreamControl *control, + MateMixerStream *stream); + +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); + +gboolean mate_mixer_stream_control_get_monitor_enabled (MateMixerStreamControl *control); +gboolean mate_mixer_stream_control_set_monitor_enabled (MateMixerStreamControl *control, + gboolean enabled); + +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 diff --git a/libmatemixer/matemixer-stream.c b/libmatemixer/matemixer-stream.c index 03902bd..3d8b96e 100644 --- a/libmatemixer/matemixer-stream.c +++ b/libmatemixer/matemixer-stream.c @@ -257,10 +257,9 @@ mate_mixer_stream_set_property (GObject *object, /* Construct-only object */ stream->priv->device = g_value_get_object (value); - if (stream->priv->device != NULL) { + if (stream->priv->device != NULL) g_object_add_weak_pointer (G_OBJECT (stream->priv->device), (gpointer *) &stream->priv->device); - } break; case PROP_DEFAULT_CONTROL: /* Construct-only object */ @@ -301,6 +300,7 @@ mate_mixer_stream_finalize (GObject *object) stream = MATE_MIXER_STREAM (object); g_free (stream->priv->name); + g_free (stream->priv->label); G_OBJECT_CLASS (mate_mixer_stream_parent_class)->finalize (object); } @@ -356,6 +356,7 @@ mate_mixer_stream_get_device (MateMixerStream *stream) /** * mate_mixer_stream_get_control: * @stream: a #MateMixerStream + * @name: the name of a stream control */ MateMixerStreamControl * mate_mixer_stream_get_control (MateMixerStream *stream, const gchar *name) @@ -369,6 +370,7 @@ mate_mixer_stream_get_control (MateMixerStream *stream, const gchar *name) /** * mate_mixer_stream_get_switch: * @stream: a #MateMixerStream + * @name: the name of a stream switch */ MateMixerSwitch * mate_mixer_stream_get_switch (MateMixerStream *stream, const gchar *name) @@ -398,9 +400,16 @@ mate_mixer_stream_get_default_control (MateMixerStream *stream) const GList * mate_mixer_stream_list_controls (MateMixerStream *stream) { + MateMixerStreamClass *klass; + g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), NULL); - return MATE_MIXER_STREAM_GET_CLASS (stream)->list_controls (stream); + klass = MATE_MIXER_STREAM_GET_CLASS (stream); + + if G_LIKELY (klass->list_controls != NULL) + return klass->list_controls (stream); + + return NULL; } /** @@ -410,9 +419,16 @@ mate_mixer_stream_list_controls (MateMixerStream *stream) const GList * mate_mixer_stream_list_switches (MateMixerStream *stream) { + MateMixerStreamClass *klass; + g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), NULL); - return MATE_MIXER_STREAM_GET_CLASS (stream)->list_switches (stream); + klass = MATE_MIXER_STREAM_GET_CLASS (stream); + + if G_LIKELY (klass->list_switches != NULL) + return klass->list_switches (stream); + + return NULL; } static MateMixerStreamControl * @@ -482,6 +498,5 @@ _mate_mixer_stream_set_default_control (MateMixerStream *stream, mate_mixer_stream_get_name (stream)); } - g_object_notify_by_pspec (G_OBJECT (stream), - properties[PROP_DEFAULT_CONTROL]); + g_object_notify_by_pspec (G_OBJECT (stream), properties[PROP_DEFAULT_CONTROL]); } diff --git a/libmatemixer/matemixer-stream.h b/libmatemixer/matemixer-stream.h index c030196..7f7c857 100644 --- a/libmatemixer/matemixer-stream.h +++ b/libmatemixer/matemixer-stream.h @@ -58,8 +58,9 @@ struct _MateMixerStream /** * MateMixerStreamClass: + * @parent_class: The parent class. * - * The class structure of #MateMixerStream. + * The class structure for #MateMixerStream. */ struct _MateMixerStreamClass { @@ -90,6 +91,7 @@ GType mate_mixer_stream_get_type (void) G_GNUC_CONS const gchar * mate_mixer_stream_get_name (MateMixerStream *stream); const gchar * mate_mixer_stream_get_label (MateMixerStream *stream); + MateMixerDirection mate_mixer_stream_get_direction (MateMixerStream *stream); MateMixerDevice * mate_mixer_stream_get_device (MateMixerStream *stream); diff --git a/libmatemixer/matemixer-switch-option.c b/libmatemixer/matemixer-switch-option.c index fc0c5b6..4c0e0fa 100644 --- a/libmatemixer/matemixer-switch-option.c +++ b/libmatemixer/matemixer-switch-option.c @@ -22,7 +22,7 @@ #include "matemixer-switch-option-private.h" /** - * SECTION:matemixer-stream-switch-option + * SECTION:matemixer-switch-option * @include: libmatemixer/matemixer.h */ @@ -69,6 +69,12 @@ mate_mixer_switch_option_class_init (MateMixerSwitchOptionClass *klass) object_class->get_property = mate_mixer_switch_option_get_property; object_class->set_property = mate_mixer_switch_option_set_property; + /** + * MateMixerSwitchOption:name: + * + * The name of the switch option. The name serves as a unique identifier + * and in most cases it is not in a user-readable form. + */ properties[PROP_NAME] = g_param_spec_string ("name", "Name", @@ -78,6 +84,12 @@ mate_mixer_switch_option_class_init (MateMixerSwitchOptionClass *klass) G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + /** + * MateMixerSwitchOption:label: + * + * The label of the switch option. This is a potentially translated string + * that should be presented to users in the user interface. + */ properties[PROP_LABEL] = g_param_spec_string ("label", "Label", @@ -87,6 +99,11 @@ mate_mixer_switch_option_class_init (MateMixerSwitchOptionClass *klass) G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + /** + * MateMixerSwitchOption:icon: + * + * The XDG icon name of the switch option. + */ properties[PROP_ICON] = g_param_spec_string ("icon", "Icon", @@ -182,6 +199,16 @@ mate_mixer_switch_option_finalize (GObject *object) /** * mate_mixer_switch_option_get_name: + * @option: a #MateMixerSwitchOption + * + * Gets the name of the switch option. The name serves as a unique identifier + * and in most cases it is not in a user-readable form. + * + * The returned name is guaranteed to be unique across all the switch options + * of a particular #MateMixerSwitch and may be used to get the #MateMixerSwitchOption + * using mate_mixer_switch_get_option(). + * + * Returns: the name of the switch option. */ const gchar * mate_mixer_switch_option_get_name (MateMixerSwitchOption *option) @@ -193,6 +220,12 @@ mate_mixer_switch_option_get_name (MateMixerSwitchOption *option) /** * mate_mixer_switch_option_get_label: + * @option: a #MateMixerSwitchOption + * + * Gets the label of the switch option. This is a potentially translated string + * that should be presented to users in the user interface. + * + * Returns: the label of the switch option. */ const gchar * mate_mixer_switch_option_get_label (MateMixerSwitchOption *option) @@ -204,6 +237,11 @@ mate_mixer_switch_option_get_label (MateMixerSwitchOption *option) /** * mate_mixer_switch_option_get_icon: + * @option: a #MateMixerSwitchOption + * + * Gets the XDG icon name of the switch option. + * + * Returns: the icon name or %NULL. */ const gchar * mate_mixer_switch_option_get_icon (MateMixerSwitchOption *option) diff --git a/libmatemixer/matemixer-switch-option.h b/libmatemixer/matemixer-switch-option.h index ae87718..03f3608 100644 --- a/libmatemixer/matemixer-switch-option.h +++ b/libmatemixer/matemixer-switch-option.h @@ -57,8 +57,9 @@ struct _MateMixerSwitchOption /** * MateMixerSwitchOptionClass: + * @parent_class: The parent class. * - * The class structure of #MateMixerSwitchOption. + * The class structure for #MateMixerSwitchOption. */ struct _MateMixerSwitchOptionClass { diff --git a/libmatemixer/matemixer-switch.c b/libmatemixer/matemixer-switch.c index 461b49e..87580dd 100644 --- a/libmatemixer/matemixer-switch.c +++ b/libmatemixer/matemixer-switch.c @@ -241,6 +241,13 @@ mate_mixer_switch_finalize (GObject *object) /** * mate_mixer_switch_get_name: * @swtch: a #MateMixerSwitch + * + * Gets the name of the switch. + * + * The name serves as a unique identifier and in most cases it is not in a + * user-readable form. + * + * Returns: the name of the switch. */ const gchar * mate_mixer_switch_get_name (MateMixerSwitch *swtch) @@ -253,6 +260,13 @@ mate_mixer_switch_get_name (MateMixerSwitch *swtch) /** * mate_mixer_switch_get_label: * @swtch: a #MateMixerSwitch + * + * Gets the label of the switch. + * + * This is a potentially translated string that should be presented to users + * in the user interface. + * + * Returns: the label of the switch option. */ const gchar * mate_mixer_switch_get_label (MateMixerSwitch *swtch) @@ -265,6 +279,11 @@ mate_mixer_switch_get_label (MateMixerSwitch *swtch) /** * mate_mixer_switch_get_flags: * @swtch: a #MateMixerSwitch + * + * Gets the flags of the switch. See #MateMixerSwitchFlags for information about + * the meaning of the individual flags. + * + * Returns: the flags of the switch. */ MateMixerSwitchFlags mate_mixer_switch_get_flags (MateMixerSwitch *swtch) @@ -277,6 +296,11 @@ mate_mixer_switch_get_flags (MateMixerSwitch *swtch) /** * mate_mixer_switch_get_role: * @swtch: a #MateMixerSwitch + * + * Gets the role of the switch. The role identifies the purpose of the switch. + + * Note that while the role identification should be reliable, it may be based on + * looking for well-known switch names on some sound systems. */ MateMixerSwitchRole mate_mixer_switch_get_role (MateMixerSwitch *swtch) @@ -289,6 +313,11 @@ mate_mixer_switch_get_role (MateMixerSwitch *swtch) /** * mate_mixer_switch_get_option: * @swtch: a #MateMixerSwitch + * @name: the name of an option + * + * Gets the #MateMixerSwitchOption with the given name. + * + * Returns: a #MateMixerSwitchOption or %NULL if there is no such switch option. */ MateMixerSwitchOption * mate_mixer_switch_get_option (MateMixerSwitch *swtch, const gchar *name) @@ -301,6 +330,10 @@ mate_mixer_switch_get_option (MateMixerSwitch *swtch, const gchar *name) /** * mate_mixer_switch_get_active_option: * @swtch: a #MateMixerSwitch + * + * Gets the #MateMixerSwitchOption which is currently active. + * + * Returns: a #MateMixerSwitchOption. */ MateMixerSwitchOption * mate_mixer_switch_get_active_option (MateMixerSwitch *swtch) @@ -313,19 +346,26 @@ mate_mixer_switch_get_active_option (MateMixerSwitch *swtch) /** * mate_mixer_switch_set_active_option: * @swtch: a #MateMixerSwitch + * @option: the #MateMixerSwitchOption to set as the active option + * + * Changes the currently active switch option. + * + * Returns: %TRUE on success or %FALSE on failure. */ gboolean mate_mixer_switch_set_active_option (MateMixerSwitch *swtch, MateMixerSwitchOption *option) { + MateMixerSwitchClass *klass; + g_return_val_if_fail (MATE_MIXER_IS_SWITCH (swtch), FALSE); - if (swtch->priv->active != option) { - MateMixerSwitchClass *klass; + klass = MATE_MIXER_SWITCH_GET_CLASS (swtch); + if (klass->set_active_option == NULL) + return FALSE; - klass = MATE_MIXER_SWITCH_GET_CLASS (swtch); - if (klass->set_active_option == NULL || - klass->set_active_option (swtch, option) == FALSE) + if (swtch->priv->active != option) { + if (klass->set_active_option (swtch, option) == FALSE) return FALSE; _mate_mixer_switch_set_active_option (swtch, option); @@ -334,8 +374,15 @@ mate_mixer_switch_set_active_option (MateMixerSwitch *swtch, } /** - * mate_mixer_switch_get_name: + * mate_mixer_switch_list_options: * @swtch: a #MateMixerSwitch + * + * Gets the list of switch options that belong to the switch. + * + * The returned #GList is owned by the #MateMixerSwitch and may be invalidated + * at any time. + * + * Returns: a #GList of the switch options. */ const GList * mate_mixer_switch_list_options (MateMixerSwitch *swtch) @@ -364,8 +411,7 @@ _mate_mixer_switch_set_active_option (MateMixerSwitch *swtch, else swtch->priv->active = NULL; - g_object_notify_by_pspec (G_OBJECT (swtch), - properties[PROP_ACTIVE_OPTION]); + g_object_notify_by_pspec (G_OBJECT (swtch), properties[PROP_ACTIVE_OPTION]); } static MateMixerSwitchOption * diff --git a/libmatemixer/matemixer-switch.h b/libmatemixer/matemixer-switch.h index 7f0109f..7881486 100644 --- a/libmatemixer/matemixer-switch.h +++ b/libmatemixer/matemixer-switch.h @@ -26,17 +26,17 @@ G_BEGIN_DECLS -#define MATE_MIXER_TYPE_SWITCH \ +#define MATE_MIXER_TYPE_SWITCH \ (mate_mixer_switch_get_type ()) -#define MATE_MIXER_SWITCH(o) \ +#define MATE_MIXER_SWITCH(o) \ (G_TYPE_CHECK_INSTANCE_CAST ((o), MATE_MIXER_TYPE_SWITCH, MateMixerSwitch)) -#define MATE_MIXER_IS_SWITCH(o) \ +#define MATE_MIXER_IS_SWITCH(o) \ (G_TYPE_CHECK_INSTANCE_TYPE ((o), MATE_MIXER_TYPE_SWITCH)) -#define MATE_MIXER_SWITCH_CLASS(k) \ +#define MATE_MIXER_SWITCH_CLASS(k) \ (G_TYPE_CHECK_CLASS_CAST ((k), MATE_MIXER_TYPE_SWITCH, MateMixerSwitchClass)) -#define MATE_MIXER_IS_SWITCH_CLASS(k) \ +#define MATE_MIXER_IS_SWITCH_CLASS(k) \ (G_TYPE_CHECK_CLASS_TYPE ((k), MATE_MIXER_TYPE_SWITCH)) -#define MATE_MIXER_SWITCH_GET_CLASS(o) \ +#define MATE_MIXER_SWITCH_GET_CLASS(o) \ (G_TYPE_INSTANCE_GET_CLASS ((o), MATE_MIXER_TYPE_SWITCH, MateMixerSwitchClass)) typedef struct _MateMixerSwitchClass MateMixerSwitchClass; @@ -58,8 +58,9 @@ struct _MateMixerSwitch /** * MateMixerSwitchClass: + * @parent_class: The parent class. * - * The class structure of #MateMixerSwitch. + * The class structure for #MateMixerSwitch. */ struct _MateMixerSwitchClass { diff --git a/libmatemixer/matemixer-toggle.c b/libmatemixer/matemixer-toggle.c index 0db6e3b..78f7f5b 100644 --- a/libmatemixer/matemixer-toggle.c +++ b/libmatemixer/matemixer-toggle.c @@ -15,7 +15,6 @@ * License along with this library; if not, see <http://www.gnu.org/licenses/>. */ -#include <string.h> #include <glib.h> #include <glib-object.h> @@ -25,6 +24,7 @@ /** * SECTION:matemixer-toggle + * @short_description: On/Off switch * @include: libmatemixer/matemixer.h */ @@ -38,8 +38,8 @@ struct _MateMixerTogglePrivate enum { PROP_0, PROP_STATE, - PROP_STATE_OPTION_ON, - PROP_STATE_OPTION_OFF, + PROP_ON_STATE_OPTION, + PROP_OFF_STATE_OPTION, N_PROPERTIES }; @@ -81,27 +81,43 @@ mate_mixer_toggle_class_init (MateMixerToggleClass *klass) switch_class->get_option = mate_mixer_toggle_get_option; switch_class->list_options = mate_mixer_toggle_list_options; + /** + * MateMixerToggle:state: + * + * The current state of the toggle. %TRUE corresponds to the 'on' state and + * %FALSE to the 'off' state. + */ properties[PROP_STATE] = g_param_spec_boolean ("state", "State", "Current state of the toggle", FALSE, - G_PARAM_READABLE | + G_PARAM_READWRITE | 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", + /** + * MateMixerToggle:on-state-option: + * + * The #MateMixerSwitchOption representing the 'on' value of the toggle. + */ + properties[PROP_ON_STATE_OPTION] = + g_param_spec_object ("on-state-option", + "On state option", + "On state option", 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", + /** + * MateMixerToggle:off-state-option: + * + * The #MateMixerSwitchOption representing the 'off' value of the toggle. + */ + properties[PROP_OFF_STATE_OPTION] = + g_param_spec_object ("off-state-option", + "Off state option", + "Off state option", MATE_MIXER_TYPE_SWITCH_OPTION, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | @@ -126,10 +142,10 @@ mate_mixer_toggle_get_property (GObject *object, case PROP_STATE: g_value_set_boolean (value, mate_mixer_toggle_get_state (toggle)); break; - case PROP_STATE_OPTION_ON: + case PROP_ON_STATE_OPTION: g_value_set_object (value, toggle->priv->on); break; - case PROP_STATE_OPTION_OFF: + case PROP_OFF_STATE_OPTION: g_value_set_object (value, toggle->priv->off); break; @@ -150,11 +166,14 @@ mate_mixer_toggle_set_property (GObject *object, toggle = MATE_MIXER_TOGGLE (object); switch (param_id) { - case PROP_STATE_OPTION_ON: + case PROP_STATE: + mate_mixer_toggle_set_state (toggle, g_value_get_boolean (value)); + break; + case PROP_ON_STATE_OPTION: /* Construct-only object */ toggle->priv->on = g_value_dup_object (value); break; - case PROP_STATE_OPTION_OFF: + case PROP_OFF_STATE_OPTION: /* Construct-only object */ toggle->priv->off = g_value_dup_object (value); break; @@ -181,11 +200,10 @@ mate_mixer_toggle_dispose (GObject *object) toggle = MATE_MIXER_TOGGLE (object); if (toggle->priv->options != NULL) { - g_list_free_full (toggle->priv->options, g_object_unref); + g_list_free (toggle->priv->options); toggle->priv->options = NULL; } - /* FIXME: crashes on ALSA without the polling thread */ g_clear_object (&toggle->priv->on); g_clear_object (&toggle->priv->off); @@ -195,6 +213,11 @@ mate_mixer_toggle_dispose (GObject *object) /** * mate_mixer_toggle_get_state: * @toggle: a #MateMixerToggle + * + * Gets the current state of the toggle. %TRUE corresponds to the 'on' state and + * %FALSE to the 'off' state. + * + * Returns: %TRUE or %FALSE. */ gboolean mate_mixer_toggle_get_state (MateMixerToggle *toggle) @@ -204,6 +227,9 @@ mate_mixer_toggle_get_state (MateMixerToggle *toggle) g_return_val_if_fail (MATE_MIXER_IS_TOGGLE (toggle), FALSE); active = mate_mixer_switch_get_active_option (MATE_MIXER_SWITCH (toggle)); + if G_UNLIKELY (active == NULL) + return FALSE; + if (active == toggle->priv->on) return TRUE; else @@ -213,6 +239,11 @@ mate_mixer_toggle_get_state (MateMixerToggle *toggle) /** * mate_mixer_toggle_get_state_option: * @toggle: a #MateMixerToggle + * @state: the state to get the #MateMixerSwitchOption for + * + * Gets the #MateMixerSwitchOption representing the selected state. + * + * Returns: a #MateMixerSwitchOption. */ MateMixerSwitchOption * mate_mixer_toggle_get_state_option (MateMixerToggle *toggle, gboolean state) @@ -228,6 +259,14 @@ mate_mixer_toggle_get_state_option (MateMixerToggle *toggle, gboolean state) /** * mate_mixer_toggle_set_state: * @toggle: a #MateMixerToggle + * @state: the state to set + * + * Sets the @toggle to the selected state. + * + * This function is equivalent to using mate_mixer_switch_set_active_option() + * with a #MateMixerSwitchOption representing the selected state. + * + * Returns: %TRUE on success or %FALSE on failure. */ gboolean mate_mixer_toggle_set_state (MateMixerToggle *toggle, gboolean state) @@ -241,6 +280,9 @@ mate_mixer_toggle_set_state (MateMixerToggle *toggle, gboolean state) else active = toggle->priv->off; + if G_UNLIKELY (active == NULL) + return FALSE; + return mate_mixer_switch_set_active_option (MATE_MIXER_SWITCH (toggle), active); } @@ -250,12 +292,13 @@ mate_mixer_toggle_get_option (MateMixerSwitch *swtch, const gchar *name) MateMixerToggle *toggle; g_return_val_if_fail (MATE_MIXER_IS_TOGGLE (swtch), NULL); + g_return_val_if_fail (name != NULL, NULL); toggle = MATE_MIXER_TOGGLE (swtch); - if (strcmp (name, mate_mixer_switch_option_get_name (toggle->priv->on)) == 0) + if (g_strcmp0 (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) + if (g_strcmp0 (name, mate_mixer_switch_option_get_name (toggle->priv->off)) == 0) return toggle->priv->off; return NULL; @@ -271,10 +314,12 @@ mate_mixer_toggle_list_options (MateMixerSwitch *swtch) toggle = MATE_MIXER_TOGGLE (swtch); if (toggle->priv->options == NULL) { - toggle->priv->options = g_list_prepend (toggle->priv->options, - toggle->priv->off); - toggle->priv->options = g_list_prepend (toggle->priv->options, - toggle->priv->on); + if G_LIKELY (toggle->priv->off != NULL) + toggle->priv->options = g_list_prepend (toggle->priv->options, + toggle->priv->off); + if G_LIKELY (toggle->priv->on != NULL) + toggle->priv->options = g_list_prepend (toggle->priv->options, + toggle->priv->on); } return toggle->priv->options; } diff --git a/libmatemixer/matemixer-toggle.h b/libmatemixer/matemixer-toggle.h index 44946f7..09e8943 100644 --- a/libmatemixer/matemixer-toggle.h +++ b/libmatemixer/matemixer-toggle.h @@ -57,8 +57,9 @@ struct _MateMixerToggle /** * MateMixerToggleClass: + * @parent_class: The parent class. * - * The class structure of #MateMixerToggle. + * The class structure for #MateMixerToggle. */ struct _MateMixerToggleClass { diff --git a/libmatemixer/matemixer-types.h b/libmatemixer/matemixer-types.h index 57a64a1..271009c 100644 --- a/libmatemixer/matemixer-types.h +++ b/libmatemixer/matemixer-types.h @@ -21,9 +21,8 @@ G_BEGIN_DECLS typedef struct _MateMixerAppInfo MateMixerAppInfo; -typedef struct _MateMixerDevice MateMixerDevice; typedef struct _MateMixerContext MateMixerContext; -typedef struct _MateMixerDeviceProfile MateMixerDeviceProfile; +typedef struct _MateMixerDevice MateMixerDevice; typedef struct _MateMixerStoredControl MateMixerStoredControl; typedef struct _MateMixerStream MateMixerStream; typedef struct _MateMixerStreamControl MateMixerStreamControl; diff --git a/libmatemixer/matemixer.c b/libmatemixer/matemixer.c index a5bca6f..5e7c825 100644 --- a/libmatemixer/matemixer.c +++ b/libmatemixer/matemixer.c @@ -28,8 +28,17 @@ /** * SECTION:matemixer * @short_description: Library initialization and support functions - * @title: MateMixer * @include: libmatemixer/matemixer.h + * @see_also: #MateMixerContext + * + * The libmatemixer library must be initialized before it is used by an + * application. The initialization function loads dynamic modules which provide + * access to sound systems (also called backends) and it only succeeds if there + * is at least one usable module present on the target system. + * + * To connect to a sound system and access the mixer functionality after the + * library is initialized, create a #MateMixerContext using the + * mate_mixer_context_new() function. */ static void load_modules (void); @@ -100,14 +109,28 @@ mate_mixer_is_initialized (void) return initialized; } -/* Internal: return a list of loaded backend modules */ +/** + * _mate_mixer_list_modules: + * + * Gets a list of loaded backend modules. + * + * Returns: a #GList. + */ const GList * _mate_mixer_list_modules (void) { return (const GList *) modules; } -/* Internal: create a channel mask using the given list of channel positions */ +/** + * _mate_mixer_create_channel_mask: + * @positions: an array of channel positions + * @n: number of channel positions in the array + * + * Creates a channel mask using the given list of channel positions. + * + * Returns: a channel mask. + */ guint32 _mate_mixer_create_channel_mask (MateMixerChannelPosition *positions, guint n) { @@ -130,7 +153,7 @@ load_modules (void) if (loaded == TRUE) return; - if (G_LIKELY (g_module_supported () == TRUE)) { + if G_LIKELY (g_module_supported () == TRUE) { GDir *dir; GError *error = NULL; @@ -158,13 +181,14 @@ load_modules (void) g_error_free (error); } } else { - g_critical ("Unable to load backend modules: not supported"); + g_critical ("Unable to load backend modules: Not supported"); } loaded = TRUE; } -/* Backend modules sorting function, higher priority number means higher priority */ +/* Backend modules sorting function, higher priority number means higher priority + * of the backend module */ static gint compare_modules (gconstpointer a, gconstpointer b) { |