core_graphics2/
display_configuration.rs

1use std::ptr::null_mut;
2
3use core_foundation::dictionary::CFDictionaryRef;
4use libc::{c_double, c_void};
5
6use crate::{
7    base::boolean_t,
8    color_space::CGColorSpaceRef,
9    direct_display::{CGDirectDisplayID, CGDisplayModeRef},
10    error::CGError,
11    geometry::CGSize,
12};
13
14#[repr(C)]
15pub struct _CGDisplayConfigRef(c_void);
16
17pub type CGDisplayConfigRef = *mut _CGDisplayConfigRef;
18
19bitflags! {
20    #[repr(C)]
21    #[derive(Clone, Copy, Debug, Default, PartialEq)]
22    pub struct CGConfigureOption: u32 {
23        #[doc(alias = "kCGConfigureForAppOnly")]
24        const ForAppOnly = 0;
25        #[doc(alias = "kCGConfigureForSession")]
26        const ForSession = 1;
27        #[doc(alias = "kCGConfigurePermanently")]
28        const Permanently = 2;
29    }
30}
31
32bitflags! {
33    #[repr(C)]
34    #[derive(Clone, Copy, Debug, Default, PartialEq)]
35    pub struct CGDisplayChangeSummaryFlags: u32 {
36        #[doc(alias = "kCGDisplayBeginConfigurationFlag")]
37        const BeginConfigurationFlag  = 1 << 0;
38        #[doc(alias = "kCGDisplayMovedFlag")]
39        const MovedFlag               = 1 << 1;
40        #[doc(alias = "kCGDisplaySetMainFlag")]
41        const SetMainFlag             = 1 << 2;
42        #[doc(alias = "kCGDisplaySetModeFlag")]
43        const SetModeFlag             = 1 << 3;
44        #[doc(alias = "kCGDisplayAddFlag")]
45        const AddFlag                 = 1 << 4;
46        #[doc(alias = "kCGDisplayRemoveFlag")]
47        const RemoveFlag              = 1 << 5;
48        #[doc(alias = "kCGDisplayEnabledFlag")]
49        const EnabledFlag             = 1 << 8;
50        #[doc(alias = "kCGDisplayDisabledFlag")]
51        const DisabledFlag            = 1 << 9;
52        #[doc(alias = "kCGDisplayMirrorFlag")]
53        const MirrorFlag              = 1 << 10;
54        #[doc(alias = "kCGDisplayUnMirrorFlag")]
55        const UnMirrorFlag            = 1 << 11;
56        #[doc(alias = "kCGDisplayDesktopShapeChangedFlag")]
57        const DesktopShapeChangedFlag = 1 << 12;
58    }
59}
60
61pub type CGDisplayReconfigurationCallBack = extern "C" fn(display: CGDirectDisplayID, flags: CGDisplayChangeSummaryFlags, userInfo: *mut c_void);
62
63extern "C" {
64    pub fn CGBeginDisplayConfiguration(config: *mut CGDisplayConfigRef) -> CGError;
65    pub fn CGConfigureDisplayOrigin(config: CGDisplayConfigRef, display: CGDirectDisplayID, x: i32, y: i32) -> CGError;
66    pub fn CGConfigureDisplayWithDisplayMode(
67        config: CGDisplayConfigRef,
68        display: CGDirectDisplayID,
69        mode: CGDisplayModeRef,
70        options: CFDictionaryRef,
71    ) -> CGError;
72    pub fn CGConfigureDisplayStereoOperation(
73        config: CGDisplayConfigRef,
74        display: CGDirectDisplayID,
75        stereo: boolean_t,
76        forceBlueLine: boolean_t,
77    ) -> CGError;
78    pub fn CGConfigureDisplayMirrorOfDisplay(config: CGDisplayConfigRef, display: CGDirectDisplayID, master: CGDirectDisplayID) -> CGError;
79    pub fn CGCancelDisplayConfiguration(config: CGDisplayConfigRef) -> CGError;
80    pub fn CGCompleteDisplayConfiguration(config: CGDisplayConfigRef, options: CGConfigureOption) -> CGError;
81    pub fn CGRestorePermanentDisplayConfiguration();
82    pub fn CGDisplayRegisterReconfigurationCallback(callback: CGDisplayReconfigurationCallBack, userInfo: *mut c_void) -> CGError;
83    pub fn CGDisplayRemoveReconfigurationCallback(callback: CGDisplayReconfigurationCallBack, userInfo: *mut c_void) -> CGError;
84    pub fn CGDisplaySetStereoOperation(
85        display: CGDirectDisplayID,
86        stereo: boolean_t,
87        forceBlueLine: boolean_t,
88        options: CGConfigureOption,
89    ) -> CGError;
90    pub fn CGDisplayIsActive(display: CGDirectDisplayID) -> boolean_t;
91    pub fn CGDisplayIsAsleep(display: CGDirectDisplayID) -> boolean_t;
92    pub fn CGDisplayIsOnline(display: CGDirectDisplayID) -> boolean_t;
93    pub fn CGDisplayIsMain(display: CGDirectDisplayID) -> boolean_t;
94    pub fn CGDisplayIsBuiltin(display: CGDirectDisplayID) -> boolean_t;
95    pub fn CGDisplayIsInMirrorSet(display: CGDirectDisplayID) -> boolean_t;
96    pub fn CGDisplayIsAlwaysInMirrorSet(display: CGDirectDisplayID) -> boolean_t;
97    pub fn CGDisplayIsInHWMirrorSet(display: CGDirectDisplayID) -> boolean_t;
98    pub fn CGDisplayMirrorsDisplay(display: CGDirectDisplayID) -> CGDirectDisplayID;
99    pub fn CGDisplayUsesOpenGLAcceleration(display: CGDirectDisplayID) -> boolean_t;
100    pub fn CGDisplayIsStereo(display: CGDirectDisplayID) -> boolean_t;
101    pub fn CGDisplayPrimaryDisplay(display: CGDirectDisplayID) -> CGDirectDisplayID;
102    pub fn CGDisplayUnitNumber(display: CGDirectDisplayID) -> u32;
103    pub fn CGDisplayVendorNumber(display: CGDirectDisplayID) -> u32;
104    pub fn CGDisplayModelNumber(display: CGDirectDisplayID) -> u32;
105    pub fn CGDisplaySerialNumber(display: CGDirectDisplayID) -> u32;
106    pub fn CGDisplayScreenSize(display: CGDirectDisplayID) -> CGSize;
107    pub fn CGDisplayRotation(display: CGDirectDisplayID) -> c_double;
108    pub fn CGDisplayCopyColorSpace(display: CGDirectDisplayID) -> CGColorSpaceRef;
109    pub fn CGConfigureDisplayMode(config: CGDisplayConfigRef, display: CGDirectDisplayID, mode: CFDictionaryRef) -> CGError;
110}
111
112pub fn begin_configuration() -> Result<CGDisplayConfigRef, CGError> {
113    let mut config: CGDisplayConfigRef = null_mut();
114    let result = unsafe { CGBeginDisplayConfiguration(&mut config) };
115    if result == CGError::Success {
116        Ok(config)
117    } else {
118        Err(result)
119    }
120}
121
122pub fn configure_display_origin(config: &CGDisplayConfigRef, display: CGDirectDisplayID, x: i32, y: i32) -> Result<(), CGError> {
123    let result = unsafe { CGConfigureDisplayOrigin(*config, display, x, y) };
124    if result == CGError::Success {
125        Ok(())
126    } else {
127        Err(result)
128    }
129}
130
131pub fn configure_display_with_display_mode(
132    config: &CGDisplayConfigRef,
133    display: CGDirectDisplayID,
134    mode: CGDisplayModeRef,
135    options: CFDictionaryRef,
136) -> Result<(), CGError> {
137    let result = unsafe { CGConfigureDisplayWithDisplayMode(*config, display, mode, options) };
138    if result == CGError::Success {
139        Ok(())
140    } else {
141        Err(result)
142    }
143}
144
145pub fn configure_display_stereo_operation(
146    config: &CGDisplayConfigRef,
147    display: CGDirectDisplayID,
148    stereo: bool,
149    force_blue_line: bool,
150) -> Result<(), CGError> {
151    let result = unsafe { CGConfigureDisplayStereoOperation(*config, display, stereo as boolean_t, force_blue_line as boolean_t) };
152    if result == CGError::Success {
153        Ok(())
154    } else {
155        Err(result)
156    }
157}
158
159pub fn configure_display_mirror_of_display(
160    config: &CGDisplayConfigRef,
161    display: CGDirectDisplayID,
162    master: CGDirectDisplayID,
163) -> Result<(), CGError> {
164    let result = unsafe { CGConfigureDisplayMirrorOfDisplay(*config, display, master) };
165    if result == CGError::Success {
166        Ok(())
167    } else {
168        Err(result)
169    }
170}
171
172pub fn cancel_display_configuration(config: &CGDisplayConfigRef) -> Result<(), CGError> {
173    let result = unsafe { CGCancelDisplayConfiguration(*config) };
174    if result == CGError::Success {
175        Ok(())
176    } else {
177        Err(result)
178    }
179}
180
181pub fn complete_display_configuration(config: &CGDisplayConfigRef, options: CGConfigureOption) -> Result<(), CGError> {
182    let result = unsafe { CGCompleteDisplayConfiguration(*config, options) };
183    if result == CGError::Success {
184        Ok(())
185    } else {
186        Err(result)
187    }
188}
189
190pub fn restore_permanent_display_configuration() {
191    unsafe { CGRestorePermanentDisplayConfiguration() };
192}