core_graphics/
window.rs

1// Copyright 2018 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
12use core_foundation::array::{CFArray, CFArrayRef};
13use core_foundation::base::{CFType, TCFType};
14use core_foundation::dictionary::CFDictionary;
15use core_foundation::string::{CFString, CFStringRef};
16use foreign_types::ForeignType;
17
18use crate::geometry::CGRect;
19use crate::image::CGImage;
20use crate::sys;
21
22pub type CGWindowID = u32;
23pub type CGWindowLevel = i32;
24
25pub const kCGNullWindowID: CGWindowID = 0;
26
27// https://developer.apple.com/documentation/coregraphics/cgwindowsharingtype?language=objc
28pub type CGWindowSharingType = u32;
29pub const kCGWindowSharingNone: CGWindowSharingType = 0;
30pub const kCGWindowSharingReadOnly: CGWindowSharingType = 1;
31pub const kCGWindowSharingReadWrite: CGWindowSharingType = 2;
32
33pub type CGWindowBackingType = u32;
34pub const kCGWindowBackingStoreRetained: CGWindowBackingType = 0;
35pub const kCGWindowBackingStoreNonretained: CGWindowBackingType = 1;
36pub const kCGWindowBackingStoreBuffered: CGWindowBackingType = 2;
37
38// https://developer.apple.com/documentation/coregraphics/quartz_window_services/window_list_option_constants?language=objc
39pub type CGWindowListOption = u32;
40pub const kCGWindowListOptionAll: CGWindowListOption = 0;
41pub const kCGWindowListOptionOnScreenOnly: CGWindowListOption = 1 << 0;
42pub const kCGWindowListOptionOnScreenAboveWindow: CGWindowListOption = 1 << 1;
43pub const kCGWindowListOptionOnScreenBelowWindow: CGWindowListOption = 1 << 2;
44pub const kCGWindowListOptionIncludingWindow: CGWindowListOption = 1 << 3;
45pub const kCGWindowListExcludeDesktopElements: CGWindowListOption = 1 << 4;
46
47pub type CGWindowImageOption = u32;
48pub const kCGWindowImageDefault: CGWindowImageOption = 0;
49pub const kCGWindowImageBoundsIgnoreFraming: CGWindowImageOption = 1 << 0;
50pub const kCGWindowImageShouldBeOpaque: CGWindowImageOption = 1 << 1;
51pub const kCGWindowImageOnlyShadows: CGWindowImageOption = 1 << 2;
52pub const kCGWindowImageBestResolution: CGWindowImageOption = 1 << 3;
53pub const kCGWindowImageNominalResolution: CGWindowImageOption = 1 << 4;
54
55pub fn copy_window_info(
56    option: CGWindowListOption,
57    relative_to_window: CGWindowID,
58) -> Option<CFArray> {
59    unsafe {
60        let array = CGWindowListCopyWindowInfo(option, relative_to_window);
61        if array.is_null() {
62            None
63        } else {
64            Some(TCFType::wrap_under_create_rule(array))
65        }
66    }
67}
68
69pub fn create_window_list(
70    option: CGWindowListOption,
71    relative_to_window: CGWindowID,
72) -> Option<CFArray<CGWindowID>> {
73    unsafe {
74        let array = CGWindowListCreate(option, relative_to_window);
75        if array.is_null() {
76            None
77        } else {
78            Some(TCFType::wrap_under_create_rule(array))
79        }
80    }
81}
82
83pub fn create_description_from_array(
84    window_array: CFArray<CGWindowID>,
85) -> Option<CFArray<CFDictionary<CFString, CFType>>> {
86    unsafe {
87        let array = CGWindowListCreateDescriptionFromArray(window_array.as_concrete_TypeRef());
88        if array.is_null() {
89            None
90        } else {
91            Some(TCFType::wrap_under_create_rule(array))
92        }
93    }
94}
95
96pub fn create_image(
97    screen_bounds: CGRect,
98    list_option: CGWindowListOption,
99    window_id: CGWindowID,
100    image_option: CGWindowImageOption,
101) -> Option<CGImage> {
102    unsafe {
103        let image = CGWindowListCreateImage(screen_bounds, list_option, window_id, image_option);
104        if image.is_null() {
105            None
106        } else {
107            Some(CGImage::from_ptr(image))
108        }
109    }
110}
111
112pub fn create_image_from_array(
113    screen_bounds: CGRect,
114    window_array: CFArray,
115    image_option: CGWindowImageOption,
116) -> Option<CGImage> {
117    unsafe {
118        let image = CGWindowListCreateImageFromArray(
119            screen_bounds,
120            window_array.as_concrete_TypeRef(),
121            image_option,
122        );
123        if image.is_null() {
124            None
125        } else {
126            Some(CGImage::from_ptr(image))
127        }
128    }
129}
130
131#[cfg_attr(feature = "link", link(name = "CoreGraphics", kind = "framework"))]
132extern "C" {
133    pub static kCGWindowNumber: CFStringRef;
134    pub static kCGWindowStoreType: CFStringRef;
135    pub static kCGWindowLayer: CFStringRef;
136    pub static kCGWindowBounds: CFStringRef;
137    pub static kCGWindowSharingState: CFStringRef;
138    pub static kCGWindowAlpha: CFStringRef;
139    pub static kCGWindowOwnerPID: CFStringRef;
140    pub static kCGWindowMemoryUsage: CFStringRef;
141    pub static kCGWindowWorkspace: CFStringRef;
142    pub static kCGWindowOwnerName: CFStringRef;
143    pub static kCGWindowName: CFStringRef;
144    pub static kCGWindowIsOnscreen: CFStringRef;
145    pub static kCGWindowBackingLocationVideoMemory: CFStringRef;
146
147    pub fn CGWindowListCopyWindowInfo(
148        option: CGWindowListOption,
149        relativeToWindow: CGWindowID,
150    ) -> CFArrayRef;
151    pub fn CGWindowListCreate(
152        option: CGWindowListOption,
153        relativeToWindow: CGWindowID,
154    ) -> CFArrayRef;
155    pub fn CGWindowListCreateDescriptionFromArray(windowArray: CFArrayRef) -> CFArrayRef;
156    pub fn CGWindowListCreateImage(
157        screenBounds: CGRect,
158        listOption: CGWindowListOption,
159        windowID: CGWindowID,
160        imageOption: CGWindowImageOption,
161    ) -> *mut sys::CGImage;
162    pub fn CGWindowListCreateImageFromArray(
163        screenBounds: CGRect,
164        windowArray: CFArrayRef,
165        imageOption: CGWindowImageOption,
166    ) -> *mut sys::CGImage;
167}