1use std::ffi::c_void;
3
4#[repr(C)]
8#[derive(Debug, Clone, Copy, Default)]
9pub struct FFIRect {
10 pub x: f64,
11 pub y: f64,
12 pub width: f64,
13 pub height: f64,
14}
15
16#[repr(C)]
18#[derive(Debug, Clone, Copy)]
19pub struct FFIDisplayData {
20 pub display_id: u32,
21 pub width: i32,
22 pub height: i32,
23 pub frame: FFIRect,
24}
25
26#[repr(C)]
28#[derive(Debug, Clone, Copy)]
29pub struct FFIWindowData {
30 pub window_id: u32,
31 pub window_layer: i32,
32 pub is_on_screen: bool,
33 pub is_active: bool,
34 pub frame: FFIRect,
35 pub title_offset: u32,
36 pub title_length: u32,
37 pub owning_app_process_id: i32,
38 #[doc(hidden)]
39 pub _padding: i32,
40}
41
42#[repr(C)]
44#[derive(Debug, Clone, Copy)]
45pub struct FFIApplicationData {
46 pub process_id: i32,
47 #[doc(hidden)]
48 pub _padding: i32,
49 pub bundle_id_offset: u32,
50 pub bundle_id_length: u32,
51 pub app_name_offset: u32,
52 pub app_name_length: u32,
53}
54
55use core::mem::{align_of, offset_of, size_of};
68
69const _: () = assert!(size_of::<FFIRect>() == 32);
70const _: () = assert!(align_of::<FFIRect>() == 8);
71const _: () = assert!(offset_of!(FFIRect, x) == 0);
72const _: () = assert!(offset_of!(FFIRect, y) == 8);
73const _: () = assert!(offset_of!(FFIRect, width) == 16);
74const _: () = assert!(offset_of!(FFIRect, height) == 24);
75
76const _: () = assert!(size_of::<FFIDisplayData>() == 48);
77const _: () = assert!(align_of::<FFIDisplayData>() == 8);
78const _: () = assert!(offset_of!(FFIDisplayData, display_id) == 0);
79const _: () = assert!(offset_of!(FFIDisplayData, width) == 4);
80const _: () = assert!(offset_of!(FFIDisplayData, height) == 8);
81const _: () = assert!(offset_of!(FFIDisplayData, frame) == 16);
82
83const _: () = assert!(size_of::<FFIWindowData>() == 64);
84const _: () = assert!(align_of::<FFIWindowData>() == 8);
85const _: () = assert!(offset_of!(FFIWindowData, window_id) == 0);
86const _: () = assert!(offset_of!(FFIWindowData, window_layer) == 4);
87const _: () = assert!(offset_of!(FFIWindowData, is_on_screen) == 8);
88const _: () = assert!(offset_of!(FFIWindowData, is_active) == 9);
89const _: () = assert!(offset_of!(FFIWindowData, frame) == 16);
90const _: () = assert!(offset_of!(FFIWindowData, title_offset) == 48);
91const _: () = assert!(offset_of!(FFIWindowData, title_length) == 52);
92const _: () = assert!(offset_of!(FFIWindowData, owning_app_process_id) == 56);
93const _: () = assert!(offset_of!(FFIWindowData, _padding) == 60);
94
95const _: () = assert!(size_of::<FFIApplicationData>() == 24);
96const _: () = assert!(align_of::<FFIApplicationData>() == 4);
97const _: () = assert!(offset_of!(FFIApplicationData, process_id) == 0);
98const _: () = assert!(offset_of!(FFIApplicationData, _padding) == 4);
99const _: () = assert!(offset_of!(FFIApplicationData, bundle_id_offset) == 8);
100const _: () = assert!(offset_of!(FFIApplicationData, bundle_id_length) == 12);
101const _: () = assert!(offset_of!(FFIApplicationData, app_name_offset) == 16);
102const _: () = assert!(offset_of!(FFIApplicationData, app_name_length) == 20);
103
104extern "C" {
106 pub fn sc_initialize_core_graphics();
109
110 pub fn sc_verify_ffi_layout() -> bool;
116}
117
118extern "C" {
120 pub fn sc_shareable_content_get_with_options(
122 exclude_desktop_windows: bool,
123 on_screen_windows_only: bool,
124 callback: extern "C" fn(*const c_void, *const i8, *mut c_void),
125 user_data: *mut c_void,
126 );
127
128 pub fn sc_shareable_content_get(
129 callback: extern "C" fn(*const c_void, *const i8, *mut c_void),
130 user_data: *mut c_void,
131 );
132 pub fn sc_shareable_content_get_current_process_displays(
133 callback: extern "C" fn(*const c_void, *const i8, *mut c_void),
134 user_data: *mut c_void,
135 );
136 pub fn sc_shareable_content_current_process_is_available() -> bool;
137 pub fn sc_shareable_content_get_below_window(
138 exclude_desktop_windows: bool,
139 reference_window: *const c_void,
140 callback: extern "C" fn(*const c_void, *const i8, *mut c_void),
141 user_data: *mut c_void,
142 );
143 pub fn sc_shareable_content_get_above_window(
144 exclude_desktop_windows: bool,
145 reference_window: *const c_void,
146 callback: extern "C" fn(*const c_void, *const i8, *mut c_void),
147 user_data: *mut c_void,
148 );
149 pub fn sc_shareable_content_retain(content: *const c_void) -> *const c_void;
150 pub fn sc_shareable_content_release(content: *const c_void);
151 pub fn sc_shareable_content_get_displays_count(content: *const c_void) -> isize;
152 pub fn sc_shareable_content_get_display_at(
153 content: *const c_void,
154 index: isize,
155 ) -> *const c_void;
156 pub fn sc_shareable_content_get_windows_count(content: *const c_void) -> isize;
157 pub fn sc_shareable_content_get_window_at(
158 content: *const c_void,
159 index: isize,
160 ) -> *const c_void;
161 pub fn sc_shareable_content_get_applications_count(content: *const c_void) -> isize;
162 pub fn sc_shareable_content_get_application_at(
163 content: *const c_void,
164 index: isize,
165 ) -> *const c_void;
166
167 pub fn sc_shareable_content_get_displays_batch(
169 content: *const c_void,
170 buffer: *mut c_void, max_displays: isize,
172 ) -> isize;
173
174 pub fn sc_shareable_content_get_applications_batch(
175 content: *const c_void,
176 buffer: *mut c_void, max_apps: isize,
178 string_buffer: *mut i8,
179 string_buffer_size: isize,
180 string_buffer_used: *mut isize,
181 ) -> isize;
182
183 pub fn sc_shareable_content_get_windows_batch(
184 content: *const c_void,
185 buffer: *mut c_void, max_windows: isize,
187 string_buffer: *mut i8,
188 string_buffer_size: isize,
189 string_buffer_used: *mut isize,
190 ) -> isize;
191}
192
193extern "C" {
195 pub fn sc_display_retain(display: *const c_void) -> *const c_void;
196 pub fn sc_display_release(display: *const c_void);
197 pub fn sc_display_get_display_id(display: *const c_void) -> u32;
198 pub fn sc_display_get_width(display: *const c_void) -> isize;
199 pub fn sc_display_get_height(display: *const c_void) -> isize;
200 pub fn sc_display_get_frame(
201 display: *const c_void,
202 x: *mut f64,
203 y: *mut f64,
204 width: *mut f64,
205 height: *mut f64,
206 );
207 pub fn sc_display_get_frame_packed(
209 display: *const c_void,
210 x: *mut f64,
211 y: *mut f64,
212 width: *mut f64,
213 height: *mut f64,
214 );
215}
216
217extern "C" {
219 pub fn sc_window_retain(window: *const c_void) -> *const c_void;
220 pub fn sc_window_release(window: *const c_void);
221 pub fn sc_window_get_window_id(window: *const c_void) -> u32;
222 pub fn sc_window_get_frame(
223 window: *const c_void,
224 x: *mut f64,
225 y: *mut f64,
226 width: *mut f64,
227 height: *mut f64,
228 );
229 pub fn sc_window_get_frame_packed(
231 window: *const c_void,
232 x: *mut f64,
233 y: *mut f64,
234 width: *mut f64,
235 height: *mut f64,
236 );
237 pub fn sc_window_get_title(window: *const c_void, buffer: *mut i8, buffer_size: isize) -> bool;
238 pub fn sc_window_get_title_owned(window: *const c_void) -> *mut i8;
240 pub fn sc_window_get_window_layer(window: *const c_void) -> isize;
241 pub fn sc_window_is_on_screen(window: *const c_void) -> bool;
242 pub fn sc_window_get_owning_application(window: *const c_void) -> *const c_void;
243 pub fn sc_window_is_active(window: *const c_void) -> bool;
244}
245
246extern "C" {
248 pub fn sc_running_application_retain(app: *const c_void) -> *const c_void;
249 pub fn sc_running_application_release(app: *const c_void);
250 pub fn sc_running_application_get_bundle_identifier(
251 app: *const c_void,
252 buffer: *mut i8,
253 buffer_size: isize,
254 ) -> bool;
255 pub fn sc_running_application_get_bundle_identifier_owned(app: *const c_void) -> *mut i8;
257 pub fn sc_running_application_get_application_name(
258 app: *const c_void,
259 buffer: *mut i8,
260 buffer_size: isize,
261 ) -> bool;
262 pub fn sc_running_application_get_application_name_owned(app: *const c_void) -> *mut i8;
264 pub fn sc_running_application_get_process_id(app: *const c_void) -> i32;
265}
266
267extern "C" {
269 pub fn sc_free_string(str: *mut i8);
271}
272
273extern "C" {
275 pub fn sc_stream_configuration_create() -> *const c_void;
276 pub fn sc_stream_configuration_copy(config: *const c_void) -> *const c_void;
277 pub fn sc_stream_configuration_retain(config: *const c_void) -> *const c_void;
278 pub fn sc_stream_configuration_release(config: *const c_void);
279
280 pub fn sc_stream_configuration_set_width(config: *const c_void, width: isize);
281 pub fn sc_stream_configuration_get_width(config: *const c_void) -> isize;
282
283 pub fn sc_stream_configuration_set_height(config: *const c_void, height: isize);
284 pub fn sc_stream_configuration_get_height(config: *const c_void) -> isize;
285
286 pub fn sc_stream_configuration_set_shows_cursor(config: *const c_void, shows_cursor: bool);
287 pub fn sc_stream_configuration_get_shows_cursor(config: *const c_void) -> bool;
288
289 pub fn sc_stream_configuration_set_scales_to_fit(config: *const c_void, scales_to_fit: bool);
290 pub fn sc_stream_configuration_get_scales_to_fit(config: *const c_void) -> bool;
291
292 pub fn sc_stream_configuration_set_captures_audio(config: *const c_void, captures_audio: bool);
293 pub fn sc_stream_configuration_get_captures_audio(config: *const c_void) -> bool;
294
295 pub fn sc_stream_configuration_set_sample_rate(config: *const c_void, sample_rate: isize);
296 pub fn sc_stream_configuration_get_sample_rate(config: *const c_void) -> isize;
297
298 pub fn sc_stream_configuration_set_channel_count(config: *const c_void, channel_count: isize);
299 pub fn sc_stream_configuration_get_channel_count(config: *const c_void) -> isize;
300
301 pub fn sc_stream_configuration_set_queue_depth(config: *const c_void, queue_depth: isize);
302 pub fn sc_stream_configuration_get_queue_depth(config: *const c_void) -> isize;
303
304 pub fn sc_stream_configuration_set_pixel_format(config: *const c_void, pixel_format: u32);
305 pub fn sc_stream_configuration_get_pixel_format(config: *const c_void) -> u32;
306
307 pub fn sc_stream_configuration_set_minimum_frame_interval(
308 config: *const c_void,
309 value: i64,
310 timescale: i32,
311 flags: u32,
312 epoch: i64,
313 );
314 pub fn sc_stream_configuration_get_minimum_frame_interval(
315 config: *const c_void,
316 value: *mut i64,
317 timescale: *mut i32,
318 flags: *mut u32,
319 epoch: *mut i64,
320 );
321
322 pub fn sc_stream_configuration_set_source_rect(
323 config: *const c_void,
324 x: f64,
325 y: f64,
326 width: f64,
327 height: f64,
328 );
329 pub fn sc_stream_configuration_get_source_rect(
330 config: *const c_void,
331 x: *mut f64,
332 y: *mut f64,
333 width: *mut f64,
334 height: *mut f64,
335 );
336
337 pub fn sc_stream_configuration_set_destination_rect(
338 config: *const c_void,
339 x: f64,
340 y: f64,
341 width: f64,
342 height: f64,
343 );
344 pub fn sc_stream_configuration_get_destination_rect(
345 config: *const c_void,
346 x: *mut f64,
347 y: *mut f64,
348 width: *mut f64,
349 height: *mut f64,
350 );
351
352 pub fn sc_stream_configuration_set_preserves_aspect_ratio(
353 config: *const c_void,
354 preserves_aspect_ratio: bool,
355 ) -> bool;
356 pub fn sc_stream_configuration_get_preserves_aspect_ratio(config: *const c_void) -> bool;
357
358 pub fn sc_stream_configuration_set_ignores_shadows_single_window(
359 config: *const c_void,
360 ignores_shadows: bool,
361 ) -> bool;
362 pub fn sc_stream_configuration_get_ignores_shadows_single_window(config: *const c_void)
363 -> bool;
364
365 pub fn sc_stream_configuration_set_should_be_opaque(
366 config: *const c_void,
367 should_be_opaque: bool,
368 ) -> bool;
369 pub fn sc_stream_configuration_get_should_be_opaque(config: *const c_void) -> bool;
370
371 pub fn sc_stream_configuration_set_includes_child_windows(
372 config: *const c_void,
373 includes_child_windows: bool,
374 ) -> bool;
375 pub fn sc_stream_configuration_get_includes_child_windows(config: *const c_void) -> bool;
376
377 pub fn sc_stream_configuration_set_presenter_overlay_privacy_alert_setting(
378 config: *const c_void,
379 setting: i32,
380 ) -> bool;
381 pub fn sc_stream_configuration_get_presenter_overlay_privacy_alert_setting(
382 config: *const c_void,
383 setting: *mut i32,
384 ) -> bool;
385
386 pub fn sc_stream_configuration_set_background_color(
387 config: *const c_void,
388 r: f32,
389 g: f32,
390 b: f32,
391 a: f32,
392 );
393 pub fn sc_stream_configuration_get_background_color(
394 config: *const c_void,
395 r: *mut f32,
396 g: *mut f32,
397 b: *mut f32,
398 a: *mut f32,
399 ) -> bool;
400 pub fn sc_stream_configuration_set_color_space_name(config: *const c_void, name: *const i8);
401 pub fn sc_stream_configuration_get_color_space_name(
402 config: *const c_void,
403 buffer: *mut i8,
404 buffer_size: isize,
405 ) -> bool;
406 pub fn sc_stream_configuration_set_color_matrix(config: *const c_void, matrix: *const i8);
407 pub fn sc_stream_configuration_get_color_matrix(
408 config: *const c_void,
409 buffer: *mut i8,
410 buffer_size: isize,
411 ) -> bool;
412
413 pub fn sc_stream_configuration_set_capture_resolution_type(
415 config: *const c_void,
416 value: i32,
417 ) -> bool;
418 pub fn sc_stream_configuration_get_capture_resolution_type(
419 config: *const c_void,
420 value: *mut i32,
421 ) -> bool;
422
423 pub fn sc_stream_configuration_set_ignores_shadow_display_configuration(
424 config: *const c_void,
425 ignores_shadow: bool,
426 ) -> bool;
427 pub fn sc_stream_configuration_get_ignores_shadow_display_configuration(
428 config: *const c_void,
429 ) -> bool;
430
431 pub fn sc_stream_configuration_set_preserve_aspect_ratio(
432 config: *const c_void,
433 preserve: bool,
434 ) -> bool;
435 pub fn sc_stream_configuration_get_preserve_aspect_ratio(config: *const c_void) -> bool;
436
437 pub fn sc_stream_configuration_set_captures_shadows_only(
438 config: *const c_void,
439 captures_shadows_only: bool,
440 ) -> bool;
441 pub fn sc_stream_configuration_get_captures_shadows_only(config: *const c_void) -> bool;
442
443 pub fn sc_stream_configuration_set_captures_microphone(
444 config: *const c_void,
445 captures_microphone: bool,
446 ) -> bool;
447 pub fn sc_stream_configuration_get_captures_microphone(config: *const c_void) -> bool;
448
449 pub fn sc_stream_configuration_set_excludes_current_process_audio(
450 config: *const c_void,
451 excludes: bool,
452 );
453 pub fn sc_stream_configuration_get_excludes_current_process_audio(
454 config: *const c_void,
455 ) -> bool;
456
457 pub fn sc_stream_configuration_set_microphone_capture_device_id(
458 config: *const c_void,
459 device_id: *const i8,
460 ) -> bool;
461 pub fn sc_stream_configuration_get_microphone_capture_device_id(
462 config: *const c_void,
463 buffer: *mut i8,
464 buffer_size: isize,
465 ) -> bool;
466
467 pub fn sc_stream_configuration_set_stream_name(config: *const c_void, name: *const i8) -> bool;
468 pub fn sc_stream_configuration_get_stream_name(
469 config: *const c_void,
470 buffer: *mut i8,
471 buffer_size: isize,
472 ) -> bool;
473
474 pub fn sc_stream_configuration_set_capture_dynamic_range(
475 config: *const c_void,
476 value: i32,
477 ) -> bool;
478 pub fn sc_stream_configuration_get_capture_dynamic_range(
479 config: *const c_void,
480 value: *mut i32,
481 ) -> bool;
482}
483
484extern "C" {
486 pub fn sc_content_filter_create_with_desktop_independent_window(
487 window: *const c_void,
488 ) -> *const c_void;
489 pub fn sc_content_filter_create_with_display_excluding_windows(
490 display: *const c_void,
491 windows: *const *const c_void,
492 windows_count: isize,
493 ) -> *const c_void;
494 pub fn sc_content_filter_create_with_display_including_windows(
495 display: *const c_void,
496 windows: *const *const c_void,
497 windows_count: isize,
498 ) -> *const c_void;
499 pub fn sc_content_filter_create_with_display_including_applications_excepting_windows(
500 display: *const c_void,
501 apps: *const *const c_void,
502 apps_count: isize,
503 windows: *const *const c_void,
504 windows_count: isize,
505 ) -> *const c_void;
506 pub fn sc_content_filter_create_with_display_excluding_applications_excepting_windows(
507 display: *const c_void,
508 apps: *const *const c_void,
509 apps_count: isize,
510 windows: *const *const c_void,
511 windows_count: isize,
512 ) -> *const c_void;
513 pub fn sc_content_filter_retain(filter: *const c_void) -> *const c_void;
514 pub fn sc_content_filter_release(filter: *const c_void);
515 pub fn sc_content_filter_get_content_rect(
516 filter: *const c_void,
517 x: *mut f64,
518 y: *mut f64,
519 width: *mut f64,
520 height: *mut f64,
521 );
522 pub fn sc_content_filter_get_content_rect_packed(
524 filter: *const c_void,
525 x: *mut f64,
526 y: *mut f64,
527 width: *mut f64,
528 height: *mut f64,
529 );
530}
531
532extern "C" {
534 pub fn sc_stream_create(
535 filter: *const c_void,
536 config: *const c_void,
537 context: *mut c_void,
538 error_callback: extern "C" fn(*mut c_void, i32, *const i8),
539 sample_callback: extern "C" fn(*mut c_void, *const c_void, i32),
540 context_retain: extern "C" fn(*mut c_void),
541 context_release: extern "C" fn(*mut c_void),
542 ) -> *const c_void;
543 pub fn sc_stream_add_stream_output(stream: *const c_void, output_type: i32) -> bool;
544 pub fn sc_stream_add_stream_output_with_queue(
545 stream: *const c_void,
546 output_type: i32,
547 dispatch_queue: *const c_void,
548 ) -> bool;
549 pub fn sc_stream_remove_stream_output(stream: *const c_void, output_type: i32) -> bool;
550 pub fn sc_stream_set_delegate_event_callback(
551 stream: *const c_void,
552 callback: extern "C" fn(*mut c_void, i32),
553 ) -> bool;
554 pub fn sc_stream_start_capture(
555 stream: *const c_void,
556 context: *mut c_void,
557 callback: extern "C" fn(*mut c_void, bool, *const i8),
558 );
559 pub fn sc_stream_start_capture_with_timeout_cleanup(
560 stream: *const c_void,
561 context: *mut c_void,
562 callback: extern "C" fn(*mut c_void, bool, *const i8) -> bool,
563 );
564 pub fn sc_stream_stop_capture(
565 stream: *const c_void,
566 context: *mut c_void,
567 callback: extern "C" fn(*mut c_void, bool, *const i8),
568 );
569 pub fn sc_stream_update_configuration(
570 stream: *const c_void,
571 config: *const c_void,
572 context: *mut c_void,
573 callback: extern "C" fn(*mut c_void, bool, *const i8),
574 );
575 pub fn sc_stream_update_content_filter(
576 stream: *const c_void,
577 filter: *const c_void,
578 context: *mut c_void,
579 callback: extern "C" fn(*mut c_void, bool, *const i8),
580 );
581 pub fn sc_stream_add_recording_output(
582 stream: *const c_void,
583 recording_output: *const c_void,
584 callback: extern "C" fn(*mut c_void, bool, *const i8),
585 context: *mut c_void,
586 );
587 pub fn sc_stream_remove_recording_output(
588 stream: *const c_void,
589 recording_output: *const c_void,
590 callback: extern "C" fn(*mut c_void, bool, *const i8),
591 context: *mut c_void,
592 );
593 pub fn sc_stream_retain(stream: *const c_void) -> *const c_void;
594 pub fn sc_stream_release(stream: *const c_void);
595
596 pub fn sc_stream_get_synchronization_clock(stream: *const c_void) -> *const c_void;
598}
599
600extern "C" {
602 pub fn dispatch_queue_release(queue: *const c_void);
603 pub fn dispatch_queue_retain(queue: *const c_void) -> *const c_void;
604}
605
606extern "C" {
608 pub fn cv_pixel_buffer_get_iosurface(pixel_buffer: *const c_void) -> *const c_void;
609 pub fn cv_pixel_buffer_is_backed_by_iosurface(pixel_buffer: *const c_void) -> bool;
610 pub fn iosurface_get_width(iosurface: *const c_void) -> isize;
611 pub fn iosurface_get_height(iosurface: *const c_void) -> isize;
612 pub fn iosurface_get_bytes_per_row(iosurface: *const c_void) -> isize;
613 pub fn iosurface_get_pixel_format(iosurface: *const c_void) -> u32;
614 pub fn iosurface_get_base_address(iosurface: *const c_void) -> *mut u8;
615 pub fn iosurface_lock(iosurface: *const c_void, options: u32) -> i32;
616 pub fn iosurface_unlock(iosurface: *const c_void, options: u32) -> i32;
617 pub fn iosurface_is_in_use(iosurface: *const c_void) -> bool;
618 pub fn iosurface_release(iosurface: *const c_void);
619
620 pub fn iosurface_get_plane_count(iosurface: *const c_void) -> isize;
622 pub fn iosurface_get_width_of_plane(iosurface: *const c_void, plane: isize) -> isize;
623 pub fn iosurface_get_height_of_plane(iosurface: *const c_void, plane: isize) -> isize;
624 pub fn iosurface_get_bytes_per_row_of_plane(iosurface: *const c_void, plane: isize) -> isize;
625
626 pub fn io_surface_create(
628 width: usize,
629 height: usize,
630 pixel_format: u32,
631 bytes_per_element: usize,
632 surface_out: *mut *mut c_void,
633 ) -> i32;
634
635 pub fn io_surface_create_with_properties(
637 width: usize,
638 height: usize,
639 pixel_format: u32,
640 bytes_per_element: usize,
641 bytes_per_row: usize,
642 alloc_size: usize,
643 plane_count: usize,
644 plane_widths: *const usize,
645 plane_heights: *const usize,
646 plane_bytes_per_row: *const usize,
647 plane_bytes_per_element: *const usize,
648 plane_offsets: *const usize,
649 plane_sizes: *const usize,
650 surface_out: *mut *mut c_void,
651 ) -> i32;
652}
653
654extern "C" {
656 pub fn sc_content_sharing_picker_is_available() -> bool;
657 pub fn sc_content_sharing_picker_configuration_create() -> *const c_void;
658 pub fn sc_content_sharing_picker_configuration_set_allowed_picker_modes(
659 config: *const c_void,
660 modes: *const i32,
661 count: usize,
662 );
663 pub fn sc_content_sharing_picker_configuration_get_allowed_picker_modes_mask(
664 config: *const c_void,
665 ) -> u64;
666 pub fn sc_content_sharing_picker_configuration_set_allows_changing_selected_content(
667 config: *const c_void,
668 allows: bool,
669 );
670 pub fn sc_content_sharing_picker_configuration_get_allows_changing_selected_content(
671 config: *const c_void,
672 ) -> bool;
673 pub fn sc_content_sharing_picker_configuration_set_excluded_bundle_ids(
674 config: *const c_void,
675 bundle_ids: *const *const i8,
676 count: usize,
677 );
678 pub fn sc_content_sharing_picker_configuration_get_excluded_bundle_ids_count(
679 config: *const c_void,
680 ) -> usize;
681 pub fn sc_content_sharing_picker_configuration_get_excluded_bundle_id_at(
682 config: *const c_void,
683 index: usize,
684 buffer: *mut i8,
685 buffer_size: usize,
686 ) -> bool;
687 pub fn sc_content_sharing_picker_configuration_set_excluded_window_ids(
688 config: *const c_void,
689 window_ids: *const u32,
690 count: usize,
691 );
692 pub fn sc_content_sharing_picker_configuration_get_excluded_window_ids_count(
693 config: *const c_void,
694 ) -> usize;
695 pub fn sc_content_sharing_picker_configuration_get_excluded_window_id_at(
696 config: *const c_void,
697 index: usize,
698 ) -> u32;
699 pub fn sc_content_sharing_picker_configuration_retain(config: *const c_void) -> *const c_void;
700 pub fn sc_content_sharing_picker_configuration_copy(config: *const c_void) -> *const c_void;
701 pub fn sc_content_sharing_picker_configuration_release(config: *const c_void);
702
703 pub fn sc_content_sharing_picker_set_maximum_stream_count(count: usize);
705 pub fn sc_content_sharing_picker_get_maximum_stream_count() -> usize;
706
707 pub fn sc_content_sharing_picker_create_default_configuration() -> *const c_void;
712
713 pub fn sc_content_sharing_picker_get_active() -> bool;
715 pub fn sc_content_sharing_picker_set_active(active: bool);
717
718 pub fn sc_content_sharing_picker_set_default_configuration(config: *const c_void) -> bool;
721 pub fn sc_content_sharing_picker_set_configuration_for_stream(
724 config: *const c_void,
725 stream: *const c_void,
726 ) -> bool;
727
728 pub fn sc_content_sharing_picker_add_observer(
736 callback: extern "C" fn(i32, *const c_void, *const i8, *const c_void, *mut c_void),
737 context_release: extern "C" fn(*mut c_void),
738 user_data: *mut c_void,
739 ) -> i64;
740 pub fn sc_content_sharing_picker_remove_observer(token: i64) -> bool;
742 pub fn sc_content_sharing_picker_remove_all_observers() -> usize;
744
745 pub fn sc_content_sharing_picker_present(style: i32);
747 pub fn sc_content_sharing_picker_present_for_stream(stream: *const c_void, style: i32);
749 pub fn sc_content_sharing_picker_deactivate();
751
752 pub fn sc_content_sharing_picker_show(
753 config: *const c_void,
754 callback: extern "C" fn(i32, *const c_void, *mut c_void),
755 user_data: *mut c_void,
756 );
757 pub fn sc_content_sharing_picker_show_with_result(
758 config: *const c_void,
759 callback: extern "C" fn(i32, *const c_void, *mut c_void),
760 user_data: *mut c_void,
761 );
762 pub fn sc_content_sharing_picker_show_for_stream(
763 config: *const c_void,
764 stream: *const c_void,
765 callback: extern "C" fn(i32, *const c_void, *mut c_void),
766 user_data: *mut c_void,
767 );
768 pub fn sc_content_sharing_picker_show_using_style(
769 config: *const c_void,
770 style: i32,
771 callback: extern "C" fn(i32, *const c_void, *mut c_void),
772 user_data: *mut c_void,
773 );
774 pub fn sc_content_sharing_picker_show_for_stream_using_style(
775 config: *const c_void,
776 stream: *const c_void,
777 style: i32,
778 callback: extern "C" fn(i32, *const c_void, *mut c_void),
779 user_data: *mut c_void,
780 );
781 pub fn sc_picker_result_get_filter(result: *const c_void) -> *const c_void;
782 pub fn sc_picker_result_get_content_rect(
783 result: *const c_void,
784 x: *mut f64,
785 y: *mut f64,
786 width: *mut f64,
787 height: *mut f64,
788 );
789 pub fn sc_picker_result_get_scale(result: *const c_void) -> f64;
790 pub fn sc_picker_result_get_windows_count(result: *const c_void) -> usize;
791 pub fn sc_picker_result_get_window_at(result: *const c_void, index: usize) -> *const c_void;
792 pub fn sc_picker_result_get_displays_count(result: *const c_void) -> usize;
793 pub fn sc_picker_result_get_display_at(result: *const c_void, index: usize) -> *const c_void;
794 pub fn sc_picker_result_get_applications_count(result: *const c_void) -> usize;
795 pub fn sc_picker_result_get_application_at(
796 result: *const c_void,
797 index: usize,
798 ) -> *const c_void;
799 pub fn sc_picker_result_release(result: *const c_void);
800}
801
802extern "C" {
804 pub fn sc_recording_output_is_available() -> bool;
805 pub fn sc_recording_output_configuration_create() -> *const c_void;
806 pub fn sc_recording_output_configuration_copy(config: *const c_void) -> *const c_void;
807 pub fn sc_recording_output_configuration_set_output_url(config: *const c_void, path: *const i8);
808 pub fn sc_recording_output_configuration_get_output_url(
809 config: *const c_void,
810 buffer: *mut i8,
811 buffer_size: isize,
812 ) -> bool;
813 pub fn sc_recording_output_configuration_get_output_path_owned(
814 config: *const c_void,
815 ) -> *mut i8;
816 pub fn sc_recording_output_configuration_set_video_codec(config: *const c_void, codec: i32);
817 pub fn sc_recording_output_configuration_retain(config: *const c_void) -> *const c_void;
818 pub fn sc_recording_output_configuration_release(config: *const c_void);
819 pub fn sc_recording_output_create(config: *const c_void) -> *const c_void;
820 pub fn sc_recording_output_retain(output: *const c_void) -> *const c_void;
821 pub fn sc_recording_output_release(output: *const c_void);
822}
823
824extern "C" {
826 pub fn sc_screenshot_manager_capture_image(
827 content_filter: *const c_void,
828 config: *const c_void,
829 callback: extern "C" fn(*const c_void, *const i8, *mut c_void),
830 user_data: *mut c_void,
831 );
832 pub fn sc_screenshot_manager_capture_sample_buffer(
833 content_filter: *const c_void,
834 config: *const c_void,
835 callback: extern "C" fn(*const c_void, *const i8, *mut c_void),
836 user_data: *mut c_void,
837 );
838 pub fn sc_screenshot_manager_capture_image_in_rect(
839 x: f64,
840 y: f64,
841 width: f64,
842 height: f64,
843 callback: extern "C" fn(*const c_void, *const i8, *mut c_void),
844 user_data: *mut c_void,
845 );
846 pub fn cgimage_get_width(image: *const c_void) -> usize;
847 pub fn cgimage_get_height(image: *const c_void) -> usize;
848 pub fn cgimage_get_data(
849 image: *const c_void,
850 out_ptr: *mut *const u8,
851 out_length: *mut usize,
852 ) -> bool;
853 pub fn cgimage_free_data(ptr: *mut u8);
854 pub fn cgimage_render_rgba_into(
861 image: *const c_void,
862 dest: *mut u8,
863 dest_capacity: usize,
864 ) -> usize;
865 pub fn cgimage_render_bgra_into(
871 image: *const c_void,
872 dest: *mut u8,
873 dest_capacity: usize,
874 ) -> usize;
875 pub fn cgimage_render_rgba_into_strided(
882 image: *const c_void,
883 dest: *mut u8,
884 dest_capacity: usize,
885 dest_bytes_per_row: usize,
886 ) -> usize;
887 pub fn cgimage_render_bgra_into_strided(
890 image: *const c_void,
891 dest: *mut u8,
892 dest_capacity: usize,
893 dest_bytes_per_row: usize,
894 ) -> usize;
895 pub fn cgimage_release(image: *const c_void);
896 pub fn cgimage_save_png(image: *const c_void, path: *const i8) -> bool;
897 pub fn cgimage_save_to_file(
898 image: *const c_void,
899 path: *const i8,
900 format: i32,
901 quality: f32,
902 ) -> bool;
903}
904
905extern "C" {
907 pub fn sc_screenshot_configuration_create() -> *const c_void;
908 pub fn sc_screenshot_configuration_set_width(config: *const c_void, width: isize);
909 pub fn sc_screenshot_configuration_set_height(config: *const c_void, height: isize);
910 pub fn sc_screenshot_configuration_set_shows_cursor(config: *const c_void, shows_cursor: bool);
911 pub fn sc_screenshot_configuration_set_source_rect(
912 config: *const c_void,
913 x: f64,
914 y: f64,
915 width: f64,
916 height: f64,
917 );
918 pub fn sc_screenshot_configuration_set_destination_rect(
919 config: *const c_void,
920 x: f64,
921 y: f64,
922 width: f64,
923 height: f64,
924 );
925 pub fn sc_screenshot_configuration_set_ignore_shadows(
926 config: *const c_void,
927 ignore_shadows: bool,
928 );
929 pub fn sc_screenshot_configuration_set_ignore_clipping(
930 config: *const c_void,
931 ignore_clipping: bool,
932 );
933 pub fn sc_screenshot_configuration_set_include_child_windows(
934 config: *const c_void,
935 include_child_windows: bool,
936 );
937 pub fn sc_screenshot_configuration_set_display_intent(
938 config: *const c_void,
939 display_intent: i32,
940 ) -> bool;
941 pub fn sc_screenshot_configuration_set_dynamic_range(
942 config: *const c_void,
943 dynamic_range: i32,
944 ) -> bool;
945 pub fn sc_screenshot_configuration_set_file_url(config: *const c_void, path: *const i8);
946 pub fn sc_screenshot_configuration_clear_file_url(config: *const c_void);
947 pub fn sc_screenshot_configuration_get_width(config: *const c_void) -> isize;
948 pub fn sc_screenshot_configuration_get_height(config: *const c_void) -> isize;
949 pub fn sc_screenshot_configuration_get_shows_cursor(config: *const c_void) -> bool;
950 pub fn sc_screenshot_configuration_get_source_rect(
951 config: *const c_void,
952 x: *mut f64,
953 y: *mut f64,
954 width: *mut f64,
955 height: *mut f64,
956 );
957 pub fn sc_screenshot_configuration_get_destination_rect(
958 config: *const c_void,
959 x: *mut f64,
960 y: *mut f64,
961 width: *mut f64,
962 height: *mut f64,
963 );
964 pub fn sc_screenshot_configuration_get_ignore_shadows(config: *const c_void) -> bool;
965 pub fn sc_screenshot_configuration_get_ignore_clipping(config: *const c_void) -> bool;
966 pub fn sc_screenshot_configuration_get_include_child_windows(config: *const c_void) -> bool;
967 pub fn sc_screenshot_configuration_get_display_intent(
968 config: *const c_void,
969 value: *mut i32,
970 ) -> bool;
971 pub fn sc_screenshot_configuration_get_dynamic_range(
972 config: *const c_void,
973 value: *mut i32,
974 ) -> bool;
975 pub fn sc_screenshot_configuration_get_file_path_owned(config: *const c_void) -> *mut i8;
976 pub fn sc_screenshot_configuration_release(config: *const c_void);
977
978 pub fn sc_screenshot_configuration_set_content_type(
980 config: *const c_void,
981 identifier: *const i8,
982 );
983 pub fn sc_screenshot_configuration_get_content_type(
984 config: *const c_void,
985 buffer: *mut i8,
986 buffer_size: usize,
987 ) -> bool;
988 pub fn sc_screenshot_configuration_get_supported_content_types_count() -> usize;
989 pub fn sc_screenshot_configuration_get_supported_content_type_at(
990 index: usize,
991 buffer: *mut i8,
992 buffer_size: usize,
993 ) -> bool;
994}
995
996extern "C" {
998 pub fn sc_screenshot_output_get_sdr_image(output: *const c_void) -> *const c_void;
999 pub fn sc_screenshot_output_get_hdr_image(output: *const c_void) -> *const c_void;
1000 pub fn sc_screenshot_output_get_file_url(
1001 output: *const c_void,
1002 buffer: *mut i8,
1003 buffer_size: isize,
1004 ) -> bool;
1005 pub fn sc_screenshot_output_get_file_path_owned(output: *const c_void) -> *mut i8;
1006 pub fn sc_screenshot_output_release(output: *const c_void);
1007
1008 pub fn sc_screenshot_manager_capture_screenshot(
1009 content_filter: *const c_void,
1010 config: *const c_void,
1011 callback: extern "C" fn(*const c_void, *const i8, *mut c_void),
1012 user_data: *mut c_void,
1013 );
1014 pub fn sc_screenshot_manager_capture_screenshot_in_rect(
1015 x: f64,
1016 y: f64,
1017 width: f64,
1018 height: f64,
1019 config: *const c_void,
1020 callback: extern "C" fn(*const c_void, *const i8, *mut c_void),
1021 user_data: *mut c_void,
1022 );
1023}
1024
1025extern "C" {
1027 pub fn sc_stream_configuration_set_shows_mouse_clicks(
1029 config: *const c_void,
1030 value: bool,
1031 ) -> bool;
1032 pub fn sc_stream_configuration_get_shows_mouse_clicks(config: *const c_void) -> bool;
1033
1034 pub fn sc_stream_configuration_set_ignores_shadows_display(
1036 config: *const c_void,
1037 value: bool,
1038 ) -> bool;
1039 pub fn sc_stream_configuration_get_ignores_shadows_display(config: *const c_void) -> bool;
1040
1041 pub fn sc_stream_configuration_set_ignore_global_clip_display(
1043 config: *const c_void,
1044 value: bool,
1045 ) -> bool;
1046 pub fn sc_stream_configuration_get_ignore_global_clip_display(config: *const c_void) -> bool;
1047
1048 pub fn sc_stream_configuration_set_ignore_global_clip_single_window(
1050 config: *const c_void,
1051 value: bool,
1052 ) -> bool;
1053 pub fn sc_stream_configuration_get_ignore_global_clip_single_window(
1054 config: *const c_void,
1055 ) -> bool;
1056
1057 pub fn sc_stream_configuration_create_with_preset(preset: i32) -> *const c_void;
1059}
1060
1061extern "C" {
1063 pub fn sc_content_filter_get_style(filter: *const c_void, value: *mut i32) -> bool;
1065 pub fn sc_content_filter_get_point_pixel_scale(filter: *const c_void) -> f32;
1066 pub fn sc_content_filter_get_stream_type(filter: *const c_void, value: *mut i32) -> bool;
1067
1068 pub fn sc_content_filter_set_include_menu_bar(filter: *const c_void, include: bool) -> bool;
1070 pub fn sc_content_filter_get_include_menu_bar(filter: *const c_void) -> bool;
1071
1072 pub fn sc_content_filter_get_included_displays_count(filter: *const c_void) -> isize;
1074 pub fn sc_content_filter_get_included_display_at(
1075 filter: *const c_void,
1076 index: isize,
1077 ) -> *const c_void;
1078 pub fn sc_content_filter_get_included_windows_count(filter: *const c_void) -> isize;
1079 pub fn sc_content_filter_get_included_window_at(
1080 filter: *const c_void,
1081 index: isize,
1082 ) -> *const c_void;
1083 pub fn sc_content_filter_get_included_applications_count(filter: *const c_void) -> isize;
1084 pub fn sc_content_filter_get_included_application_at(
1085 filter: *const c_void,
1086 index: isize,
1087 ) -> *const c_void;
1088}
1089
1090extern "C" {
1092 pub fn sc_shareable_content_info_for_filter(filter: *const c_void) -> *const c_void;
1093 pub fn sc_shareable_content_info_get_style(info: *const c_void, value: *mut i32) -> bool;
1094 pub fn sc_shareable_content_info_get_point_pixel_scale(info: *const c_void) -> f32;
1095 pub fn sc_shareable_content_info_get_content_rect(
1096 info: *const c_void,
1097 x: *mut f64,
1098 y: *mut f64,
1099 width: *mut f64,
1100 height: *mut f64,
1101 );
1102 pub fn sc_shareable_content_info_get_content_rect_packed(
1104 info: *const c_void,
1105 x: *mut f64,
1106 y: *mut f64,
1107 width: *mut f64,
1108 height: *mut f64,
1109 );
1110 pub fn sc_shareable_content_info_retain(info: *const c_void) -> *const c_void;
1111 pub fn sc_shareable_content_info_release(info: *const c_void);
1112}
1113
1114extern "C" {
1116 pub fn sc_recording_output_configuration_set_output_file_type(
1117 config: *const c_void,
1118 file_type: i32,
1119 );
1120 pub fn sc_recording_output_configuration_set_output_file_type_identifier(
1121 config: *const c_void,
1122 identifier: *const i8,
1123 );
1124 pub fn sc_recording_output_configuration_get_output_file_type_identifier_owned(
1125 config: *const c_void,
1126 ) -> *mut i8;
1127 pub fn sc_recording_output_configuration_get_output_file_type(config: *const c_void) -> i32;
1128 pub fn sc_recording_output_configuration_get_video_codec(config: *const c_void) -> i32;
1129 pub fn sc_recording_output_configuration_set_video_codec_identifier(
1130 config: *const c_void,
1131 identifier: *const i8,
1132 );
1133 pub fn sc_recording_output_configuration_get_video_codec_identifier_owned(
1134 config: *const c_void,
1135 ) -> *mut i8;
1136 pub fn sc_recording_output_configuration_get_available_video_codecs_count(
1137 config: *const c_void,
1138 ) -> isize;
1139 pub fn sc_recording_output_configuration_get_available_video_codec_at(
1140 config: *const c_void,
1141 index: isize,
1142 ) -> i32;
1143 pub fn sc_recording_output_configuration_get_available_video_codec_identifier_at_owned(
1144 config: *const c_void,
1145 index: isize,
1146 ) -> *mut i8;
1147 pub fn sc_recording_output_configuration_get_available_output_file_types_count(
1148 config: *const c_void,
1149 ) -> isize;
1150 pub fn sc_recording_output_configuration_get_available_output_file_type_at(
1151 config: *const c_void,
1152 index: isize,
1153 ) -> i32;
1154 pub fn sc_recording_output_configuration_get_available_output_file_type_identifier_at_owned(
1155 config: *const c_void,
1156 index: isize,
1157 ) -> *mut i8;
1158 pub fn sc_recording_output_create_with_delegate(
1159 config: *const c_void,
1160 started_callback: Option<extern "C" fn(*mut c_void)>,
1161 failed_callback: Option<extern "C" fn(*mut c_void, i32, *const i8)>,
1162 finished_callback: Option<extern "C" fn(*mut c_void)>,
1163 context_release: Option<extern "C" fn(*mut c_void)>,
1164 context: *mut c_void,
1165 ) -> *const c_void;
1166 pub fn sc_recording_output_get_recorded_duration(
1167 output: *const c_void,
1168 value: *mut i64,
1169 timescale: *mut i32,
1170 );
1171 pub fn sc_recording_output_get_recorded_file_size(output: *const c_void) -> i64;
1172 pub fn sc_recording_output_wait_until_terminal(
1173 output: *const c_void,
1174 context: *mut c_void,
1175 callback: extern "C" fn(*mut c_void, bool, *const i8),
1176 );
1177}
1178
1179extern "C" {
1181 pub fn sc_audio_input_devices_snapshot_create() -> *const c_void;
1182 pub fn sc_audio_input_devices_snapshot_release(snapshot: *const c_void);
1183 pub fn sc_audio_input_devices_snapshot_count(snapshot: *const c_void) -> isize;
1184 pub fn sc_audio_input_devices_snapshot_default_index(snapshot: *const c_void) -> isize;
1185 pub fn sc_audio_input_devices_snapshot_id_owned(
1186 snapshot: *const c_void,
1187 index: isize,
1188 ) -> *mut i8;
1189 pub fn sc_audio_input_devices_snapshot_name_owned(
1190 snapshot: *const c_void,
1191 index: isize,
1192 ) -> *mut i8;
1193 pub fn sc_audio_input_devices_snapshot_is_default(
1194 snapshot: *const c_void,
1195 index: isize,
1196 ) -> bool;
1197
1198 pub fn sc_audio_get_input_device_count() -> isize;
1200
1201 pub fn sc_audio_get_input_device_id(index: isize, buffer: *mut i8, buffer_size: isize) -> bool;
1203
1204 pub fn sc_audio_get_input_device_name(
1206 index: isize,
1207 buffer: *mut i8,
1208 buffer_size: isize,
1209 ) -> bool;
1210
1211 pub fn sc_audio_is_default_input_device(index: isize) -> bool;
1213
1214 pub fn sc_audio_get_default_input_device_id(buffer: *mut i8, buffer_size: isize) -> bool;
1216
1217 pub fn sc_audio_get_default_input_device_name(buffer: *mut i8, buffer_size: isize) -> bool;
1219}
1220
1221#[cfg(all(test, not(feature = "macos_26_0")))]
1222mod fallback_tests {
1223 use std::ffi::c_void;
1224 use std::ptr::NonNull;
1225
1226 #[test]
1227 #[cfg(not(feature = "macos_14_0"))]
1228 fn shareable_content_info_style_stub_reports_unsupported() {
1229 let info = NonNull::<c_void>::dangling().as_ptr().cast_const();
1230 let mut style = -1_i32;
1231 assert!(!unsafe { super::sc_shareable_content_info_get_style(info, &raw mut style) });
1232 assert_eq!(style, 0);
1233 }
1234
1235 #[test]
1236 #[cfg(not(feature = "macos_14_0"))]
1237 fn stream_configuration_reports_unsupported_without_the_macos_14_sdk() {
1238 let config = unsafe { super::sc_stream_configuration_create() };
1239 assert!(!config.is_null());
1240 let mut raw = -1_i32;
1241 unsafe {
1242 assert!(!super::sc_stream_configuration_set_should_be_opaque(
1243 config, true
1244 ));
1245 assert!(!super::sc_stream_configuration_set_stream_name(
1246 config,
1247 std::ptr::null()
1248 ));
1249 assert!(!super::sc_stream_configuration_set_capture_resolution_type(
1250 config, 1
1251 ));
1252 assert!(!super::sc_stream_configuration_get_capture_resolution_type(
1253 config,
1254 &raw mut raw,
1255 ));
1256 super::sc_stream_configuration_release(config);
1257 }
1258 }
1259
1260 #[test]
1261 #[cfg(not(feature = "macos_15_0"))]
1262 fn preset_and_dynamic_range_stubs_report_unsupported() {
1263 assert!(unsafe { super::sc_stream_configuration_create_with_preset(0) }.is_null());
1264 let config = unsafe { super::sc_stream_configuration_create() };
1265 let mut range = -1_i32;
1266 unsafe {
1267 assert!(!super::sc_stream_configuration_set_capture_dynamic_range(
1268 config, 1
1269 ));
1270 assert!(!super::sc_stream_configuration_get_capture_dynamic_range(
1271 config,
1272 &raw mut range,
1273 ));
1274 super::sc_stream_configuration_release(config);
1275 }
1276 assert_eq!(range, 0);
1277 }
1278
1279 #[test]
1280 fn screenshot_configuration_stubs_report_unsupported() {
1281 let config = NonNull::<c_void>::dangling().as_ptr().cast_const();
1282 let mut intent = -1_i32;
1283 let mut range = -1_i32;
1284 unsafe {
1285 assert!(!super::sc_screenshot_configuration_set_display_intent(
1286 config, 0
1287 ));
1288 assert!(!super::sc_screenshot_configuration_set_dynamic_range(
1289 config, 0
1290 ));
1291 assert!(!super::sc_screenshot_configuration_get_display_intent(
1292 config,
1293 &raw mut intent,
1294 ));
1295 assert!(!super::sc_screenshot_configuration_get_dynamic_range(
1296 config,
1297 &raw mut range,
1298 ));
1299 }
1300 assert_eq!((intent, range), (0, 0));
1301 }
1302}