summaryrefslogtreecommitdiffstats
path: root/third_party/rust/core-graphics
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/core-graphics')
-rw-r--r--third_party/rust/core-graphics/.cargo-checksum.json1
-rw-r--r--third_party/rust/core-graphics/COPYRIGHT5
-rw-r--r--third_party/rust/core-graphics/Cargo.toml41
-rw-r--r--third_party/rust/core-graphics/LICENSE-APACHE201
-rw-r--r--third_party/rust/core-graphics/LICENSE-MIT25
-rw-r--r--third_party/rust/core-graphics/README.md3
-rw-r--r--third_party/rust/core-graphics/src/base.rs45
-rw-r--r--third_party/rust/core-graphics/src/color.rs35
-rw-r--r--third_party/rust/core-graphics/src/color_space.rs69
-rw-r--r--third_party/rust/core-graphics/src/context.rs775
-rw-r--r--third_party/rust/core-graphics/src/data_provider.rs162
-rw-r--r--third_party/rust/core-graphics/src/display.rs723
-rw-r--r--third_party/rust/core-graphics/src/event.rs814
-rw-r--r--third_party/rust/core-graphics/src/event_source.rs48
-rw-r--r--third_party/rust/core-graphics/src/font.rs176
-rw-r--r--third_party/rust/core-graphics/src/geometry.rs10
-rw-r--r--third_party/rust/core-graphics/src/gradient.rs62
-rw-r--r--third_party/rust/core-graphics/src/image.rs165
-rw-r--r--third_party/rust/core-graphics/src/lib.rs43
-rw-r--r--third_party/rust/core-graphics/src/path.rs129
-rw-r--r--third_party/rust/core-graphics/src/private.rs116
-rw-r--r--third_party/rust/core-graphics/src/sys.rs44
-rw-r--r--third_party/rust/core-graphics/src/window.rs149
23 files changed, 3841 insertions, 0 deletions
diff --git a/third_party/rust/core-graphics/.cargo-checksum.json b/third_party/rust/core-graphics/.cargo-checksum.json
new file mode 100644
index 0000000000..9dafee4db2
--- /dev/null
+++ b/third_party/rust/core-graphics/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"COPYRIGHT":"ec82b96487e9e778ee610c7ab245162464782cfa1f555c2299333f8dbe5c036a","Cargo.toml":"453b079ac8a6df8842e7e8a37222318c500f68e1605db7adbdf87337830df593","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"62065228e42caebca7e7d7db1204cbb867033de5982ca4009928915e4095f3a3","README.md":"6745c3c38183d2eda9b1fa265fb0a95018db5c110cbabc00b32327d951bbe2ea","src/base.rs":"838683ff67253f4aff1d4b4177531210ca73d4e61f05c5d96a8f196b2a88c787","src/color.rs":"4c8ec4ab828cbc1b2a1538a34a51f5b380927f2f1daf187dff6f732f57a43656","src/color_space.rs":"b3d7ee8a21703c789160867cb8eb2188bd1daa193e3d030f21adb6f1a6f872de","src/context.rs":"8bda7f9ecb5be768b09a29cc3b0a4f329f55d2a2ab74030d121610283862d833","src/data_provider.rs":"b25201fdea43ea1a019c68aa5e997725d04d0824a238354ddc9f2dd8a6835cc4","src/display.rs":"9db5e5440fd302849b13b48393cab4db95447df8d5057c4534a9d8be948ca480","src/event.rs":"17c601ca0b8a0d806fc576cc6cee63a784deaf4246793cf6ce3abcb562de15c5","src/event_source.rs":"d55a4f5b5e62789325028febc51bbf54c74b15ab1a4e70c6ad749a2f9753e081","src/font.rs":"2a7ac5024f17550dd2b6eb97f6971559f930c163eac3a6625d6d55703fd5e96e","src/geometry.rs":"8e12dc89835406bfa514de8fb58f5fd435724d1ddb97dc3a70392efbcf1c42ed","src/gradient.rs":"8ee8661706f36914d08e903840c4f07414b38ba40ea4a482d34b900ac6ac7cf9","src/image.rs":"a5a5df8c0f310455f038eeb16688015f481688cb417f8e8f424a4c1d2a1cdd57","src/lib.rs":"78264571227db6fc9194cb90d64beaff1738a501f88b5da55eb17ae42592d26f","src/path.rs":"c429afeaed999b02ac00f89a867b5fc64f1e223039079a4e0529306b734ff117","src/private.rs":"da3fd61338bab2d8e26aa5433b2e18ecd2a0a408c62e1ac2b33a0f87f2dad88a","src/sys.rs":"3077395beb77193530b713aa681cb61f7b86fa79e4e4060133b6d61cf9f47e09","src/window.rs":"2f6c3dc958ae2c0c9e2fc5033300b96e60ed0abee9823ea1f03797d64df0911a"},"package":"2581bbab3b8ffc6fcbd550bf46c355135d16e9ff2a6ea032ad6b9bf1d7efe4fb"} \ No newline at end of file
diff --git a/third_party/rust/core-graphics/COPYRIGHT b/third_party/rust/core-graphics/COPYRIGHT
new file mode 100644
index 0000000000..8b7291ad28
--- /dev/null
+++ b/third_party/rust/core-graphics/COPYRIGHT
@@ -0,0 +1,5 @@
+Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+<LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+option. All files in the project carrying such notice may not be
+copied, modified, or distributed except according to those terms.
diff --git a/third_party/rust/core-graphics/Cargo.toml b/third_party/rust/core-graphics/Cargo.toml
new file mode 100644
index 0000000000..b3871d54f4
--- /dev/null
+++ b/third_party/rust/core-graphics/Cargo.toml
@@ -0,0 +1,41 @@
+# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
+#
+# When uploading crates to the registry Cargo will automatically
+# "normalize" Cargo.toml files for maximal compatibility
+# with all versions of Cargo and also rewrite `path` dependencies
+# to registry (e.g., crates.io) dependencies
+#
+# If you believe there's an error in this file please file an
+# issue against the rust-lang/cargo repository. If you're
+# editing this file be aware that the upstream Cargo.toml
+# will likely look very different (and much more reasonable)
+
+[package]
+name = "core-graphics"
+version = "0.22.3"
+authors = ["The Servo Project Developers"]
+description = "Bindings to Core Graphics for macOS"
+homepage = "https://github.com/servo/core-graphics-rs"
+license = "MIT / Apache-2.0"
+repository = "https://github.com/servo/core-foundation-rs"
+[package.metadata.docs.rs]
+default-target = "x86_64-apple-darwin"
+[dependencies.bitflags]
+version = "1.0"
+
+[dependencies.core-foundation]
+version = "0.9"
+
+[dependencies.core-graphics-types]
+version = "0.1"
+
+[dependencies.foreign-types]
+version = "0.3.0"
+
+[dependencies.libc]
+version = "0.2"
+
+[features]
+default = []
+elcapitan = []
+highsierra = []
diff --git a/third_party/rust/core-graphics/LICENSE-APACHE b/third_party/rust/core-graphics/LICENSE-APACHE
new file mode 100644
index 0000000000..16fe87b06e
--- /dev/null
+++ b/third_party/rust/core-graphics/LICENSE-APACHE
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+Copyright [yyyy] [name of copyright owner]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/third_party/rust/core-graphics/LICENSE-MIT b/third_party/rust/core-graphics/LICENSE-MIT
new file mode 100644
index 0000000000..807526f57f
--- /dev/null
+++ b/third_party/rust/core-graphics/LICENSE-MIT
@@ -0,0 +1,25 @@
+Copyright (c) 2012-2013 Mozilla Foundation
+
+Permission is hereby granted, free of charge, to any
+person obtaining a copy of this software and associated
+documentation files (the "Software"), to deal in the
+Software without restriction, including without
+limitation the rights to use, copy, modify, merge,
+publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software
+is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice
+shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
+ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
+IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
diff --git a/third_party/rust/core-graphics/README.md b/third_party/rust/core-graphics/README.md
new file mode 100644
index 0000000000..22175688cd
--- /dev/null
+++ b/third_party/rust/core-graphics/README.md
@@ -0,0 +1,3 @@
+# core-graphics-rs
+
+[![Build Status](https://travis-ci.com/servo/core-graphics-rs.svg?branch=master)](https://travis-ci.com/servo/core-graphics-rs)
diff --git a/third_party/rust/core-graphics/src/base.rs b/third_party/rust/core-graphics/src/base.rs
new file mode 100644
index 0000000000..25baf89153
--- /dev/null
+++ b/third_party/rust/core-graphics/src/base.rs
@@ -0,0 +1,45 @@
+// Copyright 2013 The Servo Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// this file defines CGFloat, as well as stubbed data types.
+
+#![allow(non_camel_case_types)]
+#![allow(non_upper_case_globals)]
+
+pub use core_graphics_types::base::*;
+
+pub const kCGImageAlphaNone: u32 = 0;
+pub const kCGImageAlphaPremultipliedLast: u32 = 1;
+pub const kCGImageAlphaPremultipliedFirst: u32 = 2;
+pub const kCGImageAlphaLast: u32 = 3;
+pub const kCGImageAlphaFirst: u32 = 4;
+pub const kCGImageAlphaNoneSkipLast: u32 = 5;
+pub const kCGImageAlphaNoneSkipFirst: u32 = 6;
+
+pub const kCGBitmapByteOrderDefault: u32 = 0 << 12;
+pub const kCGBitmapByteOrder16Little: u32 = 1 << 12;
+pub const kCGBitmapByteOrder32Little: u32 = 2 << 12;
+pub const kCGBitmapByteOrder16Big: u32 = 3 << 12;
+pub const kCGBitmapByteOrder32Big: u32 = 4 << 12;
+
+pub const kCGRenderingIntentDefault: u32 = 0;
+pub const kCGRenderingIntentAbsoluteColorimetric: u32 = 1;
+pub const kCGRenderingIntentRelativeColorimetric: u32 = 2;
+pub const kCGRenderingIntentPerceptual: u32 = 3;
+pub const kCGRenderingIntentSaturation: u32 = 4;
+
+#[cfg(target_endian = "big")]
+pub const kCGBitmapByteOrder16Host: u32 = kCGBitmapByteOrder16Big;
+#[cfg(target_endian = "big")]
+pub const kCGBitmapByteOrder32Host: u32 = kCGBitmapByteOrder32Big;
+
+#[cfg(target_endian = "little")]
+pub const kCGBitmapByteOrder16Host: u32 = kCGBitmapByteOrder16Little;
+#[cfg(target_endian = "little")]
+pub const kCGBitmapByteOrder32Host: u32 = kCGBitmapByteOrder32Little;
diff --git a/third_party/rust/core-graphics/src/color.rs b/third_party/rust/core-graphics/src/color.rs
new file mode 100644
index 0000000000..79ef9a0072
--- /dev/null
+++ b/third_party/rust/core-graphics/src/color.rs
@@ -0,0 +1,35 @@
+// Copyright 2013 The Servo Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use core_foundation::base::{CFTypeID};
+use base::CGFloat;
+use core_foundation::base::TCFType;
+use super::sys::{CGColorRef};
+
+pub use super::sys::CGColorRef as SysCGColorRef;
+
+declare_TCFType!{
+ CGColor, CGColorRef
+}
+impl_TCFType!(CGColor, CGColorRef, CGColorGetTypeID);
+
+impl CGColor {
+ pub fn rgb(red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat) -> Self {
+ unsafe {
+ let ptr = CGColorCreateGenericRGB(red, green, blue, alpha);
+ CGColor::wrap_under_create_rule(ptr)
+ }
+ }
+}
+
+#[link(name = "CoreGraphics", kind = "framework")]
+extern {
+ fn CGColorCreateGenericRGB(red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat) -> ::sys::CGColorRef;
+ fn CGColorGetTypeID() -> CFTypeID;
+}
diff --git a/third_party/rust/core-graphics/src/color_space.rs b/third_party/rust/core-graphics/src/color_space.rs
new file mode 100644
index 0000000000..9eef09c30b
--- /dev/null
+++ b/third_party/rust/core-graphics/src/color_space.rs
@@ -0,0 +1,69 @@
+// Copyright 2015 The Servo Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use core_foundation::base::{CFRelease, CFRetain, CFTypeID};
+use core_foundation::string::CFStringRef;
+use foreign_types::ForeignType;
+
+foreign_type! {
+ #[doc(hidden)]
+ type CType = ::sys::CGColorSpace;
+ fn drop = |p| CFRelease(p as *mut _);
+ fn clone = |p| CFRetain(p as *const _) as *mut _;
+ pub struct CGColorSpace;
+ pub struct CGColorSpaceRef;
+}
+
+impl CGColorSpace {
+ pub fn type_id() -> CFTypeID {
+ unsafe {
+ CGColorSpaceGetTypeID()
+ }
+ }
+
+ pub fn create_with_name(name: CFStringRef) -> Option<CGColorSpace> {
+ unsafe {
+ let p = CGColorSpaceCreateWithName(name);
+ if !p.is_null() {Some(CGColorSpace::from_ptr(p))} else {None}
+ }
+ }
+
+ #[inline]
+ pub fn create_device_rgb() -> CGColorSpace {
+ unsafe {
+ let result = CGColorSpaceCreateDeviceRGB();
+ CGColorSpace::from_ptr(result)
+ }
+ }
+
+ #[inline]
+ pub fn create_device_gray() -> CGColorSpace {
+ unsafe {
+ let result = CGColorSpaceCreateDeviceGray();
+ CGColorSpace::from_ptr(result)
+ }
+ }
+}
+
+#[link(name = "CoreGraphics", kind = "framework")]
+extern {
+ pub static kCGColorSpaceSRGB: CFStringRef;
+ pub static kCGColorSpaceAdobeRGB1998: CFStringRef;
+ pub static kCGColorSpaceGenericGray: CFStringRef;
+ pub static kCGColorSpaceGenericRGB: CFStringRef;
+ pub static kCGColorSpaceGenericCMYK: CFStringRef;
+ pub static kCGColorSpaceGenericRGBLinear: CFStringRef;
+ pub static kCGColorSpaceGenericGrayGamma2_2: CFStringRef;
+
+ fn CGColorSpaceCreateDeviceRGB() -> ::sys::CGColorSpaceRef;
+ fn CGColorSpaceCreateDeviceGray() -> ::sys::CGColorSpaceRef;
+ fn CGColorSpaceCreateWithName(name: CFStringRef) -> ::sys::CGColorSpaceRef;
+ fn CGColorSpaceGetTypeID() -> CFTypeID;
+}
+
diff --git a/third_party/rust/core-graphics/src/context.rs b/third_party/rust/core-graphics/src/context.rs
new file mode 100644
index 0000000000..4efc0f70a3
--- /dev/null
+++ b/third_party/rust/core-graphics/src/context.rs
@@ -0,0 +1,775 @@
+// Copyright 2015 The Servo Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use base::CGFloat;
+use color_space::CGColorSpace;
+use core_foundation::base::{CFTypeID, TCFType};
+use font::{CGFont, CGGlyph};
+use geometry::{CGPoint, CGSize};
+use gradient::{CGGradient, CGGradientDrawingOptions};
+use color::CGColor;
+use path::CGPathRef;
+use libc::{c_int, size_t};
+use std::os::raw::c_void;
+
+use std::cmp;
+use std::ptr;
+use std::slice;
+use geometry::{CGAffineTransform, CGRect};
+use image::CGImage;
+use foreign_types::{ForeignType, ForeignTypeRef};
+
+#[repr(C)]
+#[derive(Clone, Copy, Debug)]
+pub enum CGBlendMode {
+ Normal = 0,
+ Multiply,
+ Screen,
+ Overlay,
+ Darken,
+ Lighten,
+ ColorDodge,
+ ColorBurn,
+ SoftLight,
+ HardLight,
+ Difference,
+ Exclusion,
+ Hue,
+ Saturation,
+ Color,
+ Luminosity,
+ // 10.5 and up:
+ Clear,
+ Copy,
+ SourceIn,
+ SourceOut,
+ SourceAtop,
+ DestinationOver,
+ DestinationIn,
+ DestinationOut,
+ DestinationAtop,
+ Xor,
+ PlusDarker,
+ PlusLighter,
+}
+
+#[repr(C)]
+pub enum CGTextDrawingMode {
+ CGTextFill,
+ CGTextStroke,
+ CGTextFillStroke,
+ CGTextInvisible,
+ CGTextFillClip,
+ CGTextStrokeClip,
+ CGTextFillStrokeClip,
+ CGTextClip
+}
+
+#[repr(C)]
+#[derive(Clone, Copy, Debug)]
+pub enum CGLineCap {
+ CGLineCapButt,
+ CGLineCapRound,
+ CGLineCapSquare,
+}
+
+#[repr(C)]
+#[derive(Clone, Copy, Debug)]
+pub enum CGLineJoin {
+ CGLineJoinMiter,
+ CGLineJoinRound,
+ CGLineJoinBevel,
+}
+
+#[repr(C)]
+#[derive(Clone, Copy, Debug)]
+pub enum CGPathDrawingMode {
+ CGPathFill,
+ CGPathEOFill,
+ CGPathStroke,
+ CGPathFillStroke,
+ CGPathEOFillStroke,
+}
+
+#[repr(C)]
+#[derive(Clone, Copy, Debug)]
+pub enum CGInterpolationQuality {
+ CGInterpolationQualityDefault,
+ CGInterpolationQualityNone,
+ CGInterpolationQualityLow,
+ CGInterpolationQualityMedium,
+ CGInterpolationQualityHigh,
+}
+
+foreign_type! {
+ #[doc(hidden)]
+ type CType = ::sys::CGContext;
+ fn drop = |cs| CGContextRelease(cs);
+ fn clone = |p| CGContextRetain(p);
+ pub struct CGContext;
+ pub struct CGContextRef;
+}
+
+impl CGContext {
+ pub fn type_id() -> CFTypeID {
+ unsafe {
+ CGContextGetTypeID()
+ }
+ }
+
+ /// Creates a `CGContext` instance from an existing [`CGContextRef`] pointer.
+ ///
+ /// This funtion will internally call [`CGRetain`] and hence there is no need to call it explicitly.
+ ///
+ /// This function is particularly useful for cases when the context is not instantiated/managed
+ /// by the caller, but it's retrieve via other means (e.g., by calling the method [`NSGraphicsContext::CGContext`]
+ /// in a cocoa application).
+ ///
+ /// [`CGContextRef`]: https://developer.apple.com/documentation/coregraphics/cgcontextref
+ /// [`CGRetain`]: https://developer.apple.com/documentation/coregraphics/1586506-cgcontextretain
+ /// [`NSGraphicsContext::CGContext`]: https://developer.apple.com/documentation/appkit/nsgraphicscontext/1535352-currentcontext
+ pub unsafe fn from_existing_context_ptr(ctx: *mut ::sys::CGContext) -> CGContext {
+ CGContextRetain(ctx);
+ Self::from_ptr(ctx)
+ }
+
+ pub fn create_bitmap_context(data: Option<*mut c_void>,
+ width: size_t,
+ height: size_t,
+ bits_per_component: size_t,
+ bytes_per_row: size_t,
+ space: &CGColorSpace,
+ bitmap_info: u32)
+ -> CGContext {
+ unsafe {
+ let result = CGBitmapContextCreate(data.unwrap_or(ptr::null_mut()),
+ width,
+ height,
+ bits_per_component,
+ bytes_per_row,
+ space.as_ptr(),
+ bitmap_info);
+ assert!(!result.is_null());
+ Self::from_ptr(result)
+ }
+ }
+
+ pub fn data(&mut self) -> &mut [u8] {
+ unsafe {
+ slice::from_raw_parts_mut(
+ CGBitmapContextGetData(self.as_ptr()) as *mut u8,
+ (self.height() * self.bytes_per_row()) as usize)
+ }
+ }
+}
+
+impl CGContextRef {
+ pub fn flush(&self) {
+ unsafe {
+ CGContextFlush(self.as_ptr())
+ }
+ }
+
+ pub fn width(&self) -> size_t {
+ unsafe {
+ CGBitmapContextGetWidth(self.as_ptr())
+ }
+ }
+
+ pub fn height(&self) -> size_t {
+ unsafe {
+ CGBitmapContextGetHeight(self.as_ptr())
+ }
+ }
+
+ pub fn bytes_per_row(&self) -> size_t {
+ unsafe {
+ CGBitmapContextGetBytesPerRow(self.as_ptr())
+ }
+ }
+
+ pub fn clip_bounding_box(&self) -> CGRect {
+ unsafe {
+ CGContextGetClipBoundingBox(self.as_ptr())
+ }
+ }
+
+ pub fn set_fill_color(&self, color: &CGColor) {
+ unsafe {
+ CGContextSetFillColorWithColor(self.as_ptr(), color.as_concrete_TypeRef());
+ }
+ }
+
+ pub fn set_rgb_fill_color(&self, red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat) {
+ unsafe {
+ CGContextSetRGBFillColor(self.as_ptr(), red, green, blue, alpha)
+ }
+ }
+
+ pub fn set_rgb_stroke_color(&self, red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat) {
+ unsafe {
+ CGContextSetRGBStrokeColor(self.as_ptr(), red, green, blue, alpha)
+ }
+ }
+
+ pub fn set_gray_fill_color(&self, gray: CGFloat, alpha: CGFloat) {
+ unsafe {
+ CGContextSetGrayFillColor(self.as_ptr(), gray, alpha)
+ }
+ }
+
+ pub fn set_blend_mode(&self, blend_mode: CGBlendMode) {
+ unsafe {
+ CGContextSetBlendMode(self.as_ptr(), blend_mode)
+ }
+ }
+
+ pub fn set_allows_font_smoothing(&self, allows_font_smoothing: bool) {
+ unsafe {
+ CGContextSetAllowsFontSmoothing(self.as_ptr(), allows_font_smoothing)
+ }
+ }
+
+ pub fn set_font_smoothing_style(&self, style: i32) {
+ unsafe {
+ CGContextSetFontSmoothingStyle(self.as_ptr(), style as _);
+ }
+ }
+
+ pub fn set_should_smooth_fonts(&self, should_smooth_fonts: bool) {
+ unsafe {
+ CGContextSetShouldSmoothFonts(self.as_ptr(), should_smooth_fonts)
+ }
+ }
+
+ pub fn set_allows_antialiasing(&self, allows_antialiasing: bool) {
+ unsafe {
+ CGContextSetAllowsAntialiasing(self.as_ptr(), allows_antialiasing)
+ }
+ }
+
+ pub fn set_should_antialias(&self, should_antialias: bool) {
+ unsafe {
+ CGContextSetShouldAntialias(self.as_ptr(), should_antialias)
+ }
+ }
+
+ pub fn set_allows_font_subpixel_quantization(&self, allows_font_subpixel_quantization: bool) {
+ unsafe {
+ CGContextSetAllowsFontSubpixelQuantization(self.as_ptr(), allows_font_subpixel_quantization)
+ }
+ }
+
+ pub fn set_should_subpixel_quantize_fonts(&self, should_subpixel_quantize_fonts: bool) {
+ unsafe {
+ CGContextSetShouldSubpixelQuantizeFonts(self.as_ptr(), should_subpixel_quantize_fonts)
+ }
+ }
+
+ pub fn set_allows_font_subpixel_positioning(&self, allows_font_subpixel_positioning: bool) {
+ unsafe {
+ CGContextSetAllowsFontSubpixelPositioning(self.as_ptr(), allows_font_subpixel_positioning)
+ }
+ }
+
+ pub fn set_should_subpixel_position_fonts(&self, should_subpixel_position_fonts: bool) {
+ unsafe {
+ CGContextSetShouldSubpixelPositionFonts(self.as_ptr(), should_subpixel_position_fonts)
+ }
+ }
+
+ pub fn set_text_drawing_mode(&self, mode: CGTextDrawingMode) {
+ unsafe {
+ CGContextSetTextDrawingMode(self.as_ptr(), mode)
+ }
+ }
+
+ pub fn set_line_cap(&self, cap: CGLineCap) {
+ unsafe {
+ CGContextSetLineCap(self.as_ptr(), cap)
+ }
+ }
+
+ pub fn set_line_dash(&self, phase: CGFloat, lengths: &[CGFloat]) {
+ unsafe {
+ CGContextSetLineDash(self.as_ptr(), phase, lengths.as_ptr(), lengths.len())
+ }
+ }
+
+ pub fn set_line_join(&self, join: CGLineJoin) {
+ unsafe {
+ CGContextSetLineJoin(self.as_ptr(), join)
+ }
+ }
+
+ pub fn set_line_width(&self, width: CGFloat) {
+ unsafe {
+ CGContextSetLineWidth(self.as_ptr(), width)
+ }
+ }
+
+ pub fn set_miter_limit(&self, limit: CGFloat) {
+ unsafe {
+ CGContextSetMiterLimit(self.as_ptr(), limit)
+ }
+ }
+
+ pub fn add_path(&self, path: &CGPathRef) {
+ unsafe {
+ CGContextAddPath(self.as_ptr(), path.as_ptr());
+ }
+ }
+
+ pub fn add_curve_to_point(&self,
+ cp1x: CGFloat,
+ cp1y: CGFloat,
+ cp2x: CGFloat,
+ cp2y: CGFloat,
+ x: CGFloat,
+ y: CGFloat) {
+ unsafe {
+ CGContextAddCurveToPoint(self.as_ptr(),
+ cp1x, cp1y,
+ cp2x, cp2y,
+ x, y);
+ }
+ }
+
+ pub fn add_quad_curve_to_point(&self,
+ cpx: CGFloat,
+ cpy: CGFloat,
+ x: CGFloat,
+ y: CGFloat) {
+ unsafe {
+ CGContextAddQuadCurveToPoint(self.as_ptr(),
+ cpx, cpy,
+ x, y);
+ }
+ }
+
+ pub fn add_line_to_point(&self, x: CGFloat, y: CGFloat) {
+ unsafe {
+ CGContextAddLineToPoint(self.as_ptr(), x, y);
+ }
+ }
+
+ pub fn begin_path(&self) {
+ unsafe {
+ CGContextBeginPath(self.as_ptr());
+ }
+ }
+
+ pub fn close_path(&self) {
+ unsafe {
+ CGContextClosePath(self.as_ptr());
+ }
+ }
+
+ pub fn move_to_point(&self, x: CGFloat, y: CGFloat) {
+ unsafe {
+ CGContextMoveToPoint(self.as_ptr(), x, y);
+ }
+ }
+
+ pub fn clip(&self) {
+ unsafe {
+ CGContextClip(self.as_ptr());
+ }
+ }
+
+ pub fn eo_clip(&self) {
+ unsafe {
+ CGContextEOClip(self.as_ptr());
+ }
+ }
+
+ pub fn draw_path(&self, mode: CGPathDrawingMode) {
+ unsafe {
+ CGContextDrawPath(self.as_ptr(), mode);
+ }
+ }
+
+ pub fn fill_path(&self) {
+ unsafe {
+ CGContextFillPath(self.as_ptr());
+ }
+ }
+
+ pub fn eo_fill_path(&self) {
+ unsafe {
+ CGContextEOFillPath(self.as_ptr());
+ }
+ }
+
+ pub fn stroke_path(&self) {
+ unsafe {
+ CGContextStrokePath(self.as_ptr());
+ }
+ }
+
+ pub fn fill_rect(&self, rect: CGRect) {
+ unsafe {
+ CGContextFillRect(self.as_ptr(), rect)
+ }
+ }
+
+ pub fn fill_rects(&self, rects: &[CGRect]) {
+ unsafe {
+ CGContextFillRects(self.as_ptr(), rects.as_ptr(), rects.len())
+ }
+ }
+
+ pub fn clear_rect(&self, rect: CGRect) {
+ unsafe {
+ CGContextClearRect(self.as_ptr(), rect)
+ }
+ }
+
+ pub fn stroke_rect(&self, rect: CGRect) {
+ unsafe {
+ CGContextStrokeRect(self.as_ptr(), rect)
+ }
+ }
+
+ pub fn stroke_rect_with_width(&self, rect: CGRect, width: CGFloat) {
+ unsafe {
+ CGContextStrokeRectWithWidth(self.as_ptr(), rect, width)
+ }
+ }
+
+ pub fn clip_to_rect(&self, rect: CGRect) {
+ unsafe {
+ CGContextClipToRect(self.as_ptr(), rect)
+ }
+ }
+
+ pub fn clip_to_rects(&self, rects: &[CGRect]) {
+ unsafe {
+ CGContextClipToRects(self.as_ptr(), rects.as_ptr(), rects.len())
+ }
+ }
+
+ pub fn clip_to_mask(&self, rect: CGRect, image: &CGImage) {
+ unsafe {
+ CGContextClipToMask(self.as_ptr(), rect, image.as_ptr())
+ }
+ }
+
+ pub fn replace_path_with_stroked_path(&self) {
+ unsafe {
+ CGContextReplacePathWithStrokedPath(self.as_ptr())
+ }
+ }
+
+ pub fn fill_ellipse_in_rect(&self, rect: CGRect) {
+ unsafe {
+ CGContextFillEllipseInRect(self.as_ptr(), rect)
+ }
+ }
+
+ pub fn stroke_ellipse_in_rect(&self, rect: CGRect) {
+ unsafe {
+ CGContextStrokeEllipseInRect(self.as_ptr(), rect)
+ }
+ }
+
+ pub fn stroke_line_segments(&self, points: &[CGPoint]) {
+ unsafe {
+ CGContextStrokeLineSegments(self.as_ptr(), points.as_ptr(), points.len())
+ }
+ }
+
+ pub fn set_interpolation_quality(&self, quality: CGInterpolationQuality) {
+ unsafe {
+ CGContextSetInterpolationQuality(self.as_ptr(), quality);
+ }
+ }
+
+ pub fn get_interpolation_quality(&self) -> CGInterpolationQuality {
+ unsafe {
+ CGContextGetInterpolationQuality(self.as_ptr())
+
+ }
+ }
+
+ pub fn draw_image(&self, rect: CGRect, image: &CGImage) {
+ unsafe {
+ CGContextDrawImage(self.as_ptr(), rect, image.as_ptr());
+ }
+ }
+
+ pub fn create_image(&self) -> Option<CGImage> {
+ let image = unsafe { CGBitmapContextCreateImage(self.as_ptr()) };
+ if !image.is_null() {
+ Some(unsafe { CGImage::from_ptr(image) })
+ } else {
+ None
+ }
+ }
+
+ pub fn set_font(&self, font: &CGFont) {
+ unsafe {
+ CGContextSetFont(self.as_ptr(), font.as_ptr())
+ }
+ }
+
+ pub fn set_font_size(&self, size: CGFloat) {
+ unsafe {
+ CGContextSetFontSize(self.as_ptr(), size)
+ }
+ }
+
+ pub fn set_text_matrix(&self, t: &CGAffineTransform) {
+ unsafe {
+ CGContextSetTextMatrix(self.as_ptr(), *t)
+ }
+ }
+
+ pub fn set_text_position(&self, x: CGFloat, y: CGFloat) {
+ unsafe {
+ CGContextSetTextPosition(self.as_ptr(), x, y)
+ }
+ }
+
+ pub fn show_glyphs_at_positions(&self, glyphs: &[CGGlyph], positions: &[CGPoint]) {
+ unsafe {
+ let count = cmp::min(glyphs.len(), positions.len());
+ CGContextShowGlyphsAtPositions(self.as_ptr(),
+ glyphs.as_ptr(),
+ positions.as_ptr(),
+ count)
+ }
+ }
+
+ pub fn save(&self) {
+ unsafe {
+ CGContextSaveGState(self.as_ptr());
+ }
+ }
+
+ pub fn restore(&self) {
+ unsafe {
+ CGContextRestoreGState(self.as_ptr());
+ }
+ }
+
+ pub fn translate(&self, tx: CGFloat, ty: CGFloat) {
+ unsafe {
+ CGContextTranslateCTM(self.as_ptr(), tx, ty);
+ }
+ }
+
+ pub fn scale(&self, sx: CGFloat, sy: CGFloat) {
+ unsafe {
+ CGContextScaleCTM(self.as_ptr(), sx, sy);
+ }
+ }
+
+ pub fn rotate(&self, angle: CGFloat) {
+ unsafe {
+ CGContextRotateCTM(self.as_ptr(), angle);
+ }
+ }
+
+ pub fn get_ctm(&self) -> CGAffineTransform {
+ unsafe {
+ CGContextGetCTM(self.as_ptr())
+ }
+ }
+
+ pub fn concat_ctm(&self, transform: CGAffineTransform) {
+ unsafe {
+ CGContextConcatCTM(self.as_ptr(), transform)
+ }
+ }
+
+ pub fn draw_linear_gradient(&self, gradient: &CGGradient, start_point: CGPoint, end_point: CGPoint, options: CGGradientDrawingOptions) {
+ unsafe {
+ CGContextDrawLinearGradient(self.as_ptr(), gradient.as_ptr(), start_point, end_point, options);
+ }
+ }
+
+ pub fn draw_radial_gradient(&self, gradient: &CGGradient, start_center: CGPoint, start_radius: CGFloat, end_center: CGPoint, end_radius: CGFloat, options: CGGradientDrawingOptions) {
+ unsafe {
+ CGContextDrawRadialGradient(self.as_ptr(), gradient.as_ptr(), start_center, start_radius, end_center, end_radius, options);
+ }
+ }
+
+ pub fn set_shadow(&self, offset: CGSize, blur: CGFloat) {
+ unsafe {
+ CGContextSetShadow(self.as_ptr(), offset, blur);
+ }
+ }
+
+ pub fn set_shadow_with_color(&self, offset: CGSize, blur: CGFloat, color: &CGColor) {
+ unsafe {
+ CGContextSetShadowWithColor(self.as_ptr(), offset, blur, color.as_concrete_TypeRef());
+ }
+ }
+}
+
+#[test]
+fn create_bitmap_context_test() {
+ use geometry::*;
+
+ let cs = CGColorSpace::create_device_rgb();
+ let ctx = CGContext::create_bitmap_context(None,
+ 16, 8,
+ 8, 0,
+ &cs,
+ ::base::kCGImageAlphaPremultipliedLast);
+ ctx.set_rgb_fill_color(1.,0.,1.,1.);
+ ctx.set_miter_limit(4.);
+ ctx.fill_rect(CGRect::new(&CGPoint::new(0.,0.), &CGSize::new(8.,8.)));
+ let img = ctx.create_image().unwrap();
+ assert_eq!(16, img.width());
+ assert_eq!(8, img.height());
+ assert_eq!(8, img.bits_per_component());
+ assert_eq!(32, img.bits_per_pixel());
+ let data = img.data();
+ assert_eq!(255, data.bytes()[0]);
+ assert_eq!(0, data.bytes()[1]);
+ assert_eq!(255, data.bytes()[2]);
+ assert_eq!(255, data.bytes()[3]);
+}
+
+#[link(name = "CoreGraphics", kind = "framework")]
+extern {
+ fn CGContextRetain(c: ::sys::CGContextRef) -> ::sys::CGContextRef;
+ fn CGContextRelease(c: ::sys::CGContextRef);
+
+ fn CGBitmapContextCreate(data: *mut c_void,
+ width: size_t,
+ height: size_t,
+ bitsPerComponent: size_t,
+ bytesPerRow: size_t,
+ space: ::sys::CGColorSpaceRef,
+ bitmapInfo: u32)
+ -> ::sys::CGContextRef;
+ fn CGBitmapContextGetData(context: ::sys::CGContextRef) -> *mut c_void;
+ fn CGBitmapContextGetWidth(context: ::sys::CGContextRef) -> size_t;
+ fn CGBitmapContextGetHeight(context: ::sys::CGContextRef) -> size_t;
+ fn CGBitmapContextGetBytesPerRow(context: ::sys::CGContextRef) -> size_t;
+ fn CGBitmapContextCreateImage(context: ::sys::CGContextRef) -> ::sys::CGImageRef;
+ fn CGContextGetTypeID() -> CFTypeID;
+ fn CGContextGetClipBoundingBox(c: ::sys::CGContextRef) -> CGRect;
+ fn CGContextFlush(c: ::sys::CGContextRef);
+ fn CGContextSetBlendMode(c: ::sys::CGContextRef, blendMode: CGBlendMode);
+ fn CGContextSetAllowsFontSmoothing(c: ::sys::CGContextRef, allowsFontSmoothing: bool);
+ fn CGContextSetShouldSmoothFonts(c: ::sys::CGContextRef, shouldSmoothFonts: bool);
+ fn CGContextSetFontSmoothingStyle(c: ::sys::CGContextRef, style: c_int);
+ fn CGContextSetAllowsAntialiasing(c: ::sys::CGContextRef, allowsAntialiasing: bool);
+ fn CGContextSetShouldAntialias(c: ::sys::CGContextRef, shouldAntialias: bool);
+ fn CGContextSetAllowsFontSubpixelQuantization(c: ::sys::CGContextRef,
+ allowsFontSubpixelQuantization: bool);
+ fn CGContextSetShouldSubpixelQuantizeFonts(c: ::sys::CGContextRef,
+ shouldSubpixelQuantizeFonts: bool);
+ fn CGContextSetAllowsFontSubpixelPositioning(c: ::sys::CGContextRef,
+ allowsFontSubpixelPositioning: bool);
+ fn CGContextSetShouldSubpixelPositionFonts(c: ::sys::CGContextRef,
+ shouldSubpixelPositionFonts: bool);
+ fn CGContextSetTextDrawingMode(c: ::sys::CGContextRef, mode: CGTextDrawingMode);
+ fn CGContextSetFillColorWithColor(c: ::sys::CGContextRef, color: ::sys::CGColorRef);
+ fn CGContextSetLineCap(c: ::sys::CGContextRef, cap: CGLineCap);
+ fn CGContextSetLineDash(c: ::sys::CGContextRef, phase: CGFloat, lengths: *const CGFloat, count: size_t);
+ fn CGContextSetLineJoin(c: ::sys::CGContextRef, join: CGLineJoin);
+ fn CGContextSetLineWidth(c: ::sys::CGContextRef, width: CGFloat);
+ fn CGContextSetMiterLimit(c: ::sys::CGContextRef, limit: CGFloat);
+
+ fn CGContextAddPath(c: ::sys::CGContextRef, path: ::sys::CGPathRef);
+ fn CGContextAddCurveToPoint(c: ::sys::CGContextRef,
+ cp1x: CGFloat,
+ cp1y: CGFloat,
+ cp2x: CGFloat,
+ cp2y: CGFloat,
+ x: CGFloat,
+ y: CGFloat);
+ fn CGContextAddQuadCurveToPoint(c: ::sys::CGContextRef,
+ cpx: CGFloat,
+ cpy: CGFloat,
+ x: CGFloat,
+ y: CGFloat);
+ fn CGContextAddLineToPoint(c: ::sys::CGContextRef,
+ x: CGFloat,
+ y: CGFloat);
+ fn CGContextBeginPath(c: ::sys::CGContextRef);
+ fn CGContextClosePath(c: ::sys::CGContextRef);
+ fn CGContextMoveToPoint(c: ::sys::CGContextRef,
+ x: CGFloat,
+ y: CGFloat);
+ fn CGContextDrawPath(c: ::sys::CGContextRef, mode: CGPathDrawingMode);
+ fn CGContextFillPath(c: ::sys::CGContextRef);
+ fn CGContextEOFillPath(c: ::sys::CGContextRef);
+ fn CGContextClip(c: ::sys::CGContextRef);
+ fn CGContextEOClip(c: ::sys::CGContextRef);
+ fn CGContextStrokePath(c: ::sys::CGContextRef);
+ fn CGContextSetRGBFillColor(context: ::sys::CGContextRef,
+ red: CGFloat,
+ green: CGFloat,
+ blue: CGFloat,
+ alpha: CGFloat);
+ fn CGContextSetRGBStrokeColor(context: ::sys::CGContextRef,
+ red: CGFloat,
+ green: CGFloat,
+ blue: CGFloat,
+ alpha: CGFloat);
+ fn CGContextSetGrayFillColor(context: ::sys::CGContextRef, gray: CGFloat, alpha: CGFloat);
+ fn CGContextClearRect(context: ::sys::CGContextRef,
+ rect: CGRect);
+ fn CGContextFillRect(context: ::sys::CGContextRef,
+ rect: CGRect);
+ fn CGContextFillRects(context: ::sys::CGContextRef,
+ rects: *const CGRect,
+ count: size_t);
+ fn CGContextStrokeRect(context: ::sys::CGContextRef,
+ rect: CGRect);
+ fn CGContextStrokeRectWithWidth(context: ::sys::CGContextRef,
+ rect: CGRect,
+ width: CGFloat);
+ fn CGContextClipToRect(context: ::sys::CGContextRef,
+ rect: CGRect);
+ fn CGContextClipToRects(context: ::sys::CGContextRef,
+ rects: *const CGRect,
+ count: size_t);
+ fn CGContextClipToMask(ctx: ::sys::CGContextRef, rect: CGRect, mask: ::sys::CGImageRef);
+ fn CGContextReplacePathWithStrokedPath(context: ::sys::CGContextRef);
+ fn CGContextFillEllipseInRect(context: ::sys::CGContextRef,
+ rect: CGRect);
+ fn CGContextStrokeEllipseInRect(context: ::sys::CGContextRef,
+ rect: CGRect);
+ fn CGContextStrokeLineSegments(context: ::sys::CGContextRef,
+ points: *const CGPoint,
+ count: size_t);
+ fn CGContextDrawImage(c: ::sys::CGContextRef, rect: CGRect, image: ::sys::CGImageRef);
+ fn CGContextSetInterpolationQuality(c: ::sys::CGContextRef, quality: CGInterpolationQuality);
+ fn CGContextGetInterpolationQuality(c: ::sys::CGContextRef) -> CGInterpolationQuality;
+ fn CGContextSetFont(c: ::sys::CGContextRef, font: ::sys::CGFontRef);
+ fn CGContextSetFontSize(c: ::sys::CGContextRef, size: CGFloat);
+ fn CGContextSetTextMatrix(c: ::sys::CGContextRef, t: CGAffineTransform);
+ fn CGContextSetTextPosition(c: ::sys::CGContextRef, x: CGFloat, y: CGFloat);
+ fn CGContextShowGlyphsAtPositions(c: ::sys::CGContextRef,
+ glyphs: *const CGGlyph,
+ positions: *const CGPoint,
+ count: size_t);
+
+ fn CGContextSaveGState(c: ::sys::CGContextRef);
+ fn CGContextRestoreGState(c: ::sys::CGContextRef);
+ fn CGContextTranslateCTM(c: ::sys::CGContextRef, tx: CGFloat, ty: CGFloat);
+ fn CGContextScaleCTM(c: ::sys::CGContextRef, sx: CGFloat, sy: CGFloat);
+ fn CGContextRotateCTM(c: ::sys::CGContextRef, angle: CGFloat);
+ fn CGContextGetCTM(c: ::sys::CGContextRef) -> CGAffineTransform;
+ fn CGContextConcatCTM(c: ::sys::CGContextRef, transform: CGAffineTransform);
+
+ fn CGContextDrawLinearGradient(c: ::sys::CGContextRef, gradient: ::sys::CGGradientRef, startPoint: CGPoint, endPoint: CGPoint, options: CGGradientDrawingOptions);
+ fn CGContextDrawRadialGradient(c: ::sys::CGContextRef, gradient: ::sys::CGGradientRef, startCenter: CGPoint, startRadius: CGFloat, endCenter:CGPoint, endRadius:CGFloat, options: CGGradientDrawingOptions);
+
+ fn CGContextSetShadow(c: ::sys::CGContextRef, offset: CGSize, blur: CGFloat);
+ fn CGContextSetShadowWithColor(c: ::sys::CGContextRef, offset: CGSize, blur: CGFloat, color: ::sys::CGColorRef);
+}
+
diff --git a/third_party/rust/core-graphics/src/data_provider.rs b/third_party/rust/core-graphics/src/data_provider.rs
new file mode 100644
index 0000000000..e8bb0a0241
--- /dev/null
+++ b/third_party/rust/core-graphics/src/data_provider.rs
@@ -0,0 +1,162 @@
+// Copyright 2013 The Servo Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use core_foundation::base::{CFRelease, CFRetain, CFTypeID, TCFType};
+use core_foundation::data::{CFData, CFDataRef};
+
+use libc::{size_t, off_t};
+use std::mem;
+use std::ptr;
+use std::sync::Arc;
+use std::os::raw::c_void;
+
+use foreign_types::{ForeignType, ForeignTypeRef};
+
+pub type CGDataProviderGetBytesCallback = Option<unsafe extern fn (*mut c_void, *mut c_void, size_t) -> size_t>;
+pub type CGDataProviderReleaseInfoCallback = Option<unsafe extern fn (*mut c_void)>;
+pub type CGDataProviderRewindCallback = Option<unsafe extern fn (*mut c_void)>;
+pub type CGDataProviderSkipBytesCallback = Option<unsafe extern fn (*mut c_void, size_t)>;
+pub type CGDataProviderSkipForwardCallback = Option<unsafe extern fn (*mut c_void, off_t) -> off_t>;
+
+pub type CGDataProviderGetBytePointerCallback = Option<unsafe extern fn (*mut c_void) -> *mut c_void>;
+pub type CGDataProviderGetBytesAtOffsetCallback = Option<unsafe extern fn (*mut c_void, *mut c_void, size_t, size_t)>;
+pub type CGDataProviderReleaseBytePointerCallback = Option<unsafe extern fn (*mut c_void, *const c_void)>;
+pub type CGDataProviderReleaseDataCallback = Option<unsafe extern fn (*mut c_void, *const c_void, size_t)>;
+pub type CGDataProviderGetBytesAtPositionCallback = Option<unsafe extern fn (*mut c_void, *mut c_void, off_t, size_t)>;
+
+foreign_type! {
+ #[doc(hidden)]
+ type CType = ::sys::CGDataProvider;
+ fn drop = |cs| CFRelease(cs as *mut _);
+ fn clone = |p| CFRetain(p as *const _) as *mut _;
+ pub struct CGDataProvider;
+ pub struct CGDataProviderRef;
+}
+
+impl CGDataProvider {
+ pub fn type_id() -> CFTypeID {
+ unsafe {
+ CGDataProviderGetTypeID()
+ }
+ }
+
+ /// Creates a data provider from the given reference-counted buffer.
+ ///
+ /// The `CGDataProvider` object takes ownership of the reference. Once the data provider
+ /// is destroyed, the reference count of the buffer is automatically decremented.
+ pub fn from_buffer<T: AsRef<[u8]> + Sync + Send>(buffer: Arc<T>) -> Self {
+ unsafe {
+ let ptr = (*buffer).as_ref().as_ptr() as *const c_void;
+ let len = (*buffer).as_ref().len() as size_t;
+ let info = Arc::into_raw(buffer) as *mut c_void;
+ let result = CGDataProviderCreateWithData(info, ptr, len, Some(release::<T>));
+ return CGDataProvider::from_ptr(result);
+ }
+
+ unsafe extern "C" fn release<T>(info: *mut c_void, _: *const c_void, _: size_t) {
+ drop(Arc::from_raw(info as *mut T))
+ }
+ }
+
+ /// Creates a data prvider from a given slice. The data provider does not own the slice in this
+ /// case, so it's up to the user to ensure the memory safety here.
+ pub unsafe fn from_slice(buffer: &[u8]) -> Self {
+ let ptr = buffer.as_ptr() as *const c_void;
+ let len = buffer.len() as size_t;
+ let result = CGDataProviderCreateWithData(ptr::null_mut(), ptr, len, None);
+ CGDataProvider::from_ptr(result)
+ }
+
+ /// Creates a data provider from the given raw pointer, length, and destructor function.
+ ///
+ /// This is double-boxed because the Core Text API requires that the userdata be a single
+ /// pointer.
+ pub unsafe fn from_custom_data(custom_data: Box<Box<dyn CustomData>>) -> Self {
+ let (ptr, len) = (custom_data.ptr() as *const c_void, custom_data.len());
+ let userdata = mem::transmute::<Box<Box<dyn CustomData>>, &mut c_void>(custom_data);
+ let data_provider = CGDataProviderCreateWithData(userdata, ptr, len, Some(release));
+ return CGDataProvider::from_ptr(data_provider);
+
+ unsafe extern "C" fn release(info: *mut c_void, _: *const c_void, _: size_t) {
+ drop(mem::transmute::<*mut c_void, Box<Box<dyn CustomData>>>(info))
+ }
+ }
+}
+
+impl CGDataProviderRef {
+ /// Creates a copy of the data from the underlying `CFDataProviderRef`.
+ pub fn copy_data(&self) -> CFData {
+ unsafe { CFData::wrap_under_create_rule(CGDataProviderCopyData(self.as_ptr())) }
+ }
+}
+
+/// Encapsulates custom data that can be wrapped.
+pub trait CustomData {
+ /// Returns a pointer to the start of the custom data. This pointer *must not change* during
+ /// the lifespan of this CustomData.
+ unsafe fn ptr(&self) -> *const u8;
+ /// Returns the length of this custom data. This value must not change during the lifespan of
+ /// this CustomData.
+ unsafe fn len(&self) -> usize;
+}
+
+#[test]
+fn test_data_provider() {
+ let l = vec![5];
+ CGDataProvider::from_buffer(Arc::new(l));
+
+ let l = vec![5];
+ CGDataProvider::from_buffer(Arc::new(l.into_boxed_slice()));
+
+ // Make sure the buffer is actually dropped
+ use std::sync::atomic::{AtomicBool, Ordering::SeqCst};
+ struct VecWrapper {
+ inner: Vec<u8>,
+ dropped: Arc<AtomicBool>,
+ }
+
+ impl Drop for VecWrapper {
+ fn drop(&mut self) {
+ self.dropped.store(true, SeqCst)
+ }
+ }
+
+ impl std::convert::AsRef<[u8]> for VecWrapper {
+ fn as_ref(&self) -> &[u8] {
+ &self.inner
+ }
+ }
+
+ let dropped = Arc::new(AtomicBool::default());
+ let l = Arc::new(VecWrapper {inner: vec![5], dropped: dropped.clone() });
+ let m = l.clone();
+ let dp = CGDataProvider::from_buffer(l);
+ drop(m);
+ assert!(!dropped.load(SeqCst));
+ drop(dp);
+ assert!(dropped.load(SeqCst))
+}
+
+#[link(name = "CoreGraphics", kind = "framework")]
+extern {
+ fn CGDataProviderCopyData(provider: ::sys::CGDataProviderRef) -> CFDataRef;
+ //fn CGDataProviderCreateDirect
+ //fn CGDataProviderCreateSequential
+ //fn CGDataProviderCreateWithCFData
+ fn CGDataProviderCreateWithData(info: *mut c_void,
+ data: *const c_void,
+ size: size_t,
+ releaseData: CGDataProviderReleaseDataCallback
+ ) -> ::sys::CGDataProviderRef;
+ //fn CGDataProviderCreateWithFilename(filename: *c_char) -> CGDataProviderRef;
+ //fn CGDataProviderCreateWithURL
+ fn CGDataProviderGetTypeID() -> CFTypeID;
+ //fn CGDataProviderRelease(provider: CGDataProviderRef);
+ //fn CGDataProviderRetain(provider: CGDataProviderRef) -> CGDataProviderRef;
+}
diff --git a/third_party/rust/core-graphics/src/display.rs b/third_party/rust/core-graphics/src/display.rs
new file mode 100644
index 0000000000..394520bae4
--- /dev/null
+++ b/third_party/rust/core-graphics/src/display.rs
@@ -0,0 +1,723 @@
+// Copyright 2013 The Servo Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![allow(non_upper_case_globals)]
+
+use libc;
+use std::ptr;
+use std::ops::Deref;
+
+pub use base::{CGError, boolean_t};
+pub use geometry::{CGRect, CGPoint, CGSize};
+
+use core_foundation::string::{CFString, CFStringRef};
+use core_foundation::base::{CFRetain, TCFType};
+use image::CGImage;
+use foreign_types::ForeignType;
+
+pub type CGDirectDisplayID = u32;
+pub type CGWindowID = u32;
+
+pub const kCGNullWindowID: CGWindowID = 0 as CGWindowID;
+pub const kCGNullDirectDisplayID: CGDirectDisplayID = 0 as CGDirectDisplayID;
+
+pub type CGWindowListOption = u32;
+
+pub const kCGWindowListOptionAll: CGWindowListOption = 0;
+pub const kCGWindowListOptionOnScreenOnly: CGWindowListOption = 1 << 0;
+pub const kCGWindowListOptionOnScreenAboveWindow: CGWindowListOption = 1 << 1;
+pub const kCGWindowListOptionOnScreenBelowWindow: CGWindowListOption = 1 << 2;
+pub const kCGWindowListOptionIncludingWindow: CGWindowListOption = 1 << 3;
+pub const kCGWindowListExcludeDesktopElements: CGWindowListOption = 1 << 4;
+
+pub type CGWindowImageOption = u32;
+
+pub const kCGWindowImageDefault: CGWindowImageOption = 0;
+pub const kCGWindowImageBoundsIgnoreFraming: CGWindowImageOption = 1 << 0;
+pub const kCGWindowImageShouldBeOpaque: CGWindowImageOption = 1 << 1;
+pub const kCGWindowImageOnlyShadows: CGWindowImageOption = 1 << 2;
+pub const kCGWindowImageBestResolution: CGWindowImageOption = 1 << 3;
+pub const kCGWindowImageNominalResolution: CGWindowImageOption = 1 << 4;
+
+pub const kDisplayModeValidFlag: u32 = 0x00000001;
+pub const kDisplayModeSafeFlag: u32 = 0x00000002;
+pub const kDisplayModeDefaultFlag: u32 = 0x00000004;
+pub const kDisplayModeAlwaysShowFlag: u32 = 0x00000008;
+pub const kDisplayModeNeverShowFlag: u32 = 0x00000080;
+pub const kDisplayModeNotResizeFlag: u32 = 0x00000010;
+pub const kDisplayModeRequiresPanFlag: u32 = 0x00000020;
+pub const kDisplayModeInterlacedFlag: u32 = 0x00000040;
+pub const kDisplayModeSimulscanFlag: u32 = 0x00000100;
+pub const kDisplayModeBuiltInFlag: u32 = 0x00000400;
+pub const kDisplayModeNotPresetFlag: u32 = 0x00000200;
+pub const kDisplayModeStretchedFlag: u32 = 0x00000800;
+pub const kDisplayModeNotGraphicsQualityFlag: u32 = 0x00001000;
+pub const kDisplayModeValidateAgainstDisplay: u32 = 0x00002000;
+pub const kDisplayModeTelevisionFlag: u32 = 0x00100000;
+pub const kDisplayModeValidForMirroringFlag: u32 = 0x00200000;
+pub const kDisplayModeAcceleratorBackedFlag: u32 = 0x00400000;
+pub const kDisplayModeValidForHiResFlag: u32 = 0x00800000;
+pub const kDisplayModeValidForAirPlayFlag: u32 = 0x01000000;
+pub const kDisplayModeNativeFlag: u32 = 0x02000000;
+
+pub const kDisplayModeSafetyFlags: u32 = 0x00000007;
+
+pub const IO1BitIndexedPixels: &str = "P";
+pub const IO2BitIndexedPixels: &str = "PP";
+pub const IO4BitIndexedPixels: &str = "PPPP";
+pub const IO8BitIndexedPixels: &str = "PPPPPPPP";
+pub const IO16BitDirectPixels: &str = "-RRRRRGGGGGBBBBB";
+pub const IO32BitDirectPixels: &str = "--------RRRRRRRRGGGGGGGGBBBBBBBB";
+pub const kIO30BitDirectPixels: &str = "--RRRRRRRRRRGGGGGGGGGGBBBBBBBBBB";
+pub const kIO64BitDirectPixels: &str = "-16R16G16B16";
+pub const kIO16BitFloatPixels: &str = "-16FR16FG16FB16";
+pub const kIO32BitFloatPixels: &str = "-32FR32FG32FB32";
+pub const IOYUV422Pixels: &str = "Y4U2V2";
+pub const IO8BitOverlayPixels: &str = "O8";
+
+
+pub use core_foundation::dictionary::{ CFDictionary, CFDictionaryRef, CFDictionaryGetValueIfPresent };
+pub use core_foundation::array::{ CFArray, CFArrayRef };
+pub use core_foundation::array::{ CFArrayGetCount, CFArrayGetValueAtIndex };
+pub use core_foundation::base::{ CFIndex, CFRelease, CFTypeRef };
+
+pub type CGDisplayConfigRef = *mut libc::c_void;
+
+#[repr(u32)]
+#[derive(Clone, Copy)]
+pub enum CGConfigureOption {
+ ConfigureForAppOnly = 0,
+ ConfigureForSession = 1,
+ ConfigurePermanently = 2,
+}
+
+#[derive(Copy, Clone, Debug)]
+pub struct CGDisplay {
+ pub id: CGDirectDisplayID,
+}
+
+foreign_type! {
+ #[doc(hidden)]
+ type CType = ::sys::CGDisplayMode;
+ fn drop = CGDisplayModeRelease;
+ fn clone = |p| CFRetain(p as *const _) as *mut _;
+ pub struct CGDisplayMode;
+ pub struct CGDisplayModeRef;
+}
+
+impl CGDisplay {
+ #[inline]
+ pub fn new(id: CGDirectDisplayID) -> CGDisplay {
+ CGDisplay { id: id }
+ }
+
+ /// Returns the the main display.
+ #[inline]
+ pub fn main() -> CGDisplay {
+ CGDisplay::new(unsafe { CGMainDisplayID() })
+ }
+
+ /// A value that will never correspond to actual hardware.
+ pub fn null_display() -> CGDisplay {
+ CGDisplay::new(kCGNullDirectDisplayID)
+ }
+
+ /// Returns the bounds of a display in the global display coordinate space.
+ #[inline]
+ pub fn bounds(&self) -> CGRect {
+ unsafe { CGDisplayBounds(self.id) }
+ }
+
+ /// Returns information about a display's current configuration.
+ #[inline]
+ pub fn display_mode(&self) -> Option<CGDisplayMode> {
+ unsafe {
+ let mode_ref = CGDisplayCopyDisplayMode(self.id);
+ if !mode_ref.is_null() {
+ Some(CGDisplayMode::from_ptr(mode_ref))
+ } else {
+ None
+ }
+ }
+ }
+
+ /// Begins a new set of display configuration changes.
+ pub fn begin_configuration(&self) -> Result<CGDisplayConfigRef, CGError> {
+ unsafe {
+ let mut config_ref: CGDisplayConfigRef = ptr::null_mut();
+ let result = CGBeginDisplayConfiguration(&mut config_ref);
+ if result == 0 {
+ Ok(config_ref)
+ } else {
+ Err(result)
+ }
+ }
+ }
+
+ /// Cancels a set of display configuration changes.
+ pub fn cancel_configuration(&self, config_ref: &CGDisplayConfigRef) -> Result<(), CGError> {
+ let result = unsafe { CGCancelDisplayConfiguration(*config_ref) };
+ if result == 0 {
+ Ok(())
+ } else {
+ Err(result)
+ }
+ }
+
+ /// Completes a set of display configuration changes.
+ pub fn complete_configuration(
+ &self,
+ config_ref: &CGDisplayConfigRef,
+ option: CGConfigureOption,
+ ) -> Result<(), CGError> {
+ let result = unsafe { CGCompleteDisplayConfiguration(*config_ref, option) };
+ if result == 0 {
+ Ok(())
+ } else {
+ Err(result)
+ }
+ }
+
+ /// Configures the display mode of a display.
+ pub fn configure_display_with_display_mode(
+ &self,
+ config_ref: &CGDisplayConfigRef,
+ display_mode: &CGDisplayMode,
+ ) -> Result<(), CGError> {
+ let result = unsafe {
+ CGConfigureDisplayWithDisplayMode(
+ *config_ref,
+ self.id,
+ display_mode.as_ptr(),
+ ptr::null(),
+ )
+ };
+ if result == 0 {
+ Ok(())
+ } else {
+ Err(result)
+ }
+ }
+
+ /// Configures the origin of a display in the global display coordinate space.
+ pub fn configure_display_origin(
+ &self,
+ config_ref: &CGDisplayConfigRef,
+ x: i32,
+ y: i32,
+ ) -> Result<(), CGError> {
+ let result = unsafe { CGConfigureDisplayOrigin(*config_ref, self.id, x, y) };
+
+ if result == 0 {
+ Ok(())
+ } else {
+ Err(result)
+ }
+ }
+
+ /// Changes the configuration of a mirroring set.
+ pub fn configure_display_mirror_of_display(
+ &self,
+ config_ref: &CGDisplayConfigRef,
+ master: &CGDisplay,
+ ) -> Result<(), CGError> {
+ let result = unsafe { CGConfigureDisplayMirrorOfDisplay(*config_ref, self.id, master.id) };
+
+ if result == 0 {
+ Ok(())
+ } else {
+ Err(result)
+ }
+ }
+
+ /// Returns an image containing the contents of the specified display.
+ #[inline]
+ pub fn image(&self) -> Option<CGImage> {
+ unsafe {
+ let image_ref = CGDisplayCreateImage(self.id);
+ if !image_ref.is_null() {
+ Some(CGImage::from_ptr(image_ref))
+ } else {
+ None
+ }
+ }
+ }
+
+ /// Returns a composite image based on a dynamically generated list of
+ /// windows.
+ #[inline]
+ pub fn screenshot(
+ bounds: CGRect,
+ list_option: CGWindowListOption,
+ window_id: CGWindowID,
+ image_option: CGWindowImageOption,
+ ) -> Option<CGImage> {
+ unsafe {
+ let image_ref = CGWindowListCreateImage(bounds, list_option, window_id, image_option);
+ if !image_ref.is_null() {
+ Some(CGImage::from_ptr(image_ref))
+ } else {
+ None
+ }
+ }
+ }
+
+ /// Returns a composite image of the specified windows.
+ #[inline]
+ pub fn screenshot_from_windows(
+ bounds: CGRect,
+ windows: CFArray,
+ image_option: CGWindowImageOption,
+ ) -> Option<CGImage> {
+ unsafe {
+ let image_ref = CGWindowListCreateImageFromArray(
+ bounds,
+ windows.as_concrete_TypeRef(),
+ image_option,
+ );
+ if !image_ref.is_null() {
+ Some(CGImage::from_ptr(image_ref))
+ } else {
+ None
+ }
+ }
+ }
+
+ /// Generates and returns information about the selected windows in the
+ /// current user session.
+ pub fn window_list_info(
+ option: CGWindowListOption,
+ relative_to_window: Option<CGWindowID>,
+ ) -> Option<CFArray> {
+ let relative_to_window = relative_to_window.unwrap_or(kCGNullWindowID);
+ let array_ref = unsafe { CGWindowListCopyWindowInfo(option, relative_to_window) };
+ if !array_ref.is_null() {
+ Some(unsafe { TCFType::wrap_under_create_rule(array_ref) })
+ } else {
+ None
+ }
+ }
+
+ /// Returns a Boolean value indicating whether a display is active.
+ #[inline]
+ pub fn is_active(&self) -> bool {
+ unsafe { CGDisplayIsActive(self.id) != 0 }
+ }
+
+ /// Returns a boolean indicating whether a display is always in a
+ /// mirroring set.
+ #[inline]
+ pub fn is_always_in_mirror_set(&self) -> bool {
+ unsafe { CGDisplayIsAlwaysInMirrorSet(self.id) != 0 }
+ }
+
+ /// Returns a boolean indicating whether a display is sleeping (and is
+ /// therefore not drawable.)
+ #[inline]
+ pub fn is_asleep(&self) -> bool {
+ unsafe { CGDisplayIsAsleep(self.id) != 0 }
+ }
+
+ /// Returns a boolean indicating whether a display is built-in, such as
+ /// the internal display in portable systems.
+ #[inline]
+ pub fn is_builtin(&self) -> bool {
+ unsafe { CGDisplayIsBuiltin(self.id) != 0 }
+ }
+
+ /// Returns a boolean indicating whether a display is in a hardware
+ /// mirroring set.
+ #[inline]
+ pub fn is_in_hw_mirror_set(&self) -> bool {
+ unsafe { CGDisplayIsInHWMirrorSet(self.id) != 0 }
+ }
+
+ /// Returns a boolean indicating whether a display is in a mirroring set.
+ #[inline]
+ pub fn is_in_mirror_set(&self) -> bool {
+ unsafe { CGDisplayIsInMirrorSet(self.id) != 0 }
+ }
+
+ /// Returns a boolean indicating whether a display is the main display.
+ #[inline]
+ pub fn is_main(&self) -> bool {
+ unsafe { CGDisplayIsMain(self.id) != 0 }
+ }
+
+ /// Returns a boolean indicating whether a display is connected or online.
+ #[inline]
+ pub fn is_online(&self) -> bool {
+ unsafe { CGDisplayIsOnline(self.id) != 0 }
+ }
+
+ /// Returns a boolean indicating whether Quartz is using OpenGL-based
+ /// window acceleration (Quartz Extreme) to render in a display.
+ #[inline]
+ pub fn uses_open_gl_acceleration(&self) -> bool {
+ unsafe { CGDisplayUsesOpenGLAcceleration(self.id) != 0 }
+ }
+
+ /// Returns a boolean indicating whether a display is running in a stereo
+ /// graphics mode.
+ #[inline]
+ pub fn is_stereo(&self) -> bool {
+ unsafe { CGDisplayIsStereo(self.id) != 0 }
+ }
+
+ /// For a secondary display in a mirroring set, returns the primary
+ /// display.
+ #[inline]
+ pub fn mirrors_display(&self) -> CGDirectDisplayID {
+ unsafe { CGDisplayMirrorsDisplay(self.id) }
+ }
+
+ /// Returns the primary display in a hardware mirroring set.
+ #[inline]
+ pub fn primary_display(&self) -> CGDirectDisplayID {
+ unsafe { CGDisplayPrimaryDisplay(self.id) }
+ }
+
+ /// Returns the rotation angle of a display in degrees.
+ #[inline]
+ pub fn rotation(&self) -> f64 {
+ unsafe { CGDisplayRotation(self.id) }
+ }
+
+ /// Returns the width and height of a display in millimeters.
+ #[inline]
+ pub fn screen_size(&self) -> CGSize {
+ unsafe { CGDisplayScreenSize(self.id) }
+ }
+
+ /// Returns the serial number of a display monitor.
+ #[inline]
+ pub fn serial_number(&self) -> u32 {
+ unsafe { CGDisplaySerialNumber(self.id) }
+ }
+
+ /// Returns the logical unit number of a display.
+ #[inline]
+ pub fn unit_number(&self) -> u32 {
+ unsafe { CGDisplayUnitNumber(self.id) }
+ }
+
+ /// Returns the vendor number of the specified display's monitor.
+ #[inline]
+ pub fn vendor_number(&self) -> u32 {
+ unsafe { CGDisplayVendorNumber(self.id) }
+ }
+
+ /// Returns the model number of a display monitor.
+ #[inline]
+ pub fn model_number(&self) -> u32 {
+ unsafe { CGDisplayModelNumber(self.id) }
+ }
+
+ /// Returns the display height in pixel units.
+ #[inline]
+ pub fn pixels_high(&self) -> u64 {
+ unsafe { CGDisplayPixelsHigh(self.id) as u64 }
+ }
+
+ /// Returns the display width in pixel units.
+ #[inline]
+ pub fn pixels_wide(&self) -> u64 {
+ unsafe { CGDisplayPixelsWide(self.id) as u64 }
+ }
+
+ /// Provides a list of displays that are active (or drawable).
+ #[inline]
+ pub fn active_displays() -> Result<Vec<CGDirectDisplayID>, CGError> {
+ let count = CGDisplay::active_display_count()?;
+ let mut buf: Vec<CGDirectDisplayID> = vec![0; count as usize];
+ let result =
+ unsafe { CGGetActiveDisplayList(count as u32, buf.as_mut_ptr(), ptr::null_mut()) };
+ if result == 0 {
+ Ok(buf)
+ } else {
+ Err(result)
+ }
+ }
+
+ /// Provides count of displays that are active (or drawable).
+ #[inline]
+ pub fn active_display_count() -> Result<u32, CGError> {
+ let mut count: u32 = 0;
+ let result = unsafe { CGGetActiveDisplayList(0, ptr::null_mut(), &mut count) };
+ if result == 0 {
+ Ok(count as u32)
+ } else {
+ Err(result)
+ }
+ }
+
+ /// Hides the mouse cursor, and increments the hide cursor count.
+ #[inline]
+ pub fn hide_cursor(&self) -> Result<(), CGError> {
+ let result = unsafe { CGDisplayHideCursor(self.id) };
+ if result == 0 {
+ Ok(())
+ } else {
+ Err(result)
+ }
+ }
+
+ /// Decrements the hide cursor count, and shows the mouse cursor if the
+ /// count is 0.
+ #[inline]
+ pub fn show_cursor(&self) -> Result<(), CGError> {
+ let result = unsafe { CGDisplayShowCursor(self.id) };
+ if result == 0 {
+ Ok(())
+ } else {
+ Err(result)
+ }
+ }
+
+ /// Moves the mouse cursor to a specified point relative to the display
+ /// origin (the upper-left corner of the display).
+ #[inline]
+ pub fn move_cursor_to_point(&self, point: CGPoint) -> Result<(), CGError> {
+ let result = unsafe { CGDisplayMoveCursorToPoint(self.id, point) };
+ if result == 0 {
+ Ok(())
+ } else {
+ Err(result)
+ }
+ }
+
+ /// Moves the mouse cursor without generating events.
+ #[inline]
+ pub fn warp_mouse_cursor_position(point: CGPoint) -> Result<(), CGError> {
+ let result = unsafe { CGWarpMouseCursorPosition(point) };
+ if result == 0 {
+ Ok(())
+ } else {
+ Err(result)
+ }
+ }
+
+ /// Connects or disconnects the mouse and cursor while an application is
+ /// in the foreground.
+ #[inline]
+ pub fn associate_mouse_and_mouse_cursor_position(connected: bool) -> Result<(), CGError> {
+ let result = unsafe { CGAssociateMouseAndMouseCursorPosition(connected as boolean_t) };
+ if result == 0 {
+ Ok(())
+ } else {
+ Err(result)
+ }
+ }
+}
+
+impl CGDisplayMode {
+ /// Returns all display modes for the specified display id.
+ pub fn all_display_modes(
+ display_id: CGDirectDisplayID,
+ options: CFDictionaryRef,
+ ) -> Option<Vec<CGDisplayMode>> {
+ let array_opt: Option<CFArray> = unsafe {
+ let array_ref = CGDisplayCopyAllDisplayModes(display_id, options);
+ if !array_ref.is_null() {
+ Some(CFArray::wrap_under_create_rule(array_ref))
+ } else {
+ None
+ }
+ };
+ match array_opt {
+ Some(modes) => {
+ let vec: Vec<CGDisplayMode> = modes
+ .into_iter()
+ .map(|value0| {
+ let x = *value0.deref() as *mut ::sys::CGDisplayMode;
+ unsafe { CGDisplayMode::from_ptr(x) }
+ }).collect();
+ Some(vec)
+ }
+ None => None,
+ }
+ }
+
+ /// Returns the height of the specified display mode.
+ #[inline]
+ pub fn height(&self) -> u64 {
+ unsafe { CGDisplayModeGetHeight(self.as_ptr()) as u64 }
+ }
+
+ /// Returns the width of the specified display mode.
+ #[inline]
+ pub fn width(&self) -> u64 {
+ unsafe { CGDisplayModeGetWidth(self.as_ptr()) as u64 }
+ }
+
+ /// Returns the pixel height of the specified display mode.
+ #[inline]
+ pub fn pixel_height(&self) -> u64 {
+ unsafe { CGDisplayModeGetPixelHeight(self.as_ptr()) as u64 }
+ }
+
+ /// Returns the pixel width of the specified display mode.
+ #[inline]
+ pub fn pixel_width(&self) -> u64 {
+ unsafe { CGDisplayModeGetPixelWidth(self.as_ptr()) as u64 }
+ }
+
+ #[inline]
+ pub fn refresh_rate(&self) -> f64 {
+ unsafe { CGDisplayModeGetRefreshRate(self.as_ptr()) }
+ }
+
+ /// Returns the I/O Kit flags of the specified display mode.
+ #[inline]
+ pub fn io_flags(&self) -> u32 {
+ unsafe { CGDisplayModeGetIOFlags(self.as_ptr()) as u32 }
+ }
+
+ /// Returns the pixel encoding of the specified display mode.
+ #[inline]
+ pub fn pixel_encoding(&self) -> CFString {
+ unsafe { CFString::wrap_under_create_rule(CGDisplayModeCopyPixelEncoding(self.as_ptr())) }
+ }
+
+ /// Returns the number of bits per pixel of the specified display mode.
+ pub fn bit_depth(&self) -> usize {
+ let pixel_encoding = self.pixel_encoding().to_string();
+ // my numerical representation for kIO16BitFloatPixels and kIO32bitFloatPixels
+ // are made up and possibly non-sensical
+ if pixel_encoding.eq_ignore_ascii_case(kIO32BitFloatPixels) {
+ 96
+ } else if pixel_encoding.eq_ignore_ascii_case(kIO64BitDirectPixels) {
+ 64
+ } else if pixel_encoding.eq_ignore_ascii_case(kIO16BitFloatPixels) {
+ 48
+ } else if pixel_encoding.eq_ignore_ascii_case(IO32BitDirectPixels) {
+ 32
+ } else if pixel_encoding.eq_ignore_ascii_case(kIO30BitDirectPixels) {
+ 30
+ } else if pixel_encoding.eq_ignore_ascii_case(IO16BitDirectPixels) {
+ 16
+ } else if pixel_encoding.eq_ignore_ascii_case(IO8BitIndexedPixels) {
+ 8
+ }else{
+ 0
+ }
+ }
+
+ pub fn mode_id(&self) -> i32 {
+ unsafe { CGDisplayModeGetIODisplayModeID(self.as_ptr()) }
+ }
+}
+
+#[link(name = "CoreGraphics", kind = "framework")]
+extern "C" {
+ pub static CGRectNull: CGRect;
+ pub static CGRectInfinite: CGRect;
+
+ pub static kCGDisplayShowDuplicateLowResolutionModes: CFStringRef;
+
+ pub fn CGDisplayModeRelease(mode: ::sys::CGDisplayModeRef);
+
+ pub fn CGMainDisplayID() -> CGDirectDisplayID;
+ pub fn CGDisplayIsActive(display: CGDirectDisplayID) -> boolean_t;
+ pub fn CGDisplayIsAlwaysInMirrorSet(display: CGDirectDisplayID) -> boolean_t;
+ pub fn CGDisplayIsAsleep(display: CGDirectDisplayID) -> boolean_t;
+ pub fn CGDisplayIsBuiltin(display: CGDirectDisplayID) -> boolean_t;
+ pub fn CGDisplayIsInHWMirrorSet(display: CGDirectDisplayID) -> boolean_t;
+ pub fn CGDisplayIsInMirrorSet(display: CGDirectDisplayID) -> boolean_t;
+ pub fn CGDisplayIsMain(display: CGDirectDisplayID) -> boolean_t;
+ pub fn CGDisplayIsOnline(display: CGDirectDisplayID) -> boolean_t;
+ pub fn CGDisplayIsStereo(display: CGDirectDisplayID) -> boolean_t;
+ pub fn CGDisplayMirrorsDisplay(display: CGDirectDisplayID) -> CGDirectDisplayID;
+ pub fn CGDisplayPrimaryDisplay(display: CGDirectDisplayID) -> CGDirectDisplayID;
+ pub fn CGDisplayRotation(display: CGDirectDisplayID) -> libc::c_double;
+ pub fn CGDisplayScreenSize(display: CGDirectDisplayID) -> CGSize;
+ pub fn CGDisplaySerialNumber(display: CGDirectDisplayID) -> u32;
+ pub fn CGDisplayUnitNumber(display: CGDirectDisplayID) -> u32;
+ pub fn CGDisplayUsesOpenGLAcceleration(display: CGDirectDisplayID) -> boolean_t;
+ pub fn CGDisplayVendorNumber(display: CGDirectDisplayID) -> u32;
+ pub fn CGGetActiveDisplayList(
+ max_displays: u32,
+ active_displays: *mut CGDirectDisplayID,
+ display_count: *mut u32,
+ ) -> CGError;
+ pub fn CGGetDisplaysWithRect(
+ rect: CGRect,
+ max_displays: u32,
+ displays: *mut CGDirectDisplayID,
+ matching_display_count: *mut u32,
+ ) -> CGError;
+ pub fn CGDisplayModelNumber(display: CGDirectDisplayID) -> u32;
+ pub fn CGDisplayPixelsHigh(display: CGDirectDisplayID) -> libc::size_t;
+ pub fn CGDisplayPixelsWide(display: CGDirectDisplayID) -> libc::size_t;
+ pub fn CGDisplayBounds(display: CGDirectDisplayID) -> CGRect;
+ pub fn CGDisplayCreateImage(display: CGDirectDisplayID) -> ::sys::CGImageRef;
+
+ pub fn CGBeginDisplayConfiguration(config: *mut CGDisplayConfigRef) -> CGError;
+ pub fn CGCancelDisplayConfiguration(config: CGDisplayConfigRef) -> CGError;
+ pub fn CGCompleteDisplayConfiguration(
+ config: CGDisplayConfigRef,
+ option: CGConfigureOption,
+ ) -> CGError;
+ pub fn CGConfigureDisplayWithDisplayMode(
+ config: CGDisplayConfigRef,
+ display: CGDirectDisplayID,
+ mode: ::sys::CGDisplayModeRef,
+ options: CFDictionaryRef,
+ ) -> CGError;
+ pub fn CGConfigureDisplayMirrorOfDisplay(
+ config: CGDisplayConfigRef,
+ display: CGDirectDisplayID,
+ master: CGDirectDisplayID,
+ ) -> CGError;
+ pub fn CGConfigureDisplayOrigin(
+ config: CGDisplayConfigRef,
+ display: CGDirectDisplayID,
+ x: i32,
+ y: i32,
+ ) -> CGError;
+
+ pub fn CGDisplayCopyDisplayMode(display: CGDirectDisplayID) -> ::sys::CGDisplayModeRef;
+ pub fn CGDisplayModeGetHeight(mode: ::sys::CGDisplayModeRef) -> libc::size_t;
+ pub fn CGDisplayModeGetWidth(mode: ::sys::CGDisplayModeRef) -> libc::size_t;
+ pub fn CGDisplayModeGetPixelHeight(mode: ::sys::CGDisplayModeRef) -> libc::size_t;
+ pub fn CGDisplayModeGetPixelWidth(mode: ::sys::CGDisplayModeRef) -> libc::size_t;
+ pub fn CGDisplayModeGetRefreshRate(mode: ::sys::CGDisplayModeRef) -> libc::c_double;
+ pub fn CGDisplayModeGetIOFlags(mode: ::sys::CGDisplayModeRef) -> u32;
+ pub fn CGDisplayModeCopyPixelEncoding(mode: ::sys::CGDisplayModeRef) -> CFStringRef;
+ pub fn CGDisplayModeGetIODisplayModeID(mode: ::sys::CGDisplayModeRef) -> i32;
+
+ pub fn CGDisplayCopyAllDisplayModes(
+ display: CGDirectDisplayID,
+ options: CFDictionaryRef,
+ ) -> CFArrayRef;
+
+ // mouse stuff
+ pub fn CGDisplayHideCursor(display: CGDirectDisplayID) -> CGError;
+ pub fn CGDisplayShowCursor(display: CGDirectDisplayID) -> CGError;
+ pub fn CGDisplayMoveCursorToPoint(display: CGDirectDisplayID, point: CGPoint) -> CGError;
+ pub fn CGWarpMouseCursorPosition(point: CGPoint) -> CGError;
+ pub fn CGAssociateMouseAndMouseCursorPosition(connected: boolean_t) -> CGError;
+
+ // Window Services Reference
+ pub fn CGWindowListCopyWindowInfo(
+ option: CGWindowListOption,
+ relativeToWindow: CGWindowID,
+ ) -> CFArrayRef;
+ pub fn CGWindowListCreateImage(
+ screenBounds: CGRect,
+ listOptions: CGWindowListOption,
+ windowId: CGWindowID,
+ imageOptions: CGWindowImageOption,
+ ) -> ::sys::CGImageRef;
+ pub fn CGWindowListCreateImageFromArray(
+ screenBounds: CGRect,
+ windowArray: CFArrayRef,
+ imageOptions: CGWindowImageOption,
+ ) -> ::sys::CGImageRef;
+}
diff --git a/third_party/rust/core-graphics/src/event.rs b/third_party/rust/core-graphics/src/event.rs
new file mode 100644
index 0000000000..8cf9c6262e
--- /dev/null
+++ b/third_party/rust/core-graphics/src/event.rs
@@ -0,0 +1,814 @@
+#![allow(non_upper_case_globals)]
+use core_foundation::{
+ base::{CFRelease, CFRetain, CFTypeID, TCFType},
+ mach_port::{CFMachPort, CFMachPortRef},
+};
+use event_source::CGEventSource;
+use foreign_types::ForeignType;
+use geometry::CGPoint;
+use libc::c_void;
+use std::mem::ManuallyDrop;
+
+pub type CGEventField = u32;
+pub type CGKeyCode = u16;
+pub type CGScrollEventUnit = u32;
+
+bitflags! {
+ /// Flags for events
+ ///
+ /// [Ref](http://opensource.apple.com/source/IOHIDFamily/IOHIDFamily-700/IOHIDSystem/IOKit/hidsystem/IOLLEvent.h)
+ #[repr(C)]
+ pub struct CGEventFlags: u64 {
+ const CGEventFlagNull = 0;
+
+ // Device-independent modifier key bits.
+ const CGEventFlagAlphaShift = 0x00010000;
+ const CGEventFlagShift = 0x00020000;
+ const CGEventFlagControl = 0x00040000;
+ const CGEventFlagAlternate = 0x00080000;
+ const CGEventFlagCommand = 0x00100000;
+
+ // Special key identifiers.
+ const CGEventFlagHelp = 0x00400000;
+ const CGEventFlagSecondaryFn = 0x00800000;
+
+ // Identifies key events from numeric keypad area on extended keyboards.
+ const CGEventFlagNumericPad = 0x00200000;
+
+ // Indicates if mouse/pen movement events are not being coalesced
+ const CGEventFlagNonCoalesced = 0x00000100;
+ }
+}
+
+/// Key codes for keys that are independent of keyboard layout.
+///
+/// [Ref](https://github.com/phracker/MacOSX-SDKs/blob/master/MacOSX10.13.sdk/System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/HIToolbox.framework/Versions/A/Headers/Events.h)
+#[repr(C)]
+pub struct KeyCode;
+impl KeyCode {
+ pub const RETURN: CGKeyCode = 0x24;
+ pub const TAB: CGKeyCode = 0x30;
+ pub const SPACE: CGKeyCode = 0x31;
+ pub const DELETE: CGKeyCode = 0x33;
+ pub const ESCAPE: CGKeyCode = 0x35;
+ pub const COMMAND: CGKeyCode = 0x37;
+ pub const SHIFT: CGKeyCode = 0x38;
+ pub const CAPS_LOCK: CGKeyCode = 0x39;
+ pub const OPTION: CGKeyCode = 0x3A;
+ pub const CONTROL: CGKeyCode = 0x3B;
+ pub const RIGHT_COMMAND: CGKeyCode = 0x36;
+ pub const RIGHT_SHIFT: CGKeyCode = 0x3C;
+ pub const RIGHT_OPTION: CGKeyCode = 0x3D;
+ pub const RIGHT_CONTROL: CGKeyCode = 0x3E;
+ pub const FUNCTION: CGKeyCode = 0x3F;
+ pub const VOLUME_UP: CGKeyCode = 0x48;
+ pub const VOLUME_DOWN: CGKeyCode = 0x49;
+ pub const MUTE: CGKeyCode = 0x4A;
+ pub const F1: CGKeyCode = 0x7A;
+ pub const F2: CGKeyCode = 0x78;
+ pub const F3: CGKeyCode = 0x63;
+ pub const F4: CGKeyCode = 0x76;
+ pub const F5: CGKeyCode = 0x60;
+ pub const F6: CGKeyCode = 0x61;
+ pub const F7: CGKeyCode = 0x62;
+ pub const F8: CGKeyCode = 0x64;
+ pub const F9: CGKeyCode = 0x65;
+ pub const F10: CGKeyCode = 0x6D;
+ pub const F11: CGKeyCode = 0x67;
+ pub const F12: CGKeyCode = 0x6F;
+ pub const F13: CGKeyCode = 0x69;
+ pub const F14: CGKeyCode = 0x6B;
+ pub const F15: CGKeyCode = 0x71;
+ pub const F16: CGKeyCode = 0x6A;
+ pub const F17: CGKeyCode = 0x40;
+ pub const F18: CGKeyCode = 0x4F;
+ pub const F19: CGKeyCode = 0x50;
+ pub const F20: CGKeyCode = 0x5A;
+ pub const HELP: CGKeyCode = 0x72;
+ pub const HOME: CGKeyCode = 0x73;
+ pub const PAGE_UP: CGKeyCode = 0x74;
+ pub const FORWARD_DELETE: CGKeyCode = 0x75;
+ pub const END: CGKeyCode = 0x77;
+ pub const PAGE_DOWN: CGKeyCode = 0x79;
+ pub const LEFT_ARROW: CGKeyCode = 0x7B;
+ pub const RIGHT_ARROW: CGKeyCode = 0x7C;
+ pub const DOWN_ARROW: CGKeyCode = 0x7D;
+ pub const UP_ARROW: CGKeyCode = 0x7E;
+}
+
+#[repr(C)]
+pub struct ScrollEventUnit {}
+impl ScrollEventUnit {
+ pub const PIXEL: CGScrollEventUnit = 0;
+ pub const LINE: CGScrollEventUnit = 1;
+}
+
+/// Constants that specify the different types of input events.
+///
+/// [Ref](http://opensource.apple.com/source/IOHIDFamily/IOHIDFamily-700/IOHIDSystem/IOKit/hidsystem/IOLLEvent.h)
+#[repr(u32)]
+#[derive(Clone, Copy, Debug)]
+pub enum CGEventType {
+ Null = 0,
+
+ // Mouse events.
+ LeftMouseDown = 1,
+ LeftMouseUp = 2,
+ RightMouseDown = 3,
+ RightMouseUp = 4,
+ MouseMoved = 5,
+ LeftMouseDragged = 6,
+ RightMouseDragged = 7,
+
+ // Keyboard events.
+ KeyDown = 10,
+ KeyUp = 11,
+ FlagsChanged = 12,
+
+ // Specialized control devices.
+ ScrollWheel = 22,
+ TabletPointer = 23,
+ TabletProximity = 24,
+ OtherMouseDown = 25,
+ OtherMouseUp = 26,
+ OtherMouseDragged = 27,
+
+ // Out of band event types. These are delivered to the event tap callback
+ // to notify it of unusual conditions that disable the event tap.
+ TapDisabledByTimeout = 0xFFFFFFFE,
+ TapDisabledByUserInput = 0xFFFFFFFF,
+}
+
+/// Constants used as keys to access specialized fields in low-level events.
+///
+/// [Ref](https://developer.apple.com/documentation/coregraphics/cgeventfield)
+pub struct EventField;
+impl EventField {
+ /// Key to access an integer field that contains the mouse button event
+ /// number. Matching mouse-down and mouse-up events will have the same
+ /// event number.
+ pub const MOUSE_EVENT_NUMBER: CGEventField = 0;
+
+ /// Key to access an integer field that contains the mouse button click
+ /// state. A click state of 1 represents a single click. A click state of
+ /// 2 represents a double-click. A click state of 3 represents a
+ /// triple-click.
+ pub const MOUSE_EVENT_CLICK_STATE: CGEventField = 1;
+
+ /// Key to access a double field that contains the mouse button pressure.
+ /// The pressure value may range from 0 to 1, with 0 representing the
+ /// mouse being up. This value is commonly set by tablet pens mimicking a
+ /// mouse.
+ pub const MOUSE_EVENT_PRESSURE: CGEventField = 2;
+
+ /// Key to access an integer field that contains the mouse button number.
+ pub const MOUSE_EVENT_BUTTON_NUMBER: CGEventField = 3;
+
+ /// Key to access an integer field that contains the horizontal mouse
+ /// delta since the last mouse movement event.
+ pub const MOUSE_EVENT_DELTA_X: CGEventField = 4;
+
+ /// Key to access an integer field that contains the vertical mouse delta
+ /// since the last mouse movement event.
+ pub const MOUSE_EVENT_DELTA_Y: CGEventField = 5;
+
+ /// Key to access an integer field. The value is non-zero if the event
+ /// should be ignored by the Inkwell subsystem.
+ pub const MOUSE_EVENT_INSTANT_MOUSER: CGEventField = 6;
+
+ /// Key to access an integer field that encodes the mouse event subtype as
+ /// a `kCFNumberIntType'.
+ pub const MOUSE_EVENT_SUB_TYPE: CGEventField = 7;
+
+ /// Key to access an integer field, non-zero when this is an autorepeat of
+ /// a key-down, and zero otherwise.
+ pub const KEYBOARD_EVENT_AUTOREPEAT: CGEventField = 8;
+
+ /// Key to access an integer field that contains the virtual keycode of the
+ /// key-down or key-up event.
+ pub const KEYBOARD_EVENT_KEYCODE: CGEventField = 9;
+
+ /// Key to access an integer field that contains the keyboard type
+ /// identifier.
+ pub const KEYBOARD_EVENT_KEYBOARD_TYPE: CGEventField = 10;
+
+ /// Key to access an integer field that contains scrolling data. This field
+ /// typically contains the change in vertical position since the last
+ /// scrolling event from a Mighty Mouse scroller or a single-wheel mouse
+ /// scroller.
+ pub const SCROLL_WHEEL_EVENT_DELTA_AXIS_1: CGEventField = 11;
+
+ /// Key to access an integer field that contains scrolling data. This field
+ /// typically contains the change in horizontal position since the last
+ /// scrolling event from a Mighty Mouse scroller.
+ pub const SCROLL_WHEEL_EVENT_DELTA_AXIS_2: CGEventField = 12;
+
+ /// Key to access a field that contains scrolling data. The scrolling data
+ /// represents a line-based or pixel-based change in vertical position
+ /// since the last scrolling event from a Mighty Mouse scroller or a
+ /// single-wheel mouse scroller. The scrolling data uses a fixed-point
+ /// 16.16 signed integer format. If this key is passed to
+ /// `CGEventGetDoubleValueField', the fixed-point value is converted to a
+ /// double value.
+ pub const SCROLL_WHEEL_EVENT_FIXED_POINT_DELTA_AXIS_1: CGEventField = 93;
+
+ /// Key to access a field that contains scrolling data. The scrolling data
+ /// represents a line-based or pixel-based change in horizontal position
+ /// since the last scrolling event from a Mighty Mouse scroller. The
+ /// scrolling data uses a fixed-point 16.16 signed integer format. If this
+ /// key is passed to `CGEventGetDoubleValueField', the fixed-point value is
+ /// converted to a double value.
+ pub const SCROLL_WHEEL_EVENT_FIXED_POINT_DELTA_AXIS_2: CGEventField = 94;
+
+ /// Key to access an integer field that contains pixel-based scrolling
+ /// data. The scrolling data represents the change in vertical position
+ /// since the last scrolling event from a Mighty Mouse scroller or a
+ /// single-wheel mouse scroller.
+ pub const SCROLL_WHEEL_EVENT_POINT_DELTA_AXIS_1: CGEventField = 96;
+
+ /// Key to access an integer field that contains pixel-based scrolling
+ /// data. The scrolling data represents the change in horizontal position
+ /// since the last scrolling event from a Mighty Mouse scroller.
+ pub const SCROLL_WHEEL_EVENT_POINT_DELTA_AXIS_2: CGEventField = 97;
+
+ /// Key to access an integer field that indicates whether the event should
+ /// be ignored by the Inkwell subsystem. If the value is non-zero, the
+ /// event should be ignored.
+ pub const SCROLL_WHEEL_EVENT_INSTANT_MOUSER: CGEventField = 14;
+
+ /// Key to access an integer field that contains the absolute X coordinate
+ /// in tablet space at full tablet resolution.
+ pub const TABLET_EVENT_POINT_X: CGEventField = 15;
+
+ /// Key to access an integer field that contains the absolute Y coordinate
+ /// in tablet space at full tablet resolution.
+ pub const TABLET_EVENT_POINT_Y: CGEventField = 16;
+
+ /// Key to access an integer field that contains the absolute Z coordinate
+ /// in tablet space at full tablet resolution.
+ pub const TABLET_EVENT_POINT_Z: CGEventField = 17;
+
+ /// Key to access an integer field that contains the tablet button state.
+ /// Bit 0 is the first button, and a set bit represents a closed or pressed
+ /// button. Up to 16 buttons are supported.
+ pub const TABLET_EVENT_POINT_BUTTONS: CGEventField = 18;
+
+ /// Key to access a double field that contains the tablet pen pressure. A
+ /// value of 0.0 represents no pressure, and 1.0 represents maximum
+ /// pressure.
+ pub const TABLET_EVENT_POINT_PRESSURE: CGEventField = 19;
+
+ /// Key to access a double field that contains the horizontal tablet pen
+ /// tilt. A value of 0 represents no tilt, and 1 represents maximum tilt.
+ pub const TABLET_EVENT_TILT_X: CGEventField = 20;
+
+ /// Key to access a double field that contains the vertical tablet pen
+ /// tilt. A value of 0 represents no tilt, and 1 represents maximum tilt.
+ pub const TABLET_EVENT_TILT_Y: CGEventField = 21;
+
+ /// Key to access a double field that contains the tablet pen rotation.
+ pub const TABLET_EVENT_ROTATION: CGEventField = 22;
+
+ /// Key to access a double field that contains the tangential pressure on
+ /// the device. A value of 0.0 represents no pressure, and 1.0 represents
+ /// maximum pressure.
+ pub const TABLET_EVENT_TANGENTIAL_PRESSURE: CGEventField = 23;
+
+ /// Key to access an integer field that contains the system-assigned unique
+ /// device ID.
+ pub const TABLET_EVENT_DEVICE_ID: CGEventField = 24;
+
+ /// Key to access an integer field that contains a vendor-specified value.
+ pub const TABLET_EVENT_VENDOR_1: CGEventField = 25;
+
+ /// Key to access an integer field that contains a vendor-specified value.
+ pub const TABLET_EVENT_VENDOR_2: CGEventField = 26;
+
+ /// Key to access an integer field that contains a vendor-specified value.
+ pub const TABLET_EVENT_VENDOR_3: CGEventField = 27;
+
+ /// Key to access an integer field that contains the vendor-defined ID,
+ /// typically the USB vendor ID.
+ pub const TABLET_PROXIMITY_EVENT_VENDOR_ID: CGEventField = 28;
+
+ /// Key to access an integer field that contains the vendor-defined tablet
+ /// ID, typically the USB product ID.
+ pub const TABLET_PROXIMITY_EVENT_TABLET_ID: CGEventField = 29;
+
+ /// Key to access an integer field that contains the vendor-defined ID of
+ /// the pointing device.
+ pub const TABLET_PROXIMITY_EVENT_POINTER_ID: CGEventField = 30;
+
+ /// Key to access an integer field that contains the system-assigned
+ /// device ID.
+ pub const TABLET_PROXIMITY_EVENT_DEVICE_ID: CGEventField = 31;
+
+ /// Key to access an integer field that contains the system-assigned
+ /// unique tablet ID.
+ pub const TABLET_PROXIMITY_EVENT_SYSTEM_TABLET_ID: CGEventField = 32;
+
+ /// Key to access an integer field that contains the vendor-assigned
+ /// pointer type.
+ pub const TABLET_PROXIMITY_EVENT_VENDOR_POINTER_TYPE: CGEventField = 33;
+
+ /// Key to access an integer field that contains the vendor-defined
+ /// pointer serial number.
+ pub const TABLET_PROXIMITY_EVENT_VENDOR_POINTER_SERIAL_NUMBER: CGEventField = 34;
+
+ /// Key to access an integer field that contains the vendor-defined unique
+ /// ID.
+ pub const TABLET_PROXIMITY_EVENT_VENDOR_UNIQUE_ID: CGEventField = 35;
+
+ /// Key to access an integer field that contains the device capabilities
+ /// mask.
+ pub const TABLET_PROXIMITY_EVENT_CAPABILITY_MASK: CGEventField = 36;
+
+ /// Key to access an integer field that contains the pointer type.
+ pub const TABLET_PROXIMITY_EVENT_POINTER_TYPE: CGEventField = 37;
+
+ /// Key to access an integer field that indicates whether the pen is in
+ /// proximity to the tablet. The value is non-zero if the pen is in
+ /// proximity to the tablet and zero when leaving the tablet.
+ pub const TABLET_PROXIMITY_EVENT_ENTER_PROXIMITY: CGEventField = 38;
+
+ /// Key to access a field that contains the event target process serial
+ /// number. The value is a 64-bit value.
+ pub const EVENT_TARGET_PROCESS_SERIAL_NUMBER: CGEventField = 39;
+
+ /// Key to access a field that contains the event target Unix process ID.
+ pub const EVENT_TARGET_UNIX_PROCESS_ID: CGEventField = 40;
+
+ /// Key to access a field that contains the event source Unix process ID.
+ pub const EVENT_SOURCE_UNIX_PROCESS_ID: CGEventField = 41;
+
+ /// Key to access a field that contains the event source user-supplied
+ /// data, up to 64 bits.
+ pub const EVENT_SOURCE_USER_DATA: CGEventField = 42;
+
+ /// Key to access a field that contains the event source Unix effective UID.
+ pub const EVENT_SOURCE_USER_ID: CGEventField = 43;
+
+ /// Key to access a field that contains the event source Unix effective
+ /// GID.
+ pub const EVENT_SOURCE_GROUP_ID: CGEventField = 44;
+
+ /// Key to access a field that contains the event source state ID used to
+ /// create this event.
+ pub const EVENT_SOURCE_STATE_ID: CGEventField = 45;
+
+ /// Key to access an integer field that indicates whether a scrolling event
+ /// contains continuous, pixel-based scrolling data. The value is non-zero
+ /// when the scrolling data is pixel-based and zero when the scrolling data
+ /// is line-based.
+ pub const SCROLL_WHEEL_EVENT_IS_CONTINUOUS: CGEventField = 88;
+
+ /// Added in 10.5; made public in 10.7.
+ pub const MOUSE_EVENT_WINDOW_UNDER_MOUSE_POINTER: CGEventField = 91;
+ pub const MOUSE_EVENT_WINDOW_UNDER_MOUSE_POINTER_THAT_CAN_HANDLE_THIS_EVENT: CGEventField = 92;
+}
+
+// Constants that specify buttons on a one, two, or three-button mouse.
+#[repr(C)]
+#[derive(Clone, Copy, Debug)]
+pub enum CGMouseButton {
+ Left,
+ Right,
+ Center,
+}
+
+/// Possible tapping points for events.
+#[repr(C)]
+#[derive(Clone, Copy, Debug)]
+pub enum CGEventTapLocation {
+ HID,
+ Session,
+ AnnotatedSession,
+}
+
+// The next three enums are taken from:
+// [Ref](https://github.com/phracker/MacOSX-SDKs/blob/ef9fe35d5691b6dd383c8c46d867a499817a01b6/MacOSX10.15.sdk/System/Library/Frameworks/CoreGraphics.framework/Versions/A/Headers/CGEventTypes.h)
+/* Constants that specify where a new event tap is inserted into the list of
+active event taps. */
+#[repr(u32)]
+#[derive(Clone, Copy, Debug)]
+pub enum CGEventTapPlacement {
+ HeadInsertEventTap = 0,
+ TailAppendEventTap,
+}
+
+/* Constants that specify whether a new event tap is an active filter or a
+passive listener. */
+#[repr(u32)]
+#[derive(Clone, Copy, Debug)]
+pub enum CGEventTapOptions {
+ Default = 0x00000000,
+ ListenOnly = 0x00000001,
+}
+
+pub type CGEventMask = u64;
+/* Generate an event mask for a single type of event. */
+macro_rules! CGEventMaskBit {
+ ($eventType:expr) => {
+ 1 << $eventType as CGEventMask
+ };
+}
+
+pub type CGEventTapProxy = *const c_void;
+pub type CGEventTapCallBackFn<'tap_life> =
+ Box<dyn Fn(CGEventTapProxy, CGEventType, &CGEvent) -> Option<CGEvent> + 'tap_life>;
+type CGEventTapCallBackInternal = unsafe extern "C" fn(
+ proxy: CGEventTapProxy,
+ etype: CGEventType,
+ event: ::sys::CGEventRef,
+ user_info: *const c_void,
+) -> ::sys::CGEventRef;
+
+#[no_mangle]
+unsafe extern "C" fn cg_event_tap_callback_internal(
+ _proxy: CGEventTapProxy,
+ _etype: CGEventType,
+ _event: ::sys::CGEventRef,
+ _user_info: *const c_void,
+) -> ::sys::CGEventRef {
+ let callback = _user_info as *mut CGEventTapCallBackFn;
+ let event = CGEvent::from_ptr(_event);
+ let new_event = (*callback)(_proxy, _etype, &event);
+ let event = match new_event {
+ Some(new_event) => new_event,
+ None => event,
+ };
+ ManuallyDrop::new(event).as_ptr()
+}
+
+
+/// ```no_run
+///extern crate core_foundation;
+///use core_foundation::runloop::{kCFRunLoopCommonModes, CFRunLoop};
+///use core_graphics::event::{CGEventTap, CGEventTapLocation, CGEventTapPlacement, CGEventTapOptions, CGEventType};
+///let current = CFRunLoop::get_current();
+///match CGEventTap::new(
+/// CGEventTapLocation::HID,
+/// CGEventTapPlacement::HeadInsertEventTap,
+/// CGEventTapOptions::Default,
+/// vec![CGEventType::MouseMoved],
+/// |_a, _b, d| {
+/// println!("{:?}", d.location());
+/// None
+/// },
+/// ) {
+/// Ok(tap) => unsafe {
+/// let loop_source = tap
+/// .mach_port
+/// .create_runloop_source(0)
+/// .expect("Somethings is bad ");
+/// current.add_source(&loop_source, kCFRunLoopCommonModes);
+/// tap.enable();
+/// CFRunLoop::run_current();
+/// },
+/// Err(_) => (assert!(false)),
+/// }
+/// ```
+pub struct CGEventTap<'tap_life> {
+ pub mach_port: CFMachPort,
+ pub callback_ref:
+ Box<dyn Fn(CGEventTapProxy, CGEventType, &CGEvent) -> Option<CGEvent> + 'tap_life>,
+}
+
+impl<'tap_life> CGEventTap<'tap_life> {
+ pub fn new<F: Fn(CGEventTapProxy, CGEventType, &CGEvent) -> Option<CGEvent> + 'tap_life>(
+ tap: CGEventTapLocation,
+ place: CGEventTapPlacement,
+ options: CGEventTapOptions,
+ events_of_interest: std::vec::Vec<CGEventType>,
+ callback: F,
+ ) -> Result<CGEventTap<'tap_life>, ()> {
+ let event_mask: CGEventMask = events_of_interest
+ .iter()
+ .fold(CGEventType::Null as CGEventMask, |mask, &etype| {
+ mask | CGEventMaskBit!(etype)
+ });
+ let cb = Box::new(Box::new(callback) as CGEventTapCallBackFn);
+ let cbr = Box::into_raw(cb);
+ unsafe {
+ let event_tap_ref = CGEventTapCreate(
+ tap,
+ place,
+ options,
+ event_mask,
+ cg_event_tap_callback_internal,
+ cbr as *const c_void,
+ );
+
+ if !event_tap_ref.is_null() {
+ Ok(Self {
+ mach_port: (CFMachPort::wrap_under_create_rule(event_tap_ref)),
+ callback_ref: Box::from_raw(cbr),
+ })
+ } else {
+ Box::from_raw(cbr);
+ Err(())
+ }
+ }
+ }
+
+ pub fn enable(&self) {
+ unsafe { CGEventTapEnable(self.mach_port.as_concrete_TypeRef(), true) }
+ }
+}
+
+foreign_type! {
+ #[doc(hidden)]
+ type CType = ::sys::CGEvent;
+ fn drop = |p| CFRelease(p as *mut _);
+ fn clone = |p| CFRetain(p as *const _) as *mut _;
+ pub struct CGEvent;
+ pub struct CGEventRef;
+}
+
+impl CGEvent {
+ pub fn type_id() -> CFTypeID {
+ unsafe {
+ CGEventGetTypeID()
+ }
+ }
+
+ pub fn new(source: CGEventSource) -> Result<CGEvent, ()> {
+ unsafe {
+ let event_ref = CGEventCreate(source.as_ptr());
+ if !event_ref.is_null() {
+ Ok(Self::from_ptr(event_ref))
+ } else {
+ Err(())
+ }
+ }
+ }
+
+ pub fn new_keyboard_event(
+ source: CGEventSource,
+ keycode: CGKeyCode,
+ keydown: bool
+ ) -> Result<CGEvent, ()> {
+ unsafe {
+ let event_ref = CGEventCreateKeyboardEvent(source.as_ptr(), keycode, keydown);
+ if !event_ref.is_null() {
+ Ok(Self::from_ptr(event_ref))
+ } else {
+ Err(())
+ }
+ }
+ }
+
+ pub fn new_mouse_event(
+ source: CGEventSource,
+ mouse_type: CGEventType,
+ mouse_cursor_position: CGPoint,
+ mouse_button: CGMouseButton
+ ) -> Result<CGEvent, ()> {
+ unsafe {
+ let event_ref = CGEventCreateMouseEvent(source.as_ptr(), mouse_type,
+ mouse_cursor_position, mouse_button);
+ if !event_ref.is_null() {
+ Ok(Self::from_ptr(event_ref))
+ } else {
+ Err(())
+ }
+ }
+ }
+
+ #[cfg(feature = "highsierra")]
+ pub fn new_scroll_event(
+ source: CGEventSource,
+ units: CGScrollEventUnit,
+ wheel_count: u32,
+ wheel1: i32,
+ wheel2: i32,
+ wheel3: i32,
+ ) -> Result<CGEvent, ()> {
+ unsafe {
+ let event_ref = CGEventCreateScrollWheelEvent2(
+ source.as_ptr(),
+ units,
+ wheel_count,
+ wheel1,
+ wheel2,
+ wheel3,
+ );
+ if !event_ref.is_null() {
+ Ok(Self::from_ptr(event_ref))
+ } else {
+ Err(())
+ }
+ }
+ }
+
+ pub fn post(&self, tap_location: CGEventTapLocation) {
+ unsafe {
+ CGEventPost(tap_location, self.as_ptr());
+ }
+ }
+
+ pub fn location(&self) -> CGPoint {
+ unsafe {
+ CGEventGetLocation(self.as_ptr())
+ }
+ }
+
+ #[cfg(feature = "elcapitan")]
+ pub fn post_to_pid(&self, pid: libc::pid_t) {
+ unsafe {
+ CGEventPostToPid(pid, self.as_ptr());
+ }
+ }
+
+ pub fn set_flags(&self, flags: CGEventFlags) {
+ unsafe {
+ CGEventSetFlags(self.as_ptr(), flags);
+ }
+ }
+
+ pub fn get_flags(&self) -> CGEventFlags {
+ unsafe {
+ CGEventGetFlags(self.as_ptr())
+ }
+ }
+
+ pub fn set_type(&self, event_type: CGEventType) {
+ unsafe {
+ CGEventSetType(self.as_ptr(), event_type);
+ }
+ }
+
+ pub fn get_type(&self) -> CGEventType {
+ unsafe {
+ CGEventGetType(self.as_ptr())
+ }
+ }
+
+ pub fn set_string_from_utf16_unchecked(&self, buf: &[u16]) {
+ let buflen = buf.len() as libc::c_ulong;
+ unsafe {
+ CGEventKeyboardSetUnicodeString(self.as_ptr(), buflen, buf.as_ptr());
+ }
+ }
+
+ pub fn set_string(&self, string: &str) {
+ let buf: Vec<u16> = string.encode_utf16().collect();
+ self.set_string_from_utf16_unchecked(&buf);
+ }
+
+ pub fn get_integer_value_field(&self, field: CGEventField) -> i64 {
+ unsafe { CGEventGetIntegerValueField(self.as_ptr(), field) }
+ }
+
+ pub fn set_integer_value_field(&self, field: CGEventField, value: i64) {
+ unsafe { CGEventSetIntegerValueField(self.as_ptr(), field, value) }
+ }
+
+ pub fn get_double_value_field(&self, field: CGEventField) -> f64 {
+ unsafe { CGEventGetDoubleValueField(self.as_ptr(), field) }
+ }
+
+ pub fn set_double_value_field(&self, field: CGEventField, value: f64) {
+ unsafe { CGEventSetDoubleValueField(self.as_ptr(), field, value) }
+ }
+}
+
+#[link(name = "CoreGraphics", kind = "framework")]
+extern {
+ /// Return the type identifier for the opaque type `CGEventRef'.
+ fn CGEventGetTypeID() -> CFTypeID;
+
+ /// Return a new event using the event source `source'. If `source' is NULL,
+ /// the default source is used.
+ fn CGEventCreate(source: ::sys::CGEventSourceRef) -> ::sys::CGEventRef;
+
+ /// Return a new keyboard event.
+ ///
+ /// The event source may be taken from another event, or may be NULL. Based
+ /// on the virtual key code values entered, the appropriate key down, key up,
+ /// or flags changed events are generated.
+ ///
+ /// All keystrokes needed to generate a character must be entered, including
+ /// SHIFT, CONTROL, OPTION, and COMMAND keys. For example, to produce a 'Z',
+ /// the SHIFT key must be down, the 'z' key must go down, and then the SHIFT
+ /// and 'z' key must be released:
+ fn CGEventCreateKeyboardEvent(source: ::sys::CGEventSourceRef, keycode: CGKeyCode,
+ keydown: bool) -> ::sys::CGEventRef;
+
+ /// Return a new mouse event.
+ ///
+ /// The event source may be taken from another event, or may be NULL.
+ /// `mouseType' should be one of the mouse event types. `mouseCursorPosition'
+ /// should be the position of the mouse cursor in global coordinates.
+ /// `mouseButton' should be the button that's changing state; `mouseButton'
+ /// is ignored unless `mouseType' is one of `kCGEventOtherMouseDown',
+ /// `kCGEventOtherMouseDragged', or `kCGEventOtherMouseUp'.
+ ///
+ /// The current implementation of the event system supports a maximum of
+ /// thirty-two buttons. Mouse button 0 is the primary button on the mouse.
+ /// Mouse button 1 is the secondary mouse button (right). Mouse button 2 is
+ /// the center button, and the remaining buttons are in USB device order.
+ fn CGEventCreateMouseEvent(source: ::sys::CGEventSourceRef, mouseType: CGEventType,
+ mouseCursorPosition: CGPoint, mouseButton: CGMouseButton) -> ::sys::CGEventRef;
+
+ /// A non-variadic variant version of CGEventCreateScrollWheelEvent.
+ ///
+ /// Returns a new Quartz scrolling event.
+ ///
+ /// This function allows you to create a scrolling event and customize the
+ /// event before posting it to the event system.
+ #[cfg(feature = "highsierra")]
+ fn CGEventCreateScrollWheelEvent2(
+ source: ::sys::CGEventSourceRef,
+ units: CGScrollEventUnit,
+ wheelCount: u32,
+ wheel1: i32,
+ wheel2: i32,
+ wheel3: i32,
+ ) -> ::sys::CGEventRef;
+
+ /// Post an event into the event stream at a specified location.
+ ///
+ /// This function posts the specified event immediately before any event taps
+ /// instantiated for that location, and the event passes through any such
+ /// taps.
+ fn CGEventPost(tapLocation: CGEventTapLocation, event: ::sys::CGEventRef);
+
+ #[cfg(feature = "elcapitan")]
+ /// Post an event to a specified process ID
+ fn CGEventPostToPid(pid: libc::pid_t, event: ::sys::CGEventRef);
+
+ /// Set the event flags of an event.
+ fn CGEventSetFlags(event: ::sys::CGEventRef, flags: CGEventFlags);
+
+ /// Return the event flags of an event.
+ fn CGEventGetFlags(event: ::sys::CGEventRef) -> CGEventFlags;
+
+ /// Return the location of an event in global display coordinates.
+ /// CGPointZero is returned if event is not a valid ::sys::CGEventRef.
+ fn CGEventGetLocation(event: ::sys::CGEventRef) -> CGPoint;
+
+ /// Set the event type of an event.
+ fn CGEventSetType(event: ::sys::CGEventRef, eventType: CGEventType);
+
+ /// Return the event type of an event (left mouse down, for example).
+ fn CGEventGetType(event: ::sys::CGEventRef) -> CGEventType;
+
+ /// Set the Unicode string associated with a keyboard event.
+ ///
+ /// By default, the system translates the virtual key code in a keyboard
+ /// event into a Unicode string based on the keyboard ID in the event
+ /// source. This function allows you to manually override this string.
+ /// Note that application frameworks may ignore the Unicode string in a
+ /// keyboard event and do their own translation based on the virtual
+ /// keycode and perceived event state.
+ fn CGEventKeyboardSetUnicodeString(event: ::sys::CGEventRef,
+ length: libc::c_ulong,
+ string: *const u16);
+
+ /// Return the integer value of a field in an event.
+ fn CGEventGetIntegerValueField(event: ::sys::CGEventRef, field: CGEventField) -> i64;
+
+ /// Set the integer value of a field in an event.
+ ///
+ /// Before calling this function, the event type must be set using a typed
+ /// event creation function such as `CGEventCreateMouseEvent', or by
+ /// calling `CGEventSetType'.
+ ///
+ /// If you are creating a mouse event generated by a tablet, call this
+ /// function and specify the field `kCGMouseEventSubtype' with a value of
+ /// `kCGEventMouseSubtypeTabletPoint' or
+ /// `kCGEventMouseSubtypeTabletProximity' before setting other parameters.
+ fn CGEventSetIntegerValueField(event: ::sys::CGEventRef, field: CGEventField, value: i64);
+
+ /// Return the floating-point value of a field in an event.
+ ///
+ /// In cases where the field value is represented within the event by a fixed
+ /// point number or an integer, the result is scaled to the appropriate range
+ /// as part of creating the floating-point representation.
+ fn CGEventGetDoubleValueField(event: ::sys::CGEventRef, field: CGEventField) -> f64;
+
+ /// Set the floating-point value of a field in an event.
+ ///
+ /// Before calling this function, the event type must be set using a typed
+ /// event creation function such as `CGEventCreateMouseEvent', or by calling
+ /// `CGEventSetType'.
+ ///
+ /// In cases where the field’s value is represented within the event by a
+ /// fixed point number or integer, the value parameter is scaled as needed
+ /// and converted to the appropriate type.
+ fn CGEventSetDoubleValueField(event: ::sys::CGEventRef, field: CGEventField, value: f64);
+
+ // ::sys::CGEventTapRef is actually an CFMachPortRef
+ fn CGEventTapCreate(
+ tap: CGEventTapLocation,
+ place: CGEventTapPlacement,
+ options: CGEventTapOptions,
+ eventsOfInterest: CGEventMask,
+ callback: CGEventTapCallBackInternal,
+ userInfo: *const c_void,
+ ) -> CFMachPortRef;
+
+ fn CGEventTapEnable(tap: CFMachPortRef, enable: bool);
+
+}
diff --git a/third_party/rust/core-graphics/src/event_source.rs b/third_party/rust/core-graphics/src/event_source.rs
new file mode 100644
index 0000000000..ce13f5a91c
--- /dev/null
+++ b/third_party/rust/core-graphics/src/event_source.rs
@@ -0,0 +1,48 @@
+use core_foundation::base::{CFRelease, CFRetain, CFTypeID};
+use foreign_types::ForeignType;
+
+/// Possible source states of an event source.
+#[repr(C)]
+#[derive(Clone, Copy, Debug)]
+pub enum CGEventSourceStateID {
+ Private = -1,
+ CombinedSessionState = 0,
+ HIDSystemState = 1,
+}
+
+foreign_type! {
+ #[doc(hidden)]
+ type CType = ::sys::CGEventSource;
+ fn drop = |p| CFRelease(p as *mut _);
+ fn clone = |p| CFRetain(p as *const _) as *mut _;
+ pub struct CGEventSource;
+ pub struct CGEventSourceRef;
+}
+
+impl CGEventSource {
+ pub fn type_id() -> CFTypeID {
+ unsafe {
+ CGEventSourceGetTypeID()
+ }
+ }
+
+ pub fn new(state_id: CGEventSourceStateID) -> Result<Self, ()> {
+ unsafe {
+ let event_source_ref = CGEventSourceCreate(state_id);
+ if !event_source_ref.is_null() {
+ Ok(Self::from_ptr(event_source_ref))
+ } else {
+ Err(())
+ }
+ }
+ }
+}
+
+#[link(name = "CoreGraphics", kind = "framework")]
+extern {
+ /// Return the type identifier for the opaque type `CGEventSourceRef'.
+ fn CGEventSourceGetTypeID() -> CFTypeID;
+
+ /// Return a Quartz event source created with a specified source state.
+ fn CGEventSourceCreate(stateID: CGEventSourceStateID) -> ::sys::CGEventSourceRef;
+}
diff --git a/third_party/rust/core-graphics/src/font.rs b/third_party/rust/core-graphics/src/font.rs
new file mode 100644
index 0000000000..adf7a14932
--- /dev/null
+++ b/third_party/rust/core-graphics/src/font.rs
@@ -0,0 +1,176 @@
+// Copyright 2013 The Servo Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use core_foundation::base::{CFRelease, CFRetain, CFType, CFTypeID, TCFType};
+use core_foundation::array::{CFArray, CFArrayRef};
+use core_foundation::data::{CFData, CFDataRef};
+use core_foundation::number::CFNumber;
+use core_foundation::string::{CFString, CFStringRef};
+use core_foundation::dictionary::{CFDictionary, CFDictionaryRef};
+use data_provider::CGDataProvider;
+use geometry::CGRect;
+
+use foreign_types::ForeignType;
+
+use libc::{c_int, size_t};
+
+pub use core_graphics_types::base::CGGlyph;
+
+foreign_type! {
+ #[doc(hidden)]
+ type CType = ::sys::CGFont;
+ fn drop = |p| CFRelease(p as *mut _);
+ fn clone = |p| CFRetain(p as *const _) as *mut _;
+ pub struct CGFont;
+ pub struct CGFontRef;
+}
+
+unsafe impl Send for CGFont {}
+unsafe impl Sync for CGFont {}
+
+impl CGFont {
+ pub fn type_id() -> CFTypeID {
+ unsafe {
+ CGFontGetTypeID()
+ }
+ }
+
+ pub fn from_data_provider(provider: CGDataProvider) -> Result<CGFont, ()> {
+ unsafe {
+ let font_ref = CGFontCreateWithDataProvider(provider.as_ptr());
+ if !font_ref.is_null() {
+ Ok(CGFont::from_ptr(font_ref))
+ } else {
+ Err(())
+ }
+ }
+ }
+
+ pub fn from_name(name: &CFString) -> Result<CGFont, ()> {
+ unsafe {
+ let font_ref = CGFontCreateWithFontName(name.as_concrete_TypeRef());
+ if !font_ref.is_null() {
+ Ok(CGFont::from_ptr(font_ref))
+ } else {
+ Err(())
+ }
+ }
+ }
+
+ pub fn create_copy_from_variations(&self, vars: &CFDictionary<CFString, CFNumber>) -> Result<CGFont, ()> {
+ unsafe {
+ let font_ref = CGFontCreateCopyWithVariations(self.as_ptr(),
+ vars.as_concrete_TypeRef());
+ if !font_ref.is_null() {
+ Ok(CGFont::from_ptr(font_ref))
+ } else {
+ Err(())
+ }
+ }
+ }
+
+ pub fn postscript_name(&self) -> CFString {
+ unsafe {
+ let string_ref = CGFontCopyPostScriptName(self.as_ptr());
+ TCFType::wrap_under_create_rule(string_ref)
+ }
+ }
+
+ pub fn get_glyph_b_boxes(&self, glyphs: &[CGGlyph], bboxes: &mut [CGRect]) -> bool {
+ unsafe {
+ assert!(bboxes.len() >= glyphs.len());
+ CGFontGetGlyphBBoxes(self.as_ptr(),
+ glyphs.as_ptr(),
+ glyphs.len(),
+ bboxes.as_mut_ptr())
+ }
+ }
+
+ pub fn get_glyph_advances(&self, glyphs: &[CGGlyph], advances: &mut [c_int]) -> bool {
+ unsafe {
+ assert!(advances.len() >= glyphs.len());
+ CGFontGetGlyphAdvances(self.as_ptr(),
+ glyphs.as_ptr(),
+ glyphs.len(),
+ advances.as_mut_ptr())
+ }
+ }
+
+ pub fn get_units_per_em(&self) -> c_int {
+ unsafe {
+ CGFontGetUnitsPerEm(self.as_ptr())
+ }
+ }
+
+ pub fn copy_table_tags(&self) -> CFArray<u32> {
+ unsafe {
+ TCFType::wrap_under_create_rule(CGFontCopyTableTags(self.as_ptr()))
+ }
+ }
+
+ pub fn copy_table_for_tag(&self, tag: u32) -> Option<CFData> {
+ let data_ref = unsafe { CGFontCopyTableForTag(self.as_ptr(), tag) };
+ if !data_ref.is_null() {
+ Some(unsafe { TCFType::wrap_under_create_rule(data_ref) })
+ } else {
+ None
+ }
+ }
+
+ pub fn copy_variations(&self) -> Option<CFDictionary<CFString, CFNumber>> {
+ let variations = unsafe { CGFontCopyVariations(self.as_ptr()) };
+ if !variations.is_null() {
+ Some(unsafe { TCFType::wrap_under_create_rule(variations) })
+ } else {
+ None
+ }
+ }
+
+ pub fn copy_variation_axes(&self) -> Option<CFArray<CFDictionary<CFString, CFType>>> {
+ let axes = unsafe { CGFontCopyVariationAxes(self.as_ptr()) };
+ if !axes.is_null() {
+ Some(unsafe { TCFType::wrap_under_create_rule(axes) })
+ } else {
+ None
+ }
+ }
+}
+
+#[link(name = "CoreGraphics", kind = "framework")]
+extern {
+ // TODO: basically nothing has bindings (even commented-out) besides what we use.
+ fn CGFontCreateWithDataProvider(provider: ::sys::CGDataProviderRef) -> ::sys::CGFontRef;
+ fn CGFontCreateWithFontName(name: CFStringRef) -> ::sys::CGFontRef;
+ fn CGFontCreateCopyWithVariations(font: ::sys::CGFontRef, vars: CFDictionaryRef) -> ::sys::CGFontRef;
+ fn CGFontGetTypeID() -> CFTypeID;
+
+ fn CGFontCopyPostScriptName(font: ::sys::CGFontRef) -> CFStringRef;
+
+ // These do the same thing as CFRetain/CFRelease, except
+ // gracefully handle a NULL argument. We don't use them.
+ //fn CGFontRetain(font: ::sys::CGFontRef);
+ //fn CGFontRelease(font: ::sys::CGFontRef);
+
+ fn CGFontGetGlyphBBoxes(font: ::sys::CGFontRef,
+ glyphs: *const CGGlyph,
+ count: size_t,
+ bboxes: *mut CGRect)
+ -> bool;
+ fn CGFontGetGlyphAdvances(font: ::sys::CGFontRef,
+ glyphs: *const CGGlyph,
+ count: size_t,
+ advances: *mut c_int)
+ -> bool;
+ fn CGFontGetUnitsPerEm(font: ::sys::CGFontRef) -> c_int;
+
+ fn CGFontCopyTableTags(font: ::sys::CGFontRef) -> CFArrayRef;
+ fn CGFontCopyTableForTag(font: ::sys::CGFontRef, tag: u32) -> CFDataRef;
+ fn CGFontCopyVariations(font: ::sys::CGFontRef) -> CFDictionaryRef;
+ fn CGFontCopyVariationAxes(font: ::sys::CGFontRef) -> CFArrayRef;
+}
diff --git a/third_party/rust/core-graphics/src/geometry.rs b/third_party/rust/core-graphics/src/geometry.rs
new file mode 100644
index 0000000000..fd4dc977e6
--- /dev/null
+++ b/third_party/rust/core-graphics/src/geometry.rs
@@ -0,0 +1,10 @@
+// Copyright 2013 The Servo Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+pub use core_graphics_types::geometry::*; \ No newline at end of file
diff --git a/third_party/rust/core-graphics/src/gradient.rs b/third_party/rust/core-graphics/src/gradient.rs
new file mode 100644
index 0000000000..5c6cde846e
--- /dev/null
+++ b/third_party/rust/core-graphics/src/gradient.rs
@@ -0,0 +1,62 @@
+// Copyright 2013 The Servo Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![allow(non_upper_case_globals)]
+
+use base::CGFloat;
+use color::CGColor;
+use color_space::CGColorSpace;
+
+use core_foundation::array::{ CFArray, CFArrayRef };
+use core_foundation::base::{CFRelease, CFRetain, TCFType};
+use foreign_types::ForeignType;
+
+use libc::size_t;
+
+bitflags! {
+ #[repr(C)]
+ pub struct CGGradientDrawingOptions: u32 {
+ const CGGradientDrawsBeforeStartLocation = (1 << 0);
+ const CGGradientDrawsAfterEndLocation = (1 << 1);
+ }
+}
+
+foreign_type! {
+ #[doc(hidden)]
+ type CType = ::sys::CGGradient;
+ fn drop = |p| CFRelease(p as *mut _);
+ fn clone = |p| CFRetain(p as *const _) as *mut _;
+ pub struct CGGradient;
+ pub struct CGGradientRef;
+}
+
+impl CGGradient {
+ pub fn create_with_color_components(color_space: &CGColorSpace, components: &[CGFloat], locations: &[CGFloat], count: usize) -> CGGradient {
+ unsafe {
+ let result = CGGradientCreateWithColorComponents(color_space.as_ptr(), components.as_ptr(), locations.as_ptr(), count);
+ assert!(!result.is_null());
+ Self::from_ptr(result)
+ }
+ }
+
+ pub fn create_with_colors(color_space: &CGColorSpace, colors: &CFArray<CGColor>, locations: &[CGFloat]) -> CGGradient {
+ unsafe {
+ let result = CGGradientCreateWithColors(color_space.as_ptr(), colors.as_concrete_TypeRef(), locations.as_ptr());
+ assert!(!result.is_null());
+ Self::from_ptr(result)
+ }
+ }
+}
+
+#[link(name = "CoreGraphics", kind = "framework")]
+extern {
+ fn CGGradientCreateWithColorComponents(color_space: ::sys::CGColorSpaceRef, components: *const CGFloat, locations: *const CGFloat, count: size_t) -> ::sys::CGGradientRef;
+ fn CGGradientCreateWithColors(color_space: ::sys::CGColorSpaceRef, colors: CFArrayRef, locations: *const CGFloat) -> ::sys::CGGradientRef;
+}
+
diff --git a/third_party/rust/core-graphics/src/image.rs b/third_party/rust/core-graphics/src/image.rs
new file mode 100644
index 0000000000..f1b95096d9
--- /dev/null
+++ b/third_party/rust/core-graphics/src/image.rs
@@ -0,0 +1,165 @@
+use std::ptr;
+
+use base::CGFloat;
+use core_foundation::base::{CFRetain, CFTypeID};
+use core_foundation::data::CFData;
+use color_space::CGColorSpace;
+use data_provider::{CGDataProviderRef, CGDataProvider};
+use geometry::CGRect;
+use libc::size_t;
+use foreign_types::{ForeignType, ForeignTypeRef};
+
+#[repr(C)]
+pub enum CGImageAlphaInfo {
+ CGImageAlphaNone, /* For example, RGB. */
+ CGImageAlphaPremultipliedLast, /* For example, premultiplied RGBA */
+ CGImageAlphaPremultipliedFirst, /* For example, premultiplied ARGB */
+ CGImageAlphaLast, /* For example, non-premultiplied RGBA */
+ CGImageAlphaFirst, /* For example, non-premultiplied ARGB */
+ CGImageAlphaNoneSkipLast, /* For example, RBGX. */
+ CGImageAlphaNoneSkipFirst, /* For example, XRBG. */
+ CGImageAlphaOnly /* No color data, alpha data only */
+}
+
+#[repr(C)]
+pub enum CGImageByteOrderInfo {
+ CGImageByteOrderMask = 0x7000,
+ CGImageByteOrder16Little = 1 << 12,
+ CGImageByteOrder32Little = 2 << 12,
+ CGImageByteOrder16Big = 3 << 12,
+ CGImageByteOrder32Big = 4 << 12
+}
+
+foreign_type! {
+ #[doc(hidden)]
+ type CType = ::sys::CGImage;
+ fn drop = CGImageRelease;
+ fn clone = |p| CFRetain(p as *const _) as *mut _;
+ pub struct CGImage;
+ pub struct CGImageRef;
+}
+
+impl CGImage {
+ pub fn new(width: size_t,
+ height: size_t,
+ bits_per_component: size_t,
+ bits_per_pixel: size_t,
+ bytes_per_row: size_t,
+ colorspace: &CGColorSpace,
+ bitmap_info: u32,
+ provider: &CGDataProvider,
+ should_interpolate: bool,
+ rendering_intent: u32)
+ -> Self {
+ unsafe {
+ let result = CGImageCreate(width,
+ height,
+ bits_per_component,
+ bits_per_pixel,
+ bytes_per_row,
+ colorspace.as_ptr(),
+ bitmap_info,
+ provider.as_ptr(),
+ ptr::null_mut(),
+ should_interpolate,
+ rendering_intent);
+ assert!(!result.is_null());
+ Self::from_ptr(result)
+ }
+ }
+
+ pub fn type_id() -> CFTypeID {
+ unsafe {
+ CGImageGetTypeID()
+ }
+ }
+}
+
+impl CGImageRef {
+ pub fn width(&self) -> size_t {
+ unsafe {
+ CGImageGetWidth(self.as_ptr())
+ }
+ }
+
+ pub fn height(&self) -> size_t {
+ unsafe {
+ CGImageGetHeight(self.as_ptr())
+ }
+ }
+
+ pub fn bits_per_component(&self) -> size_t {
+ unsafe {
+ CGImageGetBitsPerComponent(self.as_ptr())
+ }
+ }
+
+ pub fn bits_per_pixel(&self) -> size_t {
+ unsafe {
+ CGImageGetBitsPerPixel(self.as_ptr())
+ }
+ }
+
+ pub fn bytes_per_row(&self) -> size_t {
+ unsafe {
+ CGImageGetBytesPerRow(self.as_ptr())
+ }
+ }
+
+ pub fn color_space(&self) -> CGColorSpace {
+ unsafe {
+ let cs = CGImageGetColorSpace(self.as_ptr());
+ CFRetain(cs as *mut _);
+ CGColorSpace::from_ptr(cs)
+ }
+ }
+
+ /// Returns the raw image bytes wrapped in `CFData`. Note, the returned `CFData` owns the
+ /// underlying buffer.
+ pub fn data(&self) -> CFData {
+ let data_provider = unsafe {
+ CGDataProviderRef::from_ptr(CGImageGetDataProvider(self.as_ptr()))
+ };
+ data_provider.copy_data()
+ }
+
+ /// Returns a cropped image. If the `rect` specifies a rectangle which lies outside of the
+ /// image bounds, the `None` is returned.
+ pub fn cropped(&self, rect: CGRect) -> Option<CGImage> {
+ let image_ptr = unsafe { CGImageCreateWithImageInRect(self.as_ptr(), rect) };
+ if !image_ptr.is_null() {
+ Some(unsafe { CGImage::from_ptr(image_ptr) })
+ } else {
+ None
+ }
+ }
+}
+
+#[link(name = "CoreGraphics", kind = "framework")]
+extern {
+ fn CGImageGetTypeID() -> CFTypeID;
+ fn CGImageGetWidth(image: ::sys::CGImageRef) -> size_t;
+ fn CGImageGetHeight(image: ::sys::CGImageRef) -> size_t;
+ fn CGImageGetBitsPerComponent(image: ::sys::CGImageRef) -> size_t;
+ fn CGImageGetBitsPerPixel(image: ::sys::CGImageRef) -> size_t;
+ fn CGImageGetBytesPerRow(image: ::sys::CGImageRef) -> size_t;
+ fn CGImageGetColorSpace(image: ::sys::CGImageRef) -> ::sys::CGColorSpaceRef;
+ fn CGImageGetDataProvider(image: ::sys::CGImageRef) -> ::sys::CGDataProviderRef;
+ fn CGImageRelease(image: ::sys::CGImageRef);
+ fn CGImageCreate(width: size_t,
+ height: size_t,
+ bitsPerComponent: size_t,
+ bitsPerPixel: size_t,
+ bytesPerRow: size_t,
+ space: ::sys::CGColorSpaceRef,
+ bitmapInfo: u32,
+ provider: ::sys::CGDataProviderRef,
+ decode: *const CGFloat,
+ shouldInterpolate: bool,
+ intent: u32)
+ -> ::sys::CGImageRef;
+ fn CGImageCreateWithImageInRect(image: ::sys::CGImageRef, rect: CGRect) -> ::sys::CGImageRef;
+
+ //fn CGImageGetAlphaInfo(image: ::sys::CGImageRef) -> CGImageAlphaInfo;
+ //fn CGImageCreateCopyWithColorSpace(image: ::sys::CGImageRef, space: ::sys::CGColorSpaceRef) -> ::sys::CGImageRef
+}
diff --git a/third_party/rust/core-graphics/src/lib.rs b/third_party/rust/core-graphics/src/lib.rs
new file mode 100644
index 0000000000..5238774e7c
--- /dev/null
+++ b/third_party/rust/core-graphics/src/lib.rs
@@ -0,0 +1,43 @@
+// Copyright 2013 The Servo Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+extern crate libc;
+
+#[macro_use]
+extern crate core_foundation;
+
+#[macro_use]
+extern crate bitflags;
+
+#[macro_use]
+extern crate foreign_types;
+
+extern crate core_graphics_types;
+
+pub mod base;
+pub mod color;
+pub mod color_space;
+pub mod context;
+pub mod data_provider;
+#[cfg(target_os = "macos")]
+pub mod display;
+#[cfg(target_os = "macos")]
+pub mod event;
+#[cfg(target_os = "macos")]
+pub mod event_source;
+pub mod font;
+pub mod geometry;
+pub mod gradient;
+#[cfg(target_os = "macos")]
+pub mod window;
+#[cfg(target_os = "macos")]
+pub mod private;
+pub mod image;
+pub mod path;
+pub mod sys;
diff --git a/third_party/rust/core-graphics/src/path.rs b/third_party/rust/core-graphics/src/path.rs
new file mode 100644
index 0000000000..dc1c804644
--- /dev/null
+++ b/third_party/rust/core-graphics/src/path.rs
@@ -0,0 +1,129 @@
+// Copyright 2017 The Servo Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+pub use sys::CGPathRef as SysCGPathRef;
+
+use core_foundation::base::{CFRelease, CFRetain, CFTypeID};
+use foreign_types::ForeignType;
+use geometry::{CGAffineTransform, CGPoint, CGRect};
+use libc::c_void;
+use std::fmt::{self, Debug, Formatter};
+use std::marker::PhantomData;
+use std::ops::Deref;
+use std::ptr;
+use std::slice;
+
+foreign_type! {
+ #[doc(hidden)]
+ type CType = ::sys::CGPath;
+ fn drop = |p| CFRelease(p as *mut _);
+ fn clone = |p| CFRetain(p as *const _) as *mut _;
+ pub struct CGPath;
+ pub struct CGPathRef;
+}
+
+impl CGPath {
+ pub fn from_rect(rect: CGRect, transform: Option<&CGAffineTransform>) -> CGPath {
+ unsafe {
+ let transform = match transform {
+ None => ptr::null(),
+ Some(transform) => transform as *const CGAffineTransform,
+ };
+ CGPath(CGPathCreateWithRect(rect, transform))
+ }
+ }
+
+ pub fn type_id() -> CFTypeID {
+ unsafe {
+ CGPathGetTypeID()
+ }
+ }
+
+ pub fn apply<'a, F>(&'a self, mut closure: &'a F) where F: FnMut(CGPathElementRef<'a>) {
+ unsafe {
+ CGPathApply(self.as_ptr(), &mut closure as *mut _ as *mut c_void, do_apply::<F>);
+ }
+
+ unsafe extern "C" fn do_apply<'a, F>(info: *mut c_void, element: *const CGPathElement)
+ where F: FnMut(CGPathElementRef<'a>) {
+ let closure = info as *mut *mut F;
+ (**closure)(CGPathElementRef::new(element))
+ }
+ }
+}
+
+#[repr(i32)]
+#[derive(Clone, Copy, Debug, PartialEq)]
+pub enum CGPathElementType {
+ MoveToPoint = 0,
+ AddLineToPoint = 1,
+ AddQuadCurveToPoint = 2,
+ AddCurveToPoint = 3,
+ CloseSubpath = 4,
+}
+
+pub struct CGPathElementRef<'a> {
+ element: *const CGPathElement,
+ phantom: PhantomData<&'a CGPathElement>,
+}
+
+impl<'a> CGPathElementRef<'a> {
+ fn new<'b>(element: *const CGPathElement) -> CGPathElementRef<'b> {
+ CGPathElementRef {
+ element: element,
+ phantom: PhantomData,
+ }
+ }
+}
+
+impl<'a> Deref for CGPathElementRef<'a> {
+ type Target = CGPathElement;
+ fn deref(&self) -> &CGPathElement {
+ unsafe {
+ &*self.element
+ }
+ }
+}
+
+#[repr(C)]
+pub struct CGPathElement {
+ pub element_type: CGPathElementType,
+ points: *mut CGPoint,
+}
+
+impl Debug for CGPathElement {
+ fn fmt(&self, formatter: &mut Formatter) -> Result<(), fmt::Error> {
+ write!(formatter, "{:?}: {:?}", self.element_type, self.points())
+ }
+}
+
+impl CGPathElement {
+ pub fn points(&self) -> &[CGPoint] {
+ unsafe {
+ match self.element_type {
+ CGPathElementType::CloseSubpath => &[],
+ CGPathElementType::MoveToPoint | CGPathElementType::AddLineToPoint => {
+ slice::from_raw_parts(self.points, 1)
+ }
+ CGPathElementType::AddQuadCurveToPoint => slice::from_raw_parts(self.points, 2),
+ CGPathElementType::AddCurveToPoint => slice::from_raw_parts(self.points, 3),
+ }
+ }
+ }
+}
+
+type CGPathApplierFunction = unsafe extern "C" fn(info: *mut c_void,
+ element: *const CGPathElement);
+
+#[link(name = "CoreGraphics", kind = "framework")]
+extern {
+ fn CGPathCreateWithRect(rect: CGRect, transform: *const CGAffineTransform) -> ::sys::CGPathRef;
+ fn CGPathApply(path: ::sys::CGPathRef, info: *mut c_void, function: CGPathApplierFunction);
+ fn CGPathGetTypeID() -> CFTypeID;
+}
diff --git a/third_party/rust/core-graphics/src/private.rs b/third_party/rust/core-graphics/src/private.rs
new file mode 100644
index 0000000000..0bc193b408
--- /dev/null
+++ b/third_party/rust/core-graphics/src/private.rs
@@ -0,0 +1,116 @@
+// Copyright 2016 The Servo Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Evil private APIs.
+//!
+//! These are liable to change at any time. Use with caution!
+
+use geometry::CGRect;
+use libc::{c_int, c_uint};
+use std::ptr;
+
+pub struct CGSRegion {
+ region: ffi::CGSRegionRef,
+}
+
+impl Drop for CGSRegion {
+ fn drop(&mut self) {
+ unsafe {
+ ffi::CGSRegionRelease(self.region)
+ }
+ }
+}
+
+impl CGSRegion {
+ #[inline]
+ pub fn from_rect(rect: &CGRect) -> CGSRegion {
+ unsafe {
+ let mut region = ptr::null_mut();
+ assert!(ffi::CGSNewRegionWithRect(rect, &mut region) == 0);
+ CGSRegion {
+ region: region,
+ }
+ }
+ }
+
+ #[inline]
+ pub fn from_rects(rects: &[CGRect]) -> CGSRegion {
+ unsafe {
+ let mut region = ptr::null_mut();
+ assert!(ffi::CGSNewRegionWithRectList(rects.as_ptr(),
+ rects.len() as c_uint,
+ &mut region) == 0);
+ CGSRegion {
+ region: region,
+ }
+ }
+ }
+}
+
+/// This should always be memory-safe; the window server rejects any invalid surface IDs.
+pub struct CGSSurface {
+ context_id: c_uint,
+ window_number: c_int,
+ surface_id: c_uint,
+}
+
+impl CGSSurface {
+ #[inline]
+ pub fn from_ids(context_id: c_uint, window_number: c_int, surface_id: c_uint) -> CGSSurface {
+ CGSSurface {
+ context_id: context_id,
+ window_number: window_number,
+ surface_id: surface_id,
+ }
+ }
+
+ #[inline]
+ pub fn id(&self) -> c_uint {
+ self.surface_id
+ }
+
+ #[inline]
+ pub fn set_shape(&self, region: &CGSRegion) {
+ unsafe {
+ assert!(ffi::CGSSetSurfaceShape(self.context_id,
+ self.window_number,
+ self.surface_id,
+ region.region) == 0)
+ }
+ }
+}
+
+mod ffi {
+ use geometry::CGRect;
+ use libc::{c_int, c_uint};
+
+ // This is an enum so that we can't easily make instances of this opaque type.
+ pub enum CGSRegionObject {}
+
+ pub type CGError = OSStatus;
+ pub type CGSRegionRef = *mut CGSRegionObject;
+ pub type OSStatus = i32;
+
+ #[link(name = "CoreGraphics", kind = "framework")]
+ extern {
+ pub fn CGSRegionRelease(region: CGSRegionRef);
+ pub fn CGSNewRegionWithRect(rect: *const CGRect, outRegion: *mut CGSRegionRef) -> CGError;
+ pub fn CGSNewRegionWithRectList(rects: *const CGRect,
+ rectCount: c_uint,
+ outRegion: *mut CGSRegionRef)
+ -> CGError;
+
+ pub fn CGSSetSurfaceShape(contextID: c_uint,
+ windowNumber: c_int,
+ surfaceID: c_uint,
+ region: CGSRegionRef)
+ -> CGError;
+ }
+}
+
diff --git a/third_party/rust/core-graphics/src/sys.rs b/third_party/rust/core-graphics/src/sys.rs
new file mode 100644
index 0000000000..85df442d5f
--- /dev/null
+++ b/third_party/rust/core-graphics/src/sys.rs
@@ -0,0 +1,44 @@
+use std::os::raw::c_void;
+
+pub enum CGImage {}
+pub type CGImageRef = *mut CGImage;
+
+#[repr(C)]
+pub struct __CGColor(c_void);
+
+pub type CGColorRef = *const __CGColor;
+
+pub enum CGColorSpace {}
+pub type CGColorSpaceRef = *mut CGColorSpace;
+
+pub enum CGPath {}
+pub type CGPathRef = *mut CGPath;
+
+pub enum CGDataProvider {}
+pub type CGDataProviderRef = *mut CGDataProvider;
+
+pub enum CGFont {}
+pub type CGFontRef = *mut CGFont;
+
+pub enum CGContext {}
+pub type CGContextRef = *mut CGContext;
+
+pub enum CGGradient {}
+pub type CGGradientRef = *mut CGGradient;
+
+#[cfg(target_os = "macos")]
+mod macos {
+ pub enum CGEventTap {}
+ pub type CGEventTapRef = core_foundation::mach_port::CFMachPortRef;
+ pub enum CGEvent {}
+ pub type CGEventRef = *mut CGEvent;
+
+ pub enum CGEventSource {}
+ pub type CGEventSourceRef = *mut CGEventSource;
+
+ pub enum CGDisplayMode {}
+ pub type CGDisplayModeRef = *mut CGDisplayMode;
+}
+
+#[cfg(target_os = "macos")]
+pub use self::macos::*;
diff --git a/third_party/rust/core-graphics/src/window.rs b/third_party/rust/core-graphics/src/window.rs
new file mode 100644
index 0000000000..aa7293ff7f
--- /dev/null
+++ b/third_party/rust/core-graphics/src/window.rs
@@ -0,0 +1,149 @@
+// Copyright 2018 The Servo Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![allow(non_upper_case_globals)]
+
+use core_foundation::array::{CFArray, CFArrayRef};
+use core_foundation::base::{CFType, TCFType};
+use core_foundation::dictionary::CFDictionary;
+use core_foundation::string::{CFString, CFStringRef};
+use foreign_types::ForeignType;
+
+use geometry::CGRect;
+use image::CGImage;
+use sys;
+
+pub type CGWindowID = u32;
+
+pub type CGWindowSharingType = u32;
+pub const kCGWindowSharingNone: CGWindowSharingType = 0;
+pub const kCGWindowSharingReadOnly: CGWindowSharingType = 1;
+pub const kCGWindowSharingReadWrite: CGWindowSharingType = 1;
+
+pub type CGWindowBackingType = u32;
+pub const kCGWindowBackingStoreRetained: CGWindowBackingType = 0;
+pub const kCGWindowBackingStoreNonretained: CGWindowBackingType = 1;
+pub const kCGWindowBackingStoreBuffered: CGWindowBackingType = 2;
+
+pub type CGWindowListOption = u32;
+pub const kCGWindowListOptionAll: CGWindowListOption = 1 << 0;
+pub const kCGWindowListOptionOnScreenOnly: CGWindowListOption = 1 << 1;
+pub const kCGWindowListOptionOnScreenAboveWindow: CGWindowListOption = 1 << 2;
+pub const kCGWindowListOptionOnScreenBelowWindow: CGWindowListOption = 1 << 3;
+pub const kCGWindowListOptionIncludingWindow: CGWindowListOption = 1 << 4;
+pub const kCGWindowListOptionExcludeDesktopElements: CGWindowListOption = 1 << 5;
+
+pub type CGWindowImageOption = u32;
+pub const kCGWindowImageDefault: CGWindowImageOption = 0;
+pub const kCGWindowImageBoundsIgnoreFraming: CGWindowImageOption = 1 << 0;
+pub const kCGWindowImageShouldBeOpaque: CGWindowImageOption = 1 << 1;
+pub const kCGWindowImageOnlyShadows: CGWindowImageOption = 1 << 2;
+pub const kCGWindowImageBestResolution: CGWindowImageOption = 1 << 3;
+pub const kCGWindowImageNominalResolution: CGWindowImageOption = 1 << 4;
+
+pub const kCGNullWindowID: CGWindowID = 0;
+
+pub fn copy_window_info(option: CGWindowListOption, relative_to_window: CGWindowID)
+ -> Option<CFArray> {
+ unsafe {
+ let array = CGWindowListCopyWindowInfo(option, relative_to_window);
+ if array.is_null() {
+ None
+ } else {
+ Some(TCFType::wrap_under_create_rule(array))
+ }
+ }
+}
+
+pub fn create_window_list(option: CGWindowListOption, relative_to_window: CGWindowID)
+ -> Option<CFArray<CGWindowID>> {
+ unsafe {
+ let array = CGWindowListCreate(option, relative_to_window);
+ if array.is_null() {
+ None
+ } else {
+ Some(TCFType::wrap_under_create_rule(array))
+ }
+ }
+}
+
+pub fn create_description_from_array(window_array: CFArray<CGWindowID>) ->
+ Option<CFArray<CFDictionary<CFString, CFType>>> {
+ unsafe {
+ let array = CGWindowListCreateDescriptionFromArray(window_array.as_concrete_TypeRef());
+ if array.is_null() {
+ None
+ } else {
+ Some(TCFType::wrap_under_create_rule(array))
+ }
+ }
+}
+
+pub fn create_image(screen_bounds: CGRect,
+ list_option: CGWindowListOption,
+ window_id: CGWindowID,
+ image_option: CGWindowImageOption)
+ -> Option<CGImage> {
+ unsafe {
+ let image = CGWindowListCreateImage(screen_bounds, list_option, window_id, image_option);
+ if image.is_null() {
+ None
+ } else {
+ Some(CGImage::from_ptr(image))
+ }
+ }
+}
+
+pub fn create_image_from_array(screen_bounds: CGRect,
+ window_array: CFArray,
+ image_option: CGWindowImageOption)
+ -> Option<CGImage> {
+ unsafe {
+ let image = CGWindowListCreateImageFromArray(screen_bounds,
+ window_array.as_concrete_TypeRef(),
+ image_option);
+ if image.is_null() {
+ None
+ } else {
+ Some(CGImage::from_ptr(image))
+ }
+ }
+}
+
+#[link(name = "CoreGraphics", kind = "framework")]
+extern {
+ pub static kCGWindowNumber: CFStringRef;
+ pub static kCGWindowStoreType: CFStringRef;
+ pub static kCGWindowLayer: CFStringRef;
+ pub static kCGWindowBounds: CFStringRef;
+ pub static kCGWindowSharingState: CFStringRef;
+ pub static kCGWindowAlpha: CFStringRef;
+ pub static kCGWindowOwnerPID: CFStringRef;
+ pub static kCGWindowMemoryUsage: CFStringRef;
+ pub static kCGWindowWorkspace: CFStringRef;
+ pub static kCGWindowOwnerName: CFStringRef;
+ pub static kCGWindowName: CFStringRef;
+ pub static kCGWindowIsOnscreen: CFStringRef;
+ pub static kCGWindowBackingLocationVideoMemory: CFStringRef;
+
+ pub fn CGWindowListCopyWindowInfo(option: CGWindowListOption, relativeToWindow: CGWindowID)
+ -> CFArrayRef;
+ pub fn CGWindowListCreate(option: CGWindowListOption, relativeToWindow: CGWindowID)
+ -> CFArrayRef;
+ pub fn CGWindowListCreateDescriptionFromArray(windowArray: CFArrayRef) -> CFArrayRef;
+ pub fn CGWindowListCreateImage(screenBounds: CGRect,
+ listOption: CGWindowListOption,
+ windowID: CGWindowID,
+ imageOption: CGWindowImageOption)
+ -> *mut sys::CGImage;
+ pub fn CGWindowListCreateImageFromArray(screenBounds: CGRect,
+ windowArray: CFArrayRef,
+ imageOption: CGWindowImageOption)
+ -> *mut sys::CGImage;
+}