Skip to content

Commit 612d5cb

Browse files
committed
add PA v15 changes
note, the documentation change to `pa_proplist_get()` was already taken care of in eea623f. note, i changed the `messaging_api.txt` url to link to the newer gitlab instance rather than the older cgit instance.
1 parent 6c65c64 commit 612d5cb

File tree

4 files changed

+91
-0
lines changed

4 files changed

+91
-0
lines changed

pulse-binding/src/context/introspect.rs

+65
Original file line numberDiff line numberDiff line change
@@ -172,12 +172,20 @@
172172
//! Server modules can be remotely loaded and unloaded using [`Introspector::load_module()`] and
173173
//! [`Introspector::unload_module()`].
174174
//!
175+
//! # Messages
176+
//!
177+
//! Server objects like sinks, sink inputs or modules can register a message handler to communicate
178+
//! with clients. A message can be sent to a named message handler using
179+
//! [`Introspector::send_message_to_object()`].
180+
//!
175181
//! # Clients
176182
//!
177183
//! The only operation supported on clients is the possibility of kicking them off the server using
178184
//! [`Introspector::kill_client()`].
179185
180186
use std::os::raw::c_void;
187+
#[cfg(any(doc, feature = "pa_v15"))]
188+
use std::os::raw::c_char;
181189
use std::ffi::{CStr, CString};
182190
use std::borrow::Cow;
183191
use std::ptr::null_mut;
@@ -1278,6 +1286,63 @@ fn context_index_cb_proxy(_: *mut ContextInternal, index: u32, userdata: *mut c_
12781286
});
12791287
}
12801288

1289+
////////////////////////////////////////////////////////////////////////////////////////////////////
1290+
// Messages
1291+
////////////////////////////////////////////////////////////////////////////////////////////////////
1292+
1293+
impl Introspector {
1294+
/// Send a message to an object that registered a message handler.
1295+
///
1296+
/// The callback must accept two params, firstly a boolean indicating success if `true`, and
1297+
/// secondly, the response string. The response string may possibly not be given if
1298+
/// unsuccessful.
1299+
///
1300+
/// For more information see the [messaging_api.txt] documentation in the PulseAudio repository.
1301+
///
1302+
/// [messaging_api.txt]: https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/blob/master/doc/messaging_api.txt
1303+
#[cfg(any(doc, feature = "pa_v15"))]
1304+
#[cfg_attr(docsrs, doc(cfg(feature = "pa_v15")))]
1305+
pub fn send_message_to_object<F>(&mut self, recipient_name: &str, message: &str,
1306+
message_parameters: &str, callback: F) -> Operation<dyn FnMut(bool, Option<String>)>
1307+
where F: FnMut(bool, Option<String>) + 'static
1308+
{
1309+
// Warning: New CStrings will be immediately freed if not bound to a variable, leading to
1310+
// as_ptr() giving dangling pointers!
1311+
let c_recipient_name = CString::new(recipient_name.clone()).unwrap();
1312+
let c_message = CString::new(message.clone()).unwrap();
1313+
let c_message_parameters = CString::new(message_parameters.clone()).unwrap();
1314+
1315+
let cb_data = box_closure_get_capi_ptr::<dyn FnMut(bool, Option<String>)>(Box::new(callback));
1316+
let ptr = unsafe { capi::pa_context_send_message_to_object(self.context,
1317+
c_recipient_name.as_ptr(), c_message.as_ptr(), c_message_parameters.as_ptr(),
1318+
Some(send_message_to_object_cb_proxy), cb_data) };
1319+
Operation::from_raw(ptr, cb_data as *mut Box<dyn FnMut(bool, Option<String>)>)
1320+
}
1321+
}
1322+
1323+
/// Proxy for send message to object callbacks.
1324+
///
1325+
/// Warning: This is for single-use cases only! It destroys the actual closure callback.
1326+
#[cfg(any(doc, feature = "pa_v15"))]
1327+
extern "C"
1328+
fn send_message_to_object_cb_proxy(_: *mut ContextInternal, success: i32, response: *const c_char,
1329+
userdata: *mut c_void)
1330+
{
1331+
let success_actual = match success { 0 => false, _ => true };
1332+
let _ = std::panic::catch_unwind(|| {
1333+
let r = match response.is_null() {
1334+
true => None,
1335+
false => {
1336+
let tmp = unsafe { CStr::from_ptr(response) };
1337+
Some(tmp.to_string_lossy().into_owned())
1338+
},
1339+
};
1340+
// Note, destroys closure callback after use - restoring outer box means it gets dropped
1341+
let mut callback = get_su_callback::<dyn FnMut(bool, Option<String>)>(userdata);
1342+
(callback)(success_actual, r);
1343+
});
1344+
}
1345+
12811346
////////////////////////////////////////////////////////////////////////////////////////////////////
12821347
// Client info
12831348
////////////////////////////////////////////////////////////////////////////////////////////////////

pulse-binding/src/proplist.rs

+6
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,12 @@ pub mod properties {
9797
pub use capi::PA_PROP_MODULE_VERSION as MODULE_VERSION;
9898
pub use capi::PA_PROP_FORMAT_RATE as FORMAT_RATE;
9999
pub use capi::PA_PROP_FORMAT_CHANNELS as FORMAT_CHANNELS;
100+
#[cfg(any(doc, feature = "pa_v15"))]
101+
#[cfg_attr(docsrs, doc(cfg(feature = "pa_v15")))]
102+
pub use capi::PA_PROP_CONTEXT_FORCE_DISABLE_SHM as CONTEXT_FORCE_DISABLE_SHM;
103+
#[cfg(any(doc, feature = "pa_v15"))]
104+
#[cfg_attr(docsrs, doc(cfg(feature = "pa_v15")))]
105+
pub use capi::PA_PROP_BLUETOOTH_CODEC as BLUETOOTH_CODEC;
100106

101107
/* These need defining here, rather than `pub use`, in order to correctly link to other things
102108
* in their doc comments */

pulse-sys/src/context/introspect.rs

+8
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,10 @@ pub struct pa_sample_info {
335335

336336
pub type pa_sample_info_cb_t = Option<extern "C" fn(c: *mut pa_context, i: *const pa_sample_info, eol: i32, userdata: *mut c_void)>;
337337

338+
#[cfg(any(doc, feature = "pa_v15"))]
339+
#[cfg_attr(docsrs, doc(cfg(feature = "pa_v15")))]
340+
pub type pa_context_string_cb_t = Option<extern "C" fn(c: *mut pa_context, success: i32, response: *const c_char, userdata: *mut c_void)>;
341+
338342
#[link(name="pulse")]
339343
extern "C" {
340344
pub fn pa_context_get_sink_info_by_name(c: *mut pa_context, name: *const c_char, cb: pa_sink_info_cb_t, userdata: *mut c_void) -> *mut pa_operation;
@@ -368,6 +372,10 @@ extern "C" {
368372
pub fn pa_context_load_module(c: *mut pa_context, name: *const c_char, argument: *const c_char, cb: pa_context_index_cb_t, userdata: *mut c_void) -> *mut pa_operation;
369373
pub fn pa_context_unload_module(c: *mut pa_context, idx: u32, cb: pa_context_success_cb_t, userdata: *mut c_void) -> *mut pa_operation;
370374

375+
#[cfg(any(doc, feature = "pa_v15"))]
376+
#[cfg_attr(docsrs, doc(cfg(feature = "pa_v15")))]
377+
pub fn pa_context_send_message_to_object(c: *mut pa_context, recipient_name: *const c_char, message: *const c_char, message_parameters: *const c_char, cb: pa_context_string_cb_t, userdata: *mut c_void) -> *mut pa_operation;
378+
371379
pub fn pa_context_get_client_info(c: *mut pa_context, idx: u32, cb: pa_client_info_cb_t, userdata: *mut c_void) -> *mut pa_operation;
372380
pub fn pa_context_get_client_info_list(c: *mut pa_context, cb: pa_client_info_cb_t, userdata: *mut c_void) -> *mut pa_operation;
373381
pub fn pa_context_kill_client(c: *mut pa_context, idx: u32, cb: pa_context_success_cb_t, userdata: *mut c_void) -> *mut pa_operation;

pulse-sys/src/proplist.rs

+12
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,18 @@ pub const PA_PROP_FORMAT_CHANNELS: &str = "format.channels";
291291
/// For PCM formats: the channel map of the stream as returned by `pa_channel_map_snprint`.
292292
pub const PA_PROP_FORMAT_CHANNEL_MAP: &str = "format.channel_map";
293293

294+
/// For context: whether to forcefully disable data transfer via POSIX or memfd shared memory.
295+
/// This property overrides any other client configuration which would otherwise enable SHM
296+
/// communication channels.
297+
#[cfg(any(doc, feature = "pa_v15"))]
298+
#[cfg_attr(docsrs, doc(cfg(feature = "pa_v15")))]
299+
pub const PA_PROP_CONTEXT_FORCE_DISABLE_SHM: &str = "context.force.disable.shm";
300+
301+
/// For a bluez device: the currently selected codec name.
302+
#[cfg(any(doc, feature = "pa_v15"))]
303+
#[cfg_attr(docsrs, doc(cfg(feature = "pa_v15")))]
304+
pub const PA_PROP_BLUETOOTH_CODEC: &str = "bluetooth.codec";
305+
294306
/// A property list object. Basically a dictionary with ASCII strings as keys and arbitrary data as
295307
/// values.
296308
#[repr(C)] pub struct pa_proplist { _private: [u8; 0] }

0 commit comments

Comments
 (0)