Skip to main content

core_graphics2/
display_configuration.rs

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