diff --git a/Cargo.toml b/Cargo.toml index c8b88d770..6da867b25 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,6 +34,7 @@ gtk-sys = "0.4.0" lazy_static = "0.2.8" libc = "0.2.31" libnotify = { version = "^1.0.2", optional = true } +libpulse-sys = "0.0.0" log = "0.3.8" png = "0.10.0" serde = "1.0.15" diff --git a/src/audio/mod.rs b/src/audio/mod.rs index 230129e32..167ba4bb6 100644 --- a/src/audio/mod.rs +++ b/src/audio/mod.rs @@ -2,3 +2,4 @@ pub mod alsa; pub mod frontend; +pub mod pulseaudio; diff --git a/src/audio/pulseaudio.rs b/src/audio/pulseaudio.rs new file mode 100644 index 000000000..e69de29bb diff --git a/src/bin.rs b/src/bin.rs index 6d9cf671c..16622cfae 100644 --- a/src/bin.rs +++ b/src/bin.rs @@ -1,6 +1,8 @@ #![feature(alloc_system)] extern crate alloc_system; extern crate getopts; +extern crate libpulse_sys; +extern crate libc; extern crate pnmixerlib; @@ -10,9 +12,79 @@ use app_state::*; use getopts::Options; use std::rc::Rc; use std::env; +use audio::pulseaudio; +use libpulse_sys::*; +use std::ffi::{CString, CStr}; +use std::os::raw::c_char; +use std::ptr; +static mut CONTEXT_READY: bool = false; + + +unsafe extern "C" fn context_state_cb( + ctx: *mut pa_context, data: *mut libc::c_void) { + + let mainloop: *mut pa_threaded_mainloop = data as *mut pa_threaded_mainloop; + let state = pa_context_get_state(ctx); + + match state { + PA_CONTEXT_READY => { + CONTEXT_READY = true; + pa_threaded_mainloop_signal(mainloop, 1); + }, + _ => () + } + +} + fn main() { + unsafe { + let mainloop: *mut pa_threaded_mainloop = pa_threaded_mainloop_new(); + + if mainloop.is_null() { + panic!("Oh no"); + } + + let api: *mut pa_mainloop_api = pa_threaded_mainloop_get_api(mainloop); + + let context_name = CString::new("pnmixer-rs").unwrap(); + let context: *mut pa_context = pa_context_new(api, + context_name.as_ptr()); + + if context.is_null() { + panic!("Oh no"); + } + + pa_context_set_state_callback(context, + Some(context_state_cb), + mainloop as *mut libc::c_void); + let ret = pa_context_connect(context, + std::ptr::null_mut(), + 0, + std::ptr::null_mut()); + + if ret < 0 { + panic!("Oh no"); + } + + let ret = pa_threaded_mainloop_start(mainloop); + + if ret < 0 { + panic!("Oh no"); + } + + pa_threaded_mainloop_lock(mainloop); + while !CONTEXT_READY { + pa_threaded_mainloop_wait(mainloop); + } + pa_threaded_mainloop_accept(mainloop); + pa_threaded_mainloop_unlock(mainloop); + CONTEXT_READY = false; + + } + + let args: Vec = env::args().collect(); let mut opts = Options::new();