pipewire_native_spa/interface/
ffi.rs

1// SPDX-License-Identifier: MIT
2// SPDX-FileCopyrightText: Copyright (c) 2025 Asymptotic Inc.
3// SPDX-FileCopyrightText: Copyright (c) 2025 Arun Raghavan
4
5use std::ffi::{c_char, c_int, c_void};
6
7/* spa_callbacks */
8#[repr(C)]
9#[derive(Copy, Clone)]
10pub struct CCallbacks {
11    pub funcs: *const c_void,
12    pub data: *mut c_void,
13}
14
15/* spa_interface */
16#[repr(C)]
17pub struct CInterface {
18    pub type_: *const c_char,
19    pub version: u32,
20    pub cb: CCallbacks,
21}
22
23/* spa_support */
24#[repr(C)]
25pub struct CSupport {
26    pub type_: *mut c_char,
27    pub data: *mut c_void,
28}
29
30/* spa_list */
31#[repr(C)]
32pub struct CList {
33    pub next: *mut CList,
34    pub prev: *mut CList,
35}
36
37/* spa_hook_list */
38#[repr(C)]
39pub struct CHookList {
40    pub list: CList,
41}
42
43/* spa_hook */
44#[repr(C)]
45pub struct CHook {
46    pub link: CList,
47    pub cb: CCallbacks,
48    // Option<> because the function pointer is nullable. Function pointers may not be null in
49    // Rust, and this is the correct way to represent that concept.
50    // https://doc.rust-lang.org/nomicon/ffi.html#the-nullable-pointer-optimization
51    pub removed: Option<extern "C" fn(hook: *mut CHook)>,
52    pub priv_: *mut c_void,
53}
54
55impl CHook {
56    pub fn new() -> Self {
57        CHook {
58            link: CList {
59                next: std::ptr::null_mut(),
60                prev: std::ptr::null_mut(),
61            },
62            cb: CCallbacks {
63                funcs: std::ptr::null_mut(),
64                data: std::ptr::null_mut(),
65            },
66            removed: None,
67            priv_: std::ptr::null_mut(),
68        }
69    }
70}
71
72impl Default for CHook {
73    fn default() -> Self {
74        Self::new()
75    }
76}
77
78#[repr(C)]
79pub struct CControlHooks {
80    pub version: u32,
81    pub before: extern "C" fn(data: *mut c_void),
82    pub after: extern "C" fn(data: *mut c_void),
83}
84
85#[repr(C)]
86pub struct CLoop {
87    pub iface: CInterface,
88}
89
90unsafe impl Send for CLoop {}
91
92#[repr(C)]
93#[derive(Clone)]
94pub struct CSource {
95    /*
96     * this should be *mut, but mutable dererefence via dyn Any
97     * (when used as CLoopImpl inner) does not work
98     */
99    pub loop_: *const CLoop,
100    pub func: CSourceFunc,
101    pub data: *mut c_void,
102    pub fd: c_int,
103    pub mask: u32,
104    pub rmask: u32,
105    pub priv_: *mut c_void,
106}
107
108unsafe impl Send for CSource {}
109
110pub type CSourceFunc = extern "C" fn(source: *mut CSource);