diff options
Diffstat (limited to 'backends/oss/oss-stream.c')
-rw-r--r-- | backends/oss/oss-stream.c | 251 |
1 files changed, 171 insertions, 80 deletions
diff --git a/backends/oss/oss-stream.c b/backends/oss/oss-stream.c index 5f0c629..227c88b 100644 --- a/backends/oss/oss-stream.c +++ b/backends/oss/oss-stream.c @@ -16,32 +16,32 @@ */ #include <glib.h> +#include <glib/gi18n.h> #include <glib-object.h> #include <libmatemixer/matemixer.h> +#include <libmatemixer/matemixer-private.h> -#include "oss-device.h" #include "oss-stream.h" #include "oss-stream-control.h" +#include "oss-switch.h" + +#define OSS_STREAM_SWITCH_NAME "port" struct _OssStreamPrivate { - GHashTable *controls; - OssStreamControl *control; + OssSwitch *swtch; + GList *switches; + GList *controls; }; -static void oss_stream_class_init (OssStreamClass *klass); - -static void oss_stream_init (OssStream *ostream); -static void oss_stream_dispose (GObject *object); -static void oss_stream_finalize (GObject *object); +static void oss_stream_class_init (OssStreamClass *klass); +static void oss_stream_init (OssStream *stream); +static void oss_stream_dispose (GObject *object); G_DEFINE_TYPE (OssStream, oss_stream, MATE_MIXER_TYPE_STREAM) -static MateMixerStreamControl *oss_stream_get_control (MateMixerStream *stream, - const gchar *name); -static MateMixerStreamControl *oss_stream_get_default_control (MateMixerStream *stream); - -static GList * oss_stream_list_controls (MateMixerStream *stream); +static const GList *oss_stream_list_controls (MateMixerStream *mms); +static const GList *oss_stream_list_switches (MateMixerStream *mms); static void oss_stream_class_init (OssStreamClass *klass) @@ -50,13 +50,11 @@ oss_stream_class_init (OssStreamClass *klass) MateMixerStreamClass *stream_class; object_class = G_OBJECT_CLASS (klass); - object_class->dispose = oss_stream_dispose; - object_class->finalize = oss_stream_finalize; + object_class->dispose = oss_stream_dispose; stream_class = MATE_MIXER_STREAM_CLASS (klass); - stream_class->get_control = oss_stream_get_control; - stream_class->get_default_control = oss_stream_get_default_control; - stream_class->list_controls = oss_stream_list_controls; + stream_class->list_controls = oss_stream_list_controls; + stream_class->list_switches = oss_stream_list_switches; g_type_class_add_private (object_class, sizeof (OssStreamPrivate)); } @@ -67,11 +65,6 @@ oss_stream_init (OssStream *stream) stream->priv = G_TYPE_INSTANCE_GET_PRIVATE (stream, OSS_TYPE_STREAM, OssStreamPrivate); - - stream->priv->controls = g_hash_table_new_full (g_str_hash, - g_str_equal, - g_free, - g_object_unref); } static void @@ -81,103 +74,201 @@ oss_stream_dispose (GObject *object) stream = OSS_STREAM (object); - g_clear_object (&stream->priv->control); - g_hash_table_remove_all (stream->priv->controls); + 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_clear_object (&stream->priv->swtch); G_OBJECT_CLASS (oss_stream_parent_class)->dispose (object); } -static void -oss_stream_finalize (GObject *object) +OssStream * +oss_stream_new (const gchar *name, + MateMixerDevice *device, + MateMixerDirection direction) { - OssStream *stream; + const gchar *label = mate_mixer_device_get_label (device); + + return g_object_new (OSS_TYPE_STREAM, + "name", name, + "label", label, + "device", device, + "direction", direction, + NULL); +} - stream = OSS_STREAM (object); +void +oss_stream_add_control (OssStream *stream, OssStreamControl *control) +{ + const gchar *name; + + g_return_if_fail (OSS_IS_STREAM (stream)); + g_return_if_fail (OSS_IS_STREAM_CONTROL (control)); - g_hash_table_destroy (stream->priv->controls); + name = mate_mixer_stream_control_get_name (MATE_MIXER_STREAM_CONTROL (control)); + + stream->priv->controls = + g_list_append (stream->priv->controls, g_object_ref (control)); - G_OBJECT_CLASS (oss_stream_parent_class)->finalize (object); + g_signal_emit_by_name (G_OBJECT (stream), + "control-added", + name); } -OssStream * -oss_stream_new (const gchar *name, - MateMixerDevice *device, - MateMixerStreamFlags flags) +void +oss_stream_load (OssStream *stream) { - OssStream *stream; + GList *list; + + g_return_if_fail (OSS_IS_STREAM (stream)); + + list = stream->priv->controls; + while (list != NULL) { + OssStreamControl *control = OSS_STREAM_CONTROL (list->data); - stream = g_object_new (OSS_TYPE_STREAM, - "name", name, - "device", device, - "flags", flags, - NULL); - return stream; + oss_stream_control_load (control); + list = list->next; + } + + if (stream->priv->swtch != NULL) + oss_switch_load (stream->priv->swtch); } gboolean -oss_stream_add_control (OssStream *stream, OssStreamControl *control) +oss_stream_has_controls (OssStream *stream) { - const gchar *name; - g_return_val_if_fail (OSS_IS_STREAM (stream), FALSE); - g_return_val_if_fail (OSS_IS_STREAM_CONTROL (control), FALSE); - name = mate_mixer_stream_control_get_name (MATE_MIXER_STREAM_CONTROL (control)); + if (stream->priv->controls != NULL) + return TRUE; - g_hash_table_insert (stream->priv->controls, - g_strdup (name), - control); - return TRUE; + return FALSE; } gboolean -oss_stream_set_default_control (OssStream *stream, OssStreamControl *control) +oss_stream_has_default_control (OssStream *stream) { g_return_val_if_fail (OSS_IS_STREAM (stream), FALSE); - g_return_val_if_fail (OSS_IS_STREAM_CONTROL (control), FALSE); - - /* 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); - if G_LIKELY (control != NULL) - stream->priv->control = g_object_ref (control); - else - stream->priv->control = NULL; + if (mate_mixer_stream_get_default_control (MATE_MIXER_STREAM (stream)) != NULL) + return TRUE; - return TRUE; + return FALSE; } -static MateMixerStreamControl * -oss_stream_get_control (MateMixerStream *mms, const gchar *name) +OssStreamControl * +oss_stream_get_default_control (OssStream *stream) { - g_return_val_if_fail (OSS_IS_STREAM (mms), NULL); - g_return_val_if_fail (name != NULL, NULL); + MateMixerStreamControl *control; + + g_return_val_if_fail (OSS_IS_STREAM (stream), NULL); + + control = mate_mixer_stream_get_default_control (MATE_MIXER_STREAM (stream)); + if (control != NULL) + return OSS_STREAM_CONTROL (control); - return g_hash_table_lookup (OSS_STREAM (mms)->priv->controls, name); + return NULL; } -static MateMixerStreamControl * -oss_stream_get_default_control (MateMixerStream *mms) +void +oss_stream_set_default_control (OssStream *stream, OssStreamControl *control) { - g_return_val_if_fail (OSS_IS_STREAM (mms), NULL); + g_return_if_fail (OSS_IS_STREAM (stream)); + g_return_if_fail (control == NULL || OSS_IS_STREAM_CONTROL (control)); + + if (control == NULL) + _mate_mixer_stream_set_default_control (MATE_MIXER_STREAM (stream), NULL); + else + _mate_mixer_stream_set_default_control (MATE_MIXER_STREAM (stream), + MATE_MIXER_STREAM_CONTROL (control)); +} - return MATE_MIXER_STREAM_CONTROL (OSS_STREAM (mms)->priv->control); +void +oss_stream_set_switch_data (OssStream *stream, gint fd, GList *options) +{ + g_return_if_fail (OSS_IS_STREAM (stream)); + g_return_if_fail (fd != -1); + g_return_if_fail (options != NULL); + + /* Function may only be called once */ + if G_UNLIKELY (stream->priv->swtch != NULL) { + g_warn_if_reached (); + return; + } + + /* Takes ownership of options */ + stream->priv->swtch = oss_switch_new (OSS_STREAM_SWITCH_NAME, + _("Capture Source"), + fd, + options); + + /* Read the active selection */ + oss_switch_load (stream->priv->swtch); + + stream->priv->switches = g_list_prepend (NULL, g_object_ref (stream->priv->swtch)); + g_signal_emit_by_name (G_OBJECT (stream), + "switch-added", + OSS_STREAM_SWITCH_NAME); } -static GList * -oss_stream_list_controls (MateMixerStream *mms) +void +oss_stream_remove_all (OssStream *stream) { GList *list; + g_return_if_fail (OSS_IS_STREAM (stream)); + + list = stream->priv->controls; + while (list != NULL) { + MateMixerStreamControl *control = MATE_MIXER_STREAM_CONTROL (list->data); + GList *next = list->next; + + oss_stream_control_close (OSS_STREAM_CONTROL (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 */ + oss_stream_set_default_control (stream, NULL); + + if (stream->priv->swtch != NULL) { + oss_switch_close (stream->priv->swtch); + + g_list_free_full (stream->priv->switches, g_object_unref); + stream->priv->switches = NULL; + + g_signal_emit_by_name (G_OBJECT (stream), + "switch-removed", + OSS_STREAM_SWITCH_NAME); + + g_clear_object (&stream->priv->swtch); + } +} + +static const GList * +oss_stream_list_controls (MateMixerStream *mms) +{ g_return_val_if_fail (OSS_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 (OSS_STREAM (mms)->priv->controls); - if (list != NULL) - g_list_foreach (list, (GFunc) g_object_ref, NULL); + return OSS_STREAM (mms)->priv->controls; +} + +static const GList * +oss_stream_list_switches (MateMixerStream *mms) +{ + g_return_val_if_fail (OSS_IS_STREAM (mms), NULL); - return list; + return OSS_STREAM (mms)->priv->switches; } |