Update
This commit is contained in:
parent
a5bfb1e27d
commit
f8939ec581
@ -44,24 +44,36 @@ impl AlsaCard {
|
||||
match card_name {
|
||||
Some(name) => {
|
||||
if name == "(default)" {
|
||||
get_default_alsa_card()
|
||||
let default = get_default_alsa_card();
|
||||
if alsa_card_has_playable_selem(&default) {
|
||||
default
|
||||
} else {
|
||||
warn!("Default alsa card not playabla, trying others");
|
||||
get_first_playable_alsa_card()?
|
||||
}
|
||||
} else {
|
||||
get_alsa_card_by_name(name)?
|
||||
let mycard = get_alsa_card_by_name(name.clone());
|
||||
match mycard {
|
||||
Ok(card) => card,
|
||||
Err(_) => {
|
||||
warn!("Card {} not playable, trying others", name);
|
||||
get_first_playable_alsa_card()?
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
None => get_default_alsa_card(),
|
||||
None => get_first_playable_alsa_card()?,
|
||||
}
|
||||
};
|
||||
let mixer = get_mixer(&card)?;
|
||||
|
||||
let vec_pollfd = PollDescriptors::get(&mixer)?;
|
||||
|
||||
let selem_id =
|
||||
get_selem_by_name(&mixer,
|
||||
elem_name.unwrap_or(String::from("Master")))
|
||||
.unwrap()
|
||||
get_playable_selem_by_name(&mixer,
|
||||
elem_name.unwrap_or(String::from("Master")))?
|
||||
.get_id();
|
||||
|
||||
let vec_pollfd = PollDescriptors::get(&mixer)?;
|
||||
|
||||
let acard = Box::new(AlsaCard {
|
||||
_cannot_construct: (),
|
||||
card: card,
|
||||
@ -114,7 +126,7 @@ impl AlsaCard {
|
||||
pub fn set_vol(&self, new_vol: f64) -> Result<()> {
|
||||
let selem = self.selem();
|
||||
/* auto-unmute */
|
||||
if self.get_mute()? {
|
||||
if self.has_mute() && self.get_mute()? {
|
||||
self.set_mute(false)?;
|
||||
}
|
||||
|
||||
@ -241,6 +253,7 @@ extern "C" fn watch_cb(chan: *mut glib_sys::GIOChannel,
|
||||
debug!("G_IO_STATUS_AGAIN");
|
||||
continue;
|
||||
}
|
||||
// TODO: handle these failure cases
|
||||
glib_sys::G_IO_STATUS_NORMAL => debug!("G_IO_STATUS_NORMAL"),
|
||||
glib_sys::G_IO_STATUS_ERROR => debug!("G_IO_STATUS_ERROR"),
|
||||
glib_sys::G_IO_STATUS_EOF => debug!("G_IO_STATUS_EOF"),
|
||||
|
@ -30,10 +30,14 @@ impl AppS {
|
||||
let gui =
|
||||
Gui::new(builder_popup_window, builder_popup_menu, &prefs.borrow());
|
||||
|
||||
let card_name = prefs.borrow().device_prefs.card.clone();
|
||||
let chan_name = prefs.borrow().device_prefs.channel.clone();
|
||||
|
||||
return AppS {
|
||||
_cant_construct: (),
|
||||
gui: gui,
|
||||
audio: Audio::new(None, Some(String::from("Master")))
|
||||
audio: Audio::new(Some(card_name),
|
||||
Some(chan_name))
|
||||
.unwrap(),
|
||||
prefs: prefs,
|
||||
};
|
||||
@ -54,6 +58,7 @@ impl AppS {
|
||||
return self.gui.popup_window.update(&self.audio);
|
||||
}
|
||||
|
||||
// TODO
|
||||
pub fn show_preferences(&self) {
|
||||
// show_prefs_dialog(self);
|
||||
}
|
||||
|
@ -1,9 +1,10 @@
|
||||
use alsa::card::Card;
|
||||
use alsa::mixer::{Mixer, Selem, Elem};
|
||||
use alsa::mixer::{Mixer, Selem, SelemId, Elem};
|
||||
use alsa;
|
||||
use errors::*;
|
||||
use libc::c_int;
|
||||
use std::iter::Map;
|
||||
use std::iter::Filter;
|
||||
|
||||
|
||||
|
||||
@ -22,11 +23,34 @@ pub fn get_alsa_cards() -> alsa::card::Iter {
|
||||
}
|
||||
|
||||
|
||||
pub fn get_alsa_card_names() -> Vec<String> {
|
||||
pub fn get_first_playable_alsa_card() -> Result<Card> {
|
||||
for m_card in get_alsa_cards() {
|
||||
match m_card {
|
||||
Ok(card) => {
|
||||
if alsa_card_has_playable_selem(&card) {
|
||||
return Ok(card);
|
||||
}
|
||||
},
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
bail!("No playable alsa card found!")
|
||||
}
|
||||
|
||||
|
||||
pub fn get_playable_alsa_card_names() -> Vec<String> {
|
||||
let mut vec = vec![];
|
||||
for card in get_alsa_cards() {
|
||||
match card.and_then(|c| c.get_name()) {
|
||||
Ok(name) => vec.push(name),
|
||||
for m_card in get_alsa_cards() {
|
||||
match m_card {
|
||||
Ok(card) => {
|
||||
if alsa_card_has_playable_selem(&card) {
|
||||
let m_name = card.get_name();
|
||||
if m_name.is_ok() {
|
||||
vec.push(m_name.unwrap())
|
||||
}
|
||||
}
|
||||
},
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
@ -47,6 +71,17 @@ pub fn get_alsa_card_by_name(name: String) -> Result<Card> {
|
||||
}
|
||||
|
||||
|
||||
pub fn alsa_card_has_playable_selem(card: &Card) -> bool {
|
||||
let mixer = try_wr!(get_mixer(&card), false);
|
||||
for selem in get_playable_selems(&mixer) {
|
||||
if selem_is_playable(&selem) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
pub fn get_mixer(card: &Card) -> Result<Mixer> {
|
||||
return Mixer::new(&format!("hw:{}", card.get_index()), false).from_err();
|
||||
}
|
||||
@ -60,14 +95,18 @@ pub fn get_selem(elem: Elem) -> Selem {
|
||||
}
|
||||
|
||||
|
||||
pub fn get_selems(mixer: &Mixer) -> Map<alsa::mixer::Iter, fn(Elem) -> Selem> {
|
||||
return mixer.iter().map(get_selem);
|
||||
pub fn get_playable_selems(mixer: &Mixer) -> Vec<Selem> {
|
||||
let mut v = vec![];
|
||||
for s in mixer.iter().map(get_selem).filter(selem_is_playable) {
|
||||
v.push(s);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
pub fn get_selem_names(mixer: &Mixer) -> Vec<String> {
|
||||
pub fn get_playable_selem_names(mixer: &Mixer) -> Vec<String> {
|
||||
let mut vec = vec![];
|
||||
for selem in get_selems(mixer) {
|
||||
for selem in get_playable_selems(mixer) {
|
||||
let n = selem.get_id().get_name().map(|y| String::from(y));
|
||||
match n {
|
||||
Ok(name) => vec.push(name),
|
||||
@ -79,8 +118,8 @@ pub fn get_selem_names(mixer: &Mixer) -> Vec<String> {
|
||||
}
|
||||
|
||||
|
||||
pub fn get_selem_by_name(mixer: &Mixer, name: String) -> Result<Selem> {
|
||||
for selem in get_selems(mixer) {
|
||||
pub fn get_playable_selem_by_name(mixer: &Mixer, name: String) -> Result<Selem> {
|
||||
for selem in get_playable_selems(mixer) {
|
||||
let n = selem.get_id()
|
||||
.get_name()
|
||||
.map(|y| String::from(y))?;
|
||||
@ -89,7 +128,12 @@ pub fn get_selem_by_name(mixer: &Mixer, name: String) -> Result<Selem> {
|
||||
return Ok(selem);
|
||||
}
|
||||
}
|
||||
bail!("Not found a matching selem named {}", name);
|
||||
bail!("Not found a matching playable selem named {}", name);
|
||||
}
|
||||
|
||||
|
||||
pub fn selem_is_playable(selem: &Selem) -> bool {
|
||||
return selem.has_playback_volume();
|
||||
}
|
||||
|
||||
|
||||
|
@ -38,13 +38,7 @@ pub fn init_popup_menu(appstate: Rc<AppS>) {
|
||||
return;
|
||||
}
|
||||
match (s, u) {
|
||||
(_, _) => {
|
||||
let muted = try_w!(apps.audio.get_mute());
|
||||
apps.gui
|
||||
.popup_menu
|
||||
.mute_check
|
||||
.set_active(muted);
|
||||
}
|
||||
(_, _) => set_mute_check(&apps)
|
||||
}
|
||||
}));
|
||||
|
||||
@ -57,11 +51,7 @@ pub fn init_popup_menu(appstate: Rc<AppS>) {
|
||||
.popup_menu
|
||||
.menu
|
||||
.connect_show(move |_| {
|
||||
let muted = try_w!(apps.audio.get_mute());
|
||||
apps.gui
|
||||
.popup_menu
|
||||
.mute_check
|
||||
.set_active(muted);
|
||||
set_mute_check(&apps)
|
||||
});
|
||||
|
||||
}
|
||||
@ -75,12 +65,14 @@ pub fn init_popup_menu(appstate: Rc<AppS>) {
|
||||
});
|
||||
}
|
||||
|
||||
/* about_item.connect_activate_link */
|
||||
/* mute_item.connect_activate_link */
|
||||
{
|
||||
let apps = appstate.clone();
|
||||
let mute_item = &appstate.gui.popup_menu.mute_item;
|
||||
mute_item.connect_activate(move |_| {
|
||||
try_w!(apps.audio.toggle_mute(AudioUser::Popup));
|
||||
if apps.audio.has_mute() {
|
||||
try_w!(apps.audio.toggle_mute(AudioUser::Popup));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ -93,7 +85,7 @@ pub fn init_popup_menu(appstate: Rc<AppS>) {
|
||||
});
|
||||
}
|
||||
|
||||
/* about_item.connect_activate_link */
|
||||
/* prefs_item.connect_activate_link */
|
||||
{
|
||||
let apps = appstate.clone();
|
||||
let prefs_item = &appstate.gui.popup_menu.prefs_item;
|
||||
@ -157,3 +149,30 @@ fn on_prefs_item_activate(appstate: &Rc<AppS>) {
|
||||
/* TODO: only create if needed */
|
||||
show_prefs_dialog(appstate);
|
||||
}
|
||||
|
||||
|
||||
fn set_mute_check(apps: &Rc<AppS>) {
|
||||
let mute_check = &apps.gui
|
||||
.popup_menu
|
||||
.mute_check;
|
||||
let m_muted = apps.audio.get_mute();
|
||||
match m_muted {
|
||||
Ok(muted) => {
|
||||
mute_check
|
||||
.set_sensitive(false);
|
||||
mute_check
|
||||
.set_active(muted);
|
||||
mute_check.set_tooltip_text(
|
||||
"");
|
||||
},
|
||||
Err(_) => {
|
||||
mute_check
|
||||
.set_active(true);
|
||||
mute_check
|
||||
.set_sensitive(false);
|
||||
mute_check.set_tooltip_text(
|
||||
"Soundcard has no mute switch",
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -48,12 +48,13 @@ impl PopupWindow {
|
||||
}
|
||||
|
||||
pub fn update_mute_check(&self, audio: &Audio) {
|
||||
let muted = audio.get_mute();
|
||||
let m_muted = audio.get_mute();
|
||||
|
||||
glib::signal_handler_block(&self.mute_check, self.toggle_signal.get());
|
||||
|
||||
match muted {
|
||||
match m_muted {
|
||||
Ok(val) => {
|
||||
self.mute_check.set_sensitive(true);
|
||||
self.mute_check.set_active(val);
|
||||
self.mute_check.set_tooltip_text("");
|
||||
}
|
||||
|
@ -329,7 +329,7 @@ fn fill_card_combo(appstate: &AppS) {
|
||||
/* set card combo */
|
||||
let cur_card_name = try_w!(acard.card_name(),
|
||||
"Can't get current card name!");
|
||||
let available_card_names = get_alsa_card_names();
|
||||
let available_card_names = get_playable_alsa_card_names();
|
||||
|
||||
/* set_active_id doesn't work, so save the index */
|
||||
let mut c_index: i32 = -1;
|
||||
@ -362,7 +362,7 @@ fn fill_chan_combo(appstate: &AppS, cardname: Option<String>) {
|
||||
/* set chan combo */
|
||||
let cur_chan_name = try_w!(cur_acard.chan_name());
|
||||
let mixer = try_w!(get_mixer(&card));
|
||||
let available_chan_names = get_selem_names(&mixer);
|
||||
let available_chan_names = get_playable_selem_names(&mixer);
|
||||
|
||||
/* set_active_id doesn't work, so save the index */
|
||||
let mut c_index: i32 = -1;
|
||||
|
@ -415,7 +415,9 @@ fn on_tray_button_release_event(appstate: &AppS,
|
||||
|
||||
match middle_click_action {
|
||||
&MiddleClickAction::ToggleMute => {
|
||||
try_wr!(audio.toggle_mute(AudioUser::Popup), false);
|
||||
if audio.has_mute() {
|
||||
try_wr!(audio.toggle_mute(AudioUser::Popup), false);
|
||||
}
|
||||
}
|
||||
&MiddleClickAction::ShowPreferences => (),
|
||||
&MiddleClickAction::VolumeControl => {
|
||||
|
Loading…
Reference in New Issue
Block a user