use std::ffi::CStr;
use std::pin::Pin;
use std::ptr::NonNull;
use pipewire_wrapper_proc_macro::{interface, RawWrapper, Wrapper};
use crate::core_api::context::Context;
use crate::core_api::core::events::CoreEvents;
use crate::core_api::properties::Properties;
use crate::core_api::registry::{Registry, RegistryRef};
use crate::listeners::{AddListener, OwnListeners};
use crate::spa_interface_call;
use crate::wrapper::{RawWrapper, Wrapper};
use crate::{i32_as_void_result, new_instance_raw_wrapper, raw_wrapper};
pub mod events;
pub mod info;
#[derive(RawWrapper, Debug)]
#[interface(methods=pw_sys::pw_core_methods, interface="Core")]
#[repr(transparent)]
pub struct CoreRef {
#[raw]
raw: pw_sys::pw_core,
}
#[derive(Wrapper, Debug)]
pub struct Core {
#[raw_wrapper]
ref_: NonNull<CoreRef>,
context: std::rc::Rc<Context>,
}
impl Core {
pub fn connect(context: &std::rc::Rc<Context>, properties: Properties) -> crate::Result<Self> {
let ptr =
unsafe { pw_sys::pw_context_connect(context.as_raw_ptr(), properties.into_raw(), 0) };
Ok(Self {
ref_: new_instance_raw_wrapper(ptr)?,
context: context.clone(),
})
}
pub fn context(&self) -> &std::rc::Rc<Context> {
&self.context
}
pub fn get_registry(&self, version: u32) -> crate::Result<Registry> {
use crate::core_api::proxy::Proxied;
use crate::core_api::registry::restricted::RegistryBind;
let ref_: &RegistryRef = self.as_ref().get_registry(version, 0)?;
Ok(Registry::from_ref(self, ref_.as_proxy()))
}
}
impl Default for Core {
fn default() -> Self {
Core::connect(&std::rc::Rc::new(Context::default()), Properties::default()).unwrap()
}
}
impl Drop for Core {
fn drop(&mut self) {
unsafe {
pw_sys::pw_core_disconnect(self.as_raw_ptr());
}
}
}
impl CoreRef {
pub fn hello(&self, version: u32) -> crate::Result<()> {
let result = spa_interface_call!(self, hello, version)?;
i32_as_void_result(result)
}
pub fn sync(&self, id: u32, seq: i32) -> crate::Result<()> {
let result = spa_interface_call!(self, sync, id, seq)?;
i32_as_void_result(result)
}
pub fn pong(&self, id: u32, seq: i32) -> crate::Result<()> {
let result = spa_interface_call!(self, pong, id, seq)?;
i32_as_void_result(result)
}
pub fn error(
&self,
id: u32,
seq: i32,
error_code: i32,
description: &CStr,
) -> crate::Result<()> {
let result = spa_interface_call!(self, error, id, seq, error_code, description.as_ptr())?;
i32_as_void_result(result)
}
fn get_registry(&self, version: u32, user_data_size: usize) -> crate::Result<&RegistryRef> {
let ptr = spa_interface_call!(self, get_registry, version, user_data_size)?;
raw_wrapper(ptr)
}
}
impl<'a> AddListener<'a> for CoreRef {
type Events = CoreEvents<'a>;
fn add_listener(&self, events: Pin<Box<Self::Events>>) -> Pin<Box<Self::Events>> {
unsafe {
spa_interface_call!(
self,
add_listener,
events.hook().as_raw_ptr(),
events.as_raw_ptr(),
&*events as *const _ as *mut _
)
};
events
}
}