1 // Copyright 2013 The Servo Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution.
3 //
4 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
5 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
6 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
7 // option. This file may not be copied, modified, or distributed
8 // except according to those terms.
9 
10 #![allow(non_upper_case_globals)]
11 
12 use libc;
13 use std::ptr;
14 use std::ops::Deref;
15 
16 pub use base::{CGError, boolean_t};
17 pub use geometry::{CGRect, CGPoint, CGSize};
18 
19 use core_foundation::string::{CFString, CFStringRef};
20 use core_foundation::base::{CFRetain, TCFType};
21 use image::CGImage;
22 use foreign_types::ForeignType;
23 
24 pub type CGDirectDisplayID = u32;
25 pub type CGWindowID        = u32;
26 
27 pub const kCGNullWindowID: CGWindowID = 0 as CGWindowID;
28 pub const kCGNullDirectDisplayID: CGDirectDisplayID = 0 as CGDirectDisplayID;
29 
30 pub type CGWindowListOption = u32;
31 
32 pub const kCGWindowListOptionAll:              CGWindowListOption    = 0;
33 pub const kCGWindowListOptionOnScreenOnly:     CGWindowListOption    = 1 << 0;
34 pub const kCGWindowListOptionOnScreenAboveWindow: CGWindowListOption = 1 << 1;
35 pub const kCGWindowListOptionOnScreenBelowWindow: CGWindowListOption = 1 << 2;
36 pub const kCGWindowListOptionIncludingWindow:  CGWindowListOption    = 1 << 3;
37 pub const kCGWindowListExcludeDesktopElements: CGWindowListOption    = 1 << 4;
38 
39 pub type CGWindowImageOption = u32;
40 
41 pub const kCGWindowImageDefault: CGWindowImageOption = 0;
42 pub const kCGWindowImageBoundsIgnoreFraming: CGWindowImageOption = 1 << 0;
43 pub const kCGWindowImageShouldBeOpaque: CGWindowImageOption = 1 << 1;
44 pub const kCGWindowImageOnlyShadows: CGWindowImageOption = 1 << 2;
45 pub const kCGWindowImageBestResolution: CGWindowImageOption = 1 << 3;
46 pub const kCGWindowImageNominalResolution: CGWindowImageOption = 1 << 4;
47 
48 pub const kDisplayModeValidFlag: u32               = 0x00000001;
49 pub const kDisplayModeSafeFlag: u32                = 0x00000002;
50 pub const kDisplayModeDefaultFlag: u32             = 0x00000004;
51 pub const kDisplayModeAlwaysShowFlag: u32          = 0x00000008;
52 pub const kDisplayModeNeverShowFlag: u32           = 0x00000080;
53 pub const kDisplayModeNotResizeFlag: u32           = 0x00000010;
54 pub const kDisplayModeRequiresPanFlag: u32         = 0x00000020;
55 pub const kDisplayModeInterlacedFlag: u32          = 0x00000040;
56 pub const kDisplayModeSimulscanFlag: u32           = 0x00000100;
57 pub const kDisplayModeBuiltInFlag: u32             = 0x00000400;
58 pub const kDisplayModeNotPresetFlag: u32           = 0x00000200;
59 pub const kDisplayModeStretchedFlag: u32           = 0x00000800;
60 pub const kDisplayModeNotGraphicsQualityFlag: u32  = 0x00001000;
61 pub const kDisplayModeValidateAgainstDisplay: u32  = 0x00002000;
62 pub const kDisplayModeTelevisionFlag: u32          = 0x00100000;
63 pub const kDisplayModeValidForMirroringFlag: u32   = 0x00200000;
64 pub const kDisplayModeAcceleratorBackedFlag: u32   = 0x00400000;
65 pub const kDisplayModeValidForHiResFlag: u32       = 0x00800000;
66 pub const kDisplayModeValidForAirPlayFlag: u32     = 0x01000000;
67 pub const kDisplayModeNativeFlag: u32              = 0x02000000;
68 
69 pub const kDisplayModeSafetyFlags: u32             = 0x00000007;
70 
71 pub const IO1BitIndexedPixels: &str =     "P";
72 pub const IO2BitIndexedPixels: &str =     "PP";
73 pub const IO4BitIndexedPixels: &str =     "PPPP";
74 pub const IO8BitIndexedPixels: &str =     "PPPPPPPP";
75 pub const IO16BitDirectPixels: &str =     "-RRRRRGGGGGBBBBB";
76 pub const IO32BitDirectPixels: &str =     "--------RRRRRRRRGGGGGGGGBBBBBBBB";
77 pub const kIO30BitDirectPixels: &str =    "--RRRRRRRRRRGGGGGGGGGGBBBBBBBBBB";
78 pub const kIO64BitDirectPixels: &str =    "-16R16G16B16";
79 pub const kIO16BitFloatPixels: &str =     "-16FR16FG16FB16";
80 pub const kIO32BitFloatPixels: &str =     "-32FR32FG32FB32";
81 pub const IOYUV422Pixels: &str =          "Y4U2V2";
82 pub const IO8BitOverlayPixels: &str =     "O8";
83 
84 
85 pub use core_foundation::dictionary::{ CFDictionary, CFDictionaryRef, CFDictionaryGetValueIfPresent };
86 pub use core_foundation::array::{ CFArray, CFArrayRef };
87 pub use core_foundation::array::{ CFArrayGetCount, CFArrayGetValueAtIndex };
88 pub use core_foundation::base::{  CFIndex, CFRelease, CFTypeRef };
89 
90 pub type CGDisplayConfigRef = *mut libc::c_void;
91 
92 #[repr(u32)]
93 #[derive(Clone, Copy)]
94 pub enum CGConfigureOption {
95     ConfigureForAppOnly = 0,
96     ConfigureForSession = 1,
97     ConfigurePermanently = 2,
98 }
99 
100 #[derive(Copy, Clone, Debug)]
101 pub struct CGDisplay {
102     pub id: CGDirectDisplayID,
103 }
104 
105 foreign_type! {
106     #[doc(hidden)]
107     type CType = ::sys::CGDisplayMode;
108     fn drop = CGDisplayModeRelease;
109     fn clone = |p| CFRetain(p as *const _) as *mut _;
110     pub struct CGDisplayMode;
111     pub struct CGDisplayModeRef;
112 }
113 
114 impl CGDisplay {
115     #[inline]
new(id: CGDirectDisplayID) -> CGDisplay116     pub fn new(id: CGDirectDisplayID) -> CGDisplay {
117         CGDisplay { id: id }
118     }
119 
120     /// Returns the the main display.
121     #[inline]
main() -> CGDisplay122     pub fn main() -> CGDisplay {
123         CGDisplay::new(unsafe { CGMainDisplayID() })
124     }
125 
126     /// A value that will never correspond to actual hardware.
null_display() -> CGDisplay127     pub fn null_display() -> CGDisplay {
128         CGDisplay::new(kCGNullDirectDisplayID)
129     }
130 
131     /// Returns the bounds of a display in the global display coordinate space.
132     #[inline]
bounds(&self) -> CGRect133     pub fn bounds(&self) -> CGRect {
134         unsafe { CGDisplayBounds(self.id) }
135     }
136 
137     /// Returns information about a display's current configuration.
138     #[inline]
display_mode(&self) -> Option<CGDisplayMode>139     pub fn display_mode(&self) -> Option<CGDisplayMode> {
140         unsafe {
141             let mode_ref = CGDisplayCopyDisplayMode(self.id);
142             if !mode_ref.is_null() {
143                 Some(CGDisplayMode::from_ptr(mode_ref))
144             } else {
145                 None
146             }
147         }
148     }
149 
150     /// Begins a new set of display configuration changes.
begin_configuration(&self) -> Result<CGDisplayConfigRef, CGError>151     pub fn begin_configuration(&self) -> Result<CGDisplayConfigRef, CGError> {
152         unsafe {
153             let mut config_ref: CGDisplayConfigRef = ptr::null_mut();
154             let result = CGBeginDisplayConfiguration(&mut config_ref);
155             if result == 0 {
156                 Ok(config_ref)
157             } else {
158                 Err(result)
159             }
160         }
161     }
162 
163     /// Cancels a set of display configuration changes.
cancel_configuration(&self, config_ref: &CGDisplayConfigRef) -> Result<(), CGError>164     pub fn cancel_configuration(&self, config_ref: &CGDisplayConfigRef) -> Result<(), CGError> {
165         let result = unsafe { CGCancelDisplayConfiguration(*config_ref) };
166         if result == 0 {
167             Ok(())
168         } else {
169             Err(result)
170         }
171     }
172 
173     /// Completes a set of display configuration changes.
complete_configuration( &self, config_ref: &CGDisplayConfigRef, option: CGConfigureOption, ) -> Result<(), CGError>174     pub fn complete_configuration(
175         &self,
176         config_ref: &CGDisplayConfigRef,
177         option: CGConfigureOption,
178     ) -> Result<(), CGError> {
179         let result = unsafe { CGCompleteDisplayConfiguration(*config_ref, option) };
180         if result == 0 {
181             Ok(())
182         } else {
183             Err(result)
184         }
185     }
186 
187     /// Configures the display mode of a display.
configure_display_with_display_mode( &self, config_ref: &CGDisplayConfigRef, display_mode: &CGDisplayMode, ) -> Result<(), CGError>188     pub fn configure_display_with_display_mode(
189         &self,
190         config_ref: &CGDisplayConfigRef,
191         display_mode: &CGDisplayMode,
192     ) -> Result<(), CGError> {
193         let result = unsafe {
194             CGConfigureDisplayWithDisplayMode(
195                 *config_ref,
196                 self.id,
197                 display_mode.as_ptr(),
198                 ptr::null(),
199             )
200         };
201         if result == 0 {
202             Ok(())
203         } else {
204             Err(result)
205         }
206     }
207 
208     /// Configures the origin of a display in the global display coordinate space.
configure_display_origin( &self, config_ref: &CGDisplayConfigRef, x: i32, y: i32, ) -> Result<(), CGError>209     pub fn configure_display_origin(
210         &self,
211         config_ref: &CGDisplayConfigRef,
212         x: i32,
213         y: i32,
214     ) -> Result<(), CGError> {
215         let result = unsafe { CGConfigureDisplayOrigin(*config_ref, self.id, x, y) };
216 
217         if result == 0 {
218             Ok(())
219         } else {
220             Err(result)
221         }
222     }
223 
224     /// Changes the configuration of a mirroring set.
configure_display_mirror_of_display( &self, config_ref: &CGDisplayConfigRef, master: &CGDisplay, ) -> Result<(), CGError>225     pub fn configure_display_mirror_of_display(
226         &self,
227         config_ref: &CGDisplayConfigRef,
228         master: &CGDisplay,
229     ) -> Result<(), CGError> {
230         let result = unsafe { CGConfigureDisplayMirrorOfDisplay(*config_ref, self.id, master.id) };
231 
232         if result == 0 {
233             Ok(())
234         } else {
235             Err(result)
236         }
237     }
238 
239     /// Returns an image containing the contents of the specified display.
240     #[inline]
image(&self) -> Option<CGImage>241     pub fn image(&self) -> Option<CGImage> {
242         unsafe {
243             let image_ref = CGDisplayCreateImage(self.id);
244             if !image_ref.is_null() {
245                 Some(CGImage::from_ptr(image_ref))
246             } else {
247                 None
248             }
249         }
250     }
251 
252     /// Returns a composite image based on a dynamically generated list of
253     /// windows.
254     #[inline]
screenshot( bounds: CGRect, list_option: CGWindowListOption, window_id: CGWindowID, image_option: CGWindowImageOption, ) -> Option<CGImage>255     pub fn screenshot(
256         bounds: CGRect,
257         list_option: CGWindowListOption,
258         window_id: CGWindowID,
259         image_option: CGWindowImageOption,
260     ) -> Option<CGImage> {
261         unsafe {
262             let image_ref = CGWindowListCreateImage(bounds, list_option, window_id, image_option);
263             if !image_ref.is_null() {
264                 Some(CGImage::from_ptr(image_ref))
265             } else {
266                 None
267             }
268         }
269     }
270 
271     /// Returns a composite image of the specified windows.
272     #[inline]
screenshot_from_windows( bounds: CGRect, windows: CFArray, image_option: CGWindowImageOption, ) -> Option<CGImage>273     pub fn screenshot_from_windows(
274         bounds: CGRect,
275         windows: CFArray,
276         image_option: CGWindowImageOption,
277     ) -> Option<CGImage> {
278         unsafe {
279             let image_ref = CGWindowListCreateImageFromArray(
280                 bounds,
281                 windows.as_concrete_TypeRef(),
282                 image_option,
283             );
284             if !image_ref.is_null() {
285                 Some(CGImage::from_ptr(image_ref))
286             } else {
287                 None
288             }
289         }
290     }
291 
292     /// Generates and returns information about the selected windows in the
293     /// current user session.
window_list_info( option: CGWindowListOption, relative_to_window: Option<CGWindowID>, ) -> Option<CFArray>294     pub fn window_list_info(
295         option: CGWindowListOption,
296         relative_to_window: Option<CGWindowID>,
297     ) -> Option<CFArray> {
298         let relative_to_window = relative_to_window.unwrap_or(kCGNullWindowID);
299         let array_ref = unsafe { CGWindowListCopyWindowInfo(option, relative_to_window) };
300         if !array_ref.is_null() {
301             Some(unsafe { TCFType::wrap_under_create_rule(array_ref) })
302         } else {
303             None
304         }
305     }
306 
307     /// Returns a Boolean value indicating whether a display is active.
308     #[inline]
is_active(&self) -> bool309     pub fn is_active(&self) -> bool {
310         unsafe { CGDisplayIsActive(self.id) != 0 }
311     }
312 
313     /// Returns a boolean indicating whether a display is always in a
314     /// mirroring set.
315     #[inline]
is_always_in_mirror_set(&self) -> bool316     pub fn is_always_in_mirror_set(&self) -> bool {
317         unsafe { CGDisplayIsAlwaysInMirrorSet(self.id) != 0 }
318     }
319 
320     /// Returns a boolean indicating whether a display is sleeping (and is
321     /// therefore not drawable.)
322     #[inline]
is_asleep(&self) -> bool323     pub fn is_asleep(&self) -> bool {
324         unsafe { CGDisplayIsAsleep(self.id) != 0 }
325     }
326 
327     /// Returns a boolean indicating whether a display is built-in, such as
328     /// the internal display in portable systems.
329     #[inline]
is_builtin(&self) -> bool330     pub fn is_builtin(&self) -> bool {
331         unsafe { CGDisplayIsBuiltin(self.id) != 0 }
332     }
333 
334     /// Returns a boolean indicating whether a display is in a hardware
335     /// mirroring set.
336     #[inline]
is_in_hw_mirror_set(&self) -> bool337     pub fn is_in_hw_mirror_set(&self) -> bool {
338         unsafe { CGDisplayIsInHWMirrorSet(self.id) != 0 }
339     }
340 
341     /// Returns a boolean indicating whether a display is in a mirroring set.
342     #[inline]
is_in_mirror_set(&self) -> bool343     pub fn is_in_mirror_set(&self) -> bool {
344         unsafe { CGDisplayIsInMirrorSet(self.id) != 0 }
345     }
346 
347     /// Returns a boolean indicating whether a display is the main display.
348     #[inline]
is_main(&self) -> bool349     pub fn is_main(&self) -> bool {
350         unsafe { CGDisplayIsMain(self.id) != 0 }
351     }
352 
353     /// Returns a boolean indicating whether a display is connected or online.
354     #[inline]
is_online(&self) -> bool355     pub fn is_online(&self) -> bool {
356         unsafe { CGDisplayIsOnline(self.id) != 0 }
357     }
358 
359     /// Returns a boolean indicating whether Quartz is using OpenGL-based
360     /// window acceleration (Quartz Extreme) to render in a display.
361     #[inline]
uses_open_gl_acceleration(&self) -> bool362     pub fn uses_open_gl_acceleration(&self) -> bool {
363         unsafe { CGDisplayUsesOpenGLAcceleration(self.id) != 0 }
364     }
365 
366     /// Returns a boolean indicating whether a display is running in a stereo
367     /// graphics mode.
368     #[inline]
is_stereo(&self) -> bool369     pub fn is_stereo(&self) -> bool {
370         unsafe { CGDisplayIsStereo(self.id) != 0 }
371     }
372 
373     /// For a secondary display in a mirroring set, returns the primary
374     /// display.
375     #[inline]
mirrors_display(&self) -> CGDirectDisplayID376     pub fn mirrors_display(&self) -> CGDirectDisplayID {
377         unsafe { CGDisplayMirrorsDisplay(self.id) }
378     }
379 
380     /// Returns the primary display in a hardware mirroring set.
381     #[inline]
primary_display(&self) -> CGDirectDisplayID382     pub fn primary_display(&self) -> CGDirectDisplayID {
383         unsafe { CGDisplayPrimaryDisplay(self.id) }
384     }
385 
386     /// Returns the rotation angle of a display in degrees.
387     #[inline]
rotation(&self) -> f64388     pub fn rotation(&self) -> f64 {
389         unsafe { CGDisplayRotation(self.id) }
390     }
391 
392     /// Returns the width and height of a display in millimeters.
393     #[inline]
screen_size(&self) -> CGSize394     pub fn screen_size(&self) -> CGSize {
395         unsafe { CGDisplayScreenSize(self.id) }
396     }
397 
398     /// Returns the serial number of a display monitor.
399     #[inline]
serial_number(&self) -> u32400     pub fn serial_number(&self) -> u32 {
401         unsafe { CGDisplaySerialNumber(self.id) }
402     }
403 
404     /// Returns the logical unit number of a display.
405     #[inline]
unit_number(&self) -> u32406     pub fn unit_number(&self) -> u32 {
407         unsafe { CGDisplayUnitNumber(self.id) }
408     }
409 
410     /// Returns the vendor number of the specified display's monitor.
411     #[inline]
vendor_number(&self) -> u32412     pub fn vendor_number(&self) -> u32 {
413         unsafe { CGDisplayVendorNumber(self.id) }
414     }
415 
416     /// Returns the model number of a display monitor.
417     #[inline]
model_number(&self) -> u32418     pub fn model_number(&self) -> u32 {
419         unsafe { CGDisplayModelNumber(self.id) }
420     }
421 
422     /// Returns the display height in pixel units.
423     #[inline]
pixels_high(&self) -> u64424     pub fn pixels_high(&self) -> u64 {
425         unsafe { CGDisplayPixelsHigh(self.id) as u64 }
426     }
427 
428     /// Returns the display width in pixel units.
429     #[inline]
pixels_wide(&self) -> u64430     pub fn pixels_wide(&self) -> u64 {
431         unsafe { CGDisplayPixelsWide(self.id) as u64 }
432     }
433 
434     /// Provides a list of displays that are active (or drawable).
435     #[inline]
active_displays() -> Result<Vec<CGDirectDisplayID>, CGError>436     pub fn active_displays() -> Result<Vec<CGDirectDisplayID>, CGError> {
437         let count = CGDisplay::active_display_count()?;
438         let mut buf: Vec<CGDirectDisplayID> = vec![0; count as usize];
439         let result =
440             unsafe { CGGetActiveDisplayList(count as u32, buf.as_mut_ptr(), ptr::null_mut()) };
441         if result == 0 {
442             Ok(buf)
443         } else {
444             Err(result)
445         }
446     }
447 
448     /// Provides count of displays that are active (or drawable).
449     #[inline]
active_display_count() -> Result<u32, CGError>450     pub fn active_display_count() -> Result<u32, CGError> {
451         let mut count: u32 = 0;
452         let result = unsafe { CGGetActiveDisplayList(0, ptr::null_mut(), &mut count) };
453         if result == 0 {
454             Ok(count as u32)
455         } else {
456             Err(result)
457         }
458     }
459 
460     /// Hides the mouse cursor, and increments the hide cursor count.
461     #[inline]
hide_cursor(&self) -> Result<(), CGError>462     pub fn hide_cursor(&self) -> Result<(), CGError> {
463         let result = unsafe { CGDisplayHideCursor(self.id) };
464         if result == 0 {
465             Ok(())
466         } else {
467             Err(result)
468         }
469     }
470 
471     /// Decrements the hide cursor count, and shows the mouse cursor if the
472     /// count is 0.
473     #[inline]
show_cursor(&self) -> Result<(), CGError>474     pub fn show_cursor(&self) -> Result<(), CGError> {
475         let result = unsafe { CGDisplayShowCursor(self.id) };
476         if result == 0 {
477             Ok(())
478         } else {
479             Err(result)
480         }
481     }
482 
483     /// Moves the mouse cursor to a specified point relative to the display
484     /// origin (the upper-left corner of the display).
485     #[inline]
move_cursor_to_point(&self, point: CGPoint) -> Result<(), CGError>486     pub fn move_cursor_to_point(&self, point: CGPoint) -> Result<(), CGError> {
487         let result = unsafe { CGDisplayMoveCursorToPoint(self.id, point) };
488         if result == 0 {
489             Ok(())
490         } else {
491             Err(result)
492         }
493     }
494 
495     /// Moves the mouse cursor without generating events.
496     #[inline]
warp_mouse_cursor_position(point: CGPoint) -> Result<(), CGError>497     pub fn warp_mouse_cursor_position(point: CGPoint) -> Result<(), CGError> {
498         let result = unsafe { CGWarpMouseCursorPosition(point) };
499         if result == 0 {
500             Ok(())
501         } else {
502             Err(result)
503         }
504     }
505 
506     /// Connects or disconnects the mouse and cursor while an application is
507     /// in the foreground.
508     #[inline]
associate_mouse_and_mouse_cursor_position(connected: bool) -> Result<(), CGError>509     pub fn associate_mouse_and_mouse_cursor_position(connected: bool) -> Result<(), CGError> {
510         let result = unsafe { CGAssociateMouseAndMouseCursorPosition(connected as boolean_t) };
511         if result == 0 {
512             Ok(())
513         } else {
514             Err(result)
515         }
516     }
517 }
518 
519 impl CGDisplayMode {
520     /// Returns all display modes for the specified display id.
all_display_modes( display_id: CGDirectDisplayID, options: CFDictionaryRef, ) -> Option<Vec<CGDisplayMode>>521     pub fn all_display_modes(
522         display_id: CGDirectDisplayID,
523         options: CFDictionaryRef,
524     ) -> Option<Vec<CGDisplayMode>> {
525         let array_opt: Option<CFArray> = unsafe {
526             let array_ref = CGDisplayCopyAllDisplayModes(display_id, options);
527             if !array_ref.is_null() {
528                 Some(CFArray::wrap_under_create_rule(array_ref))
529             } else {
530                 None
531             }
532         };
533         match array_opt {
534             Some(modes) => {
535                 let vec: Vec<CGDisplayMode> = modes
536                     .into_iter()
537                     .map(|value0| {
538                         let x = *value0.deref() as *mut ::sys::CGDisplayMode;
539                         unsafe { CGDisplayMode::from_ptr(x) }
540                     }).collect();
541                 Some(vec)
542             }
543             None => None,
544         }
545     }
546 
547     /// Returns the height of the specified display mode.
548     #[inline]
height(&self) -> u64549     pub fn height(&self) -> u64 {
550         unsafe { CGDisplayModeGetHeight(self.as_ptr()) as u64 }
551     }
552 
553     /// Returns the width of the specified display mode.
554     #[inline]
width(&self) -> u64555     pub fn width(&self) -> u64 {
556         unsafe { CGDisplayModeGetWidth(self.as_ptr()) as u64 }
557     }
558 
559     /// Returns the pixel height of the specified display mode.
560     #[inline]
pixel_height(&self) -> u64561     pub fn pixel_height(&self) -> u64 {
562         unsafe { CGDisplayModeGetPixelHeight(self.as_ptr()) as u64 }
563     }
564 
565     /// Returns the pixel width of the specified display mode.
566     #[inline]
pixel_width(&self) -> u64567     pub fn pixel_width(&self) -> u64 {
568         unsafe { CGDisplayModeGetPixelWidth(self.as_ptr()) as u64 }
569     }
570 
571     #[inline]
refresh_rate(&self) -> f64572     pub fn refresh_rate(&self) -> f64 {
573         unsafe { CGDisplayModeGetRefreshRate(self.as_ptr()) }
574     }
575 
576     /// Returns the I/O Kit flags of the specified display mode.
577     #[inline]
io_flags(&self) -> u32578     pub fn io_flags(&self) -> u32 {
579         unsafe { CGDisplayModeGetIOFlags(self.as_ptr()) as u32 }
580     }
581 
582     /// Returns the pixel encoding of the specified display mode.
583     #[inline]
pixel_encoding(&self) -> CFString584     pub fn pixel_encoding(&self) -> CFString {
585         unsafe { CFString::wrap_under_create_rule(CGDisplayModeCopyPixelEncoding(self.as_ptr())) }
586     }
587 
588     /// Returns the number of bits per pixel of the specified display mode.
bit_depth(&self) -> usize589     pub fn bit_depth(&self) -> usize {
590         let pixel_encoding = self.pixel_encoding().to_string();
591         // my numerical representation for kIO16BitFloatPixels and kIO32bitFloatPixels
592         // are made up and possibly non-sensical
593         if pixel_encoding.eq_ignore_ascii_case(kIO32BitFloatPixels) {
594             96
595         } else if pixel_encoding.eq_ignore_ascii_case(kIO64BitDirectPixels) {
596             64
597         } else if pixel_encoding.eq_ignore_ascii_case(kIO16BitFloatPixels) {
598             48
599         } else if pixel_encoding.eq_ignore_ascii_case(IO32BitDirectPixels) {
600             32
601         } else if pixel_encoding.eq_ignore_ascii_case(kIO30BitDirectPixels) {
602             30
603         } else if pixel_encoding.eq_ignore_ascii_case(IO16BitDirectPixels) {
604             16
605         } else if pixel_encoding.eq_ignore_ascii_case(IO8BitIndexedPixels) {
606             8
607         }else{
608             0
609         }
610     }
611 }
612 
613 #[link(name = "CoreGraphics", kind = "framework")]
614 extern "C" {
615     pub static CGRectNull: CGRect;
616     pub static CGRectInfinite: CGRect;
617 
618     pub static kCGDisplayShowDuplicateLowResolutionModes: CFStringRef;
619 
CGDisplayModeRelease(mode: ::sys::CGDisplayModeRef)620     pub fn CGDisplayModeRelease(mode: ::sys::CGDisplayModeRef);
621 
CGMainDisplayID() -> CGDirectDisplayID622     pub fn CGMainDisplayID() -> CGDirectDisplayID;
CGDisplayIsActive(display: CGDirectDisplayID) -> boolean_t623     pub fn CGDisplayIsActive(display: CGDirectDisplayID) -> boolean_t;
CGDisplayIsAlwaysInMirrorSet(display: CGDirectDisplayID) -> boolean_t624     pub fn CGDisplayIsAlwaysInMirrorSet(display: CGDirectDisplayID) -> boolean_t;
CGDisplayIsAsleep(display: CGDirectDisplayID) -> boolean_t625     pub fn CGDisplayIsAsleep(display: CGDirectDisplayID) -> boolean_t;
CGDisplayIsBuiltin(display: CGDirectDisplayID) -> boolean_t626     pub fn CGDisplayIsBuiltin(display: CGDirectDisplayID) -> boolean_t;
CGDisplayIsInHWMirrorSet(display: CGDirectDisplayID) -> boolean_t627     pub fn CGDisplayIsInHWMirrorSet(display: CGDirectDisplayID) -> boolean_t;
CGDisplayIsInMirrorSet(display: CGDirectDisplayID) -> boolean_t628     pub fn CGDisplayIsInMirrorSet(display: CGDirectDisplayID) -> boolean_t;
CGDisplayIsMain(display: CGDirectDisplayID) -> boolean_t629     pub fn CGDisplayIsMain(display: CGDirectDisplayID) -> boolean_t;
CGDisplayIsOnline(display: CGDirectDisplayID) -> boolean_t630     pub fn CGDisplayIsOnline(display: CGDirectDisplayID) -> boolean_t;
CGDisplayIsStereo(display: CGDirectDisplayID) -> boolean_t631     pub fn CGDisplayIsStereo(display: CGDirectDisplayID) -> boolean_t;
CGDisplayMirrorsDisplay(display: CGDirectDisplayID) -> CGDirectDisplayID632     pub fn CGDisplayMirrorsDisplay(display: CGDirectDisplayID) -> CGDirectDisplayID;
CGDisplayPrimaryDisplay(display: CGDirectDisplayID) -> CGDirectDisplayID633     pub fn CGDisplayPrimaryDisplay(display: CGDirectDisplayID) -> CGDirectDisplayID;
CGDisplayRotation(display: CGDirectDisplayID) -> libc::c_double634     pub fn CGDisplayRotation(display: CGDirectDisplayID) -> libc::c_double;
CGDisplayScreenSize(display: CGDirectDisplayID) -> CGSize635     pub fn CGDisplayScreenSize(display: CGDirectDisplayID) -> CGSize;
CGDisplaySerialNumber(display: CGDirectDisplayID) -> u32636     pub fn CGDisplaySerialNumber(display: CGDirectDisplayID) -> u32;
CGDisplayUnitNumber(display: CGDirectDisplayID) -> u32637     pub fn CGDisplayUnitNumber(display: CGDirectDisplayID) -> u32;
CGDisplayUsesOpenGLAcceleration(display: CGDirectDisplayID) -> boolean_t638     pub fn CGDisplayUsesOpenGLAcceleration(display: CGDirectDisplayID) -> boolean_t;
CGDisplayVendorNumber(display: CGDirectDisplayID) -> u32639     pub fn CGDisplayVendorNumber(display: CGDirectDisplayID) -> u32;
CGGetActiveDisplayList( max_displays: u32, active_displays: *mut CGDirectDisplayID, display_count: *mut u32, ) -> CGError640     pub fn CGGetActiveDisplayList(
641         max_displays: u32,
642         active_displays: *mut CGDirectDisplayID,
643         display_count: *mut u32,
644     ) -> CGError;
CGGetDisplaysWithRect( rect: CGRect, max_displays: u32, displays: *mut CGDirectDisplayID, matching_display_count: *mut u32, ) -> CGError645     pub fn CGGetDisplaysWithRect(
646         rect: CGRect,
647         max_displays: u32,
648         displays: *mut CGDirectDisplayID,
649         matching_display_count: *mut u32,
650     ) -> CGError;
CGDisplayModelNumber(display: CGDirectDisplayID) -> u32651     pub fn CGDisplayModelNumber(display: CGDirectDisplayID) -> u32;
CGDisplayPixelsHigh(display: CGDirectDisplayID) -> libc::size_t652     pub fn CGDisplayPixelsHigh(display: CGDirectDisplayID) -> libc::size_t;
CGDisplayPixelsWide(display: CGDirectDisplayID) -> libc::size_t653     pub fn CGDisplayPixelsWide(display: CGDirectDisplayID) -> libc::size_t;
CGDisplayBounds(display: CGDirectDisplayID) -> CGRect654     pub fn CGDisplayBounds(display: CGDirectDisplayID) -> CGRect;
CGDisplayCreateImage(display: CGDirectDisplayID) -> ::sys::CGImageRef655     pub fn CGDisplayCreateImage(display: CGDirectDisplayID) -> ::sys::CGImageRef;
656 
CGBeginDisplayConfiguration(config: *mut CGDisplayConfigRef) -> CGError657     pub fn CGBeginDisplayConfiguration(config: *mut CGDisplayConfigRef) -> CGError;
CGCancelDisplayConfiguration(config: CGDisplayConfigRef) -> CGError658     pub fn CGCancelDisplayConfiguration(config: CGDisplayConfigRef) -> CGError;
CGCompleteDisplayConfiguration( config: CGDisplayConfigRef, option: CGConfigureOption, ) -> CGError659     pub fn CGCompleteDisplayConfiguration(
660         config: CGDisplayConfigRef,
661         option: CGConfigureOption,
662     ) -> CGError;
CGConfigureDisplayWithDisplayMode( config: CGDisplayConfigRef, display: CGDirectDisplayID, mode: ::sys::CGDisplayModeRef, options: CFDictionaryRef, ) -> CGError663     pub fn CGConfigureDisplayWithDisplayMode(
664         config: CGDisplayConfigRef,
665         display: CGDirectDisplayID,
666         mode: ::sys::CGDisplayModeRef,
667         options: CFDictionaryRef,
668     ) -> CGError;
CGConfigureDisplayMirrorOfDisplay( config: CGDisplayConfigRef, display: CGDirectDisplayID, master: CGDirectDisplayID, ) -> CGError669     pub fn CGConfigureDisplayMirrorOfDisplay(
670         config: CGDisplayConfigRef,
671         display: CGDirectDisplayID,
672         master: CGDirectDisplayID,
673     ) -> CGError;
CGConfigureDisplayOrigin( config: CGDisplayConfigRef, display: CGDirectDisplayID, x: i32, y: i32, ) -> CGError674     pub fn CGConfigureDisplayOrigin(
675         config: CGDisplayConfigRef,
676         display: CGDirectDisplayID,
677         x: i32,
678         y: i32,
679     ) -> CGError;
680 
CGDisplayCopyDisplayMode(display: CGDirectDisplayID) -> ::sys::CGDisplayModeRef681     pub fn CGDisplayCopyDisplayMode(display: CGDirectDisplayID) -> ::sys::CGDisplayModeRef;
CGDisplayModeGetHeight(mode: ::sys::CGDisplayModeRef) -> libc::size_t682     pub fn CGDisplayModeGetHeight(mode: ::sys::CGDisplayModeRef) -> libc::size_t;
CGDisplayModeGetWidth(mode: ::sys::CGDisplayModeRef) -> libc::size_t683     pub fn CGDisplayModeGetWidth(mode: ::sys::CGDisplayModeRef) -> libc::size_t;
CGDisplayModeGetPixelHeight(mode: ::sys::CGDisplayModeRef) -> libc::size_t684     pub fn CGDisplayModeGetPixelHeight(mode: ::sys::CGDisplayModeRef) -> libc::size_t;
CGDisplayModeGetPixelWidth(mode: ::sys::CGDisplayModeRef) -> libc::size_t685     pub fn CGDisplayModeGetPixelWidth(mode: ::sys::CGDisplayModeRef) -> libc::size_t;
CGDisplayModeGetRefreshRate(mode: ::sys::CGDisplayModeRef) -> libc::c_double686     pub fn CGDisplayModeGetRefreshRate(mode: ::sys::CGDisplayModeRef) -> libc::c_double;
CGDisplayModeGetIOFlags(mode: ::sys::CGDisplayModeRef) -> u32687     pub fn CGDisplayModeGetIOFlags(mode: ::sys::CGDisplayModeRef) -> u32;
CGDisplayModeCopyPixelEncoding(mode: ::sys::CGDisplayModeRef) -> CFStringRef688     pub fn CGDisplayModeCopyPixelEncoding(mode: ::sys::CGDisplayModeRef) -> CFStringRef;
689 
CGDisplayCopyAllDisplayModes( display: CGDirectDisplayID, options: CFDictionaryRef, ) -> CFArrayRef690     pub fn CGDisplayCopyAllDisplayModes(
691         display: CGDirectDisplayID,
692         options: CFDictionaryRef,
693     ) -> CFArrayRef;
694 
695     // mouse stuff
CGDisplayHideCursor(display: CGDirectDisplayID) -> CGError696     pub fn CGDisplayHideCursor(display: CGDirectDisplayID) -> CGError;
CGDisplayShowCursor(display: CGDirectDisplayID) -> CGError697     pub fn CGDisplayShowCursor(display: CGDirectDisplayID) -> CGError;
CGDisplayMoveCursorToPoint(display: CGDirectDisplayID, point: CGPoint) -> CGError698     pub fn CGDisplayMoveCursorToPoint(display: CGDirectDisplayID, point: CGPoint) -> CGError;
CGWarpMouseCursorPosition(point: CGPoint) -> CGError699     pub fn CGWarpMouseCursorPosition(point: CGPoint) -> CGError;
CGAssociateMouseAndMouseCursorPosition(connected: boolean_t) -> CGError700     pub fn CGAssociateMouseAndMouseCursorPosition(connected: boolean_t) -> CGError;
701 
702     // Window Services Reference
CGWindowListCopyWindowInfo( option: CGWindowListOption, relativeToWindow: CGWindowID, ) -> CFArrayRef703     pub fn CGWindowListCopyWindowInfo(
704         option: CGWindowListOption,
705         relativeToWindow: CGWindowID,
706     ) -> CFArrayRef;
CGWindowListCreateImage( screenBounds: CGRect, listOptions: CGWindowListOption, windowId: CGWindowID, imageOptions: CGWindowImageOption, ) -> ::sys::CGImageRef707     pub fn CGWindowListCreateImage(
708         screenBounds: CGRect,
709         listOptions: CGWindowListOption,
710         windowId: CGWindowID,
711         imageOptions: CGWindowImageOption,
712     ) -> ::sys::CGImageRef;
CGWindowListCreateImageFromArray( screenBounds: CGRect, windowArray: CFArrayRef, imageOptions: CGWindowImageOption, ) -> ::sys::CGImageRef713     pub fn CGWindowListCreateImageFromArray(
714         screenBounds: CGRect,
715         windowArray: CFArrayRef,
716         imageOptions: CGWindowImageOption,
717     ) -> ::sys::CGImageRef;
718 }
719