Import core-graphics.
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
*~
|
||||
*#
|
||||
*.o
|
||||
*.a
|
||||
*.so
|
||||
*.dylib
|
||||
*.dSYM
|
||||
*.dll
|
||||
*.dummy
|
||||
cocoa-test
|
||||
build
|
||||
/target
|
||||
/doc
|
||||
/Cargo.lock
|
||||
@@ -0,0 +1,13 @@
|
||||
language: rust
|
||||
os: osx
|
||||
rust:
|
||||
- nightly
|
||||
- beta
|
||||
- stable
|
||||
|
||||
script:
|
||||
- cargo test
|
||||
- cargo test --features="elcapitan"
|
||||
|
||||
notifications:
|
||||
webhooks: http://build.servo.org:54856/travis
|
||||
@@ -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.
|
||||
@@ -0,0 +1,18 @@
|
||||
[package]
|
||||
name = "core-graphics"
|
||||
description = "Bindings to Core Graphics for OS X"
|
||||
homepage = "https://github.com/servo/core-graphics-rs"
|
||||
repository = "https://github.com/servo/core-graphics-rs"
|
||||
version = "0.13.0"
|
||||
authors = ["The Servo Project Developers"]
|
||||
license = "MIT / Apache-2.0"
|
||||
|
||||
[features]
|
||||
default = []
|
||||
elcapitan = []
|
||||
|
||||
[dependencies]
|
||||
bitflags = "1.0"
|
||||
core-foundation = "0.5"
|
||||
foreign-types = "0.3.0"
|
||||
libc = "0.2"
|
||||
@@ -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.
|
||||
@@ -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.
|
||||
@@ -0,0 +1,3 @@
|
||||
# core-graphics-rs
|
||||
|
||||
[](https://travis-ci.org/servo/core-graphics-rs)
|
||||
@@ -0,0 +1,53 @@
|
||||
// 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)]
|
||||
|
||||
use libc;
|
||||
|
||||
#[cfg(any(target_arch = "x86",
|
||||
target_arch = "arm",
|
||||
target_arch = "aarch64"))]
|
||||
pub type boolean_t = libc::c_int;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
pub type boolean_t = libc::c_uint;
|
||||
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
pub type CGFloat = libc::c_double;
|
||||
#[cfg(not(target_pointer_width = "64"))]
|
||||
pub type CGFloat = libc::c_float;
|
||||
|
||||
pub type CGError = libc::int32_t;
|
||||
|
||||
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);
|
||||
|
||||
#[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;
|
||||
@@ -0,0 +1,59 @@
|
||||
// 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}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create_device_rgb() -> CGColorSpace {
|
||||
unsafe {
|
||||
let result = CGColorSpaceCreateDeviceRGB();
|
||||
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 CGColorSpaceCreateWithName(name: CFStringRef) -> ::sys::CGColorSpaceRef;
|
||||
fn CGColorSpaceGetTypeID() -> CFTypeID;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,284 @@
|
||||
// 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::{CFRelease, CFRetain, CFTypeID};
|
||||
use font::{CGFont, CGGlyph};
|
||||
use geometry::CGPoint;
|
||||
use libc::{c_void, c_int, size_t};
|
||||
|
||||
use std::cmp;
|
||||
use std::ptr;
|
||||
use std::slice;
|
||||
use geometry::{CGAffineTransform, CGRect};
|
||||
use image::CGImage;
|
||||
use foreign_types::ForeignType;
|
||||
|
||||
#[repr(C)]
|
||||
pub enum CGTextDrawingMode {
|
||||
CGTextFill,
|
||||
CGTextStroke,
|
||||
CGTextFillStroke,
|
||||
CGTextInvisible,
|
||||
CGTextFillClip,
|
||||
CGTextStrokeClip,
|
||||
CGTextClip
|
||||
}
|
||||
|
||||
foreign_type! {
|
||||
#[doc(hidden)]
|
||||
type CType = ::sys::CGContext;
|
||||
fn drop = |cs| CFRelease(cs as *mut _);
|
||||
fn clone = |p| CFRetain(p as *const _) as *mut _;
|
||||
pub struct CGContext;
|
||||
pub struct CGContextRef;
|
||||
}
|
||||
|
||||
impl CGContext {
|
||||
pub fn type_id() -> CFTypeID {
|
||||
unsafe {
|
||||
CGContextGetTypeID()
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
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 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_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 fill_rect(&self, rect: CGRect) {
|
||||
unsafe {
|
||||
CGContextFillRect(self.as_ptr(), rect)
|
||||
}
|
||||
}
|
||||
|
||||
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 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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[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.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 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 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 CGContextSetRGBFillColor(context: ::sys::CGContextRef,
|
||||
red: CGFloat,
|
||||
green: CGFloat,
|
||||
blue: CGFloat,
|
||||
alpha: CGFloat);
|
||||
fn CGContextFillRect(context: ::sys::CGContextRef,
|
||||
rect: CGRect);
|
||||
fn CGContextDrawImage(c: ::sys::CGContextRef, rect: CGRect, image: ::sys::CGImageRef);
|
||||
fn CGContextSetFont(c: ::sys::CGContextRef, font: ::sys::CGFontRef);
|
||||
fn CGContextSetFontSize(c: ::sys::CGContextRef, size: CGFloat);
|
||||
fn CGContextSetTextMatrix(c: ::sys::CGContextRef, t: CGAffineTransform);
|
||||
fn CGContextShowGlyphsAtPositions(c: ::sys::CGContextRef,
|
||||
glyphs: *const CGGlyph,
|
||||
positions: *const CGPoint,
|
||||
count: size_t);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
// 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::{c_void, size_t, off_t};
|
||||
use std::mem;
|
||||
use std::sync::Arc;
|
||||
|
||||
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(buffer: Arc<Vec<u8>>) -> Self {
|
||||
unsafe {
|
||||
let ptr = (*buffer).as_ptr() as *const c_void;
|
||||
let len = buffer.len() as size_t;
|
||||
let info = mem::transmute::<Arc<Vec<u8>>, *mut c_void>(buffer);
|
||||
let result = CGDataProviderCreateWithData(info, ptr, len, Some(release));
|
||||
return CGDataProvider::from_ptr(result);
|
||||
}
|
||||
|
||||
unsafe extern "C" fn release(info: *mut c_void, _: *const c_void, _: size_t) {
|
||||
drop(mem::transmute::<*mut c_void, Arc<Vec<u8>>>(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())) }
|
||||
}
|
||||
}
|
||||
|
||||
#[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;
|
||||
}
|
||||
@@ -0,0 +1,468 @@
|
||||
// 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;
|
||||
pub use base::{CGError, boolean_t};
|
||||
pub use geometry::{CGRect, CGPoint, CGSize};
|
||||
|
||||
use core_foundation::base::{CFRetain, TCFType};
|
||||
use image::CGImage;
|
||||
use foreign_types::ForeignType;
|
||||
|
||||
pub type CGDirectDisplayID = libc::uint32_t;
|
||||
pub type CGWindowID = libc::uint32_t;
|
||||
|
||||
pub const kCGNullWindowID: CGWindowID = 0 as CGWindowID;
|
||||
|
||||
|
||||
pub type CGWindowListOption = libc::uint32_t;
|
||||
|
||||
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 = libc::uint32_t;
|
||||
|
||||
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 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 };
|
||||
|
||||
#[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() })
|
||||
}
|
||||
|
||||
/// 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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 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 != ptr::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 = try!(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: libc::uint32_t = 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 {
|
||||
#[inline]
|
||||
pub fn height(&self) -> u64 {
|
||||
unsafe { CGDisplayModeGetHeight(self.as_ptr()) as u64 }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn width(&self) -> u64 {
|
||||
unsafe { CGDisplayModeGetWidth(self.as_ptr()) as u64 }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn pixel_height(&self) -> u64 {
|
||||
unsafe { CGDisplayModeGetPixelHeight(self.as_ptr()) as u64 }
|
||||
}
|
||||
|
||||
#[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()) }
|
||||
}
|
||||
}
|
||||
|
||||
#[link(name = "CoreGraphics", kind = "framework")]
|
||||
extern "C" {
|
||||
pub static CGRectNull: CGRect;
|
||||
pub static CGRectInfinite: CGRect;
|
||||
|
||||
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) -> libc::uint32_t;
|
||||
pub fn CGDisplayUnitNumber(display: CGDirectDisplayID) -> libc::uint32_t;
|
||||
pub fn CGDisplayUsesOpenGLAcceleration(display: CGDirectDisplayID) -> boolean_t;
|
||||
pub fn CGDisplayVendorNumber(display: CGDirectDisplayID) -> libc::uint32_t;
|
||||
pub fn CGGetActiveDisplayList(
|
||||
max_displays: libc::uint32_t,
|
||||
active_displays: *mut CGDirectDisplayID,
|
||||
display_count: *mut libc::uint32_t,
|
||||
) -> CGError;
|
||||
pub fn CGDisplayModelNumber(display: CGDirectDisplayID) -> libc::uint32_t;
|
||||
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 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;
|
||||
|
||||
// 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;
|
||||
}
|
||||
@@ -0,0 +1,619 @@
|
||||
#![allow(non_upper_case_globals)]
|
||||
|
||||
use core_foundation::base::{CFRelease, CFRetain, CFTypeID};
|
||||
use geometry::CGPoint;
|
||||
use event_source::CGEventSource;
|
||||
|
||||
use libc;
|
||||
|
||||
use foreign_types::ForeignType;
|
||||
|
||||
pub type CGEventField = libc::uint32_t;
|
||||
pub type CGKeyCode = libc::uint16_t;
|
||||
|
||||
/// Flags for events
|
||||
///
|
||||
/// [Ref](http://opensource.apple.com/source/IOHIDFamily/IOHIDFamily-700/IOHIDSystem/IOKit/hidsystem/IOLLEvent.h)
|
||||
bitflags! {
|
||||
#[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;
|
||||
}
|
||||
|
||||
/// Constants that specify the different types of input events.
|
||||
///
|
||||
/// [Ref](http://opensource.apple.com/source/IOHIDFamily/IOHIDFamily-700/IOHIDSystem/IOKit/hidsystem/IOLLEvent.h)
|
||||
#[repr(C)]
|
||||
#[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,
|
||||
}
|
||||
|
||||
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(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
/// 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);
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
// 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 std::ptr;
|
||||
use core_foundation::base::{CFRelease, CFRetain, CFTypeID, TCFType};
|
||||
use core_foundation::array::{CFArray, CFArrayRef};
|
||||
use core_foundation::data::{CFData, CFDataRef};
|
||||
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::{self, c_int, size_t};
|
||||
|
||||
pub type CGGlyph = libc::c_ushort;
|
||||
|
||||
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) -> 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 != ptr::null() {
|
||||
Some(unsafe { TCFType::wrap_under_create_rule(data_ref) })
|
||||
} 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;
|
||||
}
|
||||
@@ -0,0 +1,195 @@
|
||||
// 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 base::CGFloat;
|
||||
use core_foundation::base::TCFType;
|
||||
use core_foundation::dictionary::CFDictionary;
|
||||
|
||||
pub const CG_ZERO_POINT: CGPoint = CGPoint {
|
||||
x: 0.0,
|
||||
y: 0.0,
|
||||
};
|
||||
|
||||
pub const CG_ZERO_SIZE: CGSize = CGSize {
|
||||
width: 0.0,
|
||||
height: 0.0,
|
||||
};
|
||||
|
||||
pub const CG_ZERO_RECT: CGRect = CGRect {
|
||||
origin: CG_ZERO_POINT,
|
||||
size: CG_ZERO_SIZE,
|
||||
};
|
||||
|
||||
pub const CG_AFFINE_TRANSFORM_IDENTITY: CGAffineTransform = CGAffineTransform {
|
||||
a: 1.0, b: 0.0,
|
||||
c: 0.0, d: 1.0,
|
||||
tx: 0.0, ty: 0.0,
|
||||
};
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy, Debug, Default)]
|
||||
pub struct CGSize {
|
||||
pub width: CGFloat,
|
||||
pub height: CGFloat,
|
||||
}
|
||||
|
||||
impl CGSize {
|
||||
#[inline]
|
||||
pub fn new(width: CGFloat, height: CGFloat) -> CGSize {
|
||||
CGSize {
|
||||
width: width,
|
||||
height: height,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn apply_transform(&self, t: &CGAffineTransform) -> CGSize {
|
||||
unsafe {
|
||||
ffi::CGSizeApplyAffineTransform(*self, *t)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy, Debug, Default)]
|
||||
pub struct CGPoint {
|
||||
pub x: CGFloat,
|
||||
pub y: CGFloat,
|
||||
}
|
||||
|
||||
impl CGPoint {
|
||||
#[inline]
|
||||
pub fn new(x: CGFloat, y: CGFloat) -> CGPoint {
|
||||
CGPoint {
|
||||
x: x,
|
||||
y: y,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn apply_transform(&self, t: &CGAffineTransform) -> CGPoint {
|
||||
unsafe {
|
||||
ffi::CGPointApplyAffineTransform(*self, *t)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy, Debug, Default)]
|
||||
pub struct CGRect {
|
||||
pub origin: CGPoint,
|
||||
pub size: CGSize
|
||||
}
|
||||
|
||||
impl CGRect {
|
||||
#[inline]
|
||||
pub fn new(origin: &CGPoint, size: &CGSize) -> CGRect {
|
||||
CGRect {
|
||||
origin: *origin,
|
||||
size: *size,
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn inset(&self, size: &CGSize) -> CGRect {
|
||||
unsafe {
|
||||
ffi::CGRectInset(*self, size.width, size.height)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn from_dict_representation(dict: &CFDictionary) -> Option<CGRect> {
|
||||
let mut rect = CGRect::new(&CGPoint::new(0., 0.), &CGSize::new(0., 0.));
|
||||
let result = unsafe {
|
||||
ffi::CGRectMakeWithDictionaryRepresentation(dict.as_concrete_TypeRef(), &mut rect)
|
||||
};
|
||||
if result == 0 {
|
||||
None
|
||||
} else {
|
||||
Some(rect)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_empty(&self) -> bool {
|
||||
unsafe {
|
||||
// I use one, as it seems that `YES` is not available from this crate.
|
||||
ffi::CGRectIsEmpty(*self) == 1
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_intersects(&self, other: &CGRect) -> bool {
|
||||
unsafe {
|
||||
// I use one, as it seems that `YES` is not available from this crate.
|
||||
ffi::CGRectIntersectsRect(*self, *other) == 1
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn apply_transform(&self, t: &CGAffineTransform) -> CGRect {
|
||||
unsafe {
|
||||
ffi::CGRectApplyAffineTransform(*self, *t)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy, Debug, Default)]
|
||||
pub struct CGAffineTransform {
|
||||
pub a: CGFloat,
|
||||
pub b: CGFloat,
|
||||
pub c: CGFloat,
|
||||
pub d: CGFloat,
|
||||
pub tx: CGFloat,
|
||||
pub ty: CGFloat,
|
||||
}
|
||||
|
||||
impl CGAffineTransform {
|
||||
#[inline]
|
||||
pub fn new(
|
||||
a: CGFloat,
|
||||
b: CGFloat,
|
||||
c: CGFloat,
|
||||
d: CGFloat,
|
||||
tx: CGFloat,
|
||||
ty: CGFloat,
|
||||
) -> CGAffineTransform {
|
||||
CGAffineTransform { a, b, c, d, tx, ty }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn invert(&self) -> CGAffineTransform {
|
||||
unsafe {
|
||||
ffi::CGAffineTransformInvert(*self)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mod ffi {
|
||||
use base::{CGFloat, boolean_t};
|
||||
use geometry::{CGAffineTransform, CGPoint, CGRect, CGSize};
|
||||
use core_foundation::dictionary::CFDictionaryRef;
|
||||
|
||||
#[link(name = "CoreGraphics", kind = "framework")]
|
||||
extern {
|
||||
pub fn CGRectInset(rect: CGRect, dx: CGFloat, dy: CGFloat) -> CGRect;
|
||||
pub fn CGRectMakeWithDictionaryRepresentation(dict: CFDictionaryRef,
|
||||
rect: *mut CGRect) -> boolean_t;
|
||||
pub fn CGRectIsEmpty(rect: CGRect) -> boolean_t;
|
||||
pub fn CGRectIntersectsRect(rect1: CGRect, rect2: CGRect) -> boolean_t;
|
||||
|
||||
pub fn CGAffineTransformInvert(t: CGAffineTransform) -> CGAffineTransform;
|
||||
|
||||
pub fn CGPointApplyAffineTransform(point: CGPoint, t: CGAffineTransform) -> CGPoint;
|
||||
pub fn CGRectApplyAffineTransform(rect: CGRect, t: CGAffineTransform) -> CGRect;
|
||||
pub fn CGSizeApplyAffineTransform(size: CGSize, t: CGAffineTransform) -> CGSize;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,109 @@
|
||||
use core_foundation::base::{CFRetain, CFTypeID};
|
||||
use core_foundation::data::CFData;
|
||||
use color_space::CGColorSpace;
|
||||
use data_provider::CGDataProviderRef;
|
||||
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 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()
|
||||
}
|
||||
}
|
||||
|
||||
#[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 CGImageGetAlphaInfo(image: ::sys::CGImageRef) -> CGImageAlphaInfo;
|
||||
//fn CGImageCreateCopyWithColorSpace(image: ::sys::CGImageRef, space: ::sys::CGColorSpaceRef) -> ::sys::CGImageRef
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
// 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;
|
||||
extern crate core_foundation;
|
||||
|
||||
#[macro_use]
|
||||
#[cfg(target_os = "macos")]
|
||||
extern crate bitflags;
|
||||
|
||||
#[macro_use]
|
||||
extern crate foreign_types;
|
||||
|
||||
pub mod base;
|
||||
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;
|
||||
#[cfg(target_os = "macos")]
|
||||
pub mod private;
|
||||
pub mod image;
|
||||
pub mod path;
|
||||
mod sys;
|
||||
@@ -0,0 +1,115 @@
|
||||
// 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.
|
||||
|
||||
use core_foundation::base::{CFRelease, CFRetain, CFTypeID};
|
||||
use foreign_types::ForeignType;
|
||||
use geometry::CGPoint;
|
||||
use libc::c_void;
|
||||
use std::fmt::{self, Debug, Formatter};
|
||||
use std::marker::PhantomData;
|
||||
use std::ops::Deref;
|
||||
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 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 CGPathApply(path: ::sys::CGPathRef, info: *mut c_void, function: CGPathApplierFunction);
|
||||
fn CGPathGetTypeID() -> CFTypeID;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
pub enum CGImage {}
|
||||
pub type CGImageRef = *mut CGImage;
|
||||
|
||||
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;
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
mod macos {
|
||||
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::*;
|
||||
Reference in New Issue
Block a user