summaryrefslogtreecommitdiff
path: root/backends/alsa/alsa-stream.c
diff options
context:
space:
mode:
authorMichal Ratajsky <[email protected]>2014-08-18 20:49:17 +0200
committerMichal Ratajsky <[email protected]>2014-08-18 20:49:17 +0200
commit5f20ab328add9442082277a57c23273a3a2125ed (patch)
treefb458ba63f25db35de6b5a9c9acf0f967020107f /backends/alsa/alsa-stream.c
parent94d24482d8b1013947c0e2dac7330180b6ae02f6 (diff)
downloadlibmatemixer-5f20ab328add9442082277a57c23273a3a2125ed.tar.bz2
libmatemixer-5f20ab328add9442082277a57c23273a3a2125ed.tar.xz
Global update
Diffstat (limited to 'backends/alsa/alsa-stream.c')
-rw-r--r--backends/alsa/alsa-stream.c335
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);
}