summaryrefslogtreecommitdiff
path: root/backends/oss/oss-device.c
diff options
context:
space:
mode:
authorMichal Ratajsky <[email protected]>2014-08-12 04:56:55 +0200
committerMichal Ratajsky <[email protected]>2014-08-12 04:56:55 +0200
commit6c6d4239ddc807e922df3874654f99eea291aadb (patch)
tree558f48fc965476344a946d93088680db3b5bac41 /backends/oss/oss-device.c
parent8436ec1641eee8868128755f6d1475230cea25e6 (diff)
downloadlibmatemixer-6c6d4239ddc807e922df3874654f99eea291aadb.tar.bz2
libmatemixer-6c6d4239ddc807e922df3874654f99eea291aadb.tar.xz
Add ALSA, improve OSS and remove OSS4
Diffstat (limited to 'backends/oss/oss-device.c')
-rw-r--r--backends/oss/oss-device.c609
1 files changed, 244 insertions, 365 deletions
diff --git a/backends/oss/oss-device.c b/backends/oss/oss-device.c
index f33ff57..cf51705 100644
--- a/backends/oss/oss-device.c
+++ b/backends/oss/oss-device.c
@@ -22,12 +22,8 @@
#include <glib/gstdio.h>
#include <glib-object.h>
-#include <libmatemixer/matemixer-device.h>
-#include <libmatemixer/matemixer-enums.h>
-#include <libmatemixer/matemixer-port.h>
-#include <libmatemixer/matemixer-port-private.h>
-#include <libmatemixer/matemixer-stream.h>
-#include <libmatemixer/matemixer-stream-control.h>
+#include <libmatemixer/matemixer.h>
+#include <libmatemixer/matemixer-private.h>
#include "oss-common.h"
#include "oss-device.h"
@@ -36,490 +32,373 @@
#define OSS_DEVICE_ICON "audio-card"
+typedef enum
+{
+ OSS_DEV_ANY,
+ OSS_DEV_INPUT,
+ OSS_DEV_OUTPUT
+} OssDevType;
+
typedef struct
{
gchar *name;
- gchar *description;
+ gchar *label;
MateMixerStreamControlRole role;
- MateMixerStreamFlags flags;
-} OssDeviceName;
-
-static const OssDeviceName const oss_devices[] = {
- { "vol", N_("Volume"), MATE_MIXER_STREAM_CONTROL_ROLE_MASTER, MATE_MIXER_STREAM_OUTPUT },
- { "bass", N_("Bass"), MATE_MIXER_STREAM_CONTROL_ROLE_BASS, MATE_MIXER_STREAM_OUTPUT },
- { "treble", N_("Treble"), MATE_MIXER_STREAM_CONTROL_ROLE_TREBLE, MATE_MIXER_STREAM_OUTPUT },
- { "synth", N_("Synth"), MATE_MIXER_STREAM_CONTROL_ROLE_UNKNOWN, MATE_MIXER_STREAM_INPUT },
- { "pcm", N_("PCM"), MATE_MIXER_STREAM_CONTROL_ROLE_PCM, MATE_MIXER_STREAM_OUTPUT },
- { "speaker", N_("Speaker"), MATE_MIXER_STREAM_CONTROL_ROLE_SPEAKER, MATE_MIXER_STREAM_OUTPUT },
- { "line", N_("Line-in"), MATE_MIXER_STREAM_CONTROL_ROLE_PORT, MATE_MIXER_STREAM_INPUT },
- { "mic", N_("Microphone"), MATE_MIXER_STREAM_CONTROL_ROLE_PORT, MATE_MIXER_STREAM_INPUT },
- { "cd", N_("CD"), MATE_MIXER_STREAM_CONTROL_ROLE_CD, MATE_MIXER_STREAM_INPUT },
+ OssDevType type;
+} OssDev;
+
+static const OssDev oss_devices[] = {
+ { "vol", N_("Volume"), MATE_MIXER_STREAM_CONTROL_ROLE_MASTER, OSS_DEV_OUTPUT },
+ { "bass", N_("Bass"), MATE_MIXER_STREAM_CONTROL_ROLE_BASS, OSS_DEV_OUTPUT },
+ { "treble", N_("Treble"), MATE_MIXER_STREAM_CONTROL_ROLE_TREBLE, OSS_DEV_OUTPUT },
+ { "synth", N_("Synth"), MATE_MIXER_STREAM_CONTROL_ROLE_UNKNOWN, OSS_DEV_INPUT },
+ { "pcm", N_("PCM"), MATE_MIXER_STREAM_CONTROL_ROLE_PCM, OSS_DEV_OUTPUT },
+ /* OSS manual says this should be the beeper, but Linux OSS seems to assign it to
+ * regular volume control */
+ { "speaker", N_("Speaker"), MATE_MIXER_STREAM_CONTROL_ROLE_SPEAKER, OSS_DEV_OUTPUT },
+ { "line", N_("Line-in"), MATE_MIXER_STREAM_CONTROL_ROLE_PORT, OSS_DEV_INPUT },
+ { "mic", N_("Microphone"), MATE_MIXER_STREAM_CONTROL_ROLE_PORT, OSS_DEV_INPUT },
+ { "cd", N_("CD"), MATE_MIXER_STREAM_CONTROL_ROLE_CD, OSS_DEV_INPUT },
/* Recording monitor */
- { "mix", N_("Mixer"), MATE_MIXER_STREAM_CONTROL_ROLE_UNKNOWN, MATE_MIXER_STREAM_OUTPUT },
- { "pcm2", N_("PCM-2"), MATE_MIXER_STREAM_CONTROL_ROLE_PCM, MATE_MIXER_STREAM_OUTPUT },
+ { "mix", N_("Mixer"), MATE_MIXER_STREAM_CONTROL_ROLE_UNKNOWN, OSS_DEV_OUTPUT },
+ { "pcm2", N_("PCM-2"), MATE_MIXER_STREAM_CONTROL_ROLE_PCM, OSS_DEV_OUTPUT },
/* Recording level (master input) */
- { "rec", N_("Record"), MATE_MIXER_STREAM_CONTROL_ROLE_MASTER, MATE_MIXER_STREAM_INPUT },
- { "igain", N_("In-gain"), MATE_MIXER_STREAM_CONTROL_ROLE_UNKNOWN, MATE_MIXER_STREAM_INPUT },
- { "ogain", N_("Out-gain"), MATE_MIXER_STREAM_CONTROL_ROLE_UNKNOWN, MATE_MIXER_STREAM_OUTPUT },
- { "line1", N_("Line-1"), MATE_MIXER_STREAM_CONTROL_ROLE_PORT, MATE_MIXER_STREAM_INPUT },
- { "line2", N_("Line-2"), MATE_MIXER_STREAM_CONTROL_ROLE_PORT, MATE_MIXER_STREAM_INPUT },
- { "line3", N_("Line-3"), MATE_MIXER_STREAM_CONTROL_ROLE_PORT, MATE_MIXER_STREAM_INPUT },
- { "dig1", N_("Digital-1"), MATE_MIXER_STREAM_CONTROL_ROLE_PORT, MATE_MIXER_STREAM_NO_FLAGS },
- { "dig2", N_("Digital-2"), MATE_MIXER_STREAM_CONTROL_ROLE_PORT, MATE_MIXER_STREAM_NO_FLAGS },
- { "dig3", N_("Digital-3"), MATE_MIXER_STREAM_CONTROL_ROLE_PORT, MATE_MIXER_STREAM_NO_FLAGS },
- { "phin", N_("Phone-in"), MATE_MIXER_STREAM_CONTROL_ROLE_PORT, MATE_MIXER_STREAM_INPUT },
- { "phout", N_("Phone-out"), MATE_MIXER_STREAM_CONTROL_ROLE_PORT, MATE_MIXER_STREAM_OUTPUT },
- { "video", N_("Video"), MATE_MIXER_STREAM_CONTROL_ROLE_PORT, MATE_MIXER_STREAM_INPUT },
- { "radio", N_("Radio"), MATE_MIXER_STREAM_CONTROL_ROLE_PORT, MATE_MIXER_STREAM_INPUT },
- { "monitor", N_("Monitor"), MATE_MIXER_STREAM_CONTROL_ROLE_UNKNOWN, MATE_MIXER_STREAM_OUTPUT },
- { "depth", N_("3D-depth"), MATE_MIXER_STREAM_CONTROL_ROLE_UNKNOWN, MATE_MIXER_STREAM_OUTPUT },
- { "center", N_("3D-center"), MATE_MIXER_STREAM_CONTROL_ROLE_UNKNOWN, MATE_MIXER_STREAM_OUTPUT },
- { "midi", N_("MIDI"), MATE_MIXER_STREAM_CONTROL_ROLE_UNKNOWN, MATE_MIXER_STREAM_INPUT }
+ { "rec", N_("Record"), MATE_MIXER_STREAM_CONTROL_ROLE_MASTER, OSS_DEV_INPUT },
+ { "igain", N_("In-gain"), MATE_MIXER_STREAM_CONTROL_ROLE_UNKNOWN, OSS_DEV_INPUT },
+ { "ogain", N_("Out-gain"), MATE_MIXER_STREAM_CONTROL_ROLE_UNKNOWN, OSS_DEV_OUTPUT },
+ { "line1", N_("Line-1"), MATE_MIXER_STREAM_CONTROL_ROLE_PORT, OSS_DEV_INPUT },
+ { "line2", N_("Line-2"), MATE_MIXER_STREAM_CONTROL_ROLE_PORT, OSS_DEV_INPUT },
+ { "line3", N_("Line-3"), MATE_MIXER_STREAM_CONTROL_ROLE_PORT, OSS_DEV_INPUT },
+ { "dig1", N_("Digital-1"), MATE_MIXER_STREAM_CONTROL_ROLE_PORT, OSS_DEV_ANY },
+ { "dig2", N_("Digital-2"), MATE_MIXER_STREAM_CONTROL_ROLE_PORT, OSS_DEV_ANY },
+ { "dig3", N_("Digital-3"), MATE_MIXER_STREAM_CONTROL_ROLE_PORT, OSS_DEV_ANY },
+ { "phin", N_("Phone-in"), MATE_MIXER_STREAM_CONTROL_ROLE_PORT, OSS_DEV_INPUT },
+ { "phout", N_("Phone-out"), MATE_MIXER_STREAM_CONTROL_ROLE_PORT, OSS_DEV_OUTPUT },
+ { "video", N_("Video"), MATE_MIXER_STREAM_CONTROL_ROLE_PORT, OSS_DEV_INPUT },
+ { "radio", N_("Radio"), MATE_MIXER_STREAM_CONTROL_ROLE_PORT, OSS_DEV_INPUT },
+ { "monitor", N_("Monitor"), MATE_MIXER_STREAM_CONTROL_ROLE_UNKNOWN, OSS_DEV_OUTPUT },
+ { "depth", N_("3D-depth"), MATE_MIXER_STREAM_CONTROL_ROLE_UNKNOWN, OSS_DEV_OUTPUT },
+ { "center", N_("3D-center"), MATE_MIXER_STREAM_CONTROL_ROLE_UNKNOWN, OSS_DEV_OUTPUT },
+ { "midi", N_("MIDI"), MATE_MIXER_STREAM_CONTROL_ROLE_UNKNOWN, OSS_DEV_INPUT }
};
+#define OSS_N_DEVICES MIN (G_N_ELEMENTS (oss_devices), SOUND_MIXER_NRDEVICES)
+
struct _OssDevicePrivate
{
- gint fd;
- gchar *path;
- gchar *name;
- gchar *description;
- MateMixerStream *input;
- MateMixerStream *output;
-};
-
-enum {
- PROP_0,
- PROP_NAME,
- PROP_DESCRIPTION,
- PROP_ICON,
- PROP_ACTIVE_PROFILE,
- PROP_PATH,
- PROP_FD
+ gint fd;
+ gchar *path;
+ gint devmask;
+ gint stereodevs;
+ gint recmask;
+ gint recsrc;
+ OssStream *input;
+ OssStream *output;
};
-static void mate_mixer_device_interface_init (MateMixerDeviceInterface *iface);
-
static void oss_device_class_init (OssDeviceClass *klass);
-
-static void oss_device_get_property (GObject *object,
- guint param_id,
- GValue *value,
- GParamSpec *pspec);
-static void oss_device_set_property (GObject *object,
- guint param_id,
- const GValue *value,
- GParamSpec *pspec);
-
static void oss_device_init (OssDevice *device);
+static void oss_device_dispose (GObject *object);
static void oss_device_finalize (GObject *object);
-G_DEFINE_TYPE_WITH_CODE (OssDevice, oss_device, G_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (MATE_MIXER_TYPE_DEVICE,
- mate_mixer_device_interface_init))
+G_DEFINE_TYPE (OssDevice, oss_device, MATE_MIXER_TYPE_DEVICE)
-static const gchar *oss_device_get_name (MateMixerDevice *device);
-static const gchar *oss_device_get_description (MateMixerDevice *device);
-static const gchar *oss_device_get_icon (MateMixerDevice *device);
+static GList * oss_device_list_streams (MateMixerDevice *device);
-static gboolean read_mixer_devices (OssDevice *device);
+static gboolean read_mixer_devices (OssDevice *device);
-static void
-mate_mixer_device_interface_init (MateMixerDeviceInterface *iface)
-{
- iface->get_name = oss_device_get_name;
- iface->get_description = oss_device_get_description;
- iface->get_icon = oss_device_get_icon;
-}
+static gboolean set_stream_default_control (OssStream *stream,
+ OssStreamControl *control,
+ gboolean force);
static void
oss_device_class_init (OssDeviceClass *klass)
{
- GObjectClass *object_class;
+ GObjectClass *object_class;
+ MateMixerDeviceClass *device_class;
object_class = G_OBJECT_CLASS (klass);
- object_class->finalize = oss_device_finalize;
- object_class->get_property = oss_device_get_property;
- object_class->set_property = oss_device_set_property;
-
- g_object_class_install_property (object_class,
- PROP_PATH,
- g_param_spec_string ("path",
- "Path",
- "Path to the device",
- NULL,
- G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_READWRITE |
- G_PARAM_STATIC_STRINGS));
-
- g_object_class_install_property (object_class,
- PROP_FD,
- g_param_spec_int ("fd",
- "File descriptor",
- "File descriptor of the device",
- G_MININT,
- G_MAXINT,
- -1,
- G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_READWRITE |
- G_PARAM_STATIC_STRINGS));
-
- g_object_class_override_property (object_class, PROP_NAME, "name");
- g_object_class_override_property (object_class, PROP_DESCRIPTION, "description");
- g_object_class_override_property (object_class, PROP_ICON, "icon");
- g_object_class_override_property (object_class, PROP_ACTIVE_PROFILE, "active-profile");
+ object_class->dispose = oss_device_dispose;
+ object_class->finalize = oss_device_finalize;
+
+ device_class = MATE_MIXER_DEVICE_CLASS (klass);
+ device_class->list_streams = oss_device_list_streams;
g_type_class_add_private (object_class, sizeof (OssDevicePrivate));
}
static void
-oss_device_get_property (GObject *object,
- guint param_id,
- GValue *value,
- GParamSpec *pspec)
+oss_device_init (OssDevice *device)
{
- OssDevice *device;
-
- device = OSS_DEVICE (object);
-
- switch (param_id) {
- case PROP_NAME:
- g_value_set_string (value, device->priv->name);
- break;
- case PROP_DESCRIPTION:
- g_value_set_string (value, device->priv->description);
- break;
- case PROP_ICON:
- g_value_set_string (value, OSS_DEVICE_ICON);
- break;
- case PROP_ACTIVE_PROFILE:
- /* Not supported */
- g_value_set_object (value, NULL);
- break;
- case PROP_PATH:
- g_value_set_string (value, device->priv->path);
- break;
- case PROP_FD:
- g_value_set_int (value, device->priv->fd);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
- break;
- }
+ device->priv = G_TYPE_INSTANCE_GET_PRIVATE (device,
+ OSS_TYPE_DEVICE,
+ OssDevicePrivate);
}
static void
-oss_device_set_property (GObject *object,
- guint param_id,
- const GValue *value,
- GParamSpec *pspec)
+oss_device_dispose (GObject *object)
{
OssDevice *device;
device = OSS_DEVICE (object);
- switch (param_id) {
- case PROP_PATH:
- /* Construct-only string */
- device->priv->path = g_strdup (g_value_get_string (value));
- break;
- case PROP_FD:
- device->priv->fd = dup (g_value_get_int (value));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
- break;
- }
-}
+ g_clear_object (&device->priv->input);
+ g_clear_object (&device->priv->output);
-static void
-oss_device_init (OssDevice *device)
-{
- device->priv = G_TYPE_INSTANCE_GET_PRIVATE (device,
- OSS_TYPE_DEVICE,
- OssDevicePrivate);
+ G_OBJECT_CLASS (oss_device_parent_class)->dispose (object);
}
static void
oss_device_finalize (GObject *object)
{
- OssDevice *device;
-
- device = OSS_DEVICE (object);
-
- g_free (device->priv->name);
- g_free (device->priv->description);
+ OssDevice *device = OSS_DEVICE (object);
- if (device->priv->fd != -1)
- g_close (device->priv->fd, NULL);
+ close (device->priv->fd);
G_OBJECT_CLASS (oss_device_parent_class)->finalize (object);
}
OssDevice *
-oss_device_new (const gchar *path, gint fd)
+oss_device_new (const gchar *name, const gchar *label, const gchar *path, gint fd)
{
OssDevice *device;
- gchar *basename;
+ gchar *stream_name;
- g_return_val_if_fail (path != NULL, NULL);
+ g_return_val_if_fail (name != NULL, NULL);
+ g_return_val_if_fail (label != NULL, NULL);
+ g_return_val_if_fail (path != NULL, NULL);
device = g_object_new (OSS_TYPE_DEVICE,
- "path", path,
- "fd", fd,
+ "name", name,
+ "label", label,
+ "icon", OSS_DEVICE_ICON,
NULL);
- basename = g_path_get_basename (path);
+ device->priv->fd = dup (fd);
+ device->priv->path = g_strdup (path);
- device->priv->name = g_strdup_printf ("oss-%s", basename);
- g_free (basename);
+ stream_name = g_strdup_printf ("oss-input-%s", name);
+ device->priv->input = oss_stream_new (stream_name,
+ MATE_MIXER_DEVICE (device),
+ MATE_MIXER_STREAM_INPUT);
+ g_free (stream_name);
+
+ stream_name = g_strdup_printf ("oss-output-%s", name);
+ device->priv->output = oss_stream_new (stream_name,
+ MATE_MIXER_DEVICE (device),
+ MATE_MIXER_STREAM_OUTPUT);
+ g_free (stream_name);
return device;
}
gboolean
-oss_device_read (OssDevice *device)
+oss_device_open (OssDevice *device)
{
- gchar *name;
- gchar *basename;
- MateMixerStreamControl *ctl;
+ gint ret;
g_return_val_if_fail (OSS_IS_DEVICE (device), FALSE);
- // XXX avoid calling this function repeatedly
-
- g_debug ("Querying device %s (%s)",
+ g_debug ("Opening device %s (%s)",
device->priv->path,
- device->priv->description);
-
- basename = g_path_get_basename (device->priv->path);
-
- name = g_strdup_printf ("oss-input-%s", basename);
- device->priv->input = MATE_MIXER_STREAM (oss_stream_new (name,
- device->priv->description,
- MATE_MIXER_STREAM_INPUT));
- g_free (name);
-
- name = g_strdup_printf ("oss-output-%s", basename);
- device->priv->output = MATE_MIXER_STREAM (oss_stream_new (name,
- device->priv->description,
- MATE_MIXER_STREAM_OUTPUT |
- MATE_MIXER_STREAM_PORTS_FIXED));
- g_free (name);
-
- if (read_mixer_devices (device) == FALSE)
- return FALSE;
-
- // XXX prefer active ports as default if there is no default
-
- ctl = mate_mixer_stream_get_default_control (device->priv->input);
- if (ctl == NULL) {
- const GList *list = mate_mixer_stream_list_controls (device->priv->input);
-
- if (list != NULL) {
- ctl = MATE_MIXER_STREAM_CONTROL (list->data);
- oss_stream_set_default_control (OSS_STREAM (device->priv->input),
- OSS_STREAM_CONTROL (ctl));
- } else
- g_clear_object (&device->priv->input);
+ mate_mixer_device_get_label (MATE_MIXER_DEVICE (device)));
+
+ /* Read the essential information about the device, these values are not
+ * expected to change and will not be queried */
+ ret = ioctl (device->priv->fd,
+ MIXER_READ (SOUND_MIXER_DEVMASK),
+ &device->priv->devmask);
+ if (ret != 0)
+ goto fail;
+
+ ret = ioctl (device->priv->fd,
+ MIXER_READ (SOUND_MIXER_STEREODEVS),
+ &device->priv->stereodevs);
+ if (ret < 0)
+ goto fail;
+
+ ret = ioctl (device->priv->fd,
+ MIXER_READ (SOUND_MIXER_RECMASK),
+ &device->priv->recmask);
+ if (ret < 0)
+ goto fail;
+
+ /* The recording source mask may change at any time, here we just read
+ * the initial value */
+ ret = ioctl (device->priv->fd,
+ MIXER_READ (SOUND_MIXER_RECSRC),
+ &device->priv->recsrc);
+ if (ret < 0)
+ goto fail;
+
+ /* NOTE: Linux also supports SOUND_MIXER_OUTSRC and SOUND_MIXER_OUTMASK which
+ * inform about/enable input->output, we could potentially create toggles
+ * for these, but these constants are not defined on any BSD. */
+
+ return TRUE;
+
+fail:
+ g_warning ("Failed to read device %s: %s",
+ device->priv->path,
+ g_strerror (errno));
+
+ return FALSE;
+}
+
+gboolean
+oss_device_load (OssDevice *device)
+{
+ MateMixerStreamControl *control;
+
+ g_return_val_if_fail (OSS_IS_DEVICE (device), FALSE);
+
+ read_mixer_devices (device);
+
+ control = mate_mixer_stream_get_default_control (MATE_MIXER_STREAM (device->priv->input));
+ if (control == NULL) {
+ // XXX pick something
}
- if (ctl != NULL)
+ if (control != NULL)
g_debug ("Default input stream control is %s",
- mate_mixer_stream_control_get_description (ctl));
-
- ctl = mate_mixer_stream_get_default_control (device->priv->output);
- if (ctl == NULL) {
- const GList *list = mate_mixer_stream_list_controls (device->priv->output);
-
- if (list != NULL) {
- ctl = MATE_MIXER_STREAM_CONTROL (list->data);
- oss_stream_set_default_control (OSS_STREAM (device->priv->output),
- OSS_STREAM_CONTROL (ctl));
- } else
- g_clear_object (&device->priv->output);
+ mate_mixer_stream_control_get_label (control));
+
+ control = mate_mixer_stream_get_default_control (MATE_MIXER_STREAM (device->priv->output));
+ if (control == NULL) {
+ // XXX pick something
}
- if (ctl != NULL)
+ if (control != NULL)
g_debug ("Default output stream control is %s",
- mate_mixer_stream_control_get_description (ctl));
+ mate_mixer_stream_control_get_label (control));
return TRUE;
}
+gint
+oss_device_get_fd (OssDevice *device)
+{
+ g_return_val_if_fail (OSS_IS_DEVICE (device), -1);
+
+ return device->priv->fd;
+}
+
const gchar *
-oss_device_get_path (OssDevice *odevice)
+oss_device_get_path (OssDevice *device)
{
- g_return_val_if_fail (OSS_IS_DEVICE (odevice), FALSE);
+ g_return_val_if_fail (OSS_IS_DEVICE (device), NULL);
- return odevice->priv->path;
+ return device->priv->path;
}
-MateMixerStream *
-oss_device_get_input_stream (OssDevice *odevice)
+OssStream *
+oss_device_get_input_stream (OssDevice *device)
{
- g_return_val_if_fail (OSS_IS_DEVICE (odevice), FALSE);
+ g_return_val_if_fail (OSS_IS_DEVICE (device), NULL);
- return odevice->priv->input;
+ return device->priv->input;
}
-MateMixerStream *
-oss_device_get_output_stream (OssDevice *odevice)
+OssStream *
+oss_device_get_output_stream (OssDevice *device)
{
- g_return_val_if_fail (OSS_IS_DEVICE (odevice), FALSE);
+ g_return_val_if_fail (OSS_IS_DEVICE (device), NULL);
- return odevice->priv->output;
+ return device->priv->output;
}
-gboolean
-oss_device_set_description (OssDevice *odevice, const gchar *description)
+static GList *
+oss_device_list_streams (MateMixerDevice *mmd)
{
- g_return_val_if_fail (OSS_IS_DEVICE (odevice), FALSE);
+ OssDevice *device;
+ GList *list = NULL;
- if (g_strcmp0 (odevice->priv->description, description) != 0) {
- g_free (odevice->priv->description);
+ g_return_val_if_fail (OSS_IS_DEVICE (mmd), NULL);
- odevice->priv->description = g_strdup (description);
+ device = OSS_DEVICE (mmd);
- g_object_notify (G_OBJECT (odevice), "description");
- return TRUE;
- }
- return FALSE;
+ if (device->priv->output != NULL)
+ list = g_list_prepend (list, g_object_ref (device->priv->output));
+ if (device->priv->input != NULL)
+ list = g_list_prepend (list, g_object_ref (device->priv->input));
+
+ return list;
}
+#define OSS_MASK_HAS_DEVICE(mask,i) ((gboolean) (((mask) & (1 << (i))) > 0))
+
static gboolean
read_mixer_devices (OssDevice *device)
{
- gint devmask,
- stereomask,
- recmask;
- gint ret;
- gint i;
- OssStreamControl *ctl;
-
- ret = ioctl (device->priv->fd, MIXER_READ (SOUND_MIXER_DEVMASK), &devmask);
- if (ret < 0)
- goto fail;
- ret = ioctl (device->priv->fd, MIXER_READ (SOUND_MIXER_STEREODEVS), &stereomask);
- if (ret < 0)
- goto fail;
- ret = ioctl (device->priv->fd, MIXER_READ (SOUND_MIXER_RECMASK), &recmask);
- if (ret < 0)
- goto fail;
+ gint i;
- for (i = 0; i < MIN (G_N_ELEMENTS (oss_devices), SOUND_MIXER_NRDEVICES); i++) {
- gboolean stereo;
- gboolean input = FALSE;
- MateMixerPort *port = NULL;
+ for (i = 0; i < OSS_N_DEVICES; i++) {
+ OssStreamControl *control;
+ gboolean input = FALSE;
/* Skip unavailable controls */
- if ((devmask & (1 << i)) == 0)
+ if (OSS_MASK_HAS_DEVICE (device->priv->devmask, i) == FALSE)
continue;
- if ((stereomask & (1 << i)) > 0)
- stereo = TRUE;
- else
- stereo = FALSE;
-
- if (oss_devices[i].flags == MATE_MIXER_STREAM_NO_FLAGS) {
- if ((recmask & (1 << i)) > 0)
- input = TRUE;
+ if (oss_devices[i].type == OSS_DEV_ANY) {
+ input = OSS_MASK_HAS_DEVICE (device->priv->recmask, i);
}
- if (oss_devices[i].flags == MATE_MIXER_STREAM_INPUT) {
- if ((recmask & (1 << i)) == 0) {
- g_debug ("Skipping non-input device %s", oss_devices[i].name);
- continue;
- }
+ else if (oss_devices[i].type == OSS_DEV_INPUT) {
input = TRUE;
}
- ctl = oss_stream_control_new (device->priv->fd,
- i,
- oss_devices[i].name,
- oss_devices[i].description,
- stereo);
-
- if (oss_devices[i].role == MATE_MIXER_STREAM_CONTROL_ROLE_PORT)
- port = _mate_mixer_port_new (oss_devices[i].name,
- oss_devices[i].description,
- NULL,
- 0,
- 0);
+ control = oss_stream_control_new (oss_devices[i].name,
+ oss_devices[i].label,
+ oss_devices[i].role,
+ device->priv->fd,
+ i,
+ OSS_MASK_HAS_DEVICE (device->priv->stereodevs, i));
if (input == TRUE) {
- oss_stream_add_control (OSS_STREAM (device->priv->input), ctl);
+ oss_stream_add_control (OSS_STREAM (device->priv->input), control);
if (i == SOUND_MIXER_RECLEV || i == SOUND_MIXER_IGAIN) {
- if (i == SOUND_MIXER_RECLEV) {
- oss_stream_set_default_control (OSS_STREAM (device->priv->input), ctl);
- } else {
- MateMixerStreamControl *defctl;
-
- defctl = mate_mixer_stream_get_default_control (device->priv->input);
- if (defctl == NULL)
- oss_stream_set_default_control (OSS_STREAM (device->priv->input), ctl);
- }
+ if (i == SOUND_MIXER_RECLEV)
+ set_stream_default_control (OSS_STREAM (device->priv->input),
+ control,
+ TRUE);
+ else
+ set_stream_default_control (OSS_STREAM (device->priv->input),
+ control,
+ FALSE);
}
-
- if (port != NULL)
- oss_stream_add_port (OSS_STREAM (device->priv->input), port);
} else {
- oss_stream_add_control (OSS_STREAM (device->priv->output), ctl);
-
- if (i == SOUND_MIXER_VOLUME) {
- oss_stream_set_default_control (OSS_STREAM (device->priv->output), ctl);
- }
- else if (i == SOUND_MIXER_PCM) {
- MateMixerStreamControl *defctl;
-
- defctl = mate_mixer_stream_get_default_control (device->priv->output);
- if (defctl == NULL)
- oss_stream_set_default_control (OSS_STREAM (device->priv->output), ctl);
+ oss_stream_add_control (OSS_STREAM (device->priv->output), control);
+
+ if (i == SOUND_MIXER_VOLUME || i == SOUND_MIXER_PCM) {
+ if (i == SOUND_MIXER_VOLUME)
+ set_stream_default_control (OSS_STREAM (device->priv->output),
+ control,
+ TRUE);
+ else
+ set_stream_default_control (OSS_STREAM (device->priv->output),
+ control,
+ FALSE);
}
-
- if (port != NULL)
- oss_stream_add_port (OSS_STREAM (device->priv->output), port);
}
- if (port != NULL)
- oss_stream_control_set_port (ctl, port);
-
- oss_stream_control_set_role (ctl, oss_devices[i].role);
-
g_debug ("Added control %s",
- mate_mixer_stream_control_get_description (MATE_MIXER_STREAM_CONTROL (ctl)));
+ mate_mixer_stream_control_get_label (MATE_MIXER_STREAM_CONTROL (control)));
- oss_stream_control_update (ctl);
+ oss_stream_control_update (control);
}
return TRUE;
-
-fail:
- g_warning ("Failed to read device %s: %s",
- device->priv->path,
- g_strerror (errno));
-
- return FALSE;
}
-static const gchar *
-oss_device_get_name (MateMixerDevice *device)
-{
- g_return_val_if_fail (OSS_IS_DEVICE (device), NULL);
-
- return OSS_DEVICE (device)->priv->name;
-}
-
-static const gchar *
-oss_device_get_description (MateMixerDevice *device)
-{
- g_return_val_if_fail (OSS_IS_DEVICE (device), NULL);
-
- return OSS_DEVICE (device)->priv->description;
-}
-
-static const gchar *
-oss_device_get_icon (MateMixerDevice *device)
+static gboolean
+set_stream_default_control (OssStream *stream, OssStreamControl *control, gboolean force)
{
- g_return_val_if_fail (OSS_IS_DEVICE (device), NULL);
+ MateMixerStreamControl *current;
- return OSS_DEVICE_ICON;
+ current = mate_mixer_stream_get_default_control (MATE_MIXER_STREAM (stream));
+ if (current == NULL || force == TRUE) {
+ oss_stream_set_default_control (stream, OSS_STREAM_CONTROL (control));
+ return TRUE;
+ }
+ return FALSE;
}