Skip to content

Commit 52550d0

Browse files
committed
Add function to redirect snd errors to an Output struct
Fixes: #138
1 parent 91360a5 commit 52550d0

File tree

2 files changed

+42
-0
lines changed

2 files changed

+42
-0
lines changed

src/chmap.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,11 @@ fn chmap_for_first_pcm() {
139139
use super::*;
140140
use std::ffi::CString;
141141
use crate::device_name::HintIter;
142+
143+
use crate::Output;
144+
145+
let output = Output::local_error_handler().unwrap();
146+
142147
let i = HintIter::new(None, &*CString::new("pcm").unwrap()).unwrap();
143148
for p in i.map(|n| n.name.unwrap()) {
144149
println!("Chmaps for {:?}:", p);
@@ -149,4 +154,10 @@ fn chmap_for_first_pcm() {
149154
Err(a) => println!(" {}", a) // It's okay to have entries in the name hint array that can't be opened
150155
}
151156
}
157+
158+
output.borrow_mut().buffer_string(|buf| {
159+
let str = CString::new(buf).unwrap();
160+
println!("Errors:\n{}", str.to_str().unwrap());
161+
});
162+
152163
}

src/io.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,19 @@
11
use crate::alsa;
22
use super::error::*;
33
use std::{slice, ptr, fmt};
4+
use std::cell::RefCell;
5+
use std::rc::Rc;
6+
use libc::{c_char, c_int};
47

58
/// [snd_output_t](http://www.alsa-project.org/alsa-doc/alsa-lib/group___output.html) wrapper
69
pub struct Output(*mut alsa::snd_output_t);
710

811
unsafe impl Send for Output {}
912

13+
thread_local! {
14+
static ERROR_OUTPUT: RefCell<Option<Rc<RefCell<Output>>>> = RefCell::new(None);
15+
}
16+
1017
impl Drop for Output {
1118
fn drop(&mut self) { unsafe { alsa::snd_output_close(self.0) }; }
1219
}
@@ -26,6 +33,14 @@ impl Output {
2633
};
2734
f(b)
2835
}
36+
37+
pub fn local_error_handler() -> Result<Rc<RefCell<Output>>> {
38+
let output = Output::buffer_open()?;
39+
let r = Rc::new(RefCell::new(output));
40+
ERROR_OUTPUT.with_borrow_mut(|e| *e = Some(r.clone()));
41+
unsafe { alsa::snd_lib_error_set_local(Some(our_error_handler)); }
42+
Ok(r)
43+
}
2944
}
3045

3146
impl fmt::Debug for Output {
@@ -47,3 +62,19 @@ impl fmt::Display for Output {
4762
}
4863

4964
pub fn output_handle(o: &Output) -> *mut alsa::snd_output_t { o.0 }
65+
66+
unsafe extern "C" fn our_error_handler(file: *const c_char,
67+
line: c_int,
68+
func: *const c_char,
69+
err: c_int,
70+
fmt: *const c_char,
71+
arg: *mut alsa::__va_list_tag,
72+
) {
73+
ERROR_OUTPUT.with_borrow(|e| {
74+
let b = e.as_ref().expect("ERROR_OUTPUT not set").borrow_mut();
75+
alsa::snd_output_puts(b.0, func);
76+
alsa::snd_output_puts(b.0, c": ".as_ptr());
77+
alsa::snd_output_vprintf(b.0, fmt, arg);
78+
alsa::snd_output_putc(b.0, '\n' as i32);
79+
})
80+
}

0 commit comments

Comments
 (0)