diff options
author | Michal Ratajsky <[email protected]> | 2014-08-18 20:49:17 +0200 |
---|---|---|
committer | Michal Ratajsky <[email protected]> | 2014-08-18 20:49:17 +0200 |
commit | 5f20ab328add9442082277a57c23273a3a2125ed (patch) | |
tree | fb458ba63f25db35de6b5a9c9acf0f967020107f /backends/alsa/alsa-stream.c | |
parent | 94d24482d8b1013947c0e2dac7330180b6ae02f6 (diff) | |
download | libmatemixer-5f20ab328add9442082277a57c23273a3a2125ed.tar.bz2 libmatemixer-5f20ab328add9442082277a57c23273a3a2125ed.tar.xz |
Global update
Diffstat (limited to 'backends/alsa/alsa-stream.c')
-rw-r--r-- | backends/alsa/alsa-stream.c | 335 |
1 files changed, 222 insertions, 113 deletions
diff --git a/backends/alsa/alsa-stream.c b/backends/alsa/alsa-stream.c index d2f68d4..bc9c1b5 100644 --- a/backends/alsa/alsa-stream.c +++ b/backends/alsa/alsa-stream.c @@ -18,6 +18,7 @@ #include <glib.h> #include <glib-object.h> #include <libmatemixer/matemixer.h> +#include <libmatemixer/matemixer-private.h> #include "alsa-element.h" #include "alsa-stream.h" @@ -26,27 +27,23 @@ struct _AlsaStreamPrivate { - GHashTable *switches; - GHashTable *controls; - MateMixerStreamControl *control; + GList *switches; + GList *controls; }; static void alsa_stream_class_init (AlsaStreamClass *klass); static void alsa_stream_init (AlsaStream *stream); static void alsa_stream_dispose (GObject *object); -static void alsa_stream_finalize (GObject *object); G_DEFINE_TYPE (AlsaStream, alsa_stream, MATE_MIXER_TYPE_STREAM) -static MateMixerStreamControl *alsa_stream_get_control (MateMixerStream *mms, - const gchar *name); -static MateMixerStreamControl *alsa_stream_get_default_control (MateMixerStream *mms); - -static MateMixerSwitch * alsa_stream_get_switch (MateMixerStream *mms, - const gchar *name); +static const GList *alsa_stream_list_controls (MateMixerStream *mms); +static const GList *alsa_stream_list_switches (MateMixerStream *mms); -static GList * alsa_stream_list_controls (MateMixerStream *mms); -static GList * alsa_stream_list_switches (MateMixerStream *mms); +static gint compare_control_name (gconstpointer a, + gconstpointer b); +static gint compare_switch_name (gconstpointer a, + gconstpointer b); static void alsa_stream_class_init (AlsaStreamClass *klass) @@ -55,15 +52,11 @@ alsa_stream_class_init (AlsaStreamClass *klass) MateMixerStreamClass *stream_class; object_class = G_OBJECT_CLASS (klass); - object_class->dispose = alsa_stream_dispose; - object_class->finalize = alsa_stream_finalize; + object_class->dispose = alsa_stream_dispose; stream_class = MATE_MIXER_STREAM_CLASS (klass); - stream_class->get_control = alsa_stream_get_control; - stream_class->get_default_control = alsa_stream_get_default_control; - stream_class->get_switch = alsa_stream_get_switch; - stream_class->list_controls = alsa_stream_list_controls; - stream_class->list_switches = alsa_stream_list_switches; + stream_class->list_controls = alsa_stream_list_controls; + stream_class->list_switches = alsa_stream_list_switches; g_type_class_add_private (object_class, sizeof (AlsaStreamPrivate)); } @@ -74,16 +67,6 @@ alsa_stream_init (AlsaStream *stream) stream->priv = G_TYPE_INSTANCE_GET_PRIVATE (stream, ALSA_TYPE_STREAM, AlsaStreamPrivate); - - stream->priv->controls = g_hash_table_new_full (g_str_hash, - g_str_equal, - g_free, - g_object_unref); - - stream->priv->switches = g_hash_table_new_full (g_str_hash, - g_str_equal, - g_free, - g_object_unref); } static void @@ -93,36 +76,30 @@ alsa_stream_dispose (GObject *object) stream = ALSA_STREAM (object); - g_hash_table_remove_all (stream->priv->controls); - g_hash_table_remove_all (stream->priv->switches); - - g_clear_object (&stream->priv->control); + if (stream->priv->controls != NULL) { + g_list_free_full (stream->priv->controls, g_object_unref); + stream->priv->controls = NULL; + } + if (stream->priv->switches != NULL) { + g_list_free_full (stream->priv->switches, g_object_unref); + stream->priv->switches = NULL; + } G_OBJECT_CLASS (alsa_stream_parent_class)->dispose (object); } -static void -alsa_stream_finalize (GObject *object) -{ - AlsaStream *stream; - - stream = ALSA_STREAM (object); - - g_hash_table_destroy (stream->priv->controls); - g_hash_table_destroy (stream->priv->switches); - - G_OBJECT_CLASS (alsa_stream_parent_class)->finalize (object); -} - AlsaStream * -alsa_stream_new (const gchar *name, - MateMixerDevice *device, - MateMixerStreamFlags flags) +alsa_stream_new (const gchar *name, + MateMixerDevice *device, + MateMixerDirection direction) { + const gchar *label = mate_mixer_device_get_label (device); + return g_object_new (ALSA_TYPE_STREAM, "name", name, + "label", label, "device", device, - "flags", flags, + "direction", direction, NULL); } @@ -135,9 +112,16 @@ alsa_stream_add_control (AlsaStream *stream, AlsaStreamControl *control) g_return_if_fail (ALSA_IS_STREAM_CONTROL (control)); name = mate_mixer_stream_control_get_name (MATE_MIXER_STREAM_CONTROL (control)); - g_hash_table_insert (stream->priv->controls, - g_strdup (name), - g_object_ref (control)); + + stream->priv->controls = + g_list_append (stream->priv->controls, g_object_ref (control)); + + g_signal_emit_by_name (G_OBJECT (stream), + "control-added", + name); + + if (alsa_stream_has_default_control (stream) == FALSE) + alsa_stream_set_default_control (stream, control); } void @@ -149,125 +133,250 @@ alsa_stream_add_switch (AlsaStream *stream, AlsaSwitch *swtch) g_return_if_fail (ALSA_IS_SWITCH (swtch)); name = mate_mixer_switch_get_name (MATE_MIXER_SWITCH (swtch)); - g_hash_table_insert (stream->priv->switches, - g_strdup (name), - g_object_ref (swtch)); + + stream->priv->switches = + g_list_append (stream->priv->switches, g_object_ref (swtch)); + + g_signal_emit_by_name (G_OBJECT (stream), + "switch-added", + name); +} + +void +alsa_stream_add_toggle (AlsaStream *stream, AlsaToggle *toggle) +{ + const gchar *name; + + g_return_if_fail (ALSA_IS_STREAM (stream)); + g_return_if_fail (ALSA_IS_TOGGLE (toggle)); + + name = mate_mixer_switch_get_name (MATE_MIXER_SWITCH (toggle)); + + /* Toggle is MateMixerSwitch, but not AlsaSwitch */ + stream->priv->switches = + g_list_append (stream->priv->switches, g_object_ref (toggle)); + + g_signal_emit_by_name (G_OBJECT (stream), + "switch-added", + name); +} + +gboolean +alsa_stream_has_controls (AlsaStream *stream) +{ + g_return_val_if_fail (ALSA_IS_STREAM (stream), FALSE); + + if (stream->priv->controls != NULL) + return TRUE; + + return FALSE; } gboolean -alsa_stream_is_empty (AlsaStream *stream) +alsa_stream_has_switches (AlsaStream *stream) { g_return_val_if_fail (ALSA_IS_STREAM (stream), FALSE); - if (g_hash_table_size (stream->priv->controls) > 0 || - g_hash_table_size (stream->priv->switches) > 0) - return FALSE; + if (stream->priv->switches != NULL) + return TRUE; - return TRUE; + return FALSE; +} + +gboolean +alsa_stream_has_controls_or_switches (AlsaStream *stream) +{ + g_return_val_if_fail (ALSA_IS_STREAM (stream), FALSE); + + if (stream->priv->controls != NULL || + stream->priv->switches != NULL) + return TRUE; + + return FALSE; +} + +gboolean +alsa_stream_has_default_control (AlsaStream *stream) +{ + g_return_val_if_fail (ALSA_IS_STREAM (stream), FALSE); + + if (mate_mixer_stream_get_default_control (MATE_MIXER_STREAM (stream)) != NULL) + return TRUE; + + return FALSE; +} + +AlsaStreamControl * +alsa_stream_get_default_control (AlsaStream *stream) +{ + MateMixerStreamControl *control; + + g_return_val_if_fail (ALSA_IS_STREAM (stream), NULL); + + control = mate_mixer_stream_get_default_control (MATE_MIXER_STREAM (stream)); + if (control != NULL) + return ALSA_STREAM_CONTROL (control); + + return NULL; } void alsa_stream_set_default_control (AlsaStream *stream, AlsaStreamControl *control) { g_return_if_fail (ALSA_IS_STREAM (stream)); - g_return_if_fail (ALSA_IS_STREAM_CONTROL (control)); - - /* This function is only used internally so avoid validating that the control - * belongs to this stream */ - if (stream->priv->control != NULL) - g_object_unref (stream->priv->control); + g_return_if_fail (control == NULL || ALSA_IS_STREAM_CONTROL (control)); - if (control != NULL) - stream->priv->control = MATE_MIXER_STREAM_CONTROL (g_object_ref (control)); + if (control == NULL) + _mate_mixer_stream_set_default_control (MATE_MIXER_STREAM (stream), NULL); else - stream->priv->control = NULL; + _mate_mixer_stream_set_default_control (MATE_MIXER_STREAM (stream), + MATE_MIXER_STREAM_CONTROL (control)); } void alsa_stream_load_elements (AlsaStream *stream, const gchar *name) { - AlsaElement *element; + GList *item; g_return_if_fail (ALSA_IS_STREAM (stream)); g_return_if_fail (name != NULL); - element = g_hash_table_lookup (stream->priv->controls, name); - if (element != NULL) - alsa_element_load (element); + item = g_list_find_custom (stream->priv->controls, name, compare_control_name); + if (item != NULL) + alsa_element_load (ALSA_ELEMENT (item->data)); - element = g_hash_table_lookup (stream->priv->switches, name); - if (element != NULL) - alsa_element_load (element); + item = g_list_find_custom (stream->priv->switches, name, compare_switch_name); + if (item != NULL) + alsa_element_load (ALSA_ELEMENT (item->data)); } gboolean alsa_stream_remove_elements (AlsaStream *stream, const gchar *name) { + GList *item; gboolean removed = FALSE; g_return_val_if_fail (ALSA_IS_STREAM (stream), FALSE); g_return_val_if_fail (name != NULL, FALSE); - if (g_hash_table_remove (stream->priv->controls, name) == TRUE) + item = g_list_find_custom (stream->priv->controls, name, compare_control_name); + if (item != NULL) { + MateMixerStreamControl *control = MATE_MIXER_STREAM_CONTROL (item->data); + + alsa_element_close (ALSA_ELEMENT (control)); + stream->priv->controls = g_list_delete_link (stream->priv->controls, item); + + /* Change the default control if we have just removed it */ + if (control == mate_mixer_stream_get_default_control (MATE_MIXER_STREAM (stream))) { + AlsaStreamControl *first = NULL; + + if (stream->priv->controls != NULL) + first = ALSA_STREAM_CONTROL (stream->priv->controls->data); + + alsa_stream_set_default_control (stream, first); + } + + g_signal_emit_by_name (G_OBJECT (stream), + "control-removed", + mate_mixer_stream_control_get_name (control)); + + g_object_unref (control); removed = TRUE; - if (g_hash_table_remove (stream->priv->switches, name) == TRUE) + } + + item = g_list_find_custom (stream->priv->switches, name, compare_switch_name); + if (item != NULL) { + MateMixerSwitch *swtch = MATE_MIXER_SWITCH (item->data); + + alsa_element_close (ALSA_ELEMENT (swtch)); + + stream->priv->switches = g_list_delete_link (stream->priv->switches, item); + g_signal_emit_by_name (G_OBJECT (stream), + "switch-removed", + mate_mixer_switch_get_name (swtch)); + + g_object_unref (swtch); removed = TRUE; + } return removed; } -static MateMixerStreamControl * -alsa_stream_get_control (MateMixerStream *mms, const gchar *name) +void +alsa_stream_remove_all (AlsaStream *stream) { - g_return_val_if_fail (ALSA_IS_STREAM (mms), NULL); + GList *list; - return g_hash_table_lookup (ALSA_STREAM (mms)->priv->controls, name); -} + g_return_if_fail (ALSA_IS_STREAM (stream)); -static MateMixerStreamControl * -alsa_stream_get_default_control (MateMixerStream *mms) -{ - g_return_val_if_fail (ALSA_IS_STREAM (mms), NULL); + /* Remove all stream controls */ + list = stream->priv->controls; + while (list != NULL) { + MateMixerStreamControl *control = MATE_MIXER_STREAM_CONTROL (list->data); + GList *next = list->next; + + alsa_element_close (ALSA_ELEMENT (control)); + + stream->priv->controls = g_list_delete_link (stream->priv->controls, list); + g_signal_emit_by_name (G_OBJECT (stream), + "control-removed", + mate_mixer_stream_control_get_name (control)); + + g_object_unref (control); + list = next; + } + + /* Unset the default stream control */ + alsa_stream_set_default_control (stream, NULL); + + /* Remove all stream switches */ + list = stream->priv->switches; + while (list != NULL) { + MateMixerSwitch *swtch = MATE_MIXER_SWITCH (list->data); + GList *next = list->next; + + alsa_element_close (ALSA_ELEMENT (swtch)); - return ALSA_STREAM (mms)->priv->control; + stream->priv->switches = g_list_delete_link (stream->priv->switches, list); + g_signal_emit_by_name (G_OBJECT (stream), + "switch-removed", + mate_mixer_switch_get_name (swtch)); + + g_object_unref (swtch); + list = next; + } } -static MateMixerSwitch * -alsa_stream_get_switch (MateMixerStream *mms, const gchar *name) +static const GList * +alsa_stream_list_controls (MateMixerStream *mms) { g_return_val_if_fail (ALSA_IS_STREAM (mms), NULL); - return g_hash_table_lookup (ALSA_STREAM (mms)->priv->switches, name); + return ALSA_STREAM (mms)->priv->controls; } -static GList * -alsa_stream_list_controls (MateMixerStream *mms) +static const GList * +alsa_stream_list_switches (MateMixerStream *mms) { - GList *list; - g_return_val_if_fail (ALSA_IS_STREAM (mms), NULL); - /* Convert the hash table to a linked list, this list is expected to be - * cached in the main library */ - list = g_hash_table_get_values (ALSA_STREAM (mms)->priv->controls); - if (list != NULL) - g_list_foreach (list, (GFunc) g_object_ref, NULL); - - return list; + return ALSA_STREAM (mms)->priv->switches; } -static GList * -alsa_stream_list_switches (MateMixerStream *mms) +static gint +compare_control_name (gconstpointer a, gconstpointer b) { - GList *list; + MateMixerStreamControl *control = MATE_MIXER_STREAM_CONTROL (a); + const gchar *name = (const gchar *) b; - g_return_val_if_fail (ALSA_IS_STREAM (mms), NULL); + return strcmp (mate_mixer_stream_control_get_name (control), name); +} - /* Convert the hash table to a linked list, this list is expected to be - * cached in the main library */ - list = g_hash_table_get_values (ALSA_STREAM (mms)->priv->switches); - if (list != NULL) - g_list_foreach (list, (GFunc) g_object_ref, NULL); +static gint +compare_switch_name (gconstpointer a, gconstpointer b) +{ + MateMixerSwitch *swtch = MATE_MIXER_SWITCH (a); + const gchar *name = (const gchar *) b; - return list; + return strcmp (mate_mixer_switch_get_name (swtch), name); } |