mirror of
https://github.com/Xetibo/ReSet.git
synced 2025-04-16 17:58:33 +02:00
233 lines
9.3 KiB
Rust
233 lines
9.3 KiB
Rust
use std::{sync::Arc, time::Duration};
|
|
|
|
use adw::prelude::{ComboRowExt, PreferencesGroupExt};
|
|
use dbus::{blocking::Connection, Error};
|
|
use glib::subclass::types::ObjectSubclassIsExt;
|
|
use gtk::{
|
|
gio,
|
|
prelude::{BoxExt, ButtonExt, CheckButtonExt, ListBoxRowExt, RangeExt},
|
|
};
|
|
use re_set_lib::audio::audio_structures::{Card, InputStream, Sink};
|
|
|
|
use crate::components::{
|
|
base::{card_entry::CardEntry, error_impl::show_error, list_entry::ListEntry},
|
|
utils::{AUDIO, BASE, DBUS_PATH},
|
|
};
|
|
|
|
use super::{
|
|
input_stream_entry::InputStreamEntry,
|
|
sink_box::SinkBox,
|
|
sink_box_handlers::{drop_down_handler, mute_handler, volume_slider_handler},
|
|
sink_entry::SinkEntry,
|
|
};
|
|
|
|
pub fn populate_sink_information(sink_box: Arc<SinkBox>, sinks: Vec<Sink>) {
|
|
glib::spawn_future(async move {
|
|
glib::idle_add_once(move || {
|
|
let sink_box_ref_select = sink_box.clone();
|
|
let sink_box_ref_slider = sink_box.clone();
|
|
let sink_box_ref_mute = sink_box.clone();
|
|
let sink_box_ref = sink_box.clone();
|
|
{
|
|
let sink_box_imp = sink_box_ref.imp();
|
|
let default_sink = sink_box_imp.reset_default_sink.clone();
|
|
let sink = default_sink.borrow();
|
|
|
|
if sink.muted {
|
|
sink_box_imp
|
|
.reset_sink_mute
|
|
.set_icon_name("audio-volume-muted-symbolic");
|
|
} else {
|
|
sink_box_imp
|
|
.reset_sink_mute
|
|
.set_icon_name("audio-volume-high-symbolic");
|
|
}
|
|
|
|
let volume = sink.volume.first().unwrap_or(&0);
|
|
let fraction = (*volume as f64 / 655.36).round();
|
|
let percentage = (fraction).to_string() + "%";
|
|
sink_box_imp.reset_volume_percentage.set_text(&percentage);
|
|
sink_box_imp.reset_volume_slider.set_value(*volume as f64);
|
|
let mut list = sink_box_imp.reset_sink_list.write().unwrap();
|
|
for sink in sinks {
|
|
let index = sink.index;
|
|
let alias = sink.alias.clone();
|
|
let mut is_default = false;
|
|
if sink_box_imp.reset_default_sink.borrow().name == sink.name {
|
|
is_default = true;
|
|
}
|
|
let sink_entry = SinkEntry::new(
|
|
is_default,
|
|
sink_box_imp.reset_default_check_button.clone(),
|
|
sink,
|
|
sink_box.clone(),
|
|
);
|
|
let sink_clone = sink_entry.clone();
|
|
let entry = Arc::new(ListEntry::new(&*sink_entry));
|
|
entry.set_activatable(false);
|
|
list.insert(index, (entry.clone(), sink_clone, alias));
|
|
sink_box_imp.reset_sinks.append(&*entry);
|
|
}
|
|
let list = sink_box_imp.reset_model_list.read().unwrap();
|
|
sink_box_imp.reset_sink_dropdown.set_model(Some(&*list));
|
|
let name = sink_box_imp.reset_default_sink.borrow();
|
|
|
|
let index = sink_box_imp.reset_model_index.read().unwrap();
|
|
let model_list = sink_box_imp.reset_model_list.read().unwrap();
|
|
for entry in 0..*index {
|
|
if model_list.string(entry) == Some(name.alias.clone().into()) {
|
|
sink_box_imp.reset_sink_dropdown.set_selected(entry);
|
|
break;
|
|
}
|
|
}
|
|
sink_box_imp
|
|
.reset_sink_dropdown
|
|
.connect_selected_notify(move |dropdown| {
|
|
drop_down_handler(sink_box_ref_select.clone(), dropdown);
|
|
});
|
|
}
|
|
sink_box_ref
|
|
.imp()
|
|
.reset_volume_slider
|
|
.connect_change_value(move |_, _, value| {
|
|
volume_slider_handler(sink_box_ref_slider.clone(), value)
|
|
});
|
|
sink_box_ref
|
|
.imp()
|
|
.reset_sink_mute
|
|
.connect_clicked(move |_| {
|
|
mute_handler(sink_box_ref_mute.clone());
|
|
});
|
|
});
|
|
});
|
|
}
|
|
|
|
pub fn refresh_default_sink(new_sink: Sink, sink_box: Arc<SinkBox>, entry: bool) {
|
|
let volume = *new_sink.volume.first().unwrap_or(&0_u32);
|
|
let fraction = (volume as f64 / 655.36).round();
|
|
let percentage = (fraction).to_string() + "%";
|
|
glib::spawn_future(async move {
|
|
glib::idle_add_once(move || {
|
|
let imp = sink_box.imp();
|
|
if !entry {
|
|
let list = imp.reset_sink_list.read().unwrap();
|
|
let entry = list.get(&new_sink.index);
|
|
if entry.is_none() {
|
|
return;
|
|
}
|
|
let entry_imp = entry.unwrap().1.imp();
|
|
entry_imp.reset_selected_sink.set_active(true);
|
|
} else {
|
|
let index = imp.reset_model_index.read().unwrap();
|
|
let model_list = imp.reset_model_list.read().unwrap();
|
|
for entry in 0..*index {
|
|
if model_list.string(entry) == Some(new_sink.alias.clone().into()) {
|
|
imp.reset_sink_dropdown.set_selected(entry);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
imp.reset_volume_percentage.set_text(&percentage);
|
|
imp.reset_volume_slider.set_value(volume as f64);
|
|
if new_sink.muted {
|
|
imp.reset_sink_mute
|
|
.set_icon_name("audio-volume-muted-symbolic");
|
|
} else {
|
|
imp.reset_sink_mute
|
|
.set_icon_name("audio-volume-high-symbolic");
|
|
}
|
|
imp.reset_default_sink.replace(new_sink);
|
|
});
|
|
});
|
|
}
|
|
|
|
pub fn populate_inputstreams(sink_box: Arc<SinkBox>) {
|
|
gio::spawn_blocking(move || {
|
|
let streams = get_input_streams(sink_box.clone());
|
|
glib::spawn_future(async move {
|
|
glib::idle_add_once(move || {
|
|
let sink_box_imp = sink_box.imp();
|
|
let mut list = sink_box_imp.reset_input_stream_list.write().unwrap();
|
|
for stream in streams {
|
|
let index = stream.index;
|
|
let input_stream = Arc::new(InputStreamEntry::new(sink_box.clone(), stream));
|
|
let entry = Arc::new(ListEntry::new(&*input_stream));
|
|
entry.set_activatable(false);
|
|
list.insert(index, (entry.clone(), input_stream.clone()));
|
|
sink_box_imp.reset_input_streams.append(&*entry);
|
|
}
|
|
});
|
|
});
|
|
});
|
|
}
|
|
|
|
pub fn populate_cards(sink_box: Arc<SinkBox>) {
|
|
gio::spawn_blocking(move || {
|
|
let sink_box_ref = sink_box.clone();
|
|
let cards = get_cards(sink_box.clone());
|
|
glib::spawn_future(async move {
|
|
glib::idle_add_once(move || {
|
|
let imp = sink_box_ref.imp();
|
|
for card in cards {
|
|
imp.reset_cards.add(&CardEntry::new(card));
|
|
}
|
|
});
|
|
});
|
|
});
|
|
}
|
|
|
|
pub fn get_input_streams(sink_box: Arc<SinkBox>) -> Vec<InputStream> {
|
|
let conn = Connection::new_session().unwrap();
|
|
let proxy = conn.with_proxy(BASE, DBUS_PATH, Duration::from_millis(1000));
|
|
let res: Result<(Vec<InputStream>,), Error> = proxy.method_call(AUDIO, "ListInputStreams", ());
|
|
if res.is_err() {
|
|
show_error::<SinkBox>(sink_box.clone(), "Failed to list input streams");
|
|
return Vec::new();
|
|
}
|
|
res.unwrap().0
|
|
}
|
|
|
|
pub fn get_sinks(sink_box: Arc<SinkBox>) -> Vec<Sink> {
|
|
let conn = Connection::new_session().unwrap();
|
|
let proxy = conn.with_proxy(BASE, DBUS_PATH, Duration::from_millis(1000));
|
|
let res: Result<(Vec<Sink>,), Error> = proxy.method_call(AUDIO, "ListSinks", ());
|
|
if res.is_err() {
|
|
show_error::<SinkBox>(sink_box.clone(), "Failed to list sinks");
|
|
return Vec::new();
|
|
}
|
|
res.unwrap().0
|
|
}
|
|
|
|
pub fn get_cards(sink_box: Arc<SinkBox>) -> Vec<Card> {
|
|
let conn = Connection::new_session().unwrap();
|
|
let proxy = conn.with_proxy(BASE, DBUS_PATH, Duration::from_millis(1000));
|
|
let res: Result<(Vec<Card>,), Error> = proxy.method_call(AUDIO, "ListCards", ());
|
|
if res.is_err() {
|
|
show_error::<SinkBox>(sink_box.clone(), "Failed to list profiles");
|
|
return Vec::new();
|
|
}
|
|
res.unwrap().0
|
|
}
|
|
|
|
pub fn get_default_sink_name(sink_box: Arc<SinkBox>) -> String {
|
|
let conn = Connection::new_session().unwrap();
|
|
let proxy = conn.with_proxy(BASE, DBUS_PATH, Duration::from_millis(1000));
|
|
let res: Result<(String,), Error> = proxy.method_call(AUDIO, "GetDefaultSinkName", ());
|
|
if res.is_err() {
|
|
show_error::<SinkBox>(sink_box.clone(), "Failed to get default sink name");
|
|
return String::from("");
|
|
}
|
|
res.unwrap().0
|
|
}
|
|
|
|
pub fn get_default_sink(sink_box: Arc<SinkBox>) -> Sink {
|
|
let conn = Connection::new_session().unwrap();
|
|
let proxy = conn.with_proxy(BASE, DBUS_PATH, Duration::from_millis(1000));
|
|
let res: Result<(Sink,), Error> = proxy.method_call(AUDIO, "GetDefaultSink", ());
|
|
if res.is_err() {
|
|
show_error::<SinkBox>(sink_box.clone(), "Failed to get default sink");
|
|
return Sink::default();
|
|
}
|
|
res.unwrap().0
|
|
}
|