use capi;
use std::ffi::CString;
use std::os::raw::{c_char, c_void};
use std::ptr::{null, null_mut};
use super::{ContextInternal, Context};
pub use capi::pa_ext_device_manager_role_priority_info as RolePriorityInfo;
pub use capi::pa_ext_device_manager_info as InfoInternal;
#[repr(C)]
pub struct Info {
pub name: *const c_char,
pub description: *const c_char,
pub icon: *const c_char,
pub index: u32,
pub n_role_priorities: u32,
pub role_priorities: *mut RolePriorityInfo,
}
pub struct DeviceManager {
pub context: *mut ContextInternal,
weak: bool,
}
impl Context {
pub fn device_manager(&self) -> DeviceManager {
unsafe { capi::pa_context_ref(self.ptr) };
DeviceManager::from_raw(self.ptr)
}
}
pub type TestCb = extern "C" fn(c: *mut ContextInternal, version: u32, userdata: *mut c_void);
pub type ReadCb = extern "C" fn(c: *mut ContextInternal, info: *const InfoInternal, eol: i32,
userdata: *mut c_void);
pub type SubscribeCb = extern "C" fn(c: *mut ContextInternal, userdata: *mut c_void);
impl DeviceManager {
pub fn from_raw(context: *mut ContextInternal) -> Self {
Self { context: context, weak: false }
}
pub fn from_raw_weak(context: *mut ContextInternal) -> Self {
Self { context: context, weak: true }
}
pub fn test(&self, cb: (TestCb, *mut c_void)) -> Option<::operation::Operation> {
let ptr = unsafe { capi::pa_ext_device_manager_test(self.context, Some(cb.0), cb.1) };
if ptr.is_null() {
return None;
}
Some(::operation::Operation::from_raw(ptr))
}
pub fn read(&self, cb: (ReadCb, *mut c_void)) -> Option<::operation::Operation> {
let ptr = unsafe { capi::pa_ext_device_manager_read(self.context, Some(cb.0), cb.1) };
if ptr.is_null() {
return None;
}
Some(::operation::Operation::from_raw(ptr))
}
pub fn set_device_description(&self, device: &str, description: &str,
cb: (::context::ContextSuccessCb, *mut c_void)) -> Option<::operation::Operation>
{
let c_dev = CString::new(device.clone()).unwrap();
let c_desc = CString::new(description.clone()).unwrap();
let ptr = unsafe {
capi::pa_ext_device_manager_set_device_description(self.context, c_dev.as_ptr(),
c_desc.as_ptr(), Some(cb.0), cb.1)
};
if ptr.is_null() {
return None;
}
Some(::operation::Operation::from_raw(ptr))
}
pub fn delete(&self, devices: &[&str], cb: (::context::ContextSuccessCb, *mut c_void)
) -> Option<::operation::Operation>
{
let mut c_devs: Vec<CString> = Vec::with_capacity(devices.len());
for device in devices {
c_devs.push(CString::new(device.clone()).unwrap());
}
let mut c_dev_ptrs: Vec<*const c_char> = Vec::with_capacity(c_devs.len()+1);
for c_dev in c_devs {
c_dev_ptrs.push(c_dev.as_ptr());
}
c_dev_ptrs.push(null());
let ptr = unsafe { capi::pa_ext_device_manager_delete(self.context, c_dev_ptrs.as_ptr(),
Some(cb.0), cb.1) };
if ptr.is_null() {
return None;
}
Some(::operation::Operation::from_raw(ptr))
}
pub fn enable_role_device_priority_routing(&self, enable: bool,
cb: (::context::ContextSuccessCb, *mut c_void)) -> Option<::operation::Operation>
{
let ptr = unsafe {
capi::pa_ext_device_manager_enable_role_device_priority_routing(self.context,
enable as i32, Some(cb.0), cb.1)
};
if ptr.is_null() {
return None;
}
Some(::operation::Operation::from_raw(ptr))
}
pub fn reorder_devices_for_role(&self, role: &str, devices: &[&str],
cb: (::context::ContextSuccessCb, *mut c_void)) -> Option<::operation::Operation>
{
let c_role = CString::new(role.clone()).unwrap();
let mut c_devs: Vec<CString> = Vec::with_capacity(devices.len());
for device in devices {
c_devs.push(CString::new(device.clone()).unwrap());
}
let mut c_dev_ptrs: Vec<*const c_char> = Vec::with_capacity(c_devs.len() + 1);
for c_dev in c_devs {
c_dev_ptrs.push(c_dev.as_ptr());
}
c_dev_ptrs.push(null());
let ptr = unsafe {
capi::pa_ext_device_manager_reorder_devices_for_role(self.context, c_role.as_ptr(),
c_dev_ptrs.as_ptr(), Some(cb.0), cb.1)
};
if ptr.is_null() {
return None;
}
Some(::operation::Operation::from_raw(ptr))
}
pub fn subscribe(&self, enable: bool, cb: (::context::ContextSuccessCb, *mut c_void)
) -> Option<::operation::Operation>
{
let ptr = unsafe { capi::pa_ext_device_manager_subscribe(self.context, enable as i32,
Some(cb.0), cb.1) };
if ptr.is_null() {
return None;
}
Some(::operation::Operation::from_raw(ptr))
}
pub fn set_subscribe_cb(&self, cb: (SubscribeCb, *mut c_void)) {
unsafe { capi::pa_ext_device_manager_set_subscribe_cb(self.context, Some(cb.0), cb.1) };
}
}
impl Drop for DeviceManager {
fn drop(&mut self) {
if !self.weak {
unsafe { capi::pa_context_unref(self.context) };
}
self.context = null_mut::<ContextInternal>();
}
}