Skip to content

Commit

Permalink
feat: Add default Sink and Source functions
Browse files Browse the repository at this point in the history
  • Loading branch information
DashieTM committed Nov 13, 2023
1 parent c1d351d commit 7f278e8
Show file tree
Hide file tree
Showing 2 changed files with 157 additions and 4 deletions.
81 changes: 77 additions & 4 deletions src/audio/audio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,10 +174,6 @@ impl PulseServer {
}
_ => (),
}
dbg!(facility);
dbg!(operation);
dbg!(index);
// unsafe { (*ml_ref.as_ptr()).signal(false) }
},
)));

Expand Down Expand Up @@ -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) => {
Expand Down Expand Up @@ -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();
Expand Down
80 changes: 80 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ mod bluetooth;
mod network;

use std::{
borrow::BorrowMut,
cell::RefCell,
collections::HashMap,
future::{self},
sync::{atomic::AtomicBool, Arc, Mutex},
Expand Down Expand Up @@ -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),
Expand All @@ -57,6 +61,8 @@ pub enum AudioRequest {
}

pub enum AudioResponse {
DefaultSink(Sink),
DefaultSource(Source),
Sources(Vec<Source>),
Sinks(Vec<Sink>),
InputStreams(Vec<InputStream>),
Expand Down Expand Up @@ -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<Sink>;
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<Source>;
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<Sink>;
Expand Down Expand Up @@ -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",
(),
Expand Down

0 comments on commit 7f278e8

Please sign in to comment.