Revision control
Copy as Markdown
Other Tools
// Copyright © 2017 Mozilla Foundation
//
// This program is made available under an ISC-style license. See the
// accompanying file LICENSE for details.
use ffi;
use std::mem;
use std::os::raw::c_void;
#[allow(non_camel_case_types)]
type pa_once_cb_t =
Option<unsafe extern "C" fn(m: *mut ffi::pa_mainloop_api, userdata: *mut c_void)>;
fn wrap_once_cb<F>(_: F) -> pa_once_cb_t
where
F: Fn(&MainloopApi, *mut c_void),
{
assert!(mem::size_of::<F>() == 0);
unsafe extern "C" fn wrapped<F>(m: *mut ffi::pa_mainloop_api, userdata: *mut c_void)
where
F: Fn(&MainloopApi, *mut c_void),
{
let api = from_raw_ptr(m);
let result = mem::transmute::<_, &F>(&())(&api, userdata);
mem::forget(api);
result
}
Some(wrapped::<F>)
}
pub struct MainloopApi(*mut ffi::pa_mainloop_api);
impl MainloopApi {
pub fn raw_mut(&self) -> &mut ffi::pa_mainloop_api {
unsafe { &mut *self.0 }
}
pub fn once<CB>(&self, cb: CB, userdata: *mut c_void)
where
CB: Fn(&MainloopApi, *mut c_void),
{
let wrapped = wrap_once_cb(cb);
unsafe {
ffi::pa_mainloop_api_once(self.raw_mut(), wrapped, userdata);
}
}
pub fn time_free(&self, e: *mut ffi::pa_time_event) {
unsafe {
if let Some(f) = self.raw_mut().time_free {
f(e);
}
}
}
}
pub unsafe fn from_raw_ptr(raw: *mut ffi::pa_mainloop_api) -> MainloopApi {
MainloopApi(raw)
}