pipewire/context/
mod.rs

1// Copyright The pipewire-rs Contributors.
2// SPDX-License-Identifier: MIT
3
4//! The context manages all locally available resources.
5//!
6//! It can be used to connect to another PipeWire instance (the main daemon, for example) and interact with it.
7//!
8//! This module contains wrappers for [`pw_context`](pw_sys::pw_context) and related items.
9
10use std::{
11    os::fd::{IntoRawFd, OwnedFd},
12    ptr,
13};
14
15use crate::{
16    core::CoreBox,
17    properties::{Properties, PropertiesBox},
18    Error,
19};
20
21mod box_;
22pub use box_::*;
23mod rc;
24pub use rc::*;
25
26/// Transparent wrapper around a [context](self).
27///
28/// This does not own the underlying object and is usually seen behind a `&` reference.
29///
30/// For owning wrappers that can construct a context, see [`ContextBox`] and [`ContextRc`].
31///
32/// For an explanation of these, see [Smart pointers to PipeWire
33/// objects](crate#smart-pointers-to-pipewire-objects).
34#[repr(transparent)]
35pub struct Context(pw_sys::pw_context);
36
37impl Context {
38    pub fn as_raw(&self) -> &pw_sys::pw_context {
39        &self.0
40    }
41
42    pub fn as_raw_ptr(&self) -> *mut pw_sys::pw_context {
43        std::ptr::addr_of!(self.0).cast_mut()
44    }
45
46    pub fn properties(&self) -> &Properties {
47        unsafe {
48            let props = pw_sys::pw_context_get_properties(self.as_raw_ptr());
49            let props = ptr::NonNull::new(props.cast_mut()).expect("context properties is NULL");
50            props.cast().as_ref()
51        }
52    }
53
54    pub fn update_properties(&self, properties: &spa::utils::dict::DictRef) {
55        unsafe {
56            pw_sys::pw_context_update_properties(self.as_raw_ptr(), properties.as_raw_ptr());
57        }
58    }
59
60    pub fn connect(&self, properties: Option<PropertiesBox>) -> Result<CoreBox<'_>, Error> {
61        let properties = properties.map_or(ptr::null_mut(), |p| p.into_raw());
62
63        unsafe {
64            let core = pw_sys::pw_context_connect(self.as_raw_ptr(), properties, 0);
65            let ptr = ptr::NonNull::new(core).ok_or(Error::CreationFailed)?;
66
67            Ok(CoreBox::from_raw(ptr))
68        }
69    }
70
71    pub fn connect_fd(
72        &self,
73        fd: OwnedFd,
74        properties: Option<PropertiesBox>,
75    ) -> Result<CoreBox<'_>, Error> {
76        let properties = properties.map_or(ptr::null_mut(), |p| p.into_raw());
77
78        unsafe {
79            let raw_fd = fd.into_raw_fd();
80            let core = pw_sys::pw_context_connect_fd(self.as_raw_ptr(), raw_fd, properties, 0);
81            let ptr = ptr::NonNull::new(core).ok_or(Error::CreationFailed)?;
82
83            Ok(CoreBox::from_raw(ptr))
84        }
85    }
86}