diff --git a/src/app_state.rs b/src/app_state.rs index 889d1232f..80775e59b 100644 --- a/src/app_state.rs +++ b/src/app_state.rs @@ -2,6 +2,7 @@ use audio::alsa::backend::*; +use audio::pulseaudio::*; use audio::frontend::*; use errors::*; use gtk; @@ -52,6 +53,19 @@ pub fn new_alsa_appstate() -> AppS { return AppS::new(prefs, audio); } +/// Create a new application state using the `PABackend`. +pub fn new_pa_appstate() -> AppS { + let prefs = RefCell::new(unwrap_error!(Prefs::new(), None)); + + let card_name = prefs.borrow().device_prefs.card.clone(); + let chan_name = prefs.borrow().device_prefs.channel.clone(); + let audio = Rc::new(unwrap_error!( + PABackend::new(Some(card_name), Some(chan_name)), + None + )); + return AppS::new(prefs, audio); +} + impl AppS where diff --git a/src/audio/alsa/backend.rs b/src/audio/alsa/backend.rs index 29318f1c1..ea154f755 100644 --- a/src/audio/alsa/backend.rs +++ b/src/audio/alsa/backend.rs @@ -136,8 +136,20 @@ impl AudioFrontend for AlsaBackend { return Ok(n); } - fn playable_chan_names(&self) -> Vec { - return get_playable_selem_names(&self.acard.borrow().mixer); + fn playable_chan_names(&self, cardname: Option) -> Vec { + match cardname { + Some(name) => { + let card = try_r!(get_alsa_card_by_name(name), Vec::default()); + let mixer = try_r!(get_mixer(&card), Vec::default()); + + return get_playable_selem_names(&mixer); + }, + None => self.acard.borrow().playable_chan_names(), + } + } + + fn playable_card_names(&self) -> Vec { + return get_playable_alsa_card_names(); } fn get_vol(&self) -> Result { @@ -286,29 +298,6 @@ impl AudioFrontend for AlsaBackend { } -/// Invokes the registered handlers. -fn invoke_handlers( - handlers: &Vec>, - signal: AudioSignal, - user: AudioUser, -) { - debug!( - "Invoking handlers for signal {:?} by user {:?}", - signal, - user - ); - if handlers.is_empty() { - debug!("No handler found"); - } else { - debug!("Executing handlers") - } - for handler in handlers { - let unboxed = handler.as_ref(); - unboxed(signal, user); - } -} - - /// The callback for alsa events that is passed to the alsa subsystem. /// This is the bridge between low-level alsa events and "high-level" /// audio system signals. diff --git a/src/audio/alsa/card.rs b/src/audio/alsa/card.rs index 3671d21be..5ade3551d 100644 --- a/src/audio/alsa/card.rs +++ b/src/audio/alsa/card.rs @@ -184,6 +184,11 @@ impl AlsaCard { } } } + + // Get playable channel names of the given card. + pub fn playable_chan_names(&self) -> Vec { + return get_playable_selem_names(&self.mixer); + } } diff --git a/src/audio/frontend.rs b/src/audio/frontend.rs index dc85683a2..04a8e0dcc 100644 --- a/src/audio/frontend.rs +++ b/src/audio/frontend.rs @@ -153,8 +153,11 @@ pub trait AudioFrontend { /// Get the current card name. fn card_name(&self) -> Result; + /// Get the currently playable card names. + fn playable_card_names(&self) -> Vec; + /// Get the currently playable channel names. - fn playable_chan_names(&self) -> Vec; + fn playable_chan_names(&self, cardname: Option) -> Vec; /// Get the current active channel name. fn chan_name(&self) -> Result; diff --git a/src/audio/pulseaudio.rs b/src/audio/pulseaudio.rs index 90725053b..f94c99e67 100644 --- a/src/audio/pulseaudio.rs +++ b/src/audio/pulseaudio.rs @@ -1,18 +1,25 @@ +#![allow(missing_docs)] + + //! Pulseaudio backend subsystem. use audio::frontend::*; use errors::*; use libc; use libpulse_sys::*; +use std::cell::Cell; use std::cell::RefCell; -use std::ffi::{CString, CStr}; -use std::mem; -use std::os::raw::c_char; +use std::ffi::{CString}; use std::ptr; use support::pulseaudio::*; use support::audio::*; +pub const PA_VOLUME_MUTED: i64 = 0x0; +pub const PA_VOLUME_NORM: i64 = 0x10000; + + + // TODO: get info based on index, not descr. // // TODO: how to hook pulseaudio events? port change? @@ -28,17 +35,47 @@ pub struct Sink { pub channels: u8, } +impl Sink { + pub fn new(sink_desc: Option, + chan_name: Option, + mainloop: *mut pa_threaded_mainloop, + context: *mut pa_context) -> Result { + let sink = { + match sink_desc.as_ref().map(|s| s.as_str()) { + Some("(default)") => get_first_sink(mainloop, context)?, + Some(sd) => { + let mysink = get_sink_by_desc(mainloop, context, sd); + match mysink { + Ok(s) => s, + Err(_) => { + warn!("Could not find sink with name {}, trying others", sd); + get_first_sink(mainloop, context)? + } + } + + } + None => get_first_sink(mainloop, context)? + } + + }; + + return Ok(sink); + } +} + pub struct PABackend { _cannot_construct: (), m: *mut pa_threaded_mainloop, c: *mut pa_context, pub sink: RefCell, + pub scroll_step: Cell, + pub handlers: Handlers, } impl PABackend { - pub fn new(sink_desc: Option) -> Result { + pub fn new(sink_desc: Option, chan_name: Option) -> Result { unsafe { let mainloop: *mut pa_threaded_mainloop = pa_threaded_mainloop_new(); @@ -86,35 +123,74 @@ impl PABackend { pa_threaded_mainloop_unlock(mainloop); CONTEXT_READY = false; - let sink = { - match sink_desc.as_ref().map(|s| s.as_str()) { - Some("(default)") => get_first_sink(mainloop, context)?, - Some(sd) => { - let mysink = get_sink_by_desc(mainloop, context, sd); - match mysink { - Ok(s) => s, - Err(_) => { - warn!("Could not find sink with name {}, trying others", sd); - get_first_sink(mainloop, context)? - } - } + let sink = Sink::new(sink_desc, chan_name, mainloop, context)?; - } - None => get_first_sink(mainloop, context)? - } + + pa_threaded_mainloop_lock(mainloop); + + let mut success: bool = false; + let data = &mut(mainloop, &mut success); + let o = pa_context_subscribe(context, + PA_SUBSCRIPTION_MASK_SINK, + Some(context_subscribe_cb), + data as *mut _ as *mut libc::c_void); + + if o.is_null() { + pa_threaded_mainloop_unlock(mainloop); + bail!("Failed to initialize PA operation!"); + } + + while pa_operation_get_state(o) == PA_OPERATION_RUNNING { + pa_threaded_mainloop_wait(mainloop); + } + pa_operation_unref(o); + pa_threaded_mainloop_unlock(mainloop); + + + let handlers = Handlers::new(); + let cb_box = { + let h_ref: &Vec> = &handlers.borrow(); + Box::new((mainloop, h_ref as *const Vec>)) }; + { + pa_context_set_subscribe_callback(context, + Some(sub_callback), + Box::into_raw(cb_box) as *mut libc::c_void); + + } + return Ok(PABackend { _cannot_construct: (), m: mainloop, c: context, sink: RefCell::new(sink), + scroll_step: Cell::new(5), + handlers, }) } } +} - pub fn get_vol(&self) -> Result { + +impl AudioFrontend for PABackend { + // TODO + fn switch_card( + &self, + card_name: Option, + elem_name: Option, + user: AudioUser, + ) -> Result<()> { + { + let mut ac = self.sink.borrow_mut(); + *ac = Sink::new(card_name, elem_name, self.m, self.c)?; + } + return Ok(()) + } + + + fn get_vol(&self) -> Result { let mut vol: u32 = 0; unsafe { @@ -140,19 +216,21 @@ impl PABackend { let _ = CString::from_raw(sink_name); } - unsafe { - return Ok(pa_sw_volume_to_linear(vol) * 100.0); - } + + return vol_to_percent(vol as i64, (PA_VOLUME_MUTED, + PA_VOLUME_NORM)) } - pub fn set_vol(&self, new_vol: f64, dir: VolDir) -> Result<()> { + + fn set_vol(&self, new_vol: f64, user: AudioUser, dir: VolDir, auto_unmute: bool) -> Result<()> { let mut res: Result<()> = Err("No value".into()); + let new_vol = percent_to_vol(new_vol, (PA_VOLUME_MUTED, + PA_VOLUME_NORM), dir)?; unsafe { pa_threaded_mainloop_lock(self.m); let data = &mut(self, &mut res); let sink_name = CString::new(self.sink.borrow().name.clone()).unwrap().into_raw(); - let new_vol = pa_sw_volume_from_linear(new_vol / 100.0); let mut vol_arr: [u32; 32] = [0; 32]; for c in 0..(self.sink.borrow().channels) { vol_arr[c as usize] = new_vol as u32; @@ -185,11 +263,44 @@ impl PABackend { return res; } - pub fn has_mute(&self) -> bool { + + fn vol_level(&self) -> VolLevel { + let muted = self.get_mute().unwrap_or(false); + if muted { + return VolLevel::Muted; + } + let cur_vol = try_r!(self.get_vol(), VolLevel::Muted); + match cur_vol { + 0. => return VolLevel::Off, + 0.0...33.0 => return VolLevel::Low, + 0.0...66.0 => return VolLevel::Medium, + 0.0...100.0 => return VolLevel::High, + _ => return VolLevel::Off, + } + } + + + fn increase_vol(&self, user: AudioUser, auto_unmute: bool) -> Result<()> { + let old_vol = self.get_vol()?; + let new_vol = old_vol + (self.scroll_step.get() as f64); + + return self.set_vol(new_vol, user, VolDir::Up, auto_unmute); + } + + fn decrease_vol(&self, user: AudioUser, auto_unmute: bool) -> Result<()> { + let old_vol = self.get_vol()?; + let new_vol = old_vol - (self.scroll_step.get() as f64); + + return self.set_vol(new_vol, user, VolDir::Down, auto_unmute); + } + + + fn has_mute(&self) -> bool { return true; } - pub fn get_mute(&self) -> Result { + + fn get_mute(&self) -> Result { let mut mute: bool = false; unsafe { @@ -216,7 +327,8 @@ impl PABackend { return Ok(mute); } - pub fn set_mute(&self, mute: bool) -> Result<()> { + + fn set_mute(&self, mute: bool, user: AudioUser) -> Result<()> { let mut res: Result<()> = Err("No value".into()); unsafe { pa_threaded_mainloop_lock(self.m); @@ -243,6 +355,45 @@ impl PABackend { return res; } + + fn toggle_mute(&self, user: AudioUser) -> Result<()> { + let muted = self.get_mute()?; + return self.set_mute(!muted, user); + } + + + // TODO + fn connect_handler(&self, cb: Box) { + self.handlers.add_handler(cb); + } + + // TODO: name or desc? + fn card_name(&self) -> Result { + return Ok(self.sink.borrow().description.clone()) + } + + fn playable_card_names(&self) -> Vec { + let sinks = try_r!(get_sinks(self.m, self.c), vec![]); + return sinks.iter().map(|s| s.description.clone()).collect(); + } + + // TODO + fn playable_chan_names(&self, cardname: Option) -> Vec { + return vec![] + } + + // TODO + fn chan_name(&self) -> Result { + return Ok(String::from("Blah")) + } + + fn set_scroll_step(&self, scroll_step: u32) { + self.scroll_step.set(scroll_step); + } + + fn get_scroll_step(&self) -> u32 { + return self.scroll_step.get(); + } } @@ -284,13 +435,14 @@ unsafe extern "C" fn context_state_cb( // TODO: Better error handling. unsafe extern "C" fn get_sink_vol( - ctx: *mut pa_context, + _: *mut pa_context, i: *const pa_sink_info, - eol: i32, + _: i32, data: *mut libc::c_void) { let (_self, res) = *(data as *mut (*mut PABackend, *mut u32)); assert!(!(*_self).m.is_null(), "Mainloop is null"); + assert!(!res.is_null(), "res is null"); if i.is_null() { return @@ -303,13 +455,14 @@ unsafe extern "C" fn get_sink_vol( // TODO: Better error handling. unsafe extern "C" fn get_sink_mute( - ctx: *mut pa_context, + _: *mut pa_context, i: *const pa_sink_info, - eol: i32, + _: i32, data: *mut libc::c_void) { let (_self, res) = *(data as *mut (*mut PABackend, *mut bool)); assert!(!(*_self).m.is_null(), "Mainloop is null"); + assert!(!res.is_null(), "res is null"); if i.is_null() { return @@ -322,12 +475,13 @@ unsafe extern "C" fn get_sink_mute( // TODO: Missing error handling. unsafe extern "C" fn set_sink_vol( - ctx: *mut pa_context, + _: *mut pa_context, success: i32, data: *mut libc::c_void) { let (_self, res) = *(data as *mut (*mut PABackend, *mut Result<()>)); assert!(!(*_self).m.is_null(), "Mainloop is null"); + assert!(!res.is_null(), "res is null"); if success > 0 { *res = Ok(()); @@ -342,12 +496,13 @@ unsafe extern "C" fn set_sink_vol( // TODO: Missing error handling. // TODO: same as 'set_sink_vol' unsafe extern "C" fn set_sink_mute( - ctx: *mut pa_context, + _: *mut pa_context, success: i32, data: *mut libc::c_void) { let (_self, res) = *(data as *mut (*mut PABackend, *mut Result<()>)); assert!(!(*_self).m.is_null(), "Mainloop is null"); + assert!(!res.is_null(), "res is null"); if success > 0 { *res = Ok(()); @@ -357,3 +512,51 @@ unsafe extern "C" fn set_sink_mute( pa_threaded_mainloop_signal((*_self).m, 0); } + + +unsafe extern "C" fn context_subscribe_cb(c: *mut pa_context, + success: i32, + data: *mut libc::c_void) { + let (mainloop, res) = *(data as *mut (*mut pa_threaded_mainloop, + *mut bool)); + + assert!(!mainloop.is_null(), "Mainloop is null"); + assert!(!res.is_null(), "res is null"); + + if success > 0 { + *res = true; + } else { + *res = false; + } + + + pa_threaded_mainloop_signal(mainloop, 0); + +} + + +unsafe extern "C" fn sub_callback(c: *mut pa_context, + t: u32, + idx: u32, + data: *mut libc::c_void) { + + let (mainloop, p_handlers) = *(data as *mut (*mut pa_threaded_mainloop, + *mut Vec>)); + + assert!(!mainloop.is_null(), "Mainloop is null"); + assert!(!p_handlers.is_null(), "Handlers are null"); + + let handlers: &Vec> = &*p_handlers; + + if (t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) == + PA_SUBSCRIPTION_EVENT_SINK { + if (t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_CHANGE { + // invoke_handlers( + // handlers, + // AudioSignal::ValuesChanged, + // AudioUser::Unknown, + // ); + } + } +} + diff --git a/src/bin.rs b/src/bin.rs index 1ca12a646..b5fb095b5 100644 --- a/src/bin.rs +++ b/src/bin.rs @@ -22,6 +22,7 @@ use support::audio::VolDir; + fn main() { @@ -73,22 +74,22 @@ fn main() { .unwrap_or_else(|e|{panic!("Logger initialization failed with {}",e)}); - let pa = PABackend::new(Some(String::from("Built-in Audio Analog Stereo"))).unwrap(); - println!("Sink: {:?}", pa.sink); - println!("Volume before: {:?}", pa.get_vol()); - pa.set_vol(80.0, VolDir::Up); - println!("Volume after: {:?}", pa.get_vol()); - println!("Mute before: {:?}", pa.get_mute()); - println!("PA_VOLUME_NORM: {:?}", PA_VOLUME_NORM); + // let pa = PABackend::new(Some(String::from("Built-in Audio Analog Stereo"))).unwrap(); + // println!("Sink: {:?}", pa.sink); + // println!("Volume before: {:?}", pa.get_vol()); + // pa.set_vol(80.0, VolDir::Up); + // println!("Volume after: {:?}", pa.get_vol()); + // println!("Mute before: {:?}", pa.get_mute()); + // println!("PA_VOLUME_NORM: {:?}", PA_VOLUME_NORM); // pa.set_mute(true); // println!("Mute after: {:?}", pa.get_mute()); - return; + // return; gtk::init() .unwrap_or_else(|e| panic!("Gtk initialization failed with {}", e)); - let apps = Rc::new(new_alsa_appstate()); + let apps = Rc::new(new_pa_appstate()); ui::entry::init(apps); diff --git a/src/notif.rs b/src/notif.rs index 670f31241..ec02588c0 100644 --- a/src/notif.rs +++ b/src/notif.rs @@ -144,37 +144,37 @@ where { { /* connect handler */ - let apps = appstate.clone(); - appstate.audio.connect_handler(Box::new(move |s, u| { - let notif = &apps.notif; - if notif.is_none() || !notif.as_ref().unwrap().enabled.get() { - return; - } - let notif = notif.as_ref().unwrap(); - match (s, - u, - (notif.from_popup.get(), - notif.from_tray.get(), - notif.from_external.get(), - notif.from_hotkeys.get())) { - (AudioSignal::NoCard, _, _) => try_w!(notif.show_text_notif("No sound card", "No playable soundcard found")), - (AudioSignal::CardDisconnected, _, _) => try_w!(notif.show_text_notif("Soundcard disconnected", "Soundcard has been disconnected, reloading sound system...")), - (AudioSignal::CardError, _, _) => (), - (AudioSignal::ValuesChanged, - AudioUser::TrayIcon, - (_, true, _, _)) => try_w!(notif.show_volume_notif(apps.audio.as_ref())), - (AudioSignal::ValuesChanged, - AudioUser::Popup, - (true, _, _, _)) => try_w!(notif.show_volume_notif(apps.audio.as_ref())), - (AudioSignal::ValuesChanged, - AudioUser::Unknown, - (_, _, true, _)) => try_w!(notif.show_volume_notif(apps.audio.as_ref())), - (AudioSignal::ValuesChanged, - AudioUser::Hotkeys, - (_, _, _, true)) => try_w!(notif.show_volume_notif(apps.audio.as_ref())), - _ => (), - } - })); + // let apps = appstate.clone(); + // appstate.audio.connect_handler(Box::new(move |s, u| { + // let notif = &apps.notif; + // if notif.is_none() || !notif.as_ref().unwrap().enabled.get() { + // return; + // } + // let notif = notif.as_ref().unwrap(); + // match (s, + // u, + // (notif.from_popup.get(), + // notif.from_tray.get(), + // notif.from_external.get(), + // notif.from_hotkeys.get())) { + // (AudioSignal::NoCard, _, _) => try_w!(notif.show_text_notif("No sound card", "No playable soundcard found")), + // (AudioSignal::CardDisconnected, _, _) => try_w!(notif.show_text_notif("Soundcard disconnected", "Soundcard has been disconnected, reloading sound system...")), + // (AudioSignal::CardError, _, _) => (), + // (AudioSignal::ValuesChanged, + // AudioUser::TrayIcon, + // (_, true, _, _)) => try_w!(notif.show_volume_notif(apps.audio.as_ref())), + // (AudioSignal::ValuesChanged, + // AudioUser::Popup, + // (true, _, _, _)) => try_w!(notif.show_volume_notif(apps.audio.as_ref())), + // (AudioSignal::ValuesChanged, + // AudioUser::Unknown, + // (_, _, true, _)) => try_w!(notif.show_volume_notif(apps.audio.as_ref())), + // (AudioSignal::ValuesChanged, + // AudioUser::Hotkeys, + // (_, _, _, true)) => try_w!(notif.show_volume_notif(apps.audio.as_ref())), + // _ => (), + // } + // })); } } diff --git a/src/support/audio.rs b/src/support/audio.rs index 82fef9d8c..6ce01c592 100644 --- a/src/support/audio.rs +++ b/src/support/audio.rs @@ -10,8 +10,6 @@ use audio::frontend::*; use errors::*; use prefs::*; -// TODO: rm alsa -use support::alsa::*; #[derive(Clone, Copy, Debug)] @@ -100,16 +98,25 @@ pub fn percent_to_vol(vol: f64, range: (i64, i64), dir: VolDir) -> Result { } -/// Get all playable card names. -pub fn get_playable_card_names() -> Vec { - return get_playable_alsa_card_names(); -} - - -/// Get all playable channel names. -pub fn get_playable_chan_names(card_name: String) -> Vec { - let card = try_r!(get_alsa_card_by_name(card_name), Vec::default()); - let mixer = try_r!(get_mixer(&card), Vec::default()); - - return get_playable_selem_names(&mixer); +/// Invokes the registered handlers. +pub fn invoke_handlers( + handlers: &Vec>, + signal: AudioSignal, + user: AudioUser, +) { + debug!( + "Invoking handlers for signal {:?} by user {:?}", + signal, + user + ); + if handlers.is_empty() { + debug!("No handler found"); + } else { + debug!("Executing handlers") + } + for handler in handlers { + debug!("Handler executing"); + let unboxed = handler.as_ref(); + unboxed(signal, user); + } } diff --git a/src/ui/entry.rs b/src/ui/entry.rs index 62bb84b90..2e565240f 100644 --- a/src/ui/entry.rs +++ b/src/ui/entry.rs @@ -63,31 +63,31 @@ where { { /* "global" audio signal handler */ - let apps = appstate.clone(); - appstate.audio.connect_handler( - Box::new(move |s, u| match (s, u) { - (AudioSignal::CardDisconnected, _) => { - try_w!(audio_reload( - apps.audio.as_ref(), - &apps.prefs.borrow(), - AudioUser::Unknown, - )); - } - (AudioSignal::CardError, _) => { - if run_audio_error_dialog( - &apps.gui.popup_menu.menu_window, - ) == (GTK_RESPONSE_YES as i32) - { - try_w!(audio_reload( - apps.audio.as_ref(), - &apps.prefs.borrow(), - AudioUser::Unknown, - )); - } - } - _ => (), - }), - ); + // let apps = appstate.clone(); + // appstate.audio.connect_handler( + // Box::new(move |s, u| match (s, u) { + // (AudioSignal::CardDisconnected, _) => { + // try_w!(audio_reload( + // apps.audio.as_ref(), + // &apps.prefs.borrow(), + // AudioUser::Unknown, + // )); + // } + // (AudioSignal::CardError, _) => { + // if run_audio_error_dialog( + // &apps.gui.popup_menu.menu_window, + // ) == (GTK_RESPONSE_YES as i32) + // { + // try_w!(audio_reload( + // apps.audio.as_ref(), + // &apps.prefs.borrow(), + // AudioUser::Unknown, + // )); + // } + // } + // _ => (), + // }), + // ); } diff --git a/src/ui/popup_menu.rs b/src/ui/popup_menu.rs index d4ea752ef..668887135 100644 --- a/src/ui/popup_menu.rs +++ b/src/ui/popup_menu.rs @@ -48,16 +48,16 @@ where { /* audio.connect_handler */ { - let apps = appstate.clone(); - appstate.audio.connect_handler(Box::new(move |s, u| { - /* skip if window is hidden */ - if !apps.gui.popup_menu.menu.get_visible() { - return; - } - match (s, u) { - (_, _) => set_mute_check(&apps), - } - })); + // let apps = appstate.clone(); + // appstate.audio.connect_handler(Box::new(move |s, u| { + // /* skip if window is hidden */ + // if !apps.gui.popup_menu.menu.get_visible() { + // return; + // } + // match (s, u) { + // (_, _) => set_mute_check(&apps), + // } + // })); } diff --git a/src/ui/popup_window.rs b/src/ui/popup_window.rs index 69ff00805..db6c562ce 100644 --- a/src/ui/popup_window.rs +++ b/src/ui/popup_window.rs @@ -125,31 +125,31 @@ where { /* audio.connect_handler */ { - let apps = appstate.clone(); - appstate.audio.connect_handler(Box::new(move |s, u| { - /* skip if window is hidden */ - if !apps.gui.popup_window.popup_window.get_visible() { - return; - } - match (s, u) { - /* Update only mute check here - * If the user changes the volume through the popup window, - * we MUST NOT update the slider value, it's been done already. - * It means that, as long as the popup window is visible, - * the slider value reflects the value set by user, - * and not the real value reported by the audio system. - */ - (_, AudioUser::Popup) => { - apps.gui.popup_window.update_mute_check( - apps.audio.as_ref(), - ); - } - /* external change, safe to update slider too */ - (_, _) => { - try_w!(apps.gui.popup_window.update(apps.audio.as_ref())); - } - } - })); + // let apps = appstate.clone(); + // appstate.audio.connect_handler(Box::new(move |s, u| { + // /* skip if window is hidden */ + // if !apps.gui.popup_window.popup_window.get_visible() { + // return; + // } + // match (s, u) { + // /* Update only mute check here + // * If the user changes the volume through the popup window, + // * we MUST NOT update the slider value, it's been done already. + // * It means that, as long as the popup window is visible, + // * the slider value reflects the value set by user, + // * and not the real value reported by the audio system. + // */ + // (_, AudioUser::Popup) => { + // apps.gui.popup_window.update_mute_check( + // apps.audio.as_ref(), + // ); + // } + // /* external change, safe to update slider too */ + // (_, _) => { + // try_w!(apps.gui.popup_window.update(apps.audio.as_ref())); + // } + // } + // })); } /* mute_check.connect_toggled */ diff --git a/src/ui/prefs_dialog.rs b/src/ui/prefs_dialog.rs index 3343326df..da6be7744 100644 --- a/src/ui/prefs_dialog.rs +++ b/src/ui/prefs_dialog.rs @@ -13,7 +13,6 @@ use prefs::*; use std::ascii::AsciiExt; use std::cell::RefCell; use std::rc::Rc; -use support::audio::*; use ui::hotkey_dialog::HotkeyDialog; @@ -434,21 +433,21 @@ where T: AudioFrontend + 'static, { let apps = appstate.clone(); - appstate.audio.connect_handler(Box::new(move |s, u| { - /* skip if prefs window is not present */ - if apps.gui.prefs_dialog.borrow().is_none() { - return; - } + // appstate.audio.connect_handler(Box::new(move |s, u| { + // /* skip if prefs window is not present */ + // if apps.gui.prefs_dialog.borrow().is_none() { + // return; + // } - match (s, u) { - (AudioSignal::CardInitialized, _) => (), - (AudioSignal::CardCleanedUp, _) => { - fill_card_combo(&apps); - fill_chan_combo(&apps, None); - } - _ => (), - } - })); + // match (s, u) { + // (AudioSignal::CardInitialized, _) => (), + // (AudioSignal::CardCleanedUp, _) => { + // fill_card_combo(&apps); + // fill_chan_combo(&apps, None); + // } + // _ => (), + // } + // })); } @@ -586,7 +585,7 @@ where /* set card combo */ let cur_card_name = try_w!(audio.card_name(), "Can't get current card name!"); - let available_card_names = get_playable_card_names(); + let available_card_names = audio.playable_card_names(); /* set_active_id doesn't work, so save the index */ let mut c_index: i32 = -1; @@ -613,10 +612,7 @@ where chan_combo.remove_all(); let audio = &appstate.audio; - let available_chan_names = match cardname { - Some(name) => get_playable_chan_names(name), - None => audio.playable_chan_names(), - }; + let available_chan_names = audio.playable_chan_names(cardname); /* set chan combo */ let cur_chan_name = try_w!(audio.chan_name()); diff --git a/src/ui/tray_icon.rs b/src/ui/tray_icon.rs index e29a2c670..d107c8b08 100644 --- a/src/ui/tray_icon.rs +++ b/src/ui/tray_icon.rs @@ -422,11 +422,14 @@ where appstate.audio.connect_handler( Box::new(move |s, u| match (s, u) { (_, _) => { - apps.gui.tray_icon.update_tooltip(apps.audio.as_ref()); - try_w!(apps.gui.tray_icon.update_vol_meter( - try_w!(apps.audio.get_vol()), - apps.audio.vol_level(), - )); + // apps.gui.tray_icon.update_tooltip(apps.audio.as_ref()); + // try_w!(apps.gui.tray_icon.update_vol_meter( + // try_w!(apps.audio.get_vol()), + // apps.audio.vol_level(), + // )); + let vol = apps.audio.get_vol(); + println!("Vol: {:?}", vol) + // println!("Gaga"); } }), );