diff options
Diffstat (limited to 'libmatemixer/matemixer-stream.c')
-rw-r--r-- | libmatemixer/matemixer-stream.c | 444 |
1 files changed, 257 insertions, 187 deletions
diff --git a/libmatemixer/matemixer-stream.c b/libmatemixer/matemixer-stream.c index 888fddb..1902de3 100644 --- a/libmatemixer/matemixer-stream.c +++ b/libmatemixer/matemixer-stream.c @@ -15,20 +15,44 @@ * License along with this library; if not, see <http://www.gnu.org/licenses/>. */ +#include <string.h> #include <glib.h> #include <glib-object.h> #include "matemixer-device.h" #include "matemixer-enums.h" #include "matemixer-enum-types.h" -#include "matemixer-port.h" #include "matemixer-stream.h" +#include "matemixer-stream-control.h" +#include "matemixer-switch.h" /** * SECTION:matemixer-stream * @include: libmatemixer/matemixer.h */ +struct _MateMixerStreamPrivate +{ + gchar *name; + GList *controls; + GList *switches; + gboolean monitor_enabled; + MateMixerDevice *device; + MateMixerStreamFlags flags; + MateMixerStreamState state; +}; + +enum { + PROP_0, + PROP_NAME, + PROP_DEVICE, + PROP_FLAGS, + PROP_STATE, + N_PROPERTIES +}; + +static GParamSpec *properties[N_PROPERTIES] = { NULL, }; + enum { MONITOR_VALUE, N_SIGNALS @@ -36,245 +60,285 @@ enum { static guint signals[N_SIGNALS] = { 0, }; -G_DEFINE_INTERFACE (MateMixerStream, mate_mixer_stream, G_TYPE_OBJECT) +static void mate_mixer_stream_class_init (MateMixerStreamClass *klass); + +static void mate_mixer_stream_get_property (GObject *object, + guint param_id, + GValue *value, + GParamSpec *pspec); +static void mate_mixer_stream_set_property (GObject *object, + guint param_id, + const GValue *value, + GParamSpec *pspec); + +static void mate_mixer_stream_init (MateMixerStream *stream); +static void mate_mixer_stream_dispose (GObject *object); +static void mate_mixer_stream_finalize (GObject *object); + +G_DEFINE_ABSTRACT_TYPE (MateMixerStream, mate_mixer_stream, G_TYPE_OBJECT) + +static MateMixerStreamControl *mate_mixer_stream_real_get_control (MateMixerStream *stream, + const gchar *name); +static MateMixerSwitch * mate_mixer_stream_real_get_switch (MateMixerStream *stream, + const gchar *name); static void -mate_mixer_stream_default_init (MateMixerStreamInterface *iface) +mate_mixer_stream_class_init (MateMixerStreamClass *klass) { - g_object_interface_install_property (iface, - g_param_spec_string ("name", - "Name", - "Name of the stream", - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); - - g_object_interface_install_property (iface, - g_param_spec_string ("description", - "Description", - "Description of the stream", - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); - - g_object_interface_install_property (iface, - g_param_spec_object ("device", - "Device", - "Device the stream belongs to", - MATE_MIXER_TYPE_DEVICE, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); - - g_object_interface_install_property (iface, - g_param_spec_flags ("flags", - "Flags", - "Capability flags of the stream", - MATE_MIXER_TYPE_STREAM_FLAGS, - MATE_MIXER_STREAM_NO_FLAGS, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); - - g_object_interface_install_property (iface, - g_param_spec_enum ("state", - "State", - "Current state of the stream", - MATE_MIXER_TYPE_STREAM_STATE, - MATE_MIXER_STREAM_STATE_UNKNOWN, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); - - g_object_interface_install_property (iface, - g_param_spec_object ("active-port", - "Active port", - "The currently active port of the stream", - MATE_MIXER_TYPE_PORT, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); + GObjectClass *object_class; + + klass->get_control = mate_mixer_stream_real_get_control; + klass->get_switch = mate_mixer_stream_real_get_switch; + + object_class = G_OBJECT_CLASS (klass); + object_class->dispose = mate_mixer_stream_dispose; + object_class->finalize = mate_mixer_stream_finalize; + object_class->get_property = mate_mixer_stream_get_property; + object_class->set_property = mate_mixer_stream_set_property; + + properties[PROP_NAME] = + g_param_spec_string ("name", + "Name", + "Name of the stream", + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + + properties[PROP_DEVICE] = + g_param_spec_object ("device", + "Device", + "Device the stream belongs to", + MATE_MIXER_TYPE_DEVICE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + + properties[PROP_FLAGS] = + g_param_spec_flags ("flags", + "Flags", + "Capability flags of the stream", + MATE_MIXER_TYPE_STREAM_FLAGS, + MATE_MIXER_STREAM_NO_FLAGS, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + + properties[PROP_STATE] = + g_param_spec_enum ("state", + "State", + "Current state of the stream", + MATE_MIXER_TYPE_STREAM_STATE, + MATE_MIXER_STREAM_STATE_UNKNOWN, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties (object_class, N_PROPERTIES, properties); signals[MONITOR_VALUE] = g_signal_new ("monitor-value", - G_TYPE_FROM_INTERFACE (iface), + G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (MateMixerStreamInterface, monitor_value), + G_STRUCT_OFFSET (MateMixerStreamClass, monitor_value), NULL, NULL, g_cclosure_marshal_VOID__DOUBLE, G_TYPE_NONE, 1, G_TYPE_DOUBLE); + + g_type_class_add_private (object_class, sizeof (MateMixerStreamPrivate)); } -const gchar * -mate_mixer_stream_get_name (MateMixerStream *stream) +static void +mate_mixer_stream_get_property (GObject *object, + guint param_id, + GValue *value, + GParamSpec *pspec) { - g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), NULL); - - /* Implementation required */ - return MATE_MIXER_STREAM_GET_INTERFACE (stream)->get_name (stream); + MateMixerStream *stream; + + stream = MATE_MIXER_STREAM (object); + + switch (param_id) { + case PROP_NAME: + g_value_set_string (value, stream->priv->name); + break; + case PROP_DEVICE: + g_value_set_object (value, stream->priv->device); + break; + case PROP_FLAGS: + g_value_set_flags (value, stream->priv->flags); + break; + case PROP_STATE: + g_value_set_enum (value, stream->priv->state); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); + break; + } } -const gchar * -mate_mixer_stream_get_description (MateMixerStream *stream) +static void +mate_mixer_stream_set_property (GObject *object, + guint param_id, + const GValue *value, + GParamSpec *pspec) { - g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), NULL); - - /* Implementation required */ - return MATE_MIXER_STREAM_GET_INTERFACE (stream)->get_description (stream); + MateMixerStream *stream; + + stream = MATE_MIXER_STREAM (object); + + switch (param_id) { + case PROP_NAME: + /* Construct-only string */ + stream->priv->name = g_value_dup_string (value); + break; + case PROP_DEVICE: + /* Construct-only object */ + stream->priv->device = g_value_dup_object (value); + break; + case PROP_FLAGS: + stream->priv->flags = g_value_get_flags (value); + break; + case PROP_STATE: + stream->priv->state = g_value_get_enum (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); + break; + } } -MateMixerDevice * -mate_mixer_stream_get_device (MateMixerStream *stream) +static void +mate_mixer_stream_init (MateMixerStream *stream) { - MateMixerDevice *device = NULL; - - g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), NULL); - - g_object_get (G_OBJECT (stream), - "device", &device, - NULL); - - if (device != NULL) - g_object_unref (device); - - return device; - + stream->priv = G_TYPE_INSTANCE_GET_PRIVATE (stream, + MATE_MIXER_TYPE_STREAM, + MateMixerStreamPrivate); } -MateMixerStreamFlags -mate_mixer_stream_get_flags (MateMixerStream *stream) +static void +mate_mixer_stream_dispose (GObject *object) { - MateMixerStreamFlags flags = MATE_MIXER_STREAM_NO_FLAGS; + MateMixerStream *stream; - g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), MATE_MIXER_STREAM_NO_FLAGS); + stream = MATE_MIXER_STREAM (object); - g_object_get (G_OBJECT (stream), - "flags", &flags, - NULL); + g_clear_object (&stream->priv->device); - return flags; + G_OBJECT_CLASS (mate_mixer_stream_parent_class)->dispose (object); } -MateMixerStreamState -mate_mixer_stream_get_state (MateMixerStream *stream) +static void +mate_mixer_stream_finalize (GObject *object) { - MateMixerStreamState state = MATE_MIXER_STREAM_STATE_UNKNOWN; + MateMixerStream *stream; - g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), MATE_MIXER_STREAM_STATE_UNKNOWN); + stream = MATE_MIXER_STREAM (object); - g_object_get (G_OBJECT (stream), - "state", &state, - NULL); + g_free (stream->priv->name); - return state; + G_OBJECT_CLASS (mate_mixer_stream_parent_class)->finalize (object); } -MateMixerStreamControl * -mate_mixer_stream_get_control (MateMixerStream *stream, const gchar *name) +const gchar * +mate_mixer_stream_get_name (MateMixerStream *stream) { g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), NULL); - /* Implementation required */ - return MATE_MIXER_STREAM_GET_INTERFACE (stream)->get_control (stream, name); + return stream->priv->name; } -MateMixerStreamControl * -mate_mixer_stream_get_default_control (MateMixerStream *stream) +MateMixerDevice * +mate_mixer_stream_get_device (MateMixerStream *stream) { g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), NULL); - /* Implementation required */ - return MATE_MIXER_STREAM_GET_INTERFACE (stream)->get_default_control (stream); + return stream->priv->device; } -MateMixerPort * -mate_mixer_stream_get_port (MateMixerStream *stream, const gchar *name) +MateMixerStreamFlags +mate_mixer_stream_get_flags (MateMixerStream *stream) { - MateMixerStreamInterface *iface; - - g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), NULL); + g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), MATE_MIXER_STREAM_NO_FLAGS); - iface = MATE_MIXER_STREAM_GET_INTERFACE (stream); + return stream->priv->flags; +} - if (iface->get_port != NULL) - return iface->get_port (stream, name); +MateMixerStreamState +mate_mixer_stream_get_state (MateMixerStream *stream) +{ + g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), MATE_MIXER_STREAM_STATE_UNKNOWN); - return FALSE; + return stream->priv->state; } -MateMixerPort * -mate_mixer_stream_get_active_port (MateMixerStream *stream) +MateMixerStreamControl * +mate_mixer_stream_get_control (MateMixerStream *stream, const gchar *name) { - MateMixerPort *port = NULL; - g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), NULL); + g_return_val_if_fail (name != NULL, NULL); - g_object_get (G_OBJECT (stream), - "active-port", &port, - NULL); - - if (port != NULL) - g_object_unref (port); - - return port; + return MATE_MIXER_STREAM_GET_CLASS (stream)->get_control (stream, name); } -gboolean -mate_mixer_stream_set_active_port (MateMixerStream *stream, MateMixerPort *port) +MateMixerSwitch * +mate_mixer_stream_get_switch (MateMixerStream *stream, const gchar *name) { - MateMixerStreamInterface *iface; - - g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), FALSE); - g_return_val_if_fail (MATE_MIXER_IS_PORT (port), FALSE); + g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), NULL); + g_return_val_if_fail (name != NULL, NULL); - iface = MATE_MIXER_STREAM_GET_INTERFACE (stream); + return MATE_MIXER_STREAM_GET_CLASS (stream)->get_switch (stream, name); +} - if (iface->set_active_port != NULL) - return iface->set_active_port (stream, port); +MateMixerStreamControl * +mate_mixer_stream_get_default_control (MateMixerStream *stream) +{ + g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), NULL); - return FALSE; + return MATE_MIXER_STREAM_GET_CLASS (stream)->get_default_control (stream); } const GList * mate_mixer_stream_list_controls (MateMixerStream *stream) { - MateMixerStreamInterface *iface; - g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), NULL); - iface = MATE_MIXER_STREAM_GET_INTERFACE (stream); - - if (iface->list_controls != NULL) - return iface->list_controls (stream); + if (stream->priv->controls == NULL) + stream->priv->controls = MATE_MIXER_STREAM_GET_CLASS (stream)->list_controls (stream); - return NULL; + return (const GList *) stream->priv->controls; } const GList * -mate_mixer_stream_list_ports (MateMixerStream *stream) +mate_mixer_stream_list_switches (MateMixerStream *stream) { - MateMixerStreamInterface *iface; - g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), NULL); - iface = MATE_MIXER_STREAM_GET_INTERFACE (stream); + if (stream->priv->switches == NULL) { + MateMixerStreamClass *klass = MATE_MIXER_STREAM_GET_CLASS (stream); - if (iface->list_ports != NULL) - return iface->list_ports (stream); + if (klass->list_switches != NULL) + stream->priv->switches = klass->list_switches (stream); + } - return NULL; + return (const GList *) stream->priv->switches; } gboolean mate_mixer_stream_suspend (MateMixerStream *stream) { - MateMixerStreamInterface *iface; - g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), FALSE); - iface = MATE_MIXER_STREAM_GET_INTERFACE (stream); + if (stream->priv->state == MATE_MIXER_STREAM_STATE_SUSPENDED) + return TRUE; - if (iface->suspend != NULL) - return iface->suspend (stream); + if (stream->priv->flags & MATE_MIXER_STREAM_CAN_SUSPEND) + return MATE_MIXER_STREAM_GET_CLASS (stream)->suspend (stream); return FALSE; } @@ -282,14 +346,13 @@ mate_mixer_stream_suspend (MateMixerStream *stream) gboolean mate_mixer_stream_resume (MateMixerStream *stream) { - MateMixerStreamInterface *iface; - g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), FALSE); - iface = MATE_MIXER_STREAM_GET_INTERFACE (stream); + if (stream->priv->state != MATE_MIXER_STREAM_STATE_SUSPENDED) + return TRUE; - if (iface->resume != NULL) - return iface->resume (stream); + if (stream->priv->flags & MATE_MIXER_STREAM_CAN_SUSPEND) + return MATE_MIXER_STREAM_GET_CLASS (stream)->resume (stream); return FALSE; } @@ -297,58 +360,65 @@ mate_mixer_stream_resume (MateMixerStream *stream) gboolean mate_mixer_stream_monitor_get_enabled (MateMixerStream *stream) { - gboolean enabled = FALSE; - g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), FALSE); - g_object_get (G_OBJECT (stream), - "monitor-enabled", &enabled, - NULL); - - return enabled; + return stream->priv->monitor_enabled; } gboolean mate_mixer_stream_monitor_set_enabled (MateMixerStream *stream, gboolean enabled) { - MateMixerStreamInterface *iface; - g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), FALSE); - iface = MATE_MIXER_STREAM_GET_INTERFACE (stream); + if (stream->priv->monitor_enabled == enabled) + return TRUE; - if (iface->monitor_set_enabled != NULL) - return iface->monitor_set_enabled (stream, enabled); + if (stream->priv->flags & MATE_MIXER_STREAM_HAS_MONITOR) { + if (enabled) + return MATE_MIXER_STREAM_GET_CLASS (stream)->monitor_start (stream); + else + return MATE_MIXER_STREAM_GET_CLASS (stream)->monitor_stop (stream); + } return FALSE; } -const gchar * -mate_mixer_stream_monitor_get_name (MateMixerStream *stream) +static MateMixerStreamControl * +mate_mixer_stream_real_get_control (MateMixerStream *stream, const gchar *name) { - MateMixerStreamInterface *iface; + const GList *list; g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), NULL); + g_return_val_if_fail (name != NULL, NULL); - iface = MATE_MIXER_STREAM_GET_INTERFACE (stream); + list = mate_mixer_stream_list_controls (stream); + while (list != NULL) { + MateMixerStreamControl *control = MATE_MIXER_STREAM_CONTROL (list->data); - if (iface->monitor_get_name != NULL) - return iface->monitor_get_name (stream); + if (strcmp (name, mate_mixer_stream_control_get_name (control)) == 0) + return control; - return FALSE; + list = list->next; + } + return NULL; } -gboolean -mate_mixer_stream_monitor_set_name (MateMixerStream *stream, const gchar *name) +static MateMixerSwitch * +mate_mixer_stream_real_get_switch (MateMixerStream *stream, const gchar *name) { - MateMixerStreamInterface *iface; + const GList *list; - g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), FALSE); + g_return_val_if_fail (MATE_MIXER_IS_STREAM (stream), NULL); + g_return_val_if_fail (name != NULL, NULL); - iface = MATE_MIXER_STREAM_GET_INTERFACE (stream); + list = mate_mixer_stream_list_switches (stream); + while (list != NULL) { + MateMixerSwitch *swtch = MATE_MIXER_SWITCH (list->data); - if (iface->monitor_set_name != NULL) - return iface->monitor_set_name (stream, name); + if (strcmp (name, mate_mixer_switch_get_name (swtch)) == 0) + return swtch; - return FALSE; + list = list->next; + } + return NULL; } |