display_link/macos/
cvdisplaylink.rs1use foreign_types::{foreign_type, ForeignType};
4use std::{
5 ffi::c_void,
6 fmt::{Debug, Formatter, Result},
7};
8
9#[derive(Debug)]
10pub enum CVDisplayLink {}
11
12foreign_type! {
13 type CType = CVDisplayLink;
14 fn drop = CVDisplayLinkRelease;
15 fn clone = CVDisplayLinkRetain;
16 pub struct DisplayLink;
17 pub struct DisplayLinkRef;
18}
19
20impl Debug for DisplayLink {
21 fn fmt(&self, formatter: &mut Formatter) -> Result {
22 formatter
23 .debug_tuple("DisplayLink")
24 .field(&self.as_ptr())
25 .finish()
26 }
27}
28
29#[doc(hidden)]
30pub enum Unimplemented {}
31
32#[repr(C)]
33pub struct CVTimeStamp {
34 pub version: u32,
35 pub video_timescale: i32,
36 pub video_time: i64,
37 pub host_time: u64,
38 pub rate_scalar: f64,
39 pub video_refresh_period: i64,
40
41 #[doc(hidden)]
42 _unimplemented: Unimplemented,
43}
44
45pub type CVDisplayLinkOutputCallback = unsafe extern "C" fn(
46 display_link_out: *mut CVDisplayLink,
47 in_now_timestamp: *const CVTimeStamp,
48 in_output_timestamp: *const CVTimeStamp,
49 flags_in: i64,
50 flagsOut: *mut i64,
51 display_link_context: *mut c_void,
52) -> i32;
53
54#[link(name = "CoreFoundation", kind = "framework")]
55#[link(name = "CoreVideo", kind = "framework")]
56#[allow(improper_ctypes)]
57extern "C" {
58 pub fn CVDisplayLinkCreateWithActiveCGDisplays(
59 display_link_out: *mut *mut CVDisplayLink,
60 ) -> i32;
61 pub fn CVDisplayLinkCreateWithCGDisplay(
62 display_id: u32,
63 display_link_out: *mut *mut CVDisplayLink,
64 ) -> i32;
65 pub fn CVDisplayLinkSetOutputCallback(
66 display_link: &mut DisplayLinkRef,
67 callback: CVDisplayLinkOutputCallback,
68 user_info: *mut c_void,
69 ) -> i32;
70 pub fn CVDisplayLinkSetCurrentCGDisplay(
71 display_link: &mut DisplayLinkRef,
72 display_id: u32,
73 ) -> i32;
74 pub fn CVDisplayLinkStart(display_link: &mut DisplayLinkRef) -> i32;
75 pub fn CVDisplayLinkStop(display_link: &mut DisplayLinkRef) -> i32;
76 pub fn CVDisplayLinkRelease(display_link: *mut CVDisplayLink);
77 pub fn CVDisplayLinkRetain(display_link: *mut CVDisplayLink) -> *mut CVDisplayLink;
78}
79
80impl DisplayLink {
81 pub unsafe fn new() -> Option<Self> {
83 let mut display_link: *mut CVDisplayLink = 0 as _;
84 let code = CVDisplayLinkCreateWithActiveCGDisplays(&mut display_link);
85 if code == 0 {
86 Some(DisplayLink::from_ptr(display_link))
87 } else {
88 None
89 }
90 }
91
92 pub unsafe fn on_display(display_id: u32) -> Option<Self> {
94 let mut display_link: *mut CVDisplayLink = 0 as _;
95 let code = CVDisplayLinkCreateWithCGDisplay(display_id, &mut display_link);
96 if code == 0 {
97 Some(DisplayLink::from_ptr(display_link))
98 } else {
99 None
100 }
101 }
102}
103
104impl DisplayLinkRef {
105 pub unsafe fn set_output_callback(
107 &mut self,
108 callback: CVDisplayLinkOutputCallback,
109 user_info: *mut c_void,
110 ) {
111 assert_eq!(CVDisplayLinkSetOutputCallback(self, callback, user_info), 0);
112 }
113
114 pub unsafe fn set_current_display(&mut self, display_id: u32) {
116 assert_eq!(CVDisplayLinkSetCurrentCGDisplay(self, display_id), 0);
117 }
118
119 pub unsafe fn start(&mut self) {
121 assert_eq!(CVDisplayLinkStart(self), 0);
122 }
123
124 pub unsafe fn stop(&mut self) {
126 assert_eq!(CVDisplayLinkStop(self), 0);
127 }
128}