diff options
| author | Michal Ratajsky <[email protected]> | 2014-10-31 14:50:29 +0100 | 
|---|---|---|
| committer | Michal Ratajsky <[email protected]> | 2014-10-31 14:50:29 +0100 | 
| commit | 20afadff90fb6a866d3e361b2b294a67775da95e (patch) | |
| tree | f5707583cb7fbe267bdba4c04a639e8e9b8dfb5c /backends | |
| parent | 1897445a80677ec89e7eef9f2a76e630fd088588 (diff) | |
| download | libmatemixer-20afadff90fb6a866d3e361b2b294a67775da95e.tar.bz2 libmatemixer-20afadff90fb6a866d3e361b2b294a67775da95e.tar.xz | |
Remove ability to have no active switch option and fix OSS to correctly handle such case
Diffstat (limited to 'backends')
| -rw-r--r-- | backends/oss/oss-switch.c | 113 | 
1 files changed, 86 insertions, 27 deletions
| diff --git a/backends/oss/oss-switch.c b/backends/oss/oss-switch.c index b138051..8e32281 100644 --- a/backends/oss/oss-switch.c +++ b/backends/oss/oss-switch.c @@ -38,10 +38,12 @@ static void oss_switch_finalize        (GObject             *object);  G_DEFINE_TYPE (OssSwitch, oss_switch, MATE_MIXER_TYPE_SWITCH) -static gboolean     oss_switch_set_active_option (MateMixerSwitch       *mms, -                                                  MateMixerSwitchOption *mmso); +static gboolean         oss_switch_set_active_option (MateMixerSwitch       *mms, +                                                      MateMixerSwitchOption *mmso); -static const GList *oss_switch_list_options      (MateMixerSwitch       *mms); +static const GList *    oss_switch_list_options      (MateMixerSwitch       *mms); + +static OssSwitchOption *choose_default_option        (OssSwitch             *swtch);  static void  oss_switch_class_init (OssSwitchClass *klass) @@ -104,10 +106,14 @@ oss_switch_new (const gchar *name,  {      OssSwitch *swtch; +    g_return_val_if_fail (name != NULL, NULL); +    g_return_val_if_fail (label != NULL, NULL); +    g_return_val_if_fail (fd != -1, NULL); +    g_return_val_if_fail (options != NULL, NULL); +      swtch = g_object_new (OSS_TYPE_SWITCH,                            "name", name,                            "label", label, -                          "flags", MATE_MIXER_SWITCH_ALLOWS_NO_ACTIVE_OPTION,                            "role", MATE_MIXER_SWITCH_ROLE_PORT,                            NULL); @@ -121,39 +127,70 @@ oss_switch_new (const gchar *name,  void  oss_switch_load (OssSwitch *swtch)  { -    GList *list; -    gint   recsrc; -    gint   ret; +    OssSwitchOption *option; +    gint             recsrc; +    gint             devnum; +    gint             ret;      g_return_if_fail (OSS_IS_SWITCH (swtch));      if G_UNLIKELY (swtch->priv->fd == -1)          return; +    /* Recsrc contains a bitmask of currently enabled recording sources */      ret = ioctl (swtch->priv->fd, MIXER_READ (SOUND_MIXER_RECSRC), &recsrc);      if (ret == -1)          return; -    if (recsrc == 0) { -        _mate_mixer_switch_set_active_option (MATE_MIXER_SWITCH (swtch), NULL); -        return; -    } -    list = swtch->priv->options; -    while (list != NULL) { -        OssSwitchOption *option = OSS_SWITCH_OPTION (list->data); -        gint             devnum = oss_switch_option_get_devnum (option); - -        /* Mark the selected option when we find it */ -        if (recsrc & (1 << devnum)) { -            _mate_mixer_switch_set_active_option (MATE_MIXER_SWITCH (swtch), -                                                  MATE_MIXER_SWITCH_OPTION (option)); -            return; +    if (recsrc != 0) { +        GList *list = swtch->priv->options; + +        /* Find out which option is currently selected */ +        while (list != NULL) { +            gint devnum; + +            option = OSS_SWITCH_OPTION (list->data); +            devnum = oss_switch_option_get_devnum (option); + +            if (recsrc & (1 << devnum)) { +                /* It is possible that some hardware might allow and have more recording +                 * sources active at the same time, but we only support one active +                 * source at a time */ +                _mate_mixer_switch_set_active_option (MATE_MIXER_SWITCH (swtch), +                                                      MATE_MIXER_SWITCH_OPTION (option)); +                return; +            } +            list = list->next;          } -        list = list->next; + +        g_debug ("Switch %s has unknown device %d as the active option", +                 mate_mixer_switch_get_name (MATE_MIXER_SWITCH (swtch)), +                 devnum); + +        /* OSS shouldn't let a non-record device be selected, let's step in and select +         * something reasonable instead... */ +    } else { +         g_debug ("Switch %s has no active device", +                  mate_mixer_switch_get_name (MATE_MIXER_SWITCH (swtch))); + +        /* According to the OSS Programmer's Guide, if the recsrc value is 0, the +         * microphone will be selected implicitly. +         * Let's not assume that's true everywhere and select something explicitly... */      } -    g_warning ("Unknown active option of switch %s", -               mate_mixer_switch_get_name (MATE_MIXER_SWITCH (swtch))); +    option = choose_default_option (swtch); + +    g_debug ("Selecting default device %s as active for switch %s", +             mate_mixer_switch_option_get_name (MATE_MIXER_SWITCH_OPTION (option)), +             mate_mixer_switch_get_name (MATE_MIXER_SWITCH (swtch))); + +    if (mate_mixer_switch_set_active_option (MATE_MIXER_SWITCH (swtch), +                                             MATE_MIXER_SWITCH_OPTION (option)) == FALSE) { +        g_debug ("Failed to set the default device, assuming it is selected anyway"); + +        _mate_mixer_switch_set_active_option (MATE_MIXER_SWITCH (swtch), +                                              MATE_MIXER_SWITCH_OPTION (option)); +    }  }  void @@ -174,7 +211,6 @@ oss_switch_set_active_option (MateMixerSwitch *mms, MateMixerSwitchOption *mmso)      OssSwitch *swtch;      gint       ret;      gint       recsrc; -    gint       devnum;      g_return_val_if_fail (OSS_IS_SWITCH (mms), FALSE);      g_return_val_if_fail (OSS_IS_SWITCH_OPTION (mmso), FALSE); @@ -184,8 +220,7 @@ oss_switch_set_active_option (MateMixerSwitch *mms, MateMixerSwitchOption *mmso)      if G_UNLIKELY (swtch->priv->fd == -1)          return FALSE; -    devnum = oss_switch_option_get_devnum (OSS_SWITCH_OPTION (mmso)); -    recsrc = 1 << devnum; +    recsrc = 1 << oss_switch_option_get_devnum (OSS_SWITCH_OPTION (mmso));      ret = ioctl (swtch->priv->fd, MIXER_WRITE (SOUND_MIXER_RECSRC), &recsrc);      if (ret == -1) @@ -201,3 +236,27 @@ oss_switch_list_options (MateMixerSwitch *mms)      return OSS_SWITCH (mms)->priv->options;  } + +#define OSS_SWITCH_PREFERRED_DEFAULT_DEVNUM 7 /* Microphone */ + +static OssSwitchOption * +choose_default_option (OssSwitch *swtch) +{ +    GList *list = swtch->priv->options; + +    /* Search for the preferred device */ +    while (list != NULL) { +        OssSwitchOption *option; +        gint             devnum; + +        option = OSS_SWITCH_OPTION (list->data); +        devnum = oss_switch_option_get_devnum (option); + +        if (devnum == OSS_SWITCH_PREFERRED_DEFAULT_DEVNUM) +            return option; + +        list = list->next; +    } +    /* If the preferred device is not present, use the first available one */ +    return OSS_SWITCH_OPTION (swtch->priv->options->data); +} | 
