use capi;
use std::os::raw::c_void;
use super::{ContextInternal, Context};
use callbacks::box_closure_get_capi_ptr;
pub use capi::context::subscribe::pa_subscription_event_type_t as EventType;
pub use capi::PA_SUBSCRIPTION_EVENT_FACILITY_MASK as FACILITY_MASK;
pub use capi::PA_SUBSCRIPTION_EVENT_TYPE_MASK as OPERATION_MASK;
pub type InterestMaskSet = capi::context::subscribe::pa_subscription_mask_t;
pub mod subscription_masks {
use capi;
use super::InterestMaskSet;
pub const NULL: InterestMaskSet = capi::PA_SUBSCRIPTION_MASK_NULL;
pub const SINK: InterestMaskSet = capi::PA_SUBSCRIPTION_MASK_SINK;
pub const SOURCE: InterestMaskSet = capi::PA_SUBSCRIPTION_MASK_SOURCE;
pub const SINK_INPUT: InterestMaskSet = capi::PA_SUBSCRIPTION_MASK_SINK_INPUT;
pub const SOURCE_OUTPUT: InterestMaskSet = capi::PA_SUBSCRIPTION_MASK_SOURCE_OUTPUT;
pub const MODULE: InterestMaskSet = capi::PA_SUBSCRIPTION_MASK_MODULE;
pub const CLIENT: InterestMaskSet = capi::PA_SUBSCRIPTION_MASK_CLIENT;
pub const SAMPLE_CACHE: InterestMaskSet = capi::PA_SUBSCRIPTION_MASK_SAMPLE_CACHE;
pub const SERVER: InterestMaskSet = capi::PA_SUBSCRIPTION_MASK_SERVER;
pub const MASK_CARD: InterestMaskSet = capi::PA_SUBSCRIPTION_MASK_CARD;
pub const ALL: InterestMaskSet = capi::PA_SUBSCRIPTION_MASK_ALL;
}
#[repr(u32)]
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum Facility {
Sink = 0,
Source = 1,
SinkInput = 2,
SourceOutput = 3,
Module = 4,
Client = 5,
SampleCache = 6,
Server = 7,
Card = 9,
}
#[repr(u32)]
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum Operation {
New = 0,
Changed = 0x10,
Removed = 0x20,
}
impl Facility {
fn from_int(value: u32) -> Option<Facility> {
match value {
0 => Some(Facility::Sink),
1 => Some(Facility::Source),
2 => Some(Facility::SinkInput),
3 => Some(Facility::SourceOutput),
4 => Some(Facility::Module),
5 => Some(Facility::Client),
6 => Some(Facility::SampleCache),
7 => Some(Facility::Server),
9 => Some(Facility::Card),
_ => None,
}
}
pub fn to_interest_mask(self) -> InterestMaskSet {
1u32 << (self as u32)
}
}
impl Operation {
fn from_int(value: u32) -> Option<Operation> {
match value {
0 => Some(Operation::New),
0x10 => Some(Operation::Changed),
0x20 => Some(Operation::Removed),
_ => None,
}
}
}
fn get_facility(value: EventType) -> Option<Facility> {
Facility::from_int((value & FACILITY_MASK) as u32)
}
fn get_operation(value: EventType) -> Option<Operation> {
Operation::from_int((value & OPERATION_MASK) as u32)
}
pub(super) type Callback = ::callbacks::MultiUseCallback<FnMut(Option<Facility>, Option<Operation>,
u32), extern "C" fn(*mut ContextInternal, EventType, u32, *mut c_void)>;
impl Context {
pub fn subscribe<F>(&mut self, mask: InterestMaskSet, callback: F
) -> ::operation::Operation<FnMut(bool)>
where F: FnMut(bool) + 'static
{
let cb_data = box_closure_get_capi_ptr::<FnMut(bool)>(Box::new(callback));
let ptr = unsafe { capi::pa_context_subscribe(self.ptr, mask, Some(super::success_cb_proxy),
cb_data) };
assert!(!ptr.is_null());
::operation::Operation::from_raw(ptr, cb_data as *mut Box<FnMut(bool)>)
}
pub fn set_subscribe_callback(&mut self,
callback: Option<Box<FnMut(Option<Facility>, Option<Operation>, u32) + 'static>>)
{
let saved = &mut self.cb_ptrs.subscribe;
*saved = Callback::new(callback);
let (cb_fn, cb_data) = saved.get_capi_params(cb_proxy);
unsafe { capi::pa_context_set_subscribe_callback(self.ptr, cb_fn, cb_data); }
}
}
extern "C"
fn cb_proxy(_: *mut ContextInternal, et: EventType, index: u32, userdata: *mut c_void) {
let facility = get_facility(et);
let operation = get_operation(et);
let callback = Callback::get_callback(userdata);
callback(facility, operation, index);
}