screencapturekit/
content_sharing_picker.rs1use crate::shareable_content::{SCDisplay, SCRunningApplication, SCWindow};
9use crate::utils::sync_completion::SyncCompletion;
10use std::ffi::c_void;
11
12extern "C" fn picker_callback(result_code: i32, stream_ptr: *const c_void, user_data: *mut c_void) {
13 let result = match result_code {
14 0 => SCContentSharingPickerResult::Cancelled,
15 1 if !stream_ptr.is_null() => {
16 SCContentSharingPickerResult::Cancelled
19 }
20 -1 => SCContentSharingPickerResult::Error("Picker failed".to_string()),
21 _ => SCContentSharingPickerResult::Cancelled,
22 };
23
24 unsafe { SyncCompletion::complete_ok(user_data, result) };
25}
26
27#[repr(i32)]
29#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
30pub enum SCContentSharingPickerMode {
31 #[default]
33 SingleWindow = 0,
34 Multiple = 1,
36 SingleDisplay = 2,
38}
39
40pub struct SCContentSharingPickerConfiguration {
42 ptr: *const c_void,
43}
44
45impl SCContentSharingPickerConfiguration {
46 #[must_use]
47 pub fn new() -> Self {
48 let ptr = unsafe { crate::ffi::sc_content_sharing_picker_configuration_create() };
49 Self { ptr }
50 }
51
52 pub fn set_allowed_picker_modes(&mut self, modes: &[SCContentSharingPickerMode]) {
54 let mode_values: Vec<i32> = modes.iter().map(|m| *m as i32).collect();
55 unsafe {
56 crate::ffi::sc_content_sharing_picker_configuration_set_allowed_picker_modes(
57 self.ptr,
58 mode_values.as_ptr(),
59 mode_values.len(),
60 );
61 }
62 }
63
64 #[must_use]
65 pub const fn as_ptr(&self) -> *const c_void {
66 self.ptr
67 }
68}
69
70impl Default for SCContentSharingPickerConfiguration {
71 fn default() -> Self {
72 Self::new()
73 }
74}
75
76impl Clone for SCContentSharingPickerConfiguration {
77 fn clone(&self) -> Self {
78 unsafe {
79 Self {
80 ptr: crate::ffi::sc_content_sharing_picker_configuration_retain(self.ptr),
81 }
82 }
83 }
84}
85
86impl Drop for SCContentSharingPickerConfiguration {
87 fn drop(&mut self) {
88 if !self.ptr.is_null() {
89 unsafe {
90 crate::ffi::sc_content_sharing_picker_configuration_release(self.ptr);
91 }
92 }
93 }
94}
95
96impl std::fmt::Debug for SCContentSharingPickerConfiguration {
97 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
98 f.debug_struct("SCContentSharingPickerConfiguration")
99 .field("ptr", &self.ptr)
100 .finish()
101 }
102}
103
104#[derive(Debug, Clone, PartialEq, Eq, Hash)]
106pub enum SCContentSharingPickerResult {
107 Display(SCDisplay),
109 Window(SCWindow),
111 Application(SCRunningApplication),
113 Cancelled,
115 Error(String),
117}
118
119pub struct SCContentSharingPicker;
123
124impl SCContentSharingPicker {
125 pub fn show(config: &SCContentSharingPickerConfiguration) -> SCContentSharingPickerResult {
130 let (completion, context) = SyncCompletion::<SCContentSharingPickerResult>::new();
131
132 unsafe {
133 crate::ffi::sc_content_sharing_picker_show(config.as_ptr(), picker_callback, context);
134 }
135
136 completion
137 .wait()
138 .unwrap_or_else(SCContentSharingPickerResult::Error)
139 }
140}
141
142unsafe impl Send for SCContentSharingPickerConfiguration {}
144unsafe impl Sync for SCContentSharingPickerConfiguration {}