diff --git a/src/audio/audio.rs b/src/audio/audio.rs index 86a3007..b40bac2 100644 --- a/src/audio/audio.rs +++ b/src/audio/audio.rs @@ -174,10 +174,6 @@ impl PulseServer { } _ => (), } - dbg!(facility); - dbg!(operation); - dbg!(index); - // unsafe { (*ml_ref.as_ptr()).signal(false) } }, ))); @@ -205,7 +201,9 @@ impl PulseServer { pub fn handle_message(&self, message: AudioRequest) { match message { AudioRequest::ListSinks => self.get_sinks(), + AudioRequest::GetDefaultSink => self.get_default_sink(), AudioRequest::ListSources => self.get_sources(), + AudioRequest::GetDefaultSource => self.get_default_source(), AudioRequest::ListInputStreams => self.get_input_streams(), AudioRequest::ListOutputStreams => self.get_output_streams(), AudioRequest::SetInputStreamMute(input_stream) => { @@ -236,6 +234,81 @@ impl PulseServer { } } + pub fn get_default_sink(&self) { + self.mainloop.borrow_mut().lock(); + let introspector = self.context.borrow().introspect(); + let sink = Rc::new(RefCell::new(Vec::new())); + let sink_ref = sink.clone(); + let sink_name = Rc::new(RefCell::new(String::from(""))); + let sink_name_ref = sink_name.clone(); + let ml_ref = Rc::clone(&self.mainloop); + introspector.get_server_info(move |result| { + if result.default_sink_name.is_some() { + let mut borrow = sink_name_ref.borrow_mut(); + *borrow = String::from(result.default_sink_name.clone().unwrap()); + } + }); + let result = + introspector.get_sink_info_by_name( + sink_name.take().as_str(), + move |result| match result { + ListResult::Item(item) => { + sink_ref.borrow_mut().push(item.into()); + } + ListResult::Error => unsafe { + (*ml_ref.as_ptr()).signal(true); + }, + ListResult::End => unsafe { + (*ml_ref.as_ptr()).signal(false); + }, + }, + ); + while result.get_state() != pulse::operation::State::Done { + self.mainloop.borrow_mut().wait(); + } + let _ = self + .sender + .send(AudioResponse::DefaultSink(sink.take().pop().unwrap())); + self.mainloop.borrow_mut().unlock(); + } + + pub fn get_default_source(&self) { + self.mainloop.borrow_mut().lock(); + let introspector = self.context.borrow().introspect(); + let source = Rc::new(RefCell::new(Vec::new())); + let source_ref = source.clone(); + let source_name = Rc::new(RefCell::new(String::from(""))); + let source_name_ref = source_name.clone(); + let ml_ref = Rc::clone(&self.mainloop); + introspector.get_server_info(move |result| { + if result.default_source_name.is_some() { + let mut borrow = source_name_ref.borrow_mut(); + *borrow = String::from(result.default_sink_name.clone().unwrap()); + } + }); + let result = + introspector.get_source_info_by_name(source_name.take().as_str(), move |result| { + match result { + ListResult::Item(item) => { + source_ref.borrow_mut().push(item.into()); + } + ListResult::Error => unsafe { + (*ml_ref.as_ptr()).signal(true); + }, + ListResult::End => unsafe { + (*ml_ref.as_ptr()).signal(false); + }, + } + }); + while result.get_state() != pulse::operation::State::Done { + self.mainloop.borrow_mut().wait(); + } + let _ = self + .sender + .send(AudioResponse::DefaultSource(source.take().pop().unwrap())); + self.mainloop.borrow_mut().unlock(); + } + pub fn get_sinks(&self) { self.mainloop.borrow_mut().lock(); let introspector = self.context.borrow().introspect(); diff --git a/src/lib.rs b/src/lib.rs index 490bdc3..588346a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,6 +3,8 @@ mod bluetooth; mod network; use std::{ + borrow::BorrowMut, + cell::RefCell, collections::HashMap, future::{self}, sync::{atomic::AtomicBool, Arc, Mutex}, @@ -39,10 +41,12 @@ use crate::{ pub enum AudioRequest { ListSources, + GetDefaultSource, SetSourceVolume(Source), SetSourceMute(Source), SetDefaultSource(Source), ListSinks, + GetDefaultSink, SetSinkVolume(Sink), SetSinkMute(Sink), SetDefaultSink(Sink), @@ -57,6 +61,8 @@ pub enum AudioRequest { } pub enum AudioResponse { + DefaultSink(Sink), + DefaultSource(Source), Sources(Vec), Sinks(Vec), InputStreams(Vec), @@ -430,6 +436,58 @@ pub async fn run_daemon() { Ok((true,)) }, ); + c.method_with_cr_async( + "GetDefaultSink", + (), + ("default_sink",), + move |mut ctx, cross, ()| { + let data: &mut DaemonData = cross.data_mut(ctx.path()).unwrap(); + let sink: Option; + let _ = data.audio_sender.send(AudioRequest::GetDefaultSink); + let response = data.audio_receiver.recv(); + if response.is_ok() { + sink = match response.unwrap() { + AudioResponse::DefaultSink(s) => Some(s), + _ => None, + } + } else { + sink = None; + } + let response: Result<(Sink,), dbus::MethodErr>; + if sink.is_none() { + response = Err(dbus::MethodErr::failed("Could not get default sink")); + } else { + response = Ok((sink.unwrap(),)); + } + async move { ctx.reply(response) } + }, + ); + c.method_with_cr_async( + "GetDefaultSource", + (), + ("default_source",), + move |mut ctx, cross, ()| { + let data: &mut DaemonData = cross.data_mut(ctx.path()).unwrap(); + let source: Option; + let _ = data.audio_sender.send(AudioRequest::GetDefaultSource); + let response = data.audio_receiver.recv(); + if response.is_ok() { + source = match response.unwrap() { + AudioResponse::DefaultSource(s) => Some(s), + _ => None, + } + } else { + source = None; + } + let response: Result<(Source,), dbus::MethodErr>; + if source.is_none() { + response = Err(dbus::MethodErr::failed("Could not get default sink")); + } else { + response = Ok((source.unwrap(),)); + } + async move { ctx.reply(response) } + }, + ); c.method_with_cr_async("ListSinks", (), ("sinks",), move |mut ctx, cross, ()| { let data: &mut DaemonData = cross.data_mut(ctx.path()).unwrap(); let sinks: Vec; @@ -562,6 +620,28 @@ pub async fn run_daemon() { async move { ctx.reply(Ok((result,))) } }, ); + c.method_with_cr_async( + "SetDefaultSource", + ("source",), + ("result",), + move |mut ctx, cross, (source,): (Source,)| { + let data: &mut DaemonData = cross.data_mut(ctx.path()).unwrap(); + let _ = data + .audio_sender + .send(AudioRequest::SetDefaultSource(source)); + let result: bool; + let res = data.audio_receiver.recv(); + if res.is_err() { + result = false; + } else { + result = match res.unwrap() { + AudioResponse::BoolResponse(b) => b, + _ => false, + }; + } + async move { ctx.reply(Ok((result,))) } + }, + ); c.method_with_cr_async( "ListInputStreams", (),