1use std::os::raw::c_void;
185#[cfg(any(doc, feature = "pa_v15"))]
186use std::os::raw::c_char;
187use std::ffi::{CStr, CString};
188use std::borrow::Cow;
189use std::ptr::null_mut;
190use num_traits::FromPrimitive;
191use capi::pa_sink_port_info as SinkPortInfoInternal;
192use capi::pa_sink_info as SinkInfoInternal;
193use capi::pa_source_port_info as SourcePortInfoInternal;
194use capi::pa_source_info as SourceInfoInternal;
195use capi::pa_server_info as ServerInfoInternal;
196use capi::pa_module_info as ModuleInfoInternal;
197use capi::pa_client_info as ClientInfoInternal;
198use capi::pa_card_profile_info2 as CardProfileInfoInternal;
199use capi::pa_card_port_info as CardPortInfoInternal;
200use capi::pa_card_info as CardInfoInternal;
201use capi::pa_sink_input_info as SinkInputInfoInternal;
202use capi::pa_source_output_info as SourceOutputInfoInternal;
203use capi::pa_sample_info as SampleInfoInternal;
204use super::{Context, ContextInternal};
205use crate::{def, sample, channelmap, format, direction};
206use crate::time::MicroSeconds;
207use crate::callbacks::{
208 ListResult, box_closure_get_capi_ptr, callback_for_list_instance, get_su_capi_params,
209 get_su_callback
210};
211use crate::volume::{ChannelVolumes, Volume};
212use crate::{operation::Operation, proplist::Proplist};
213#[cfg(any(doc, feature = "pa_v14"))]
214use crate::def::DevicePortType;
215
216pub use capi::pa_stat_info as StatInfo;
217
218pub struct Introspector {
220 context: *mut super::ContextInternal,
221}
222
223unsafe impl Send for Introspector {}
224unsafe impl Sync for Introspector {}
225
226impl Context {
227 #[inline]
232 pub fn introspect(&self) -> Introspector {
233 unsafe { capi::pa_context_ref(self.ptr) };
234 Introspector::from_raw(self.ptr)
235 }
236}
237
238impl Introspector {
239 #[inline(always)]
241 fn from_raw(context: *mut ContextInternal) -> Self {
242 Self { context: context }
243 }
244}
245
246impl Drop for Introspector {
247 fn drop(&mut self) {
248 unsafe { capi::pa_context_unref(self.context) };
249 self.context = null_mut::<super::ContextInternal>();
250 }
251}
252
253#[derive(Debug)]
262pub struct SinkPortInfo<'a> {
263 pub name: Option<Cow<'a, str>>,
265 pub description: Option<Cow<'a, str>>,
267 pub priority: u32,
269 pub available: def::PortAvailable,
271 #[cfg(any(doc, feature = "pa_v14"))]
293 #[cfg_attr(docsrs, doc(cfg(feature = "pa_v14")))]
294 pub availability_group: Option<Cow<'a, str>>,
295 #[cfg(any(doc, feature = "pa_v14"))]
297 #[cfg_attr(docsrs, doc(cfg(feature = "pa_v14")))]
298 pub r#type: DevicePortType,
299}
300
301impl<'a> SinkPortInfo<'a> {
302 fn new_from_raw(p: *const SinkPortInfoInternal) -> Self {
303 assert!(!p.is_null());
304 let src = unsafe { &*p };
305 unsafe {
306 SinkPortInfo {
307 name: match src.name.is_null() {
308 false => Some(CStr::from_ptr(src.name).to_string_lossy()),
309 true => None,
310 },
311 description: match src.description.is_null() {
312 false => Some(CStr::from_ptr(src.description).to_string_lossy()),
313 true => None,
314 },
315 priority: src.priority,
316 available: def::PortAvailable::from_i32(src.available).unwrap(),
317 #[cfg(any(doc, feature = "pa_v14"))]
318 availability_group: match src.availability_group.is_null() {
319 false => Some(CStr::from_ptr(src.availability_group).to_string_lossy()),
320 true => None,
321 },
322 #[cfg(any(doc, feature = "pa_v14"))]
323 r#type: DevicePortType::from_u32(src.r#type).unwrap(),
324 }
325 }
326 }
327}
328
329#[derive(Debug)]
334pub struct SinkInfo<'a> {
335 pub name: Option<Cow<'a, str>>,
337 pub index: u32,
339 pub description: Option<Cow<'a, str>>,
341 pub sample_spec: sample::Spec,
343 pub channel_map: channelmap::Map,
345 pub owner_module: Option<u32>,
347 pub volume: ChannelVolumes,
349 pub mute: bool,
351 pub monitor_source: u32,
353 pub monitor_source_name: Option<Cow<'a, str>>,
355 pub latency: MicroSeconds,
357 pub driver: Option<Cow<'a, str>>,
359 pub flags: def::SinkFlagSet,
361 pub proplist: Proplist,
363 pub configured_latency: MicroSeconds,
365 pub base_volume: Volume,
368 pub state: def::SinkState,
370 pub n_volume_steps: u32,
372 pub card: Option<u32>,
374 pub ports: Vec<SinkPortInfo<'a>>,
376 pub active_port: Option<Box<SinkPortInfo<'a>>>,
378 pub formats: Vec<format::Info>,
380}
381
382impl<'a> SinkInfo<'a> {
383 fn new_from_raw(p: *const SinkInfoInternal) -> Self {
384 assert!(!p.is_null());
385 let src = unsafe { &*p };
386
387 let mut port_vec = Vec::with_capacity(src.n_ports as usize);
388 assert!(src.n_ports == 0 || !src.ports.is_null());
389 for i in 0..src.n_ports as isize {
390 let indexed_ptr = unsafe { (*src.ports.offset(i)) as *mut SinkPortInfoInternal };
391 if !indexed_ptr.is_null() {
392 port_vec.push(SinkPortInfo::new_from_raw(indexed_ptr));
393 }
394 }
395 let mut formats_vec = Vec::with_capacity(src.n_formats as usize);
396 assert!(src.n_formats == 0 || !src.formats.is_null());
397 for i in 0..src.n_formats as isize {
398 let indexed_ptr = unsafe { (*src.formats.offset(i)) as *mut format::InfoInternal };
399 if !indexed_ptr.is_null() {
400 formats_vec.push(format::Info::from_raw_weak(indexed_ptr));
401 }
402 }
403
404 unsafe {
405 SinkInfo {
406 name: match src.name.is_null() {
407 false => Some(CStr::from_ptr(src.name).to_string_lossy()),
408 true => None,
409 },
410 index: src.index,
411 description: match src.description.is_null() {
412 false => Some(CStr::from_ptr(src.description).to_string_lossy()),
413 true => None,
414 },
415 sample_spec: src.sample_spec.into(),
416 channel_map: src.channel_map.into(),
417 owner_module: match src.owner_module {
418 def::INVALID_INDEX => None,
419 i => Some(i),
420 },
421 volume: src.volume.into(),
422 mute: match src.mute {
423 0 => false,
424 _ => true,
425 },
426 monitor_source: src.monitor_source,
427 monitor_source_name: match src.monitor_source_name.is_null() {
428 false => Some(CStr::from_ptr(src.monitor_source_name).to_string_lossy()),
429 true => None,
430 },
431 latency: MicroSeconds(src.latency),
432 driver: match src.driver.is_null() {
433 false => Some(CStr::from_ptr(src.driver).to_string_lossy()),
434 true => None,
435 },
436 flags: def::SinkFlagSet::from_bits_truncate(src.flags),
437 proplist: Proplist::from_raw_weak(src.proplist),
438 configured_latency: MicroSeconds(src.configured_latency),
439 base_volume: Volume(src.base_volume),
440 state: src.state.into(),
441 n_volume_steps: src.n_volume_steps,
442 card: match src.card {
443 def::INVALID_INDEX => None,
444 i => Some(i),
445 },
446 ports: port_vec,
447 active_port: match src.active_port.is_null() {
448 true => None,
449 false => Some(Box::new(SinkPortInfo::new_from_raw(src.active_port))),
450 },
451 formats: formats_vec,
452 }
453 }
454 }
455}
456
457impl Introspector {
458 pub fn get_sink_info_by_name<F>(&self, name: &str, callback: F)
462 -> Operation<dyn FnMut(ListResult<&SinkInfo>)>
463 where F: FnMut(ListResult<&SinkInfo>) + 'static
464 {
465 let c_name = CString::new(name).unwrap();
468
469 let cb_data = box_closure_get_capi_ptr::<dyn FnMut(ListResult<&SinkInfo>)>(Box::new(callback));
470 let ptr = unsafe { capi::pa_context_get_sink_info_by_name(self.context, c_name.as_ptr(),
471 Some(get_sink_info_list_cb_proxy), cb_data) };
472 Operation::from_raw(ptr, cb_data as *mut Box<dyn FnMut(ListResult<&SinkInfo>)>)
473 }
474
475 pub fn get_sink_info_by_index<F>(&self, index: u32, callback: F)
479 -> Operation<dyn FnMut(ListResult<&SinkInfo>)>
480 where F: FnMut(ListResult<&SinkInfo>) + 'static
481 {
482 let cb_data = box_closure_get_capi_ptr::<dyn FnMut(ListResult<&SinkInfo>)>(Box::new(callback));
483 let ptr = unsafe { capi::pa_context_get_sink_info_by_index(self.context, index,
484 Some(get_sink_info_list_cb_proxy), cb_data) };
485 Operation::from_raw(ptr, cb_data as *mut Box<dyn FnMut(ListResult<&SinkInfo>)>)
486 }
487
488 pub fn get_sink_info_list<F>(&self, callback: F) -> Operation<dyn FnMut(ListResult<&SinkInfo>)>
492 where F: FnMut(ListResult<&SinkInfo>) + 'static
493 {
494 let cb_data = box_closure_get_capi_ptr::<dyn FnMut(ListResult<&SinkInfo>)>(Box::new(callback));
495 let ptr = unsafe { capi::pa_context_get_sink_info_list(self.context,
496 Some(get_sink_info_list_cb_proxy), cb_data) };
497 Operation::from_raw(ptr, cb_data as *mut Box<dyn FnMut(ListResult<&SinkInfo>)>)
498 }
499
500 pub fn set_sink_volume_by_index(&mut self, index: u32, volume: &ChannelVolumes,
506 callback: Option<Box<dyn FnMut(bool) + 'static>>) -> Operation<dyn FnMut(bool)>
507 {
508 let (cb_fn, cb_data): (Option<extern "C" fn(_, _, _)>, _) =
509 get_su_capi_params::<_, _>(callback, super::success_cb_proxy);
510 let ptr = unsafe { capi::pa_context_set_sink_volume_by_index(self.context, index,
511 volume.as_ref(), cb_fn, cb_data) };
512 Operation::from_raw(ptr, cb_data as *mut Box<dyn FnMut(bool)>)
513 }
514
515 pub fn set_sink_volume_by_name(&mut self, name: &str, volume: &ChannelVolumes,
521 callback: Option<Box<dyn FnMut(bool) + 'static>>) -> Operation<dyn FnMut(bool)>
522 {
523 let c_name = CString::new(name).unwrap();
526
527 let (cb_fn, cb_data): (Option<extern "C" fn(_, _, _)>, _) =
528 get_su_capi_params::<_, _>(callback, super::success_cb_proxy);
529 let ptr = unsafe { capi::pa_context_set_sink_volume_by_name(self.context, c_name.as_ptr(),
530 volume.as_ref(), cb_fn, cb_data) };
531 Operation::from_raw(ptr, cb_data as *mut Box<dyn FnMut(bool)>)
532 }
533
534 pub fn set_sink_mute_by_index(&mut self, index: u32, mute: bool,
540 callback: Option<Box<dyn FnMut(bool) + 'static>>) -> Operation<dyn FnMut(bool)>
541 {
542 let (cb_fn, cb_data): (Option<extern "C" fn(_, _, _)>, _) =
543 get_su_capi_params::<_, _>(callback, super::success_cb_proxy);
544 let ptr = unsafe { capi::pa_context_set_sink_mute_by_index(self.context, index, mute as i32,
545 cb_fn, cb_data) };
546 Operation::from_raw(ptr, cb_data as *mut Box<dyn FnMut(bool)>)
547 }
548
549 pub fn set_sink_mute_by_name(&mut self, name: &str, mute: bool,
555 callback: Option<Box<dyn FnMut(bool) + 'static>>) -> Operation<dyn FnMut(bool)>
556 {
557 let c_name = CString::new(name).unwrap();
560
561 let (cb_fn, cb_data): (Option<extern "C" fn(_, _, _)>, _) =
562 get_su_capi_params::<_, _>(callback, super::success_cb_proxy);
563 let ptr = unsafe { capi::pa_context_set_sink_mute_by_name(self.context, c_name.as_ptr(),
564 mute as i32, cb_fn, cb_data) };
565 Operation::from_raw(ptr, cb_data as *mut Box<dyn FnMut(bool)>)
566 }
567
568 pub fn suspend_sink_by_name(&mut self, sink_name: &str, suspend: bool,
574 callback: Option<Box<dyn FnMut(bool) + 'static>>) -> Operation<dyn FnMut(bool)>
575 {
576 let c_name = CString::new(sink_name).unwrap();
579
580 let (cb_fn, cb_data): (Option<extern "C" fn(_, _, _)>, _) =
581 get_su_capi_params::<_, _>(callback, super::success_cb_proxy);
582 let ptr = unsafe { capi::pa_context_suspend_sink_by_name(self.context, c_name.as_ptr(),
583 suspend as i32, cb_fn, cb_data) };
584 Operation::from_raw(ptr, cb_data as *mut Box<dyn FnMut(bool)>)
585 }
586
587 pub fn suspend_sink_by_index(&mut self, index: u32, suspend: bool,
594 callback: Option<Box<dyn FnMut(bool) + 'static>>) -> Operation<dyn FnMut(bool)>
595 {
596 let (cb_fn, cb_data): (Option<extern "C" fn(_, _, _)>, _) =
597 get_su_capi_params::<_, _>(callback, super::success_cb_proxy);
598 let ptr = unsafe { capi::pa_context_suspend_sink_by_index(self.context, index,
599 suspend as i32, cb_fn, cb_data) };
600 Operation::from_raw(ptr, cb_data as *mut Box<dyn FnMut(bool)>)
601 }
602
603 pub fn set_sink_port_by_index(&mut self, index: u32, port: &str,
609 callback: Option<Box<dyn FnMut(bool) + 'static>>) -> Operation<dyn FnMut(bool)>
610 {
611 let c_port = CString::new(port).unwrap();
614
615 let (cb_fn, cb_data): (Option<extern "C" fn(_, _, _)>, _) =
616 get_su_capi_params::<_, _>(callback, super::success_cb_proxy);
617 let ptr = unsafe { capi::pa_context_set_sink_port_by_index(self.context, index,
618 c_port.as_ptr(), cb_fn, cb_data) };
619 Operation::from_raw(ptr, cb_data as *mut Box<dyn FnMut(bool)>)
620 }
621
622 pub fn set_sink_port_by_name(&mut self, name: &str, port: &str,
628 callback: Option<Box<dyn FnMut(bool) + 'static>>) -> Operation<dyn FnMut(bool)>
629 {
630 let c_name = CString::new(name).unwrap();
633 let c_port = CString::new(port).unwrap();
634
635 let (cb_fn, cb_data): (Option<extern "C" fn(_, _, _)>, _) =
636 get_su_capi_params::<_, _>(callback, super::success_cb_proxy);
637 let ptr = unsafe { capi::pa_context_set_sink_port_by_name(self.context, c_name.as_ptr(),
638 c_port.as_ptr(), cb_fn, cb_data) };
639 Operation::from_raw(ptr, cb_data as *mut Box<dyn FnMut(bool)>)
640 }
641}
642
643extern "C"
646fn get_sink_info_list_cb_proxy(_: *mut ContextInternal, i: *const SinkInfoInternal, eol: i32,
647 userdata: *mut c_void)
648{
649 let _ = std::panic::catch_unwind(|| {
650 callback_for_list_instance(i, eol, userdata, SinkInfo::new_from_raw);
651 });
652}
653
654#[derive(Debug)]
663pub struct SourcePortInfo<'a> {
664 pub name: Option<Cow<'a, str>>,
666 pub description: Option<Cow<'a, str>>,
668 pub priority: u32,
670 pub available: def::PortAvailable,
672 #[cfg(any(doc, feature = "pa_v14"))]
694 #[cfg_attr(docsrs, doc(cfg(feature = "pa_v14")))]
695 pub availability_group: Option<Cow<'a, str>>,
696 #[cfg(any(doc, feature = "pa_v14"))]
698 #[cfg_attr(docsrs, doc(cfg(feature = "pa_v14")))]
699 pub r#type: DevicePortType,
700}
701
702impl<'a> SourcePortInfo<'a> {
703 fn new_from_raw(p: *const SourcePortInfoInternal) -> Self {
704 assert!(!p.is_null());
705 let src = unsafe { &*p };
706 unsafe {
707 SourcePortInfo {
708 name: match src.name.is_null() {
709 false => Some(CStr::from_ptr(src.name).to_string_lossy()),
710 true => None,
711 },
712 description: match src.description.is_null() {
713 false => Some(CStr::from_ptr(src.description).to_string_lossy()),
714 true => None,
715 },
716 priority: src.priority,
717 available: def::PortAvailable::from_i32(src.available).unwrap(),
718 #[cfg(any(doc, feature = "pa_v14"))]
719 availability_group: match src.availability_group.is_null() {
720 false => Some(CStr::from_ptr(src.availability_group).to_string_lossy()),
721 true => None,
722 },
723 #[cfg(any(doc, feature = "pa_v14"))]
724 r#type: DevicePortType::from_u32(src.r#type).unwrap(),
725 }
726 }
727 }
728}
729
730#[derive(Debug)]
735pub struct SourceInfo<'a> {
736 pub name: Option<Cow<'a, str>>,
738 pub index: u32,
740 pub description: Option<Cow<'a, str>>,
742 pub sample_spec: sample::Spec,
744 pub channel_map: channelmap::Map,
746 pub owner_module: Option<u32>,
748 pub volume: ChannelVolumes,
750 pub mute: bool,
752 pub monitor_of_sink: Option<u32>,
754 pub monitor_of_sink_name: Option<Cow<'a, str>>,
756 pub latency: MicroSeconds,
758 pub driver: Option<Cow<'a, str>>,
760 pub flags: def::SourceFlagSet,
762 pub proplist: Proplist,
764 pub configured_latency: MicroSeconds,
766 pub base_volume: Volume,
769 pub state: def::SourceState,
771 pub n_volume_steps: u32,
773 pub card: Option<u32>,
775 pub ports: Vec<SourcePortInfo<'a>>,
777 pub active_port: Option<Box<SourcePortInfo<'a>>>,
779 pub formats: Vec<format::Info>,
781}
782
783impl<'a> SourceInfo<'a> {
784 fn new_from_raw(p: *const SourceInfoInternal) -> Self {
785 assert!(!p.is_null());
786 let src = unsafe { &*p };
787
788 let mut port_vec = Vec::with_capacity(src.n_ports as usize);
789 assert!(src.n_ports == 0 || !src.ports.is_null());
790 for i in 0..src.n_ports as isize {
791 let indexed_ptr = unsafe { (*src.ports.offset(i)) as *mut SourcePortInfoInternal };
792 if !indexed_ptr.is_null() {
793 port_vec.push(SourcePortInfo::new_from_raw(indexed_ptr));
794 }
795 }
796 let mut formats_vec = Vec::with_capacity(src.n_formats as usize);
797 assert!(src.n_formats == 0 || !src.formats.is_null());
798 for i in 0..src.n_formats as isize {
799 let indexed_ptr = unsafe { (*src.formats.offset(i)) as *mut format::InfoInternal };
800 if !indexed_ptr.is_null() {
801 formats_vec.push(format::Info::from_raw_weak(indexed_ptr));
802 }
803 }
804
805 unsafe {
806 SourceInfo {
807 name: match src.name.is_null() {
808 false => Some(CStr::from_ptr(src.name).to_string_lossy()),
809 true => None,
810 },
811 index: src.index,
812 description: match src.description.is_null() {
813 false => Some(CStr::from_ptr(src.description).to_string_lossy()),
814 true => None,
815 },
816 sample_spec: src.sample_spec.into(),
817 channel_map: src.channel_map.into(),
818 owner_module: match src.owner_module {
819 def::INVALID_INDEX => None,
820 i => Some(i),
821 },
822 volume: src.volume.into(),
823 mute: match src.mute {
824 0 => false,
825 _ => true,
826 },
827 monitor_of_sink: match src.monitor_of_sink {
828 def::INVALID_INDEX => None,
829 i => Some(i),
830 },
831 monitor_of_sink_name: match src.monitor_of_sink_name.is_null() {
832 false => Some(CStr::from_ptr(src.monitor_of_sink_name).to_string_lossy()),
833 true => None,
834 },
835 latency: MicroSeconds(src.latency),
836 driver: match src.driver.is_null() {
837 false => Some(CStr::from_ptr(src.driver).to_string_lossy()),
838 true => None,
839 },
840 flags: def::SourceFlagSet::from_bits_truncate(src.flags),
841 proplist: Proplist::from_raw_weak(src.proplist),
842 configured_latency: MicroSeconds(src.configured_latency),
843 base_volume: Volume(src.base_volume),
844 state: src.state.into(),
845 n_volume_steps: src.n_volume_steps,
846 card: match src.card {
847 def::INVALID_INDEX => None,
848 i => Some(i),
849 },
850 ports: port_vec,
851 active_port: match src.active_port.is_null() {
852 true => None,
853 false => Some(Box::new(SourcePortInfo::new_from_raw(src.active_port))),
854 },
855 formats: formats_vec,
856 }
857 }
858 }
859}
860
861impl Introspector {
862 pub fn get_source_info_by_name<F>(&self, name: &str, callback: F)
866 -> Operation<dyn FnMut(ListResult<&SourceInfo>)>
867 where F: FnMut(ListResult<&SourceInfo>) + 'static
868 {
869 let c_name = CString::new(name).unwrap();
872
873 let cb_data = box_closure_get_capi_ptr::<dyn FnMut(ListResult<&SourceInfo>)>(Box::new(callback));
874 let ptr = unsafe { capi::pa_context_get_source_info_by_name(self.context, c_name.as_ptr(),
875 Some(get_source_info_list_cb_proxy), cb_data) };
876 Operation::from_raw(ptr, cb_data as *mut Box<dyn FnMut(ListResult<&SourceInfo>)>)
877 }
878
879 pub fn get_source_info_by_index<F>(&self, index: u32, callback: F)
883 -> Operation<dyn FnMut(ListResult<&SourceInfo>)>
884 where F: FnMut(ListResult<&SourceInfo>) + 'static
885 {
886 let cb_data = box_closure_get_capi_ptr::<dyn FnMut(ListResult<&SourceInfo>)>(Box::new(callback));
887 let ptr = unsafe { capi::pa_context_get_source_info_by_index(self.context, index,
888 Some(get_source_info_list_cb_proxy), cb_data) };
889 Operation::from_raw(ptr, cb_data as *mut Box<dyn FnMut(ListResult<&SourceInfo>)>)
890 }
891
892 pub fn get_source_info_list<F>(&self, callback: F)
896 -> Operation<dyn FnMut(ListResult<&SourceInfo>)>
897 where F: FnMut(ListResult<&SourceInfo>) + 'static
898 {
899 let cb_data = box_closure_get_capi_ptr::<dyn FnMut(ListResult<&SourceInfo>)>(Box::new(callback));
900 let ptr = unsafe { capi::pa_context_get_source_info_list(self.context,
901 Some(get_source_info_list_cb_proxy), cb_data) };
902 Operation::from_raw(ptr, cb_data as *mut Box<dyn FnMut(ListResult<&SourceInfo>)>)
903 }
904
905 pub fn set_source_volume_by_index(&mut self, index: u32, volume: &ChannelVolumes,
911 callback: Option<Box<dyn FnMut(bool) + 'static>>) -> Operation<dyn FnMut(bool)>
912 {
913 let (cb_fn, cb_data): (Option<extern "C" fn(_, _, _)>, _) =
914 get_su_capi_params::<_, _>(callback, super::success_cb_proxy);
915 let ptr = unsafe { capi::pa_context_set_source_volume_by_index(self.context, index,
916 volume.as_ref(), cb_fn, cb_data) };
917 Operation::from_raw(ptr, cb_data as *mut Box<dyn FnMut(bool)>)
918 }
919
920 pub fn set_source_volume_by_name(&mut self, name: &str, volume: &ChannelVolumes,
926 callback: Option<Box<dyn FnMut(bool) + 'static>>) -> Operation<dyn FnMut(bool)>
927 {
928 let c_name = CString::new(name).unwrap();
931
932 let (cb_fn, cb_data): (Option<extern "C" fn(_, _, _)>, _) =
933 get_su_capi_params::<_, _>(callback, super::success_cb_proxy);
934 let ptr = unsafe { capi::pa_context_set_source_volume_by_name(self.context,
935 c_name.as_ptr(), volume.as_ref(), cb_fn, cb_data) };
936 Operation::from_raw(ptr, cb_data as *mut Box<dyn FnMut(bool)>)
937 }
938
939 pub fn set_source_mute_by_index(&mut self, index: u32, mute: bool,
945 callback: Option<Box<dyn FnMut(bool) + 'static>>) -> Operation<dyn FnMut(bool)>
946 {
947 let (cb_fn, cb_data): (Option<extern "C" fn(_, _, _)>, _) =
948 get_su_capi_params::<_, _>(callback, super::success_cb_proxy);
949 let ptr = unsafe { capi::pa_context_set_source_mute_by_index(self.context, index,
950 mute as i32, cb_fn, cb_data) };
951 Operation::from_raw(ptr, cb_data as *mut Box<dyn FnMut(bool)>)
952 }
953
954 pub fn set_source_mute_by_name(&mut self, name: &str, mute: bool,
960 callback: Option<Box<dyn FnMut(bool) + 'static>>) -> Operation<dyn FnMut(bool)>
961 {
962 let c_name = CString::new(name).unwrap();
965
966 let (cb_fn, cb_data): (Option<extern "C" fn(_, _, _)>, _) =
967 get_su_capi_params::<_, _>(callback, super::success_cb_proxy);
968 let ptr = unsafe { capi::pa_context_set_source_mute_by_name(self.context, c_name.as_ptr(),
969 mute as i32, cb_fn, cb_data) };
970 Operation::from_raw(ptr, cb_data as *mut Box<dyn FnMut(bool)>)
971 }
972
973 pub fn suspend_source_by_name(&mut self, name: &str, suspend: bool,
979 callback: Option<Box<dyn FnMut(bool) + 'static>>) -> Operation<dyn FnMut(bool)>
980 {
981 let c_name = CString::new(name).unwrap();
984
985 let (cb_fn, cb_data): (Option<extern "C" fn(_, _, _)>, _) =
986 get_su_capi_params::<_, _>(callback, super::success_cb_proxy);
987 let ptr = unsafe { capi::pa_context_suspend_source_by_name(self.context, c_name.as_ptr(),
988 suspend as i32, cb_fn, cb_data) };
989 Operation::from_raw(ptr, cb_data as *mut Box<dyn FnMut(bool)>)
990 }
991
992 pub fn suspend_source_by_index(&mut self, index: u32, suspend: bool,
999 callback: Option<Box<dyn FnMut(bool) + 'static>>) -> Operation<dyn FnMut(bool)>
1000 {
1001 let (cb_fn, cb_data): (Option<extern "C" fn(_, _, _)>, _) =
1002 get_su_capi_params::<_, _>(callback, super::success_cb_proxy);
1003 let ptr = unsafe { capi::pa_context_suspend_source_by_index(self.context, index,
1004 suspend as i32, cb_fn, cb_data) };
1005 Operation::from_raw(ptr, cb_data as *mut Box<dyn FnMut(bool)>)
1006 }
1007
1008 pub fn set_source_port_by_index(&mut self, index: u32, port: &str,
1014 callback: Option<Box<dyn FnMut(bool) + 'static>>) -> Operation<dyn FnMut(bool)>
1015 {
1016 let c_port = CString::new(port).unwrap();
1019
1020 let (cb_fn, cb_data): (Option<extern "C" fn(_, _, _)>, _) =
1021 get_su_capi_params::<_, _>(callback, super::success_cb_proxy);
1022 let ptr = unsafe { capi::pa_context_set_source_port_by_index(self.context, index,
1023 c_port.as_ptr(), cb_fn, cb_data) };
1024 Operation::from_raw(ptr, cb_data as *mut Box<dyn FnMut(bool)>)
1025 }
1026
1027 pub fn set_source_port_by_name(&mut self, name: &str, port: &str,
1033 callback: Option<Box<dyn FnMut(bool) + 'static>>) -> Operation<dyn FnMut(bool)>
1034 {
1035 let c_name = CString::new(name).unwrap();
1038 let c_port = CString::new(port).unwrap();
1039
1040 let (cb_fn, cb_data): (Option<extern "C" fn(_, _, _)>, _) =
1041 get_su_capi_params::<_, _>(callback, super::success_cb_proxy);
1042 let ptr = unsafe { capi::pa_context_set_source_port_by_name(self.context, c_name.as_ptr(),
1043 c_port.as_ptr(), cb_fn, cb_data) };
1044 Operation::from_raw(ptr, cb_data as *mut Box<dyn FnMut(bool)>)
1045 }
1046}
1047
1048extern "C"
1052fn get_source_info_list_cb_proxy(_: *mut ContextInternal, i: *const SourceInfoInternal, eol: i32,
1053 userdata: *mut c_void)
1054{
1055 let _ = std::panic::catch_unwind(|| {
1056 callback_for_list_instance(i, eol, userdata, SourceInfo::new_from_raw);
1057 });
1058}
1059
1060#[derive(Debug)]
1069pub struct ServerInfo<'a> {
1070 pub user_name: Option<Cow<'a, str>>,
1072 pub host_name: Option<Cow<'a, str>>,
1074 pub server_version: Option<Cow<'a, str>>,
1076 pub server_name: Option<Cow<'a, str>>,
1078 pub sample_spec: sample::Spec,
1080 pub default_sink_name: Option<Cow<'a, str>>,
1082 pub default_source_name: Option<Cow<'a, str>>,
1084 pub cookie: u32,
1086 pub channel_map: channelmap::Map,
1088}
1089
1090impl<'a> ServerInfo<'a> {
1091 fn new_from_raw(p: *const ServerInfoInternal) -> Self {
1092 assert!(!p.is_null());
1093 let src = unsafe { &*p };
1094 unsafe {
1095 ServerInfo {
1096 user_name: match src.user_name.is_null() {
1097 false => Some(CStr::from_ptr(src.user_name).to_string_lossy()),
1098 true => None,
1099 },
1100 host_name: match src.host_name.is_null() {
1101 false => Some(CStr::from_ptr(src.host_name).to_string_lossy()),
1102 true => None,
1103 },
1104 server_version: match src.server_version.is_null() {
1105 false => Some(CStr::from_ptr(src.server_version).to_string_lossy()),
1106 true => None,
1107 },
1108 server_name: match src.server_name.is_null() {
1109 false => Some(CStr::from_ptr(src.server_name).to_string_lossy()),
1110 true => None,
1111 },
1112 sample_spec: src.sample_spec.into(),
1113 default_sink_name: match src.default_sink_name.is_null() {
1114 false => Some(CStr::from_ptr(src.default_sink_name).to_string_lossy()),
1115 true => None,
1116 },
1117 default_source_name: match src.default_source_name.is_null() {
1118 false => Some(CStr::from_ptr(src.default_source_name).to_string_lossy()),
1119 true => None,
1120 },
1121 cookie: src.cookie,
1122 channel_map: src.channel_map.into(),
1123 }
1124 }
1125 }
1126}
1127
1128impl Introspector {
1129 pub fn get_server_info<F>(&self, callback: F) -> Operation<dyn FnMut(&ServerInfo)>
1133 where F: FnMut(&ServerInfo) + 'static
1134 {
1135 let cb_data = box_closure_get_capi_ptr::<dyn FnMut(&ServerInfo)>(Box::new(callback));
1136 let ptr = unsafe { capi::pa_context_get_server_info(self.context,
1137 Some(get_server_info_cb_proxy), cb_data) };
1138 Operation::from_raw(ptr, cb_data as *mut Box<dyn FnMut(&ServerInfo)>)
1139 }
1140}
1141
1142extern "C"
1145fn get_server_info_cb_proxy(_: *mut ContextInternal, i: *const ServerInfoInternal,
1146 userdata: *mut c_void)
1147{
1148 let _ = std::panic::catch_unwind(|| {
1149 assert!(!i.is_null());
1150 let obj = ServerInfo::new_from_raw(i);
1151
1152 let mut callback = get_su_callback::<dyn FnMut(&ServerInfo)>(userdata);
1154 (callback)(&obj);
1155 });
1156}
1157
1158#[derive(Debug)]
1167pub struct ModuleInfo<'a> {
1168 pub index: u32,
1170 pub name: Option<Cow<'a, str>>,
1172 pub argument: Option<Cow<'a, str>>,
1174 pub n_used: Option<u32>,
1176 pub proplist: Proplist,
1178}
1179
1180impl<'a> ModuleInfo<'a> {
1181 fn new_from_raw(p: *const ModuleInfoInternal) -> Self {
1182 assert!(!p.is_null());
1183 let src = unsafe { &*p };
1184 unsafe {
1185 ModuleInfo {
1186 index: src.index,
1187 name: match src.name.is_null() {
1188 false => Some(CStr::from_ptr(src.name).to_string_lossy()),
1189 true => None,
1190 },
1191 argument: match src.argument.is_null() {
1192 false => Some(CStr::from_ptr(src.argument).to_string_lossy()),
1193 true => None,
1194 },
1195 n_used: match src.n_used {
1196 def::INVALID_INDEX => None,
1197 i => Some(i),
1198 },
1199 proplist: Proplist::from_raw_weak(src.proplist),
1200 }
1201 }
1202 }
1203}
1204
1205impl Introspector {
1206 pub fn get_module_info<F>(&self, index: u32, callback: F)
1210 -> Operation<dyn FnMut(ListResult<&ModuleInfo>)>
1211 where F: FnMut(ListResult<&ModuleInfo>) + 'static
1212 {
1213 let cb_data = box_closure_get_capi_ptr::<dyn FnMut(ListResult<&ModuleInfo>)>(Box::new(callback));
1214 let ptr = unsafe { capi::pa_context_get_module_info(self.context, index,
1215 Some(mod_info_list_cb_proxy), cb_data) };
1216 Operation::from_raw(ptr, cb_data as *mut Box<dyn FnMut(ListResult<&ModuleInfo>)>)
1217 }
1218
1219 pub fn get_module_info_list<F>(&self, callback: F)
1223 -> Operation<dyn FnMut(ListResult<&ModuleInfo>)>
1224 where F: FnMut(ListResult<&ModuleInfo>) + 'static
1225 {
1226 let cb_data = box_closure_get_capi_ptr::<dyn FnMut(ListResult<&ModuleInfo>)>(Box::new(callback));
1227 let ptr = unsafe { capi::pa_context_get_module_info_list(self.context,
1228 Some(mod_info_list_cb_proxy), cb_data) };
1229 Operation::from_raw(ptr, cb_data as *mut Box<dyn FnMut(ListResult<&ModuleInfo>)>)
1230 }
1231
1232 pub fn load_module<F>(&mut self, name: &str, argument: &str, callback: F)
1237 -> Operation<dyn FnMut(u32)>
1238 where F: FnMut(u32) + 'static
1239 {
1240 let c_name = CString::new(name).unwrap();
1243 let c_arg = CString::new(argument).unwrap();
1244
1245 let cb_data = box_closure_get_capi_ptr::<dyn FnMut(u32)>(Box::new(callback));
1246 let ptr = unsafe { capi::pa_context_load_module(self.context, c_name.as_ptr(),
1247 c_arg.as_ptr(), Some(context_index_cb_proxy), cb_data) };
1248 Operation::from_raw(ptr, cb_data as *mut Box<dyn FnMut(u32)>)
1249 }
1250
1251 pub fn unload_module<F>(&mut self, index: u32, callback: F) -> Operation<dyn FnMut(bool)>
1257 where F: FnMut(bool) + 'static
1258 {
1259 let cb_data = box_closure_get_capi_ptr::<dyn FnMut(bool)>(Box::new(callback));
1260 let ptr = unsafe { capi::pa_context_unload_module(self.context, index,
1261 Some(super::success_cb_proxy), cb_data) };
1262 Operation::from_raw(ptr, cb_data as *mut Box<dyn FnMut(bool)>)
1263 }
1264}
1265
1266extern "C"
1270fn mod_info_list_cb_proxy(_: *mut ContextInternal, i: *const ModuleInfoInternal, eol: i32,
1271 userdata: *mut c_void)
1272{
1273 let _ = std::panic::catch_unwind(|| {
1274 callback_for_list_instance(i, eol, userdata, ModuleInfo::new_from_raw);
1275 });
1276}
1277
1278extern "C"
1282fn context_index_cb_proxy(_: *mut ContextInternal, index: u32, userdata: *mut c_void) {
1283 let _ = std::panic::catch_unwind(|| {
1284 let mut callback = get_su_callback::<dyn FnMut(u32)>(userdata);
1286 (callback)(index);
1287 });
1288}
1289
1290impl Introspector {
1295 #[cfg(any(doc, feature = "pa_v15"))]
1305 #[cfg_attr(docsrs, doc(cfg(feature = "pa_v15")))]
1306 pub fn send_message_to_object<F>(&mut self, recipient_name: &str, message: &str,
1307 message_parameters: &str, callback: F) -> Operation<dyn FnMut(bool, Option<String>)>
1308 where F: FnMut(bool, Option<String>) + 'static
1309 {
1310 let c_recipient_name = CString::new(recipient_name.clone()).unwrap();
1313 let c_message = CString::new(message.clone()).unwrap();
1314 let c_message_parameters = CString::new(message_parameters.clone()).unwrap();
1315
1316 let cb_data = box_closure_get_capi_ptr::<dyn FnMut(bool, Option<String>)>(Box::new(callback));
1317 let ptr = unsafe { capi::pa_context_send_message_to_object(self.context,
1318 c_recipient_name.as_ptr(), c_message.as_ptr(), c_message_parameters.as_ptr(),
1319 Some(send_message_to_object_cb_proxy), cb_data) };
1320 Operation::from_raw(ptr, cb_data as *mut Box<dyn FnMut(bool, Option<String>)>)
1321 }
1322}
1323
1324#[cfg(any(doc, feature = "pa_v15"))]
1328extern "C"
1329fn send_message_to_object_cb_proxy(_: *mut ContextInternal, success: i32, response: *const c_char,
1330 userdata: *mut c_void)
1331{
1332 let success_actual = match success {
1333 0 => false,
1334 _ => true,
1335 };
1336 let _ = std::panic::catch_unwind(|| {
1337 let r = match response.is_null() {
1338 true => None,
1339 false => {
1340 let tmp = unsafe { CStr::from_ptr(response) };
1341 Some(tmp.to_string_lossy().into_owned())
1342 },
1343 };
1344 let mut callback = get_su_callback::<dyn FnMut(bool, Option<String>)>(userdata);
1346 (callback)(success_actual, r);
1347 });
1348}
1349
1350#[derive(Debug)]
1359pub struct ClientInfo<'a> {
1360 pub index: u32,
1362 pub name: Option<Cow<'a, str>>,
1364 pub owner_module: Option<u32>,
1366 pub driver: Option<Cow<'a, str>>,
1368 pub proplist: Proplist,
1370}
1371
1372impl<'a> ClientInfo<'a> {
1373 fn new_from_raw(p: *const ClientInfoInternal) -> Self {
1374 assert!(!p.is_null());
1375 let src = unsafe { &*p };
1376 unsafe {
1377 ClientInfo {
1378 index: src.index,
1379 name: match src.name.is_null() {
1380 false => Some(CStr::from_ptr(src.name).to_string_lossy()),
1381 true => None,
1382 },
1383 owner_module: match src.owner_module {
1384 def::INVALID_INDEX => None,
1385 i => Some(i),
1386 },
1387 driver: match src.driver.is_null() {
1388 false => Some(CStr::from_ptr(src.driver).to_string_lossy()),
1389 true => None,
1390 },
1391 proplist: Proplist::from_raw_weak(src.proplist),
1392 }
1393 }
1394 }
1395}
1396
1397impl Introspector {
1398 pub fn get_client_info<F>(&self, index: u32, callback: F)
1402 -> Operation<dyn FnMut(ListResult<&ClientInfo>)>
1403 where F: FnMut(ListResult<&ClientInfo>) + 'static
1404 {
1405 let cb_data = box_closure_get_capi_ptr::<dyn FnMut(ListResult<&ClientInfo>)>(Box::new(callback));
1406 let ptr = unsafe { capi::pa_context_get_client_info(self.context, index,
1407 Some(get_client_info_list_cb_proxy), cb_data) };
1408 Operation::from_raw(ptr, cb_data as *mut Box<dyn FnMut(ListResult<&ClientInfo>)>)
1409 }
1410
1411 pub fn get_client_info_list<F>(&self, callback: F)
1415 -> Operation<dyn FnMut(ListResult<&ClientInfo>)>
1416 where F: FnMut(ListResult<&ClientInfo>) + 'static
1417 {
1418 let cb_data = box_closure_get_capi_ptr::<dyn FnMut(ListResult<&ClientInfo>)>(Box::new(callback));
1419 let ptr = unsafe { capi::pa_context_get_client_info_list(self.context,
1420 Some(get_client_info_list_cb_proxy), cb_data) };
1421 Operation::from_raw(ptr, cb_data as *mut Box<dyn FnMut(ListResult<&ClientInfo>)>)
1422 }
1423
1424 pub fn kill_client<F>(&mut self, index: u32, callback: F) -> Operation<dyn FnMut(bool)>
1430 where F: FnMut(bool) + 'static
1431 {
1432 let cb_data = box_closure_get_capi_ptr::<dyn FnMut(bool)>(Box::new(callback));
1433 let ptr = unsafe { capi::pa_context_kill_client(self.context, index,
1434 Some(super::success_cb_proxy), cb_data) };
1435 Operation::from_raw(ptr, cb_data as *mut Box<dyn FnMut(bool)>)
1436 }
1437}
1438
1439extern "C"
1443fn get_client_info_list_cb_proxy(_: *mut ContextInternal, i: *const ClientInfoInternal, eol: i32,
1444 userdata: *mut c_void)
1445{
1446 let _ = std::panic::catch_unwind(|| {
1447 callback_for_list_instance(i, eol, userdata, ClientInfo::new_from_raw);
1448 });
1449}
1450
1451#[deprecated(since = "2.28.0", note = "Use the name CardProfileInfo instead")]
1457pub type CardProfileInfo2<'a> = CardProfileInfo<'a>;
1458
1459#[derive(Debug)]
1464pub struct CardProfileInfo<'a> {
1465 pub name: Option<Cow<'a, str>>,
1467 pub description: Option<Cow<'a, str>>,
1469 pub n_sinks: u32,
1471 pub n_sources: u32,
1473 pub priority: u32,
1475 pub available: bool,
1480}
1481
1482impl<'a> CardProfileInfo<'a> {
1483 fn new_from_raw(p: *const CardProfileInfoInternal) -> Self {
1484 assert!(!p.is_null());
1485 let src = unsafe { &*p };
1486 unsafe {
1487 CardProfileInfo {
1488 name: match src.name.is_null() {
1489 false => Some(CStr::from_ptr(src.name).to_string_lossy()),
1490 true => None,
1491 },
1492 description: match src.description.is_null() {
1493 false => Some(CStr::from_ptr(src.description).to_string_lossy()),
1494 true => None,
1495 },
1496 n_sinks: src.n_sinks,
1497 n_sources: src.n_sources,
1498 priority: src.priority,
1499 available: match src.available {
1500 0 => false,
1501 _ => true,
1502 },
1503 }
1504 }
1505 }
1506}
1507
1508#[derive(Debug)]
1513pub struct CardPortInfo<'a> {
1514 pub name: Option<Cow<'a, str>>,
1516 pub description: Option<Cow<'a, str>>,
1518 pub priority: u32,
1520 pub available: def::PortAvailable,
1522 pub direction: direction::FlagSet,
1524 pub proplist: Proplist,
1526 pub latency_offset: i64,
1529 pub profiles: Vec<CardProfileInfo<'a>>,
1531 #[cfg(any(doc, feature = "pa_v14"))]
1549 #[cfg_attr(docsrs, doc(cfg(feature = "pa_v14")))]
1550 pub availability_group: Option<Cow<'a, str>>,
1551 #[cfg(any(doc, feature = "pa_v14"))]
1553 #[cfg_attr(docsrs, doc(cfg(feature = "pa_v14")))]
1554 pub r#type: DevicePortType,
1555}
1556
1557impl<'a> CardPortInfo<'a> {
1558 fn new_from_raw(p: *const CardPortInfoInternal) -> Self {
1559 assert!(!p.is_null());
1560 let src = unsafe { &*p };
1561
1562 let mut profiles_vec = Vec::with_capacity(src.n_profiles as usize);
1563
1564 assert!(src.n_profiles == 0 || !src.profiles2.is_null());
1565 for i in 0..src.n_profiles as isize {
1566 let indexed_ptr =
1567 unsafe { (*src.profiles2.offset(i)) as *mut CardProfileInfoInternal };
1568 if !indexed_ptr.is_null() {
1569 profiles_vec.push(CardProfileInfo::new_from_raw(indexed_ptr));
1570 }
1571 }
1572
1573 unsafe {
1574 CardPortInfo {
1575 name: match src.name.is_null() {
1576 false => Some(CStr::from_ptr(src.name).to_string_lossy()),
1577 true => None,
1578 },
1579 description: match src.description.is_null() {
1580 false => Some(CStr::from_ptr(src.description).to_string_lossy()),
1581 true => None,
1582 },
1583 priority: src.priority,
1584 available: def::PortAvailable::from_i32(src.available).unwrap(),
1585 direction: direction::FlagSet::from_bits_truncate(src.direction),
1586 proplist: Proplist::from_raw_weak(src.proplist),
1587 latency_offset: src.latency_offset,
1588 profiles: profiles_vec,
1589 #[cfg(any(doc, feature = "pa_v14"))]
1590 availability_group: match src.availability_group.is_null() {
1591 false => Some(CStr::from_ptr(src.availability_group).to_string_lossy()),
1592 true => None,
1593 },
1594 #[cfg(any(doc, feature = "pa_v14"))]
1595 r#type: DevicePortType::from_u32(src.r#type).unwrap(),
1596 }
1597 }
1598 }
1599}
1600
1601#[derive(Debug)]
1606pub struct CardInfo<'a> {
1607 pub index: u32,
1609 pub name: Option<Cow<'a, str>>,
1611 pub owner_module: Option<u32>,
1613 pub driver: Option<Cow<'a, str>>,
1615 pub proplist: Proplist,
1617 pub ports: Vec<CardPortInfo<'a>>,
1619 pub profiles: Vec<CardProfileInfo<'a>>,
1621 pub active_profile: Option<Box<CardProfileInfo<'a>>>,
1623}
1624
1625impl<'a> CardInfo<'a> {
1626 fn new_from_raw(p: *const CardInfoInternal) -> Self {
1627 assert!(!p.is_null());
1628 let src = unsafe { &*p };
1629
1630 let mut ports_vec = Vec::with_capacity(src.n_ports as usize);
1631 assert!(src.n_ports == 0 || !src.ports.is_null());
1632 for i in 0..src.n_ports as isize {
1633 let indexed_ptr = unsafe { (*src.ports.offset(i)) as *mut CardPortInfoInternal };
1634 if !indexed_ptr.is_null() {
1635 ports_vec.push(CardPortInfo::new_from_raw(indexed_ptr));
1636 }
1637 }
1638 let mut profiles_vec = Vec::with_capacity(src.n_profiles as usize);
1639
1640 assert!(src.n_profiles == 0 || !src.profiles2.is_null());
1641 for i in 0..src.n_profiles as isize {
1642 let indexed_ptr =
1643 unsafe { (*src.profiles2.offset(i)) as *mut CardProfileInfoInternal };
1644 if !indexed_ptr.is_null() {
1645 profiles_vec.push(CardProfileInfo::new_from_raw(indexed_ptr));
1646 }
1647 }
1648
1649 unsafe {
1650 CardInfo {
1651 index: src.index,
1652 name: match src.name.is_null() {
1653 false => Some(CStr::from_ptr(src.name).to_string_lossy()),
1654 true => None,
1655 },
1656 owner_module: match src.owner_module {
1657 def::INVALID_INDEX => None,
1658 i => Some(i),
1659 },
1660 driver: match src.driver.is_null() {
1661 false => Some(CStr::from_ptr(src.driver).to_string_lossy()),
1662 true => None,
1663 },
1664 proplist: Proplist::from_raw_weak(src.proplist),
1665 ports: ports_vec,
1666 profiles: profiles_vec,
1667 active_profile: match src.active_profile2.is_null() {
1668 true => None,
1669 false => Some(Box::new(CardProfileInfo::new_from_raw(src.active_profile2))),
1670 },
1671 }
1672 }
1673 }
1674}
1675
1676impl Introspector {
1677 pub fn get_card_info_by_index<F>(&self, index: u32, callback: F)
1681 -> Operation<dyn FnMut(ListResult<&CardInfo>)>
1682 where F: FnMut(ListResult<&CardInfo>) + 'static
1683 {
1684 let cb_data = box_closure_get_capi_ptr::<dyn FnMut(ListResult<&CardInfo>)>(Box::new(callback));
1685 let ptr = unsafe { capi::pa_context_get_card_info_by_index(self.context, index,
1686 Some(get_card_info_list_cb_proxy), cb_data) };
1687 Operation::from_raw(ptr, cb_data as *mut Box<dyn FnMut(ListResult<&CardInfo>)>)
1688 }
1689
1690 pub fn get_card_info_by_name<F>(&self, name: &str, callback: F)
1694 -> Operation<dyn FnMut(ListResult<&CardInfo>)>
1695 where F: FnMut(ListResult<&CardInfo>) + 'static
1696 {
1697 let c_name = CString::new(name).unwrap();
1700
1701 let cb_data = box_closure_get_capi_ptr::<dyn FnMut(ListResult<&CardInfo>)>(Box::new(callback));
1702 let ptr = unsafe { capi::pa_context_get_card_info_by_name(self.context, c_name.as_ptr(),
1703 Some(get_card_info_list_cb_proxy), cb_data) };
1704 Operation::from_raw(ptr, cb_data as *mut Box<dyn FnMut(ListResult<&CardInfo>)>)
1705 }
1706
1707 pub fn get_card_info_list<F>(&self, callback: F) -> Operation<dyn FnMut(ListResult<&CardInfo>)>
1711 where F: FnMut(ListResult<&CardInfo>) + 'static
1712 {
1713 let cb_data = box_closure_get_capi_ptr::<dyn FnMut(ListResult<&CardInfo>)>(Box::new(callback));
1714 let ptr = unsafe { capi::pa_context_get_card_info_list(self.context,
1715 Some(get_card_info_list_cb_proxy), cb_data) };
1716 Operation::from_raw(ptr, cb_data as *mut Box<dyn FnMut(ListResult<&CardInfo>)>)
1717 }
1718
1719 pub fn set_card_profile_by_index(&mut self, index: u32, profile: &str,
1725 callback: Option<Box<dyn FnMut(bool) + 'static>>) -> Operation<dyn FnMut(bool)>
1726 {
1727 let c_profile = CString::new(profile).unwrap();
1730
1731 let (cb_fn, cb_data): (Option<extern "C" fn(_, _, _)>, _) =
1732 get_su_capi_params::<_, _>(callback, super::success_cb_proxy);
1733 let ptr = unsafe { capi::pa_context_set_card_profile_by_index(self.context, index,
1734 c_profile.as_ptr(), cb_fn, cb_data) };
1735 Operation::from_raw(ptr, cb_data as *mut Box<dyn FnMut(bool)>)
1736 }
1737
1738 pub fn set_card_profile_by_name(&mut self, name: &str, profile: &str,
1744 callback: Option<Box<dyn FnMut(bool) + 'static>>) -> Operation<dyn FnMut(bool)>
1745 {
1746 let c_name = CString::new(name).unwrap();
1749 let c_profile = CString::new(profile).unwrap();
1750
1751 let (cb_fn, cb_data): (Option<extern "C" fn(_, _, _)>, _) =
1752 get_su_capi_params::<_, _>(callback, super::success_cb_proxy);
1753 let ptr = unsafe { capi::pa_context_set_card_profile_by_name(self.context, c_name.as_ptr(),
1754 c_profile.as_ptr(), cb_fn, cb_data) };
1755 Operation::from_raw(ptr, cb_data as *mut Box<dyn FnMut(bool)>)
1756 }
1757
1758 pub fn set_port_latency_offset(&mut self, card_name: &str, port_name: &str, offset: i64,
1764 callback: Option<Box<dyn FnMut(bool) + 'static>>) -> Operation<dyn FnMut(bool)>
1765 {
1766 let c_name = CString::new(card_name).unwrap();
1769 let c_port = CString::new(port_name).unwrap();
1770
1771 let (cb_fn, cb_data): (Option<extern "C" fn(_, _, _)>, _) =
1772 get_su_capi_params::<_, _>(callback, super::success_cb_proxy);
1773 let ptr = unsafe { capi::pa_context_set_port_latency_offset(self.context, c_name.as_ptr(),
1774 c_port.as_ptr(), offset, cb_fn, cb_data) };
1775 Operation::from_raw(ptr, cb_data as *mut Box<dyn FnMut(bool)>)
1776 }
1777}
1778
1779extern "C"
1783fn get_card_info_list_cb_proxy(_: *mut ContextInternal, i: *const CardInfoInternal, eol: i32,
1784 userdata: *mut c_void)
1785{
1786 let _ = std::panic::catch_unwind(|| {
1787 callback_for_list_instance(i, eol, userdata, CardInfo::new_from_raw);
1788 });
1789}
1790
1791#[derive(Debug)]
1800pub struct SinkInputInfo<'a> {
1801 pub index: u32,
1803 pub name: Option<Cow<'a, str>>,
1805 pub owner_module: Option<u32>,
1808 pub client: Option<u32>,
1811 pub sink: u32,
1813 pub sample_spec: sample::Spec,
1815 pub channel_map: channelmap::Map,
1817 pub volume: ChannelVolumes,
1819 pub buffer_usec: MicroSeconds,
1822 pub sink_usec: MicroSeconds,
1824 pub resample_method: Option<Cow<'a, str>>,
1826 pub driver: Option<Cow<'a, str>>,
1828 pub mute: bool,
1830 pub proplist: Proplist,
1832 pub corked: bool,
1834 pub has_volume: bool,
1837 pub volume_writable: bool,
1840 pub format: format::Info,
1842}
1843
1844impl<'a> SinkInputInfo<'a> {
1845 fn new_from_raw(p: *const SinkInputInfoInternal) -> Self {
1846 assert!(!p.is_null());
1847 let src = unsafe { &*p };
1848 unsafe {
1849 SinkInputInfo {
1850 index: src.index,
1851 name: match src.name.is_null() {
1852 false => Some(CStr::from_ptr(src.name).to_string_lossy()),
1853 true => None,
1854 },
1855 owner_module: match src.owner_module {
1856 def::INVALID_INDEX => None,
1857 i => Some(i),
1858 },
1859 client: match src.client {
1860 def::INVALID_INDEX => None,
1861 i => Some(i),
1862 },
1863 sink: src.sink,
1864 sample_spec: src.sample_spec.into(),
1865 channel_map: src.channel_map.into(),
1866 volume: src.volume.into(),
1867 buffer_usec: MicroSeconds(src.buffer_usec),
1868 sink_usec: MicroSeconds(src.sink_usec),
1869 resample_method: match src.resample_method.is_null() {
1870 false => Some(CStr::from_ptr(src.resample_method).to_string_lossy()),
1871 true => None,
1872 },
1873 driver: match src.driver.is_null() {
1874 false => Some(CStr::from_ptr(src.driver).to_string_lossy()),
1875 true => None,
1876 },
1877 mute: match src.mute {
1878 0 => false,
1879 _ => true,
1880 },
1881 proplist: Proplist::from_raw_weak(src.proplist),
1882 corked: match src.corked {
1883 0 => false,
1884 _ => true,
1885 },
1886 has_volume: match src.has_volume {
1887 0 => false,
1888 _ => true,
1889 },
1890 volume_writable: match src.volume_writable {
1891 0 => false,
1892 _ => true,
1893 },
1894 format: format::Info::from_raw_weak(src.format as *mut format::InfoInternal),
1895 }
1896 }
1897 }
1898}
1899
1900impl Introspector {
1901 pub fn get_sink_input_info<F>(&self, index: u32, callback: F)
1905 -> Operation<dyn FnMut(ListResult<&SinkInputInfo>)>
1906 where F: FnMut(ListResult<&SinkInputInfo>) + 'static
1907 {
1908 let cb_data =
1909 box_closure_get_capi_ptr::<dyn FnMut(ListResult<&SinkInputInfo>)>(Box::new(callback));
1910 let ptr = unsafe { capi::pa_context_get_sink_input_info(self.context, index,
1911 Some(get_sink_input_info_list_cb_proxy), cb_data) };
1912 Operation::from_raw(ptr, cb_data as *mut Box<dyn FnMut(ListResult<&SinkInputInfo>)>)
1913 }
1914
1915 pub fn get_sink_input_info_list<F>(&self, callback: F)
1919 -> Operation<dyn FnMut(ListResult<&SinkInputInfo>)>
1920 where F: FnMut(ListResult<&SinkInputInfo>) + 'static
1921 {
1922 let cb_data =
1923 box_closure_get_capi_ptr::<dyn FnMut(ListResult<&SinkInputInfo>)>(Box::new(callback));
1924 let ptr = unsafe { capi::pa_context_get_sink_input_info_list(self.context,
1925 Some(get_sink_input_info_list_cb_proxy), cb_data) };
1926 Operation::from_raw(ptr, cb_data as *mut Box<dyn FnMut(ListResult<&SinkInputInfo>)>)
1927 }
1928
1929 pub fn move_sink_input_by_name(&mut self, index: u32, sink_name: &str,
1935 callback: Option<Box<dyn FnMut(bool) + 'static>>) -> Operation<dyn FnMut(bool)>
1936 {
1937 let c_name = CString::new(sink_name).unwrap();
1940
1941 let (cb_fn, cb_data): (Option<extern "C" fn(_, _, _)>, _) =
1942 get_su_capi_params::<_, _>(callback, super::success_cb_proxy);
1943 let ptr = unsafe { capi::pa_context_move_sink_input_by_name(self.context, index,
1944 c_name.as_ptr(), cb_fn, cb_data) };
1945 Operation::from_raw(ptr, cb_data as *mut Box<dyn FnMut(bool)>)
1946 }
1947
1948 pub fn move_sink_input_by_index(&mut self, index: u32, sink_index: u32,
1954 callback: Option<Box<dyn FnMut(bool) + 'static>>) -> Operation<dyn FnMut(bool)>
1955 {
1956 let (cb_fn, cb_data): (Option<extern "C" fn(_, _, _)>, _) =
1957 get_su_capi_params::<_, _>(callback, super::success_cb_proxy);
1958 let ptr = unsafe { capi::pa_context_move_sink_input_by_index(self.context, index,
1959 sink_index, cb_fn, cb_data) };
1960 Operation::from_raw(ptr, cb_data as *mut Box<dyn FnMut(bool)>)
1961 }
1962
1963 pub fn set_sink_input_volume(&mut self, index: u32, volume: &ChannelVolumes,
1969 callback: Option<Box<dyn FnMut(bool) + 'static>>) -> Operation<dyn FnMut(bool)>
1970 {
1971 let (cb_fn, cb_data): (Option<extern "C" fn(_, _, _)>, _) =
1972 get_su_capi_params::<_, _>(callback, super::success_cb_proxy);
1973 let ptr = unsafe { capi::pa_context_set_sink_input_volume(self.context, index,
1974 volume.as_ref(), cb_fn, cb_data) };
1975 Operation::from_raw(ptr, cb_data as *mut Box<dyn FnMut(bool)>)
1976 }
1977
1978 pub fn set_sink_input_mute(&mut self, index: u32, mute: bool,
1984 callback: Option<Box<dyn FnMut(bool) + 'static>>) -> Operation<dyn FnMut(bool)>
1985 {
1986 let (cb_fn, cb_data): (Option<extern "C" fn(_, _, _)>, _) =
1987 get_su_capi_params::<_, _>(callback, super::success_cb_proxy);
1988 let ptr = unsafe { capi::pa_context_set_sink_input_mute(self.context, index, mute as i32,
1989 cb_fn, cb_data) };
1990 Operation::from_raw(ptr, cb_data as *mut Box<dyn FnMut(bool)>)
1991 }
1992
1993 pub fn kill_sink_input<F>(&mut self, index: u32, callback: F) -> Operation<dyn FnMut(bool)>
1999 where F: FnMut(bool) + 'static
2000 {
2001 let cb_data = box_closure_get_capi_ptr::<dyn FnMut(bool)>(Box::new(callback));
2002 let ptr = unsafe { capi::pa_context_kill_sink_input(self.context, index,
2003 Some(super::success_cb_proxy), cb_data) };
2004 Operation::from_raw(ptr, cb_data as *mut Box<dyn FnMut(bool)>)
2005 }
2006}
2007
2008extern "C"
2012fn get_sink_input_info_list_cb_proxy(_: *mut ContextInternal, i: *const SinkInputInfoInternal,
2013 eol: i32, userdata: *mut c_void)
2014{
2015 let _ = std::panic::catch_unwind(|| {
2016 callback_for_list_instance(i, eol, userdata, SinkInputInfo::new_from_raw);
2017 });
2018}
2019
2020#[derive(Debug)]
2029pub struct SourceOutputInfo<'a> {
2030 pub index: u32,
2032 pub name: Option<Cow<'a, str>>,
2034 pub owner_module: Option<u32>,
2037 pub client: Option<u32>,
2040 pub source: u32,
2042 pub sample_spec: sample::Spec,
2044 pub channel_map: channelmap::Map,
2046 pub buffer_usec: MicroSeconds,
2049 pub source_usec: MicroSeconds,
2051 pub resample_method: Option<Cow<'a, str>>,
2053 pub driver: Option<Cow<'a, str>>,
2055 pub proplist: Proplist,
2057 pub corked: bool,
2059 pub volume: ChannelVolumes,
2061 pub mute: bool,
2063 pub has_volume: bool,
2066 pub volume_writable: bool,
2069 pub format: format::Info,
2071}
2072
2073impl<'a> SourceOutputInfo<'a> {
2074 fn new_from_raw(p: *const SourceOutputInfoInternal) -> Self {
2075 assert!(!p.is_null());
2076 let src = unsafe { &*p };
2077 unsafe {
2078 SourceOutputInfo {
2079 index: src.index,
2080 name: match src.name.is_null() {
2081 false => Some(CStr::from_ptr(src.name).to_string_lossy()),
2082 true => None,
2083 },
2084 owner_module: match src.owner_module {
2085 def::INVALID_INDEX => None,
2086 i => Some(i),
2087 },
2088 client: match src.client {
2089 def::INVALID_INDEX => None,
2090 i => Some(i),
2091 },
2092 source: src.source,
2093 sample_spec: src.sample_spec.into(),
2094 channel_map: src.channel_map.into(),
2095 buffer_usec: MicroSeconds(src.buffer_usec),
2096 source_usec: MicroSeconds(src.source_usec),
2097 resample_method: match src.resample_method.is_null() {
2098 false => Some(CStr::from_ptr(src.resample_method).to_string_lossy()),
2099 true => None,
2100 },
2101 driver: match src.driver.is_null() {
2102 false => Some(CStr::from_ptr(src.driver).to_string_lossy()),
2103 true => None,
2104 },
2105 proplist: Proplist::from_raw_weak(src.proplist),
2106 corked: match src.corked {
2107 0 => false,
2108 _ => true,
2109 },
2110 volume: src.volume.into(),
2111 mute: match src.mute {
2112 0 => false,
2113 _ => true,
2114 },
2115 has_volume: match src.has_volume {
2116 0 => false,
2117 _ => true,
2118 },
2119 volume_writable: match src.volume_writable {
2120 0 => false,
2121 _ => true,
2122 },
2123 format: format::Info::from_raw_weak(src.format as *mut format::InfoInternal),
2124 }
2125 }
2126 }
2127}
2128
2129impl Introspector {
2130 pub fn get_source_output_info<F>(&self, index: u32, callback: F)
2134 -> Operation<dyn FnMut(ListResult<&SourceOutputInfo>)>
2135 where F: FnMut(ListResult<&SourceOutputInfo>) + 'static
2136 {
2137 let cb_data =
2138 box_closure_get_capi_ptr::<dyn FnMut(ListResult<&SourceOutputInfo>)>(Box::new(callback));
2139 let ptr = unsafe { capi::pa_context_get_source_output_info(self.context, index,
2140 Some(get_source_output_info_list_cb_proxy), cb_data) };
2141 Operation::from_raw(ptr, cb_data as *mut Box<dyn FnMut(ListResult<&SourceOutputInfo>)>)
2142 }
2143
2144 pub fn get_source_output_info_list<F>(&self, callback: F)
2148 -> Operation<dyn FnMut(ListResult<&SourceOutputInfo>)>
2149 where F: FnMut(ListResult<&SourceOutputInfo>) + 'static
2150 {
2151 let cb_data =
2152 box_closure_get_capi_ptr::<dyn FnMut(ListResult<&SourceOutputInfo>)>(Box::new(callback));
2153 let ptr = unsafe { capi::pa_context_get_source_output_info_list(self.context,
2154 Some(get_source_output_info_list_cb_proxy), cb_data) };
2155 Operation::from_raw(ptr, cb_data as *mut Box<dyn FnMut(ListResult<&SourceOutputInfo>)>)
2156 }
2157
2158 pub fn move_source_output_by_name(&mut self, index: u32, source_name: &str,
2164 callback: Option<Box<dyn FnMut(bool) + 'static>>) -> Operation<dyn FnMut(bool)>
2165 {
2166 let c_name = CString::new(source_name).unwrap();
2169
2170 let (cb_fn, cb_data): (Option<extern "C" fn(_, _, _)>, _) =
2171 get_su_capi_params::<_, _>(callback, super::success_cb_proxy);
2172 let ptr = unsafe { capi::pa_context_move_source_output_by_name(self.context, index,
2173 c_name.as_ptr(), cb_fn, cb_data) };
2174 Operation::from_raw(ptr, cb_data as *mut Box<dyn FnMut(bool)>)
2175 }
2176
2177 pub fn move_source_output_by_index(&mut self, index: u32, source_index: u32,
2183 callback: Option<Box<dyn FnMut(bool) + 'static>>) -> Operation<dyn FnMut(bool)>
2184 {
2185 let (cb_fn, cb_data): (Option<extern "C" fn(_, _, _)>, _) =
2186 get_su_capi_params::<_, _>(callback, super::success_cb_proxy);
2187 let ptr = unsafe { capi::pa_context_move_source_output_by_index(self.context, index,
2188 source_index, cb_fn, cb_data) };
2189 Operation::from_raw(ptr, cb_data as *mut Box<dyn FnMut(bool)>)
2190 }
2191
2192 pub fn set_source_output_volume(&mut self, index: u32, volume: &ChannelVolumes,
2198 callback: Option<Box<dyn FnMut(bool) + 'static>>) -> Operation<dyn FnMut(bool)>
2199 {
2200 let (cb_fn, cb_data): (Option<extern "C" fn(_, _, _)>, _) =
2201 get_su_capi_params::<_, _>(callback, super::success_cb_proxy);
2202 let ptr = unsafe { capi::pa_context_set_source_output_volume(self.context, index,
2203 volume.as_ref(), cb_fn, cb_data) };
2204 Operation::from_raw(ptr, cb_data as *mut Box<dyn FnMut(bool)>)
2205 }
2206
2207 pub fn set_source_output_mute(&mut self, index: u32, mute: bool,
2213 callback: Option<Box<dyn FnMut(bool) + 'static>>) -> Operation<dyn FnMut(bool)>
2214 {
2215 let (cb_fn, cb_data): (Option<extern "C" fn(_, _, _)>, _) =
2216 get_su_capi_params::<_, _>(callback, super::success_cb_proxy);
2217 let ptr = unsafe { capi::pa_context_set_source_output_mute(self.context, index, mute as i32,
2218 cb_fn, cb_data) };
2219 Operation::from_raw(ptr, cb_data as *mut Box<dyn FnMut(bool)>)
2220 }
2221
2222 pub fn kill_source_output<F>(&mut self, index: u32, callback: F) -> Operation<dyn FnMut(bool)>
2228 where F: FnMut(bool) + 'static
2229 {
2230 let cb_data = box_closure_get_capi_ptr::<dyn FnMut(bool)>(Box::new(callback));
2231 let ptr = unsafe { capi::pa_context_kill_source_output(self.context, index,
2232 Some(super::success_cb_proxy), cb_data) };
2233 Operation::from_raw(ptr, cb_data as *mut Box<dyn FnMut(bool)>)
2234 }
2235}
2236
2237extern "C"
2241fn get_source_output_info_list_cb_proxy(_: *mut ContextInternal, i: *const SourceOutputInfoInternal,
2242 eol: i32, userdata: *mut c_void)
2243{
2244 let _ = std::panic::catch_unwind(|| {
2245 callback_for_list_instance(i, eol, userdata, SourceOutputInfo::new_from_raw);
2246 });
2247}
2248
2249impl Introspector {
2254 pub fn stat<F>(&self, callback: F) -> Operation<dyn FnMut(&StatInfo)>
2258 where F: FnMut(&StatInfo) + 'static
2259 {
2260 let cb_data = box_closure_get_capi_ptr::<dyn FnMut(&StatInfo)>(Box::new(callback));
2261 let ptr =
2262 unsafe { capi::pa_context_stat(self.context, Some(get_stat_info_cb_proxy), cb_data) };
2263 Operation::from_raw(ptr, cb_data as *mut Box<dyn FnMut(&StatInfo)>)
2264 }
2265}
2266
2267extern "C"
2271fn get_stat_info_cb_proxy(_: *mut ContextInternal, i: *const StatInfo, userdata: *mut c_void) {
2272 let _ = std::panic::catch_unwind(|| {
2273 assert!(!i.is_null());
2274 let mut callback = get_su_callback::<dyn FnMut(&StatInfo)>(userdata);
2276 (callback)(unsafe { &*i });
2277 });
2278}
2279
2280#[derive(Debug)]
2289pub struct SampleInfo<'a> {
2290 pub index: u32,
2292 pub name: Option<Cow<'a, str>>,
2294 pub volume: ChannelVolumes,
2296 pub sample_spec: sample::Spec,
2298 pub channel_map: channelmap::Map,
2300 pub duration: MicroSeconds,
2302 pub bytes: u32,
2304 pub lazy: bool,
2306 pub filename: Option<Cow<'a, str>>,
2308 pub proplist: Proplist,
2310}
2311
2312impl<'a> SampleInfo<'a> {
2313 fn new_from_raw(p: *const SampleInfoInternal) -> Self {
2314 assert!(!p.is_null());
2315 let src = unsafe { &*p };
2316 unsafe {
2317 SampleInfo {
2318 index: src.index,
2319 name: match src.name.is_null() {
2320 false => Some(CStr::from_ptr(src.name).to_string_lossy()),
2321 true => None,
2322 },
2323 volume: src.volume.into(),
2324 sample_spec: src.sample_spec.into(),
2325 channel_map: src.channel_map.into(),
2326 duration: MicroSeconds(src.duration),
2327 bytes: src.bytes,
2328 lazy: match src.lazy {
2329 0 => false,
2330 _ => true,
2331 },
2332 filename: match src.filename.is_null() {
2333 false => Some(CStr::from_ptr(src.filename).to_string_lossy()),
2334 true => None,
2335 },
2336 proplist: Proplist::from_raw_weak(src.proplist),
2337 }
2338 }
2339 }
2340}
2341
2342impl Introspector {
2343 pub fn get_sample_info_by_name<F>(&self, name: &str, callback: F)
2347 -> Operation<dyn FnMut(ListResult<&SampleInfo>)>
2348 where F: FnMut(ListResult<&SampleInfo>) + 'static
2349 {
2350 let c_name = CString::new(name).unwrap();
2353
2354 let cb_data = box_closure_get_capi_ptr::<dyn FnMut(ListResult<&SampleInfo>)>(Box::new(callback));
2355 let ptr = unsafe { capi::pa_context_get_sample_info_by_name(self.context, c_name.as_ptr(),
2356 Some(get_sample_info_list_cb_proxy), cb_data) };
2357 Operation::from_raw(ptr, cb_data as *mut Box<dyn FnMut(ListResult<&SampleInfo>)>)
2358 }
2359
2360 pub fn get_sample_info_by_index<F>(&self, index: u32, callback: F)
2364 -> Operation<dyn FnMut(ListResult<&SampleInfo>)>
2365 where F: FnMut(ListResult<&SampleInfo>) + 'static
2366 {
2367 let cb_data = box_closure_get_capi_ptr::<dyn FnMut(ListResult<&SampleInfo>)>(Box::new(callback));
2368 let ptr = unsafe { capi::pa_context_get_sample_info_by_index(self.context, index,
2369 Some(get_sample_info_list_cb_proxy), cb_data) };
2370 Operation::from_raw(ptr, cb_data as *mut Box<dyn FnMut(ListResult<&SampleInfo>)>)
2371 }
2372
2373 pub fn get_sample_info_list<F>(&self, callback: F)
2377 -> Operation<dyn FnMut(ListResult<&SampleInfo>)>
2378 where F: FnMut(ListResult<&SampleInfo>) + 'static
2379 {
2380 let cb_data = box_closure_get_capi_ptr::<dyn FnMut(ListResult<&SampleInfo>)>(Box::new(callback));
2381 let ptr = unsafe { capi::pa_context_get_sample_info_list(self.context,
2382 Some(get_sample_info_list_cb_proxy), cb_data) };
2383 Operation::from_raw(ptr, cb_data as *mut Box<dyn FnMut(ListResult<&SampleInfo>)>)
2384 }
2385}
2386
2387extern "C"
2391fn get_sample_info_list_cb_proxy(_: *mut ContextInternal, i: *const SampleInfoInternal, eol: i32,
2392 userdata: *mut c_void)
2393{
2394 let _ = std::panic::catch_unwind(|| {
2395 callback_for_list_instance(i, eol, userdata, SampleInfo::new_from_raw);
2396 });
2397}