1
0
Fork 0
forked from wry/wry
wry/src/pipewire/pw_ifs/pw_core.rs
2022-07-31 11:25:57 +02:00

184 lines
4.9 KiB
Rust

#![allow(non_upper_case_globals)]
use {
crate::{
pipewire::{
pw_con::PwCon,
pw_mem::{PwMem, PwMemType},
pw_object::{PwObject, PwObjectData},
pw_parser::{PwParser, PwParserError},
pw_pod::{SPA_DATA_DmaBuf, SPA_DATA_MemFd, SpaDataType},
},
utils::bitflags::BitflagsExt,
},
std::rc::Rc,
thiserror::Error,
};
pub struct PwCore {
pub data: PwObjectData,
pub con: Rc<PwCon>,
}
pw_opcodes! {
PwCoreMethods;
Hello = 1,
Sync = 2,
Pong = 3,
Error = 4,
GetRegistry = 5,
CreateObject = 6,
Destroy = 7,
}
pw_opcodes! {
PwCoreEvents;
Info = 0,
Done = 1,
Ping = 2,
Error = 3,
RemoveId = 4,
BoundId = 5,
AddMem = 6,
RemoveMem = 7,
}
pub const PW_CORE_VERSION: i32 = 3;
impl PwCore {
pub fn handle_info(&self, mut p1: PwParser<'_>) -> Result<(), PwCoreError> {
let s1 = p1.read_struct()?;
let mut p2 = s1.fields;
let id = p2.read_int()?;
let cookie = p2.read_int()?;
let user_name = p2.read_string()?;
let host_name = p2.read_string()?;
let version_name = p2.read_string()?;
let name = p2.read_string()?;
let change_mask = p2.read_long()?;
let dict = p2.read_dict_struct()?;
log::info!("info: id={id}, cookie={cookie}, user_name={user_name}, host_name={host_name}, version_name={version_name}, name={name}, change_mask={change_mask}");
log::info!("dict: {:#?}", dict);
Ok(())
}
pub fn handle_done(&self, mut p1: PwParser<'_>) -> Result<(), PwCoreError> {
let s1 = p1.read_struct()?;
let mut p2 = s1.fields;
let id = p2.read_uint()?;
let seq = p2.read_uint()?;
if let Some(obj) = self.con.objects.get(&id) {
if obj.data().sync_id.get() <= seq {
obj.data().sync_id.set(seq);
obj.done();
}
}
Ok(())
}
pub fn handle_ping(&self, mut p1: PwParser<'_>) -> Result<(), PwCoreError> {
let s1 = p1.read_struct()?;
let mut p2 = s1.fields;
let id = p2.read_int()?;
let seq = p2.read_int()?;
self.con.send(self, PwCoreMethods::Pong, |f| {
f.write_struct(|f| {
f.write_int(id);
f.write_int(seq);
});
});
Ok(())
}
pub fn handle_error(&self, mut p1: PwParser<'_>) -> Result<(), PwCoreError> {
let s1 = p1.read_struct()?;
let mut p2 = s1.fields;
let id = p2.read_int()?;
let seq = p2.read_int()?;
let res = p2.read_int()?;
let error = p2.read_string()?;
log::info!("error: id={id}, seq={seq}, res={res}, error={error}");
Ok(())
}
pub fn handle_remove_id(&self, mut p1: PwParser<'_>) -> Result<(), PwCoreError> {
let s1 = p1.read_struct()?;
let mut p2 = s1.fields;
let id = p2.read_uint()?;
self.con.objects.remove(&id);
self.con.ids.borrow_mut().release(id);
Ok(())
}
pub fn handle_bound_id(&self, mut p1: PwParser<'_>) -> Result<(), PwCoreError> {
let s1 = p1.read_struct()?;
let mut p2 = s1.fields;
let id = p2.read_uint()?;
let bound_id = p2.read_uint()?;
if let Some(obj) = self.con.objects.get(&id) {
obj.data().bound_id.set(Some(bound_id));
obj.bound_id(bound_id);
}
Ok(())
}
pub fn handle_add_mem(&self, mut p1: PwParser<'_>) -> Result<(), PwCoreError> {
let s1 = p1.read_struct()?;
let mut p2 = s1.fields;
let id = p2.read_uint()?;
let ty = SpaDataType(p2.read_id()?);
let fd = p2.read_fd()?;
let flags = p2.read_int()?;
let read = flags.contains(1);
let write = flags.contains(2);
let ty = match ty {
SPA_DATA_MemFd => PwMemType::MemFd,
SPA_DATA_DmaBuf => PwMemType::DmaBuf,
_ => {
log::error!("Ignoring unknown mem type {:?}", ty);
return Ok(());
}
};
self.con.mem.mems.set(
id,
Rc::new(PwMem {
ty,
read,
write,
fd,
}),
);
Ok(())
}
pub fn handle_remove_mem(&self, mut p1: PwParser<'_>) -> Result<(), PwCoreError> {
let s1 = p1.read_struct()?;
let mut p2 = s1.fields;
let id = p2.read_uint()?;
self.con.mem.mems.remove(&id);
Ok(())
}
}
pw_object_base! {
PwCore, "core", PwCoreEvents;
Info => handle_info,
Done => handle_done,
Ping => handle_ping,
Error => handle_error,
RemoveId => handle_remove_id,
BoundId => handle_bound_id,
AddMem => handle_add_mem,
RemoveMem => handle_remove_mem,
}
impl PwObject for PwCore {}
#[derive(Debug, Error)]
pub enum PwCoreError {
#[error(transparent)]
PwParserError(#[from] PwParserError),
}