11use crate :: alsa;
22use super :: error:: * ;
33use 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
69pub struct Output ( * mut alsa:: snd_output_t ) ;
710
811unsafe impl Send for Output { }
912
13+ thread_local ! {
14+ static ERROR_OUTPUT : RefCell <Option <Rc <RefCell <Output >>>> = RefCell :: new( None ) ;
15+ }
16+
1017impl 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
3146impl fmt:: Debug for Output {
@@ -47,3 +62,19 @@ impl fmt::Display for Output {
4762}
4863
4964pub 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