mod application;
mod pipewire_connection;
mod view;
use glib::PRIORITY_DEFAULT;
use gtk::prelude::*;
use pipewire::spa::Direction;
#[derive(Debug, Clone)]
enum GtkMessage {
ToggleLink { port_from: u32, port_to: u32 },
Terminate,
}
#[derive(Debug, Clone)]
enum PipewireMessage {
NodeAdded {
id: u32,
name: String,
node_type: Option<NodeType>,
},
PortAdded {
id: u32,
node_id: u32,
name: String,
direction: Direction,
media_type: Option<MediaType>,
},
LinkAdded {
id: u32,
node_from: u32,
port_from: u32,
node_to: u32,
port_to: u32,
active: bool,
},
LinkStateChanged {
id: u32,
active: bool,
},
NodeRemoved {
id: u32,
},
PortRemoved {
id: u32,
node_id: u32,
},
LinkRemoved {
id: u32,
},
}
#[derive(Debug, Clone)]
pub enum NodeType {
Input,
Output,
}
#[derive(Debug, Copy, Clone)]
pub enum MediaType {
Audio,
Video,
Midi,
}
#[derive(Debug, Clone)]
pub struct PipewireLink {
pub node_from: u32,
pub port_from: u32,
pub node_to: u32,
pub port_to: u32,
}
static GLIB_LOGGER: glib::GlibLogger = glib::GlibLogger::new(
glib::GlibLoggerFormat::Structured,
glib::GlibLoggerDomain::CrateTarget,
);
fn init_glib_logger() {
log::set_logger(&GLIB_LOGGER).expect("Failed to set logger");
log::set_max_level(log::LevelFilter::Debug);
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
init_glib_logger();
gtk::init()?;
let ctx = glib::MainContext::default();
let _guard = ctx.acquire().unwrap();
let (gtk_sender, gtk_receiver) = glib::MainContext::channel(PRIORITY_DEFAULT);
let (pw_sender, pw_receiver) = pipewire::channel::channel();
let pw_thread =
std::thread::spawn(move || pipewire_connection::thread_main(gtk_sender, pw_receiver));
let app = application::Application::new(gtk_receiver, pw_sender.clone());
app.run();
pw_sender
.send(GtkMessage::Terminate)
.expect("Failed to send message");
pw_thread.join().expect("Pipewire thread panicked");
Ok(())
}