summaryrefslogtreecommitdiff
path: root/libmatemixer/matemixer-device.c
diff options
context:
space:
mode:
Diffstat (limited to 'libmatemixer/matemixer-device.c')
-rw-r--r--libmatemixer/matemixer-device.c499
1 files changed, 391 insertions, 108 deletions
diff --git a/libmatemixer/matemixer-device.c b/libmatemixer/matemixer-device.c
index 87517d6..229110f 100644
--- a/libmatemixer/matemixer-device.c
+++ b/libmatemixer/matemixer-device.c
@@ -15,12 +15,14 @@
* 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-device-profile.h"
-#include "matemixer-port.h"
+#include "matemixer-stream.h"
+#include "matemixer-switch.h"
/**
* SECTION:matemixer-device
@@ -28,45 +30,270 @@
* @include: libmatemixer/matemixer.h
*/
-G_DEFINE_INTERFACE (MateMixerDevice, mate_mixer_device, G_TYPE_OBJECT)
+struct _MateMixerDevicePrivate
+{
+ gchar *name;
+ gchar *label;
+ gchar *icon;
+ GList *streams;
+ GList *switches;
+ GList *profiles;
+ MateMixerDeviceProfile *profile;
+};
+
+enum {
+ PROP_0,
+ PROP_NAME,
+ PROP_LABEL,
+ PROP_ICON,
+ PROP_ACTIVE_PROFILE,
+ N_PROPERTIES
+};
+
+static GParamSpec *properties[N_PROPERTIES] = { NULL, };
+
+enum {
+ STREAM_ADDED,
+ STREAM_REMOVED,
+ SWITCH_ADDED,
+ SWITCH_REMOVED,
+ N_SIGNALS
+};
+
+static guint signals[N_SIGNALS] = { 0, };
+
+static void mate_mixer_device_class_init (MateMixerDeviceClass *klass);
+
+static void mate_mixer_device_get_property (GObject *object,
+ guint param_id,
+ GValue *value,
+ GParamSpec *pspec);
+static void mate_mixer_device_set_property (GObject *object,
+ guint param_id,
+ const GValue *value,
+ GParamSpec *pspec);
+
+static void mate_mixer_device_init (MateMixerDevice *device);
+static void mate_mixer_device_dispose (GObject *object);
+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 MateMixerDeviceProfile *mate_mixer_device_real_get_profile (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_profile = mate_mixer_device_real_get_profile;
+
+ object_class = G_OBJECT_CLASS (klass);
+ object_class->dispose = mate_mixer_device_dispose;
+ 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;
+
+ properties[PROP_NAME] =
+ g_param_spec_string ("name",
+ "Name",
+ "Name of the device",
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS);
+
+ properties[PROP_LABEL] =
+ g_param_spec_string ("label",
+ "Label",
+ "Label of the device",
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS);
+
+ properties[PROP_ICON] =
+ g_param_spec_string ("icon",
+ "Icon",
+ "Name of the sound device icon",
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS);
+
+ properties[PROP_ACTIVE_PROFILE] =
+ g_param_spec_object ("active-profile",
+ "Active profile",
+ "The currently active profile of the device",
+ MATE_MIXER_TYPE_DEVICE_PROFILE,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS);
+
+ g_object_class_install_properties (object_class, N_PROPERTIES, properties);
+
+ signals[STREAM_ADDED] =
+ g_signal_new ("stream-added",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (MateMixerDeviceClass, stream_added),
+ NULL,
+ NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE,
+ 1,
+ G_TYPE_STRING);
+
+ signals[STREAM_REMOVED] =
+ g_signal_new ("stream-removed",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (MateMixerDeviceClass, stream_removed),
+ NULL,
+ NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE,
+ 1,
+ G_TYPE_STRING);
+
+ signals[SWITCH_ADDED] =
+ g_signal_new ("switch-added",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (MateMixerDeviceClass, switch_added),
+ NULL,
+ NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE,
+ 1,
+ G_TYPE_STRING);
+
+ signals[SWITCH_REMOVED] =
+ g_signal_new ("switch-removed",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (MateMixerDeviceClass, switch_removed),
+ NULL,
+ NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE,
+ 1,
+ G_TYPE_STRING);
+
+ g_type_class_add_private (object_class, sizeof (MateMixerDevicePrivate));
+}
+
+static void
+mate_mixer_device_get_property (GObject *object,
+ guint param_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ MateMixerDevice *device;
+
+ device = MATE_MIXER_DEVICE (object);
+
+ switch (param_id) {
+ case PROP_NAME:
+ g_value_set_string (value, device->priv->name);
+ break;
+ case PROP_LABEL:
+ g_value_set_string (value, device->priv->label);
+ break;
+ case PROP_ICON:
+ g_value_set_string (value, device->priv->icon);
+ break;
+ case PROP_ACTIVE_PROFILE:
+ g_value_set_object (value, device->priv->profile);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+ break;
+ }
+}
+
+static void
+mate_mixer_device_set_property (GObject *object,
+ guint param_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ MateMixerDevice *device;
+
+ device = MATE_MIXER_DEVICE (object);
+
+ switch (param_id) {
+ case PROP_NAME:
+ /* Construct-only string */
+ device->priv->name = g_strdup (g_value_get_string (value));
+ break;
+ case PROP_LABEL:
+ /* Construct-only string */
+ device->priv->label = g_strdup (g_value_get_string (value));
+ break;
+ case PROP_ICON:
+ /* Construct-only string */
+ device->priv->icon = g_strdup (g_value_get_string (value));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+ break;
+ }
+}
static void
-mate_mixer_device_default_init (MateMixerDeviceInterface *iface)
-{
- g_object_interface_install_property (iface,
- g_param_spec_string ("name",
- "Name",
- "Name of the device",
- NULL,
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_STRINGS));
-
- g_object_interface_install_property (iface,
- g_param_spec_string ("description",
- "Description",
- "Description of the device",
- NULL,
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_STRINGS));
-
- g_object_interface_install_property (iface,
- g_param_spec_string ("icon",
- "Icon",
- "Name of the sound device icon",
- NULL,
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_STRINGS));
-
- g_object_interface_install_property (iface,
- g_param_spec_object ("active-profile",
- "Active profile",
- "The currently active profile of the device",
- MATE_MIXER_TYPE_DEVICE_PROFILE,
- G_PARAM_READABLE |
- G_PARAM_STATIC_STRINGS));
+mate_mixer_device_init (MateMixerDevice *device)
+{
+ device->priv = G_TYPE_INSTANCE_GET_PRIVATE (device,
+ MATE_MIXER_TYPE_DEVICE,
+ MateMixerDevicePrivate);
+}
+
+static void
+mate_mixer_device_dispose (GObject *object)
+{
+ MateMixerDevice *device;
+
+ device = MATE_MIXER_DEVICE (object);
+
+ if (device->priv->streams != NULL) {
+ g_list_free_full (device->priv->streams, g_object_unref);
+ device->priv->streams = NULL;
+ }
+ if (device->priv->switches != NULL) {
+ g_list_free_full (device->priv->switches, g_object_unref);
+ device->priv->switches = NULL;
+ }
+ if (device->priv->profiles != NULL) {
+ g_list_free_full (device->priv->profiles, g_object_unref);
+ device->priv->profiles = NULL;
+ }
+
+ g_clear_object (&device->priv->profile);
+
+ G_OBJECT_CLASS (mate_mixer_device_parent_class)->dispose (object);
+}
+
+static void
+mate_mixer_device_finalize (GObject *object)
+{
+ MateMixerDevice *device;
+
+ device = MATE_MIXER_DEVICE (object);
+
+ g_free (device->priv->name);
+ g_free (device->priv->label);
+ g_free (device->priv->icon);
+
+ G_OBJECT_CLASS (mate_mixer_device_parent_class)->finalize (object);
}
/**
@@ -78,8 +305,7 @@ mate_mixer_device_get_name (MateMixerDevice *device)
{
g_return_val_if_fail (MATE_MIXER_IS_DEVICE (device), NULL);
- /* Implementation required */
- return MATE_MIXER_DEVICE_GET_INTERFACE (device)->get_name (device);
+ return device->priv->name;
}
/**
@@ -87,18 +313,11 @@ mate_mixer_device_get_name (MateMixerDevice *device)
* @device: a #MateMixerDevice
*/
const gchar *
-mate_mixer_device_get_description (MateMixerDevice *device)
+mate_mixer_device_get_label (MateMixerDevice *device)
{
- MateMixerDeviceInterface *iface;
-
g_return_val_if_fail (MATE_MIXER_IS_DEVICE (device), NULL);
- iface = MATE_MIXER_DEVICE_GET_INTERFACE (device);
-
- if (iface->get_description)
- return iface->get_description (device);
-
- return NULL;
+ return device->priv->label;
}
/**
@@ -108,77 +327,80 @@ mate_mixer_device_get_description (MateMixerDevice *device)
const gchar *
mate_mixer_device_get_icon (MateMixerDevice *device)
{
- MateMixerDeviceInterface *iface;
-
g_return_val_if_fail (MATE_MIXER_IS_DEVICE (device), NULL);
- iface = MATE_MIXER_DEVICE_GET_INTERFACE (device);
-
- if (iface->get_icon)
- return iface->get_icon (device);
-
- return NULL;
+ return device->priv->icon;
}
/**
- * mate_mixer_device_get_port:
+ * mate_mixer_device_get_profile:
* @device: a #MateMixerDevice
- * @name: a port name
+ * @name: a profile name
*/
-MateMixerPort *
-mate_mixer_device_get_port (MateMixerDevice *device, const gchar *name)
+MateMixerDeviceProfile *
+mate_mixer_device_get_profile (MateMixerDevice *device, const gchar *name)
{
- MateMixerDeviceInterface *iface;
-
- g_return_val_if_fail (MATE_MIXER_IS_DEVICE (device), NULL);
- g_return_val_if_fail (name != NULL, NULL);
-
- iface = MATE_MIXER_DEVICE_GET_INTERFACE (device);
-
- if (iface->get_port)
- return iface->get_port (device, name);
+ return MATE_MIXER_DEVICE_GET_CLASS (device)->get_profile (device, name);
+}
- return NULL;
+/**
+ * mate_mixer_device_get_stream:
+ * @device: a #MateMixerDevice
+ * @name: a profile name
+ */
+MateMixerStream *
+mate_mixer_device_get_stream (MateMixerDevice *device, const gchar *name)
+{
+ return MATE_MIXER_DEVICE_GET_CLASS (device)->get_stream (device, name);
}
/**
- * mate_mixer_device_get_profile:
+ * mate_mixer_device_get_switch:
* @device: a #MateMixerDevice
* @name: a profile name
*/
-MateMixerDeviceProfile *
-mate_mixer_device_get_profile (MateMixerDevice *device, const gchar *name)
+MateMixerSwitch *
+mate_mixer_device_get_switch (MateMixerDevice *device, const gchar *name)
{
- MateMixerDeviceInterface *iface;
+ return MATE_MIXER_DEVICE_GET_CLASS (device)->get_switch (device, name);
+}
+/**
+ * mate_mixer_device_list_streams:
+ * @device: a #MateMixerDevice
+ */
+const GList *
+mate_mixer_device_list_streams (MateMixerDevice *device)
+{
g_return_val_if_fail (MATE_MIXER_IS_DEVICE (device), NULL);
- g_return_val_if_fail (name != NULL, NULL);
- iface = MATE_MIXER_DEVICE_GET_INTERFACE (device);
+ if (device->priv->streams == NULL) {
+ MateMixerDeviceClass *klass = MATE_MIXER_DEVICE_GET_CLASS (device);
- if (iface->get_profile)
- return iface->get_profile (device, name);
+ if (klass->list_streams != NULL)
+ device->priv->streams = klass->list_streams (device);
+ }
- return NULL;
+ return (const GList *) device->priv->streams;
}
/**
- * mate_mixer_device_list_ports:
+ * mate_mixer_device_list_switches:
* @device: a #MateMixerDevice
*/
const GList *
-mate_mixer_device_list_ports (MateMixerDevice *device)
+mate_mixer_device_list_switches (MateMixerDevice *device)
{
- MateMixerDeviceInterface *iface;
-
g_return_val_if_fail (MATE_MIXER_IS_DEVICE (device), NULL);
- iface = MATE_MIXER_DEVICE_GET_INTERFACE (device);
+ if (device->priv->switches == NULL) {
+ MateMixerDeviceClass *klass = MATE_MIXER_DEVICE_GET_CLASS (device);
- if (iface->list_ports)
- return iface->list_ports (device);
+ if (klass->list_switches != NULL)
+ device->priv->switches = klass->list_switches (device);
+ }
- return NULL;
+ return (const GList *) device->priv->switches;
}
/**
@@ -188,16 +410,16 @@ mate_mixer_device_list_ports (MateMixerDevice *device)
const GList *
mate_mixer_device_list_profiles (MateMixerDevice *device)
{
- MateMixerDeviceInterface *iface;
-
g_return_val_if_fail (MATE_MIXER_IS_DEVICE (device), NULL);
- iface = MATE_MIXER_DEVICE_GET_INTERFACE (device);
+ if (device->priv->profiles == NULL) {
+ MateMixerDeviceClass *klass = MATE_MIXER_DEVICE_GET_CLASS (device);
- if (iface->list_profiles)
- return iface->list_profiles (device);
+ if (klass->list_profiles != NULL)
+ device->priv->profiles = klass->list_profiles (device);
+ }
- return NULL;
+ return (const GList *) device->priv->profiles;
}
/**
@@ -207,16 +429,9 @@ mate_mixer_device_list_profiles (MateMixerDevice *device)
MateMixerDeviceProfile *
mate_mixer_device_get_active_profile (MateMixerDevice *device)
{
- MateMixerDeviceInterface *iface;
-
g_return_val_if_fail (MATE_MIXER_IS_DEVICE (device), NULL);
- iface = MATE_MIXER_DEVICE_GET_INTERFACE (device);
-
- if (iface->get_active_profile)
- return iface->get_active_profile (device);
-
- return NULL;
+ return device->priv->profile;
}
/**
@@ -228,15 +443,83 @@ gboolean
mate_mixer_device_set_active_profile (MateMixerDevice *device,
MateMixerDeviceProfile *profile)
{
- MateMixerDeviceInterface *iface;
-
g_return_val_if_fail (MATE_MIXER_IS_DEVICE (device), FALSE);
g_return_val_if_fail (MATE_MIXER_IS_DEVICE_PROFILE (profile), FALSE);
- iface = MATE_MIXER_DEVICE_GET_INTERFACE (device);
+ if (profile != device->priv->profile) {
+ MateMixerDeviceClass *klass;
+
+ klass = MATE_MIXER_DEVICE_GET_CLASS (device);
+
+ if (klass->set_active_profile == NULL ||
+ klass->set_active_profile (device, profile) == FALSE)
+ return FALSE;
- if (iface->set_active_profile)
- return iface->set_active_profile (device, profile);
+ if (G_LIKELY (device->priv->profile != NULL))
+ g_object_unref (device->priv->profile);
- return FALSE;
+ device->priv->profile = g_object_ref (profile);
+ }
+
+ return TRUE;
+}
+
+static MateMixerStream *
+mate_mixer_device_real_get_stream (MateMixerDevice *device, const gchar *name)
+{
+ const GList *list;
+
+ g_return_val_if_fail (MATE_MIXER_IS_DEVICE (device), NULL);
+ g_return_val_if_fail (name != NULL, NULL);
+
+ list = mate_mixer_device_list_streams (device);
+ while (list != NULL) {
+ MateMixerStream *stream = MATE_MIXER_STREAM (list->data);
+
+ if (strcmp (name, mate_mixer_stream_get_name (stream)) == 0)
+ return stream;
+
+ list = list->next;
+ }
+ return NULL;
+}
+
+static MateMixerSwitch *
+mate_mixer_device_real_get_switch (MateMixerDevice *device, const gchar *name)
+{
+ const GList *list;
+
+ g_return_val_if_fail (MATE_MIXER_IS_DEVICE (device), NULL);
+ g_return_val_if_fail (name != NULL, NULL);
+
+ list = mate_mixer_device_list_switches (device);
+ while (list != NULL) {
+ MateMixerSwitch *swtch = MATE_MIXER_SWITCH (list->data);
+
+ if (strcmp (name, mate_mixer_switch_get_name (swtch)) == 0)
+ return swtch;
+
+ list = list->next;
+ }
+ return NULL;
+}
+
+static MateMixerDeviceProfile *
+mate_mixer_device_real_get_profile (MateMixerDevice *device, const gchar *name)
+{
+ const GList *list;
+
+ g_return_val_if_fail (MATE_MIXER_IS_DEVICE (device), NULL);
+ g_return_val_if_fail (name != NULL, NULL);
+
+ list = mate_mixer_device_list_profiles (device);
+ while (list != NULL) {
+ MateMixerDeviceProfile *profile = MATE_MIXER_DEVICE_PROFILE (list->data);
+
+ if (strcmp (name, mate_mixer_device_profile_get_name (profile)) == 0)
+ return profile;
+
+ list = list->next;
+ }
+ return NULL;
}