Vendor dependencies for 0.3.0 release

This commit is contained in:
2025-09-27 10:29:08 -05:00
parent 0c8d39d483
commit 82ab7f317b
26803 changed files with 16134934 additions and 0 deletions

26
vendor/core-graphics/src/access.rs vendored Normal file
View File

@@ -0,0 +1,26 @@
pub use crate::base::boolean_t;
#[derive(Default)]
pub struct ScreenCaptureAccess;
impl ScreenCaptureAccess {
/// If current app not in list, will open window.
/// Return the same result as preflight.
#[inline]
pub fn request(&self) -> bool {
unsafe { CGRequestScreenCaptureAccess() == 1 }
}
/// Return `true` if has access
#[inline]
pub fn preflight(&self) -> bool {
unsafe { CGPreflightScreenCaptureAccess() == 1 }
}
}
#[cfg_attr(feature = "link", link(name = "CoreGraphics", kind = "framework"))]
extern "C" {
// Screen Capture Access
fn CGRequestScreenCaptureAccess() -> boolean_t;
fn CGPreflightScreenCaptureAccess() -> boolean_t;
}

45
vendor/core-graphics/src/base.rs vendored Normal file
View File

@@ -0,0 +1,45 @@
// Copyright 2013 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// this file defines CGFloat, as well as stubbed data types.
#![allow(non_camel_case_types)]
#![allow(non_upper_case_globals)]
pub use core_graphics_types::base::*;
pub const kCGImageAlphaNone: u32 = 0;
pub const kCGImageAlphaPremultipliedLast: u32 = 1;
pub const kCGImageAlphaPremultipliedFirst: u32 = 2;
pub const kCGImageAlphaLast: u32 = 3;
pub const kCGImageAlphaFirst: u32 = 4;
pub const kCGImageAlphaNoneSkipLast: u32 = 5;
pub const kCGImageAlphaNoneSkipFirst: u32 = 6;
pub const kCGBitmapByteOrderDefault: u32 = 0 << 12;
pub const kCGBitmapByteOrder16Little: u32 = 1 << 12;
pub const kCGBitmapByteOrder32Little: u32 = 2 << 12;
pub const kCGBitmapByteOrder16Big: u32 = 3 << 12;
pub const kCGBitmapByteOrder32Big: u32 = 4 << 12;
pub const kCGRenderingIntentDefault: u32 = 0;
pub const kCGRenderingIntentAbsoluteColorimetric: u32 = 1;
pub const kCGRenderingIntentRelativeColorimetric: u32 = 2;
pub const kCGRenderingIntentPerceptual: u32 = 3;
pub const kCGRenderingIntentSaturation: u32 = 4;
#[cfg(target_endian = "big")]
pub const kCGBitmapByteOrder16Host: u32 = kCGBitmapByteOrder16Big;
#[cfg(target_endian = "big")]
pub const kCGBitmapByteOrder32Host: u32 = kCGBitmapByteOrder32Big;
#[cfg(target_endian = "little")]
pub const kCGBitmapByteOrder16Host: u32 = kCGBitmapByteOrder16Little;
#[cfg(target_endian = "little")]
pub const kCGBitmapByteOrder32Host: u32 = kCGBitmapByteOrder32Little;

40
vendor/core-graphics/src/color.rs vendored Normal file
View File

@@ -0,0 +1,40 @@
// 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 super::sys::CGColorRef;
use crate::base::CGFloat;
use core_foundation::base::CFTypeID;
use core_foundation::base::TCFType;
pub use super::sys::CGColorRef as SysCGColorRef;
declare_TCFType! {
CGColor, CGColorRef
}
impl_TCFType!(CGColor, CGColorRef, CGColorGetTypeID);
impl CGColor {
pub fn rgb(red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat) -> Self {
unsafe {
let ptr = CGColorCreateGenericRGB(red, green, blue, alpha);
CGColor::wrap_under_create_rule(ptr)
}
}
}
#[cfg_attr(feature = "link", link(name = "CoreGraphics", kind = "framework"))]
extern "C" {
fn CGColorCreateGenericRGB(
red: CGFloat,
green: CGFloat,
blue: CGFloat,
alpha: CGFloat,
) -> crate::sys::CGColorRef;
fn CGColorGetTypeID() -> CFTypeID;
}

118
vendor/core-graphics/src/color_space.rs vendored Normal file
View File

@@ -0,0 +1,118 @@
// 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)]
pub unsafe type CGColorSpace {
type CType = crate::sys::CGColorSpace;
fn drop = |p| CFRelease(p as *mut _);
fn clone = |p| CFRetain(p as *const _) as *mut _;
}
}
impl CGColorSpace {
pub fn type_id() -> CFTypeID {
unsafe { CGColorSpaceGetTypeID() }
}
pub fn create_with_name(name: CFStringRef) -> Option<CGColorSpace> {
unsafe {
let p = CGColorSpaceCreateWithName(name);
if !p.is_null() {
Some(CGColorSpace::from_ptr(p))
} else {
None
}
}
}
#[inline]
pub fn create_device_rgb() -> CGColorSpace {
unsafe {
let result = CGColorSpaceCreateDeviceRGB();
CGColorSpace::from_ptr(result)
}
}
#[inline]
pub fn create_device_gray() -> CGColorSpace {
unsafe {
let result = CGColorSpaceCreateDeviceGray();
CGColorSpace::from_ptr(result)
}
}
}
#[cfg_attr(feature = "link", link(name = "CoreGraphics", kind = "framework"))]
extern "C" {
/// The Display P3 color space, created by Apple.
pub static kCGColorSpaceDisplayP3: CFStringRef;
/// The Display P3 color space, using the HLG transfer function.
pub static kCGColorSpaceDisplayP3_HLG: CFStringRef;
/// The Display P3 color space with a linear transfer function
/// and extended-range values.
pub static kCGColorSpaceExtendedLinearDisplayP3: CFStringRef;
/// The standard Red Green Blue (sRGB) color space.
pub static kCGColorSpaceSRGB: CFStringRef;
/// The sRGB color space with a linear transfer function.
pub static kCGColorSpaceLinearSRGB: CFStringRef;
/// The extended sRGB color space.
pub static kCGColorSpaceExtendedSRGB: CFStringRef;
/// The sRGB color space with a linear transfer function and
/// extended-range values.
pub static kCGColorSpaceExtendedLinearSRGB: CFStringRef;
/// The generic gray color space that has an exponential transfer
/// function with a power of 2.2.
pub static kCGColorSpaceGenericGrayGamma2_2: CFStringRef;
/// The gray color space using a linear transfer function.
pub static kCGColorSpaceLinearGray: CFStringRef;
/// The extended gray color space.
pub static kCGColorSpaceExtendedGray: CFStringRef;
/// The extended gray color space with a linear transfer function.
pub static kCGColorSpaceExtendedLinearGray: CFStringRef;
/// The generic RGB color space with a linear transfer function.
pub static kCGColorSpaceGenericRGBLinear: CFStringRef;
/// The generic CMYK color space.
pub static kCGColorSpaceGenericCMYK: CFStringRef;
/// The XYZ color space, as defined by the CIE 1931 standard.
pub static kCGColorSpaceGenericXYZ: CFStringRef;
/// The generic LAB color space.
pub static kCGColorSpaceGenericLab: CFStringRef;
/// The ACEScg color space.
pub static kCGColorSpaceACESCGLinear: CFStringRef;
/// The Adobe RGB (1998) color space.
pub static kCGColorSpaceAdobeRGB1998: CFStringRef;
/// The DCI P3 color space, which is the digital cinema standard.
pub static kCGColorSpaceDCIP3: CFStringRef;
/// The recommendation of the International Telecommunication Union
/// (ITU) Radiocommunication sector for the BT.709 color space.
pub static kCGColorSpaceITUR_709: CFStringRef;
/// The Reference Output Medium Metric (ROMM) RGB color space.
pub static kCGColorSpaceROMMRGB: CFStringRef;
/// The recommendation of the International Telecommunication Union
/// (ITU) Radiocommunication sector for the BT.2020 color space.
pub static kCGColorSpaceITUR_2020: CFStringRef;
/// The recommendation of the International Telecommunication Union
/// (ITU) Radiocommunication sector for the BT.2020 color space, with
/// a linear transfer function and extended range values.
pub static kCGColorSpaceExtendedLinearITUR_2020: CFStringRef;
/// The name of the generic RGB color space.
pub static kCGColorSpaceGenericRGB: CFStringRef;
/// The name of the generic gray color space.
pub static kCGColorSpaceGenericGray: CFStringRef;
fn CGColorSpaceCreateDeviceRGB() -> crate::sys::CGColorSpaceRef;
fn CGColorSpaceCreateDeviceGray() -> crate::sys::CGColorSpaceRef;
fn CGColorSpaceCreateWithName(name: CFStringRef) -> crate::sys::CGColorSpaceRef;
fn CGColorSpaceGetTypeID() -> CFTypeID;
}

793
vendor/core-graphics/src/context.rs vendored Normal file
View File

@@ -0,0 +1,793 @@
// 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 crate::base::CGFloat;
use crate::color::CGColor;
use crate::color_space::CGColorSpace;
use crate::font::{CGFont, CGGlyph};
use crate::geometry::{CGPoint, CGSize};
use crate::gradient::{CGGradient, CGGradientDrawingOptions};
use crate::path::CGPathRef;
use core_foundation::base::{CFTypeID, TCFType};
use libc::{c_int, size_t};
use std::os::raw::c_void;
use crate::geometry::{CGAffineTransform, CGRect};
use crate::image::CGImage;
use foreign_types::{ForeignType, ForeignTypeRef};
use std::cmp;
use std::ptr;
use std::slice;
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub enum CGBlendMode {
Normal = 0,
Multiply,
Screen,
Overlay,
Darken,
Lighten,
ColorDodge,
ColorBurn,
SoftLight,
HardLight,
Difference,
Exclusion,
Hue,
Saturation,
Color,
Luminosity,
// 10.5 and up:
Clear,
Copy,
SourceIn,
SourceOut,
SourceAtop,
DestinationOver,
DestinationIn,
DestinationOut,
DestinationAtop,
Xor,
PlusDarker,
PlusLighter,
}
#[repr(C)]
pub enum CGTextDrawingMode {
CGTextFill,
CGTextStroke,
CGTextFillStroke,
CGTextInvisible,
CGTextFillClip,
CGTextStrokeClip,
CGTextFillStrokeClip,
CGTextClip,
}
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub enum CGLineCap {
CGLineCapButt,
CGLineCapRound,
CGLineCapSquare,
}
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub enum CGLineJoin {
CGLineJoinMiter,
CGLineJoinRound,
CGLineJoinBevel,
}
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub enum CGPathDrawingMode {
CGPathFill,
CGPathEOFill,
CGPathStroke,
CGPathFillStroke,
CGPathEOFillStroke,
}
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub enum CGInterpolationQuality {
CGInterpolationQualityDefault,
CGInterpolationQualityNone,
CGInterpolationQualityLow,
CGInterpolationQualityMedium,
CGInterpolationQualityHigh,
}
foreign_type! {
#[doc(hidden)]
pub unsafe type CGContext {
type CType = crate::sys::CGContext;
fn drop = |cs| CGContextRelease(cs);
fn clone = |p| CGContextRetain(p);
}
}
impl CGContext {
pub fn type_id() -> CFTypeID {
unsafe { CGContextGetTypeID() }
}
/// Creates a `CGContext` instance from an existing [`CGContextRef`] pointer.
///
/// This funtion will internally call [`CGRetain`] and hence there is no need to call it explicitly.
///
/// This function is particularly useful for cases when the context is not instantiated/managed
/// by the caller, but it's retrieve via other means (e.g., by calling the method [`NSGraphicsContext::CGContext`]
/// in a cocoa application).
///
/// [`CGContextRef`]: https://developer.apple.com/documentation/coregraphics/cgcontextref
/// [`CGRetain`]: https://developer.apple.com/documentation/coregraphics/1586506-cgcontextretain
/// [`NSGraphicsContext::CGContext`]: https://developer.apple.com/documentation/appkit/nsgraphicscontext/1535352-currentcontext
pub unsafe fn from_existing_context_ptr(ctx: *mut crate::sys::CGContext) -> CGContext {
CGContextRetain(ctx);
Self::from_ptr(ctx)
}
pub fn create_bitmap_context(
data: Option<*mut c_void>,
width: size_t,
height: size_t,
bits_per_component: size_t,
bytes_per_row: size_t,
space: &CGColorSpace,
bitmap_info: u32,
) -> CGContext {
unsafe {
let result = CGBitmapContextCreate(
data.unwrap_or(ptr::null_mut()),
width,
height,
bits_per_component,
bytes_per_row,
space.as_ptr(),
bitmap_info,
);
assert!(!result.is_null());
Self::from_ptr(result)
}
}
pub fn data(&mut self) -> &mut [u8] {
unsafe {
slice::from_raw_parts_mut(
CGBitmapContextGetData(self.as_ptr()) as *mut u8,
self.height() * self.bytes_per_row(),
)
}
}
}
impl CGContextRef {
pub fn flush(&self) {
unsafe { CGContextFlush(self.as_ptr()) }
}
pub fn width(&self) -> size_t {
unsafe { CGBitmapContextGetWidth(self.as_ptr()) }
}
pub fn height(&self) -> size_t {
unsafe { CGBitmapContextGetHeight(self.as_ptr()) }
}
pub fn bytes_per_row(&self) -> size_t {
unsafe { CGBitmapContextGetBytesPerRow(self.as_ptr()) }
}
pub fn clip_bounding_box(&self) -> CGRect {
unsafe { CGContextGetClipBoundingBox(self.as_ptr()) }
}
pub fn set_fill_color(&self, color: &CGColor) {
unsafe {
CGContextSetFillColorWithColor(self.as_ptr(), color.as_concrete_TypeRef());
}
}
pub fn set_rgb_fill_color(&self, red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat) {
unsafe { CGContextSetRGBFillColor(self.as_ptr(), red, green, blue, alpha) }
}
pub fn set_rgb_stroke_color(
&self,
red: CGFloat,
green: CGFloat,
blue: CGFloat,
alpha: CGFloat,
) {
unsafe { CGContextSetRGBStrokeColor(self.as_ptr(), red, green, blue, alpha) }
}
pub fn set_gray_fill_color(&self, gray: CGFloat, alpha: CGFloat) {
unsafe { CGContextSetGrayFillColor(self.as_ptr(), gray, alpha) }
}
pub fn set_blend_mode(&self, blend_mode: CGBlendMode) {
unsafe { CGContextSetBlendMode(self.as_ptr(), blend_mode) }
}
pub fn set_allows_font_smoothing(&self, allows_font_smoothing: bool) {
unsafe { CGContextSetAllowsFontSmoothing(self.as_ptr(), allows_font_smoothing) }
}
pub fn set_font_smoothing_style(&self, style: i32) {
unsafe {
CGContextSetFontSmoothingStyle(self.as_ptr(), style as _);
}
}
pub fn set_should_smooth_fonts(&self, should_smooth_fonts: bool) {
unsafe { CGContextSetShouldSmoothFonts(self.as_ptr(), should_smooth_fonts) }
}
pub fn set_allows_antialiasing(&self, allows_antialiasing: bool) {
unsafe { CGContextSetAllowsAntialiasing(self.as_ptr(), allows_antialiasing) }
}
pub fn set_should_antialias(&self, should_antialias: bool) {
unsafe { CGContextSetShouldAntialias(self.as_ptr(), should_antialias) }
}
pub fn set_allows_font_subpixel_quantization(&self, allows_font_subpixel_quantization: bool) {
unsafe {
CGContextSetAllowsFontSubpixelQuantization(
self.as_ptr(),
allows_font_subpixel_quantization,
)
}
}
pub fn set_should_subpixel_quantize_fonts(&self, should_subpixel_quantize_fonts: bool) {
unsafe {
CGContextSetShouldSubpixelQuantizeFonts(self.as_ptr(), should_subpixel_quantize_fonts)
}
}
pub fn set_allows_font_subpixel_positioning(&self, allows_font_subpixel_positioning: bool) {
unsafe {
CGContextSetAllowsFontSubpixelPositioning(
self.as_ptr(),
allows_font_subpixel_positioning,
)
}
}
pub fn set_should_subpixel_position_fonts(&self, should_subpixel_position_fonts: bool) {
unsafe {
CGContextSetShouldSubpixelPositionFonts(self.as_ptr(), should_subpixel_position_fonts)
}
}
pub fn set_text_drawing_mode(&self, mode: CGTextDrawingMode) {
unsafe { CGContextSetTextDrawingMode(self.as_ptr(), mode) }
}
pub fn set_line_cap(&self, cap: CGLineCap) {
unsafe { CGContextSetLineCap(self.as_ptr(), cap) }
}
pub fn set_line_dash(&self, phase: CGFloat, lengths: &[CGFloat]) {
unsafe { CGContextSetLineDash(self.as_ptr(), phase, lengths.as_ptr(), lengths.len()) }
}
pub fn set_line_join(&self, join: CGLineJoin) {
unsafe { CGContextSetLineJoin(self.as_ptr(), join) }
}
pub fn set_line_width(&self, width: CGFloat) {
unsafe { CGContextSetLineWidth(self.as_ptr(), width) }
}
pub fn set_miter_limit(&self, limit: CGFloat) {
unsafe { CGContextSetMiterLimit(self.as_ptr(), limit) }
}
pub fn add_path(&self, path: &CGPathRef) {
unsafe {
CGContextAddPath(self.as_ptr(), path.as_ptr());
}
}
pub fn add_curve_to_point(
&self,
cp1x: CGFloat,
cp1y: CGFloat,
cp2x: CGFloat,
cp2y: CGFloat,
x: CGFloat,
y: CGFloat,
) {
unsafe {
CGContextAddCurveToPoint(self.as_ptr(), cp1x, cp1y, cp2x, cp2y, x, y);
}
}
pub fn add_quad_curve_to_point(&self, cpx: CGFloat, cpy: CGFloat, x: CGFloat, y: CGFloat) {
unsafe {
CGContextAddQuadCurveToPoint(self.as_ptr(), cpx, cpy, x, y);
}
}
pub fn add_line_to_point(&self, x: CGFloat, y: CGFloat) {
unsafe {
CGContextAddLineToPoint(self.as_ptr(), x, y);
}
}
pub fn begin_path(&self) {
unsafe {
CGContextBeginPath(self.as_ptr());
}
}
pub fn close_path(&self) {
unsafe {
CGContextClosePath(self.as_ptr());
}
}
pub fn move_to_point(&self, x: CGFloat, y: CGFloat) {
unsafe {
CGContextMoveToPoint(self.as_ptr(), x, y);
}
}
pub fn clip(&self) {
unsafe {
CGContextClip(self.as_ptr());
}
}
pub fn eo_clip(&self) {
unsafe {
CGContextEOClip(self.as_ptr());
}
}
pub fn reset_clip(&self) {
unsafe {
CGContextResetClip(self.as_ptr());
}
}
pub fn draw_path(&self, mode: CGPathDrawingMode) {
unsafe {
CGContextDrawPath(self.as_ptr(), mode);
}
}
pub fn fill_path(&self) {
unsafe {
CGContextFillPath(self.as_ptr());
}
}
pub fn eo_fill_path(&self) {
unsafe {
CGContextEOFillPath(self.as_ptr());
}
}
pub fn stroke_path(&self) {
unsafe {
CGContextStrokePath(self.as_ptr());
}
}
pub fn fill_rect(&self, rect: CGRect) {
unsafe { CGContextFillRect(self.as_ptr(), rect) }
}
pub fn fill_rects(&self, rects: &[CGRect]) {
unsafe { CGContextFillRects(self.as_ptr(), rects.as_ptr(), rects.len()) }
}
pub fn clear_rect(&self, rect: CGRect) {
unsafe { CGContextClearRect(self.as_ptr(), rect) }
}
pub fn stroke_rect(&self, rect: CGRect) {
unsafe { CGContextStrokeRect(self.as_ptr(), rect) }
}
pub fn stroke_rect_with_width(&self, rect: CGRect, width: CGFloat) {
unsafe { CGContextStrokeRectWithWidth(self.as_ptr(), rect, width) }
}
pub fn clip_to_rect(&self, rect: CGRect) {
unsafe { CGContextClipToRect(self.as_ptr(), rect) }
}
pub fn clip_to_rects(&self, rects: &[CGRect]) {
unsafe { CGContextClipToRects(self.as_ptr(), rects.as_ptr(), rects.len()) }
}
pub fn clip_to_mask(&self, rect: CGRect, image: &CGImage) {
unsafe { CGContextClipToMask(self.as_ptr(), rect, image.as_ptr()) }
}
pub fn replace_path_with_stroked_path(&self) {
unsafe { CGContextReplacePathWithStrokedPath(self.as_ptr()) }
}
pub fn fill_ellipse_in_rect(&self, rect: CGRect) {
unsafe { CGContextFillEllipseInRect(self.as_ptr(), rect) }
}
pub fn stroke_ellipse_in_rect(&self, rect: CGRect) {
unsafe { CGContextStrokeEllipseInRect(self.as_ptr(), rect) }
}
pub fn stroke_line_segments(&self, points: &[CGPoint]) {
unsafe { CGContextStrokeLineSegments(self.as_ptr(), points.as_ptr(), points.len()) }
}
pub fn set_interpolation_quality(&self, quality: CGInterpolationQuality) {
unsafe {
CGContextSetInterpolationQuality(self.as_ptr(), quality);
}
}
pub fn get_interpolation_quality(&self) -> CGInterpolationQuality {
unsafe { CGContextGetInterpolationQuality(self.as_ptr()) }
}
pub fn draw_image(&self, rect: CGRect, image: &CGImage) {
unsafe {
CGContextDrawImage(self.as_ptr(), rect, image.as_ptr());
}
}
pub fn create_image(&self) -> Option<CGImage> {
let image = unsafe { CGBitmapContextCreateImage(self.as_ptr()) };
if !image.is_null() {
Some(unsafe { CGImage::from_ptr(image) })
} else {
None
}
}
pub fn set_font(&self, font: &CGFont) {
unsafe { CGContextSetFont(self.as_ptr(), font.as_ptr()) }
}
pub fn set_font_size(&self, size: CGFloat) {
unsafe { CGContextSetFontSize(self.as_ptr(), size) }
}
pub fn set_text_matrix(&self, t: &CGAffineTransform) {
unsafe { CGContextSetTextMatrix(self.as_ptr(), *t) }
}
pub fn set_text_position(&self, x: CGFloat, y: CGFloat) {
unsafe { CGContextSetTextPosition(self.as_ptr(), x, y) }
}
pub fn show_glyphs_at_positions(&self, glyphs: &[CGGlyph], positions: &[CGPoint]) {
unsafe {
let count = cmp::min(glyphs.len(), positions.len());
CGContextShowGlyphsAtPositions(
self.as_ptr(),
glyphs.as_ptr(),
positions.as_ptr(),
count,
)
}
}
pub fn save(&self) {
unsafe {
CGContextSaveGState(self.as_ptr());
}
}
pub fn restore(&self) {
unsafe {
CGContextRestoreGState(self.as_ptr());
}
}
pub fn translate(&self, tx: CGFloat, ty: CGFloat) {
unsafe {
CGContextTranslateCTM(self.as_ptr(), tx, ty);
}
}
pub fn scale(&self, sx: CGFloat, sy: CGFloat) {
unsafe {
CGContextScaleCTM(self.as_ptr(), sx, sy);
}
}
pub fn rotate(&self, angle: CGFloat) {
unsafe {
CGContextRotateCTM(self.as_ptr(), angle);
}
}
pub fn get_ctm(&self) -> CGAffineTransform {
unsafe { CGContextGetCTM(self.as_ptr()) }
}
pub fn concat_ctm(&self, transform: CGAffineTransform) {
unsafe { CGContextConcatCTM(self.as_ptr(), transform) }
}
pub fn draw_linear_gradient(
&self,
gradient: &CGGradient,
start_point: CGPoint,
end_point: CGPoint,
options: CGGradientDrawingOptions,
) {
unsafe {
CGContextDrawLinearGradient(
self.as_ptr(),
gradient.as_ptr(),
start_point,
end_point,
options,
);
}
}
pub fn draw_radial_gradient(
&self,
gradient: &CGGradient,
start_center: CGPoint,
start_radius: CGFloat,
end_center: CGPoint,
end_radius: CGFloat,
options: CGGradientDrawingOptions,
) {
unsafe {
CGContextDrawRadialGradient(
self.as_ptr(),
gradient.as_ptr(),
start_center,
start_radius,
end_center,
end_radius,
options,
);
}
}
pub fn set_shadow(&self, offset: CGSize, blur: CGFloat) {
unsafe {
CGContextSetShadow(self.as_ptr(), offset, blur);
}
}
pub fn set_shadow_with_color(&self, offset: CGSize, blur: CGFloat, color: &CGColor) {
unsafe {
CGContextSetShadowWithColor(self.as_ptr(), offset, blur, color.as_concrete_TypeRef());
}
}
pub fn set_alpha(&self, alpha: CGFloat) {
unsafe {
CGContextSetAlpha(self.as_ptr(), alpha);
}
}
}
#[test]
fn create_bitmap_context_test() {
use crate::geometry::*;
let cs = CGColorSpace::create_device_rgb();
let ctx = CGContext::create_bitmap_context(
None,
16,
8,
8,
0,
&cs,
crate::base::kCGImageAlphaPremultipliedLast,
);
ctx.set_rgb_fill_color(1., 0., 1., 1.);
ctx.set_miter_limit(4.);
ctx.fill_rect(CGRect::new(&CGPoint::new(0., 0.), &CGSize::new(8., 8.)));
let img = ctx.create_image().unwrap();
assert_eq!(16, img.width());
assert_eq!(8, img.height());
assert_eq!(8, img.bits_per_component());
assert_eq!(32, img.bits_per_pixel());
let data = img.data();
assert_eq!(255, data.bytes()[0]);
assert_eq!(0, data.bytes()[1]);
assert_eq!(255, data.bytes()[2]);
assert_eq!(255, data.bytes()[3]);
}
#[cfg_attr(feature = "link", link(name = "CoreGraphics", kind = "framework"))]
extern "C" {
fn CGContextRetain(c: crate::sys::CGContextRef) -> crate::sys::CGContextRef;
fn CGContextRelease(c: crate::sys::CGContextRef);
fn CGBitmapContextCreate(
data: *mut c_void,
width: size_t,
height: size_t,
bitsPerComponent: size_t,
bytesPerRow: size_t,
space: crate::sys::CGColorSpaceRef,
bitmapInfo: u32,
) -> crate::sys::CGContextRef;
fn CGBitmapContextGetData(context: crate::sys::CGContextRef) -> *mut c_void;
fn CGBitmapContextGetWidth(context: crate::sys::CGContextRef) -> size_t;
fn CGBitmapContextGetHeight(context: crate::sys::CGContextRef) -> size_t;
fn CGBitmapContextGetBytesPerRow(context: crate::sys::CGContextRef) -> size_t;
fn CGBitmapContextCreateImage(context: crate::sys::CGContextRef) -> crate::sys::CGImageRef;
fn CGContextGetTypeID() -> CFTypeID;
fn CGContextGetClipBoundingBox(c: crate::sys::CGContextRef) -> CGRect;
fn CGContextFlush(c: crate::sys::CGContextRef);
fn CGContextSetBlendMode(c: crate::sys::CGContextRef, blendMode: CGBlendMode);
fn CGContextSetAllowsFontSmoothing(c: crate::sys::CGContextRef, allowsFontSmoothing: bool);
fn CGContextSetShouldSmoothFonts(c: crate::sys::CGContextRef, shouldSmoothFonts: bool);
fn CGContextSetFontSmoothingStyle(c: crate::sys::CGContextRef, style: c_int);
fn CGContextSetAllowsAntialiasing(c: crate::sys::CGContextRef, allowsAntialiasing: bool);
fn CGContextSetShouldAntialias(c: crate::sys::CGContextRef, shouldAntialias: bool);
fn CGContextSetAllowsFontSubpixelQuantization(
c: crate::sys::CGContextRef,
allowsFontSubpixelQuantization: bool,
);
fn CGContextSetShouldSubpixelQuantizeFonts(
c: crate::sys::CGContextRef,
shouldSubpixelQuantizeFonts: bool,
);
fn CGContextSetAllowsFontSubpixelPositioning(
c: crate::sys::CGContextRef,
allowsFontSubpixelPositioning: bool,
);
fn CGContextSetShouldSubpixelPositionFonts(
c: crate::sys::CGContextRef,
shouldSubpixelPositionFonts: bool,
);
fn CGContextSetTextDrawingMode(c: crate::sys::CGContextRef, mode: CGTextDrawingMode);
fn CGContextSetFillColorWithColor(c: crate::sys::CGContextRef, color: crate::sys::CGColorRef);
fn CGContextSetLineCap(c: crate::sys::CGContextRef, cap: CGLineCap);
fn CGContextSetLineDash(
c: crate::sys::CGContextRef,
phase: CGFloat,
lengths: *const CGFloat,
count: size_t,
);
fn CGContextSetLineJoin(c: crate::sys::CGContextRef, join: CGLineJoin);
fn CGContextSetLineWidth(c: crate::sys::CGContextRef, width: CGFloat);
fn CGContextSetMiterLimit(c: crate::sys::CGContextRef, limit: CGFloat);
fn CGContextAddPath(c: crate::sys::CGContextRef, path: crate::sys::CGPathRef);
fn CGContextAddCurveToPoint(
c: crate::sys::CGContextRef,
cp1x: CGFloat,
cp1y: CGFloat,
cp2x: CGFloat,
cp2y: CGFloat,
x: CGFloat,
y: CGFloat,
);
fn CGContextAddQuadCurveToPoint(
c: crate::sys::CGContextRef,
cpx: CGFloat,
cpy: CGFloat,
x: CGFloat,
y: CGFloat,
);
fn CGContextAddLineToPoint(c: crate::sys::CGContextRef, x: CGFloat, y: CGFloat);
fn CGContextBeginPath(c: crate::sys::CGContextRef);
fn CGContextClosePath(c: crate::sys::CGContextRef);
fn CGContextMoveToPoint(c: crate::sys::CGContextRef, x: CGFloat, y: CGFloat);
fn CGContextDrawPath(c: crate::sys::CGContextRef, mode: CGPathDrawingMode);
fn CGContextFillPath(c: crate::sys::CGContextRef);
fn CGContextEOFillPath(c: crate::sys::CGContextRef);
fn CGContextClip(c: crate::sys::CGContextRef);
fn CGContextEOClip(c: crate::sys::CGContextRef);
fn CGContextResetClip(c: crate::sys::CGContextRef);
fn CGContextStrokePath(c: crate::sys::CGContextRef);
fn CGContextSetRGBFillColor(
context: crate::sys::CGContextRef,
red: CGFloat,
green: CGFloat,
blue: CGFloat,
alpha: CGFloat,
);
fn CGContextSetRGBStrokeColor(
context: crate::sys::CGContextRef,
red: CGFloat,
green: CGFloat,
blue: CGFloat,
alpha: CGFloat,
);
fn CGContextSetGrayFillColor(context: crate::sys::CGContextRef, gray: CGFloat, alpha: CGFloat);
fn CGContextClearRect(context: crate::sys::CGContextRef, rect: CGRect);
fn CGContextFillRect(context: crate::sys::CGContextRef, rect: CGRect);
fn CGContextFillRects(context: crate::sys::CGContextRef, rects: *const CGRect, count: size_t);
fn CGContextStrokeRect(context: crate::sys::CGContextRef, rect: CGRect);
fn CGContextStrokeRectWithWidth(
context: crate::sys::CGContextRef,
rect: CGRect,
width: CGFloat,
);
fn CGContextClipToRect(context: crate::sys::CGContextRef, rect: CGRect);
fn CGContextClipToRects(context: crate::sys::CGContextRef, rects: *const CGRect, count: size_t);
fn CGContextClipToMask(
ctx: crate::sys::CGContextRef,
rect: CGRect,
mask: crate::sys::CGImageRef,
);
fn CGContextReplacePathWithStrokedPath(context: crate::sys::CGContextRef);
fn CGContextFillEllipseInRect(context: crate::sys::CGContextRef, rect: CGRect);
fn CGContextStrokeEllipseInRect(context: crate::sys::CGContextRef, rect: CGRect);
fn CGContextStrokeLineSegments(
context: crate::sys::CGContextRef,
points: *const CGPoint,
count: size_t,
);
fn CGContextDrawImage(c: crate::sys::CGContextRef, rect: CGRect, image: crate::sys::CGImageRef);
fn CGContextSetInterpolationQuality(
c: crate::sys::CGContextRef,
quality: CGInterpolationQuality,
);
fn CGContextGetInterpolationQuality(c: crate::sys::CGContextRef) -> CGInterpolationQuality;
fn CGContextSetFont(c: crate::sys::CGContextRef, font: crate::sys::CGFontRef);
fn CGContextSetFontSize(c: crate::sys::CGContextRef, size: CGFloat);
fn CGContextSetTextMatrix(c: crate::sys::CGContextRef, t: CGAffineTransform);
fn CGContextSetTextPosition(c: crate::sys::CGContextRef, x: CGFloat, y: CGFloat);
fn CGContextShowGlyphsAtPositions(
c: crate::sys::CGContextRef,
glyphs: *const CGGlyph,
positions: *const CGPoint,
count: size_t,
);
fn CGContextSaveGState(c: crate::sys::CGContextRef);
fn CGContextRestoreGState(c: crate::sys::CGContextRef);
fn CGContextTranslateCTM(c: crate::sys::CGContextRef, tx: CGFloat, ty: CGFloat);
fn CGContextScaleCTM(c: crate::sys::CGContextRef, sx: CGFloat, sy: CGFloat);
fn CGContextRotateCTM(c: crate::sys::CGContextRef, angle: CGFloat);
fn CGContextGetCTM(c: crate::sys::CGContextRef) -> CGAffineTransform;
fn CGContextConcatCTM(c: crate::sys::CGContextRef, transform: CGAffineTransform);
fn CGContextDrawLinearGradient(
c: crate::sys::CGContextRef,
gradient: crate::sys::CGGradientRef,
startPoint: CGPoint,
endPoint: CGPoint,
options: CGGradientDrawingOptions,
);
fn CGContextDrawRadialGradient(
c: crate::sys::CGContextRef,
gradient: crate::sys::CGGradientRef,
startCenter: CGPoint,
startRadius: CGFloat,
endCenter: CGPoint,
endRadius: CGFloat,
options: CGGradientDrawingOptions,
);
fn CGContextSetShadow(c: crate::sys::CGContextRef, offset: CGSize, blur: CGFloat);
fn CGContextSetShadowWithColor(
c: crate::sys::CGContextRef,
offset: CGSize,
blur: CGFloat,
color: crate::sys::CGColorRef,
);
fn CGContextSetAlpha(c: crate::sys::CGContextRef, alpha: CGFloat);
}

View File

@@ -0,0 +1,173 @@
// 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::{off_t, size_t};
use std::mem;
use std::os::raw::c_void;
use std::ptr;
use std::sync::Arc;
use foreign_types::{ForeignType, ForeignTypeRef};
pub type CGDataProviderGetBytesCallback =
Option<unsafe extern "C" fn(*mut c_void, *mut c_void, size_t) -> size_t>;
pub type CGDataProviderReleaseInfoCallback = Option<unsafe extern "C" fn(*mut c_void)>;
pub type CGDataProviderRewindCallback = Option<unsafe extern "C" fn(*mut c_void)>;
pub type CGDataProviderSkipBytesCallback = Option<unsafe extern "C" fn(*mut c_void, size_t)>;
pub type CGDataProviderSkipForwardCallback =
Option<unsafe extern "C" fn(*mut c_void, off_t) -> off_t>;
pub type CGDataProviderGetBytePointerCallback =
Option<unsafe extern "C" fn(*mut c_void) -> *mut c_void>;
pub type CGDataProviderGetBytesAtOffsetCallback =
Option<unsafe extern "C" fn(*mut c_void, *mut c_void, size_t, size_t)>;
pub type CGDataProviderReleaseBytePointerCallback =
Option<unsafe extern "C" fn(*mut c_void, *const c_void)>;
pub type CGDataProviderReleaseDataCallback =
Option<unsafe extern "C" fn(*mut c_void, *const c_void, size_t)>;
pub type CGDataProviderGetBytesAtPositionCallback =
Option<unsafe extern "C" fn(*mut c_void, *mut c_void, off_t, size_t)>;
foreign_type! {
#[doc(hidden)]
pub unsafe type CGDataProvider {
type CType = crate::sys::CGDataProvider;
fn drop = |cs| CFRelease(cs as *mut _);
fn clone = |p| CFRetain(p as *const _) as *mut _;
}
}
impl CGDataProvider {
pub fn type_id() -> CFTypeID {
unsafe { CGDataProviderGetTypeID() }
}
/// Creates a data provider from the given reference-counted buffer.
///
/// The `CGDataProvider` object takes ownership of the reference. Once the data provider
/// is destroyed, the reference count of the buffer is automatically decremented.
pub fn from_buffer<T: AsRef<[u8]> + Sync + Send>(buffer: Arc<T>) -> Self {
unsafe {
let ptr = (*buffer).as_ref().as_ptr() as *const c_void;
let len = (*buffer).as_ref().len() as size_t;
let info = Arc::into_raw(buffer) as *mut c_void;
let result = CGDataProviderCreateWithData(info, ptr, len, Some(release::<T>));
return CGDataProvider::from_ptr(result);
}
unsafe extern "C" fn release<T>(info: *mut c_void, _: *const c_void, _: size_t) {
drop(Arc::from_raw(info as *mut T))
}
}
/// Creates a data prvider from a given slice. The data provider does not own the slice in this
/// case, so it's up to the user to ensure the memory safety here.
pub unsafe fn from_slice(buffer: &[u8]) -> Self {
let ptr = buffer.as_ptr() as *const c_void;
let len = buffer.len() as size_t;
let result = CGDataProviderCreateWithData(ptr::null_mut(), ptr, len, None);
CGDataProvider::from_ptr(result)
}
/// Creates a data provider from the given raw pointer, length, and destructor function.
///
/// This is double-boxed because the Core Text API requires that the userdata be a single
/// pointer.
pub unsafe fn from_custom_data(custom_data: Box<Box<dyn CustomData>>) -> Self {
let (ptr, len) = (custom_data.ptr() as *const c_void, custom_data.len());
let userdata = mem::transmute::<Box<Box<dyn CustomData>>, &mut c_void>(custom_data);
let data_provider = CGDataProviderCreateWithData(userdata, ptr, len, Some(release));
return CGDataProvider::from_ptr(data_provider);
unsafe extern "C" fn release(info: *mut c_void, _: *const c_void, _: size_t) {
drop(mem::transmute::<*mut c_void, Box<Box<dyn CustomData>>>(
info,
))
}
}
}
impl CGDataProviderRef {
/// Creates a copy of the data from the underlying `CFDataProviderRef`.
pub fn copy_data(&self) -> CFData {
unsafe { CFData::wrap_under_create_rule(CGDataProviderCopyData(self.as_ptr())) }
}
}
/// Encapsulates custom data that can be wrapped.
pub trait CustomData {
/// Returns a pointer to the start of the custom data. This pointer *must not change* during
/// the lifespan of this `CustomData`.
unsafe fn ptr(&self) -> *const u8;
/// Returns the length of this custom data. This value must not change during the lifespan of
/// this `CustomData`.
unsafe fn len(&self) -> usize;
}
#[test]
fn test_data_provider() {
let l = vec![5];
CGDataProvider::from_buffer(Arc::new(l));
let l = vec![5];
CGDataProvider::from_buffer(Arc::new(l.into_boxed_slice()));
// Make sure the buffer is actually dropped
use std::sync::atomic::{AtomicBool, Ordering::SeqCst};
struct VecWrapper {
inner: Vec<u8>,
dropped: Arc<AtomicBool>,
}
impl Drop for VecWrapper {
fn drop(&mut self) {
self.dropped.store(true, SeqCst)
}
}
impl std::convert::AsRef<[u8]> for VecWrapper {
fn as_ref(&self) -> &[u8] {
&self.inner
}
}
let dropped = Arc::new(AtomicBool::default());
let l = Arc::new(VecWrapper {
inner: vec![5],
dropped: dropped.clone(),
});
let m = l.clone();
let dp = CGDataProvider::from_buffer(l);
drop(m);
assert!(!dropped.load(SeqCst));
drop(dp);
assert!(dropped.load(SeqCst))
}
#[cfg_attr(feature = "link", link(name = "CoreGraphics", kind = "framework"))]
extern "C" {
fn CGDataProviderCopyData(provider: crate::sys::CGDataProviderRef) -> CFDataRef;
//fn CGDataProviderCreateDirect
//fn CGDataProviderCreateSequential
//fn CGDataProviderCreateWithCFData
fn CGDataProviderCreateWithData(
info: *mut c_void,
data: *const c_void,
size: size_t,
releaseData: CGDataProviderReleaseDataCallback,
) -> crate::sys::CGDataProviderRef;
//fn CGDataProviderCreateWithFilename(filename: *c_char) -> CGDataProviderRef;
//fn CGDataProviderCreateWithURL
fn CGDataProviderGetTypeID() -> CFTypeID;
//fn CGDataProviderRelease(provider: CGDataProviderRef);
//fn CGDataProviderRetain(provider: CGDataProviderRef) -> CGDataProviderRef;
}

792
vendor/core-graphics/src/display.rs vendored Normal file
View File

@@ -0,0 +1,792 @@
// 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::ops::Deref;
use std::ptr;
pub use crate::base::{boolean_t, CGError};
pub use crate::geometry::{CGPoint, CGRect, CGSize};
use crate::image::CGImage;
use core_foundation::base::{CFRetain, TCFType};
use core_foundation::string::{CFString, CFStringRef};
use foreign_types::ForeignType;
pub type CGDirectDisplayID = u32;
pub type CGWindowID = u32;
pub type CGWindowLevel = i32;
pub const kCGNullWindowID: CGWindowID = 0 as CGWindowID;
pub const kCGNullDirectDisplayID: CGDirectDisplayID = 0 as CGDirectDisplayID;
pub type CGWindowListOption = u32;
pub const kCGWindowListOptionAll: CGWindowListOption = 0;
pub const kCGWindowListOptionOnScreenOnly: CGWindowListOption = 1 << 0;
pub const kCGWindowListOptionOnScreenAboveWindow: CGWindowListOption = 1 << 1;
pub const kCGWindowListOptionOnScreenBelowWindow: CGWindowListOption = 1 << 2;
pub const kCGWindowListOptionIncludingWindow: CGWindowListOption = 1 << 3;
pub const kCGWindowListExcludeDesktopElements: CGWindowListOption = 1 << 4;
pub type CGWindowImageOption = u32;
pub const kCGWindowImageDefault: CGWindowImageOption = 0;
pub const kCGWindowImageBoundsIgnoreFraming: CGWindowImageOption = 1 << 0;
pub const kCGWindowImageShouldBeOpaque: CGWindowImageOption = 1 << 1;
pub const kCGWindowImageOnlyShadows: CGWindowImageOption = 1 << 2;
pub const kCGWindowImageBestResolution: CGWindowImageOption = 1 << 3;
pub const kCGWindowImageNominalResolution: CGWindowImageOption = 1 << 4;
pub const kDisplayModeValidFlag: u32 = 0x00000001;
pub const kDisplayModeSafeFlag: u32 = 0x00000002;
pub const kDisplayModeDefaultFlag: u32 = 0x00000004;
pub const kDisplayModeAlwaysShowFlag: u32 = 0x00000008;
pub const kDisplayModeNeverShowFlag: u32 = 0x00000080;
pub const kDisplayModeNotResizeFlag: u32 = 0x00000010;
pub const kDisplayModeRequiresPanFlag: u32 = 0x00000020;
pub const kDisplayModeInterlacedFlag: u32 = 0x00000040;
pub const kDisplayModeSimulscanFlag: u32 = 0x00000100;
pub const kDisplayModeBuiltInFlag: u32 = 0x00000400;
pub const kDisplayModeNotPresetFlag: u32 = 0x00000200;
pub const kDisplayModeStretchedFlag: u32 = 0x00000800;
pub const kDisplayModeNotGraphicsQualityFlag: u32 = 0x00001000;
pub const kDisplayModeValidateAgainstDisplay: u32 = 0x00002000;
pub const kDisplayModeTelevisionFlag: u32 = 0x00100000;
pub const kDisplayModeValidForMirroringFlag: u32 = 0x00200000;
pub const kDisplayModeAcceleratorBackedFlag: u32 = 0x00400000;
pub const kDisplayModeValidForHiResFlag: u32 = 0x00800000;
pub const kDisplayModeValidForAirPlayFlag: u32 = 0x01000000;
pub const kDisplayModeNativeFlag: u32 = 0x02000000;
pub const kDisplayModeSafetyFlags: u32 = 0x00000007;
pub type CGDisplayBlendFraction = f32;
pub const kCGDisplayBlendNormal: CGDisplayBlendFraction = 0.0;
pub const kCGDisplayBlendSolidColor: CGDisplayBlendFraction = 1.0;
pub type CGDisplayFadeReservationToken = u32;
pub const kCGDisplayFadeReservationInvalidToken: CGDisplayFadeReservationToken = 0;
pub type CGDisplayFadeInterval = f32;
pub type CGDisplayReservationInterval = f32;
pub const kCGMaxDisplayReservationInterval: CGDisplayReservationInterval = 15.0;
pub const IO1BitIndexedPixels: &str = "P";
pub const IO2BitIndexedPixels: &str = "PP";
pub const IO4BitIndexedPixels: &str = "PPPP";
pub const IO8BitIndexedPixels: &str = "PPPPPPPP";
pub const IO16BitDirectPixels: &str = "-RRRRRGGGGGBBBBB";
pub const IO32BitDirectPixels: &str = "--------RRRRRRRRGGGGGGGGBBBBBBBB";
pub const kIO30BitDirectPixels: &str = "--RRRRRRRRRRGGGGGGGGGGBBBBBBBBBB";
pub const kIO64BitDirectPixels: &str = "-16R16G16B16";
pub const kIO16BitFloatPixels: &str = "-16FR16FG16FB16";
pub const kIO32BitFloatPixels: &str = "-32FR32FG32FB32";
pub const IOYUV422Pixels: &str = "Y4U2V2";
pub const IO8BitOverlayPixels: &str = "O8";
pub use core_foundation::array::{CFArray, CFArrayRef};
pub use core_foundation::array::{CFArrayGetCount, CFArrayGetValueAtIndex};
pub use core_foundation::base::{CFIndex, CFRelease, CFTypeRef};
pub use core_foundation::dictionary::{
CFDictionary, CFDictionaryGetValueIfPresent, CFDictionaryRef,
};
pub type CGDisplayConfigRef = *mut libc::c_void;
#[repr(u32)]
#[derive(Clone, Copy)]
pub enum CGConfigureOption {
ConfigureForAppOnly = 0,
ConfigureForSession = 1,
ConfigurePermanently = 2,
}
#[derive(Copy, Clone, Debug)]
pub struct CGDisplay {
pub id: CGDirectDisplayID,
}
foreign_type! {
#[doc(hidden)]
pub unsafe type CGDisplayMode {
type CType = crate::sys::CGDisplayMode;
fn drop = CGDisplayModeRelease;
fn clone = |p| CFRetain(p as *const _) as *mut _;
}
}
impl CGDisplay {
#[inline]
pub fn new(id: CGDirectDisplayID) -> CGDisplay {
CGDisplay { id }
}
/// Returns the the main display.
#[inline]
pub fn main() -> CGDisplay {
CGDisplay::new(unsafe { CGMainDisplayID() })
}
/// A value that will never correspond to actual hardware.
pub fn null_display() -> CGDisplay {
CGDisplay::new(kCGNullDirectDisplayID)
}
/// Returns the bounds of a display in the global display coordinate space.
#[inline]
pub fn bounds(&self) -> CGRect {
unsafe { CGDisplayBounds(self.id) }
}
/// Returns information about a display's current configuration.
#[inline]
pub fn display_mode(&self) -> Option<CGDisplayMode> {
unsafe {
let mode_ref = CGDisplayCopyDisplayMode(self.id);
if !mode_ref.is_null() {
Some(CGDisplayMode::from_ptr(mode_ref))
} else {
None
}
}
}
/// Begins a new set of display configuration changes.
pub fn begin_configuration(&self) -> Result<CGDisplayConfigRef, CGError> {
unsafe {
let mut config_ref: CGDisplayConfigRef = ptr::null_mut();
let result = CGBeginDisplayConfiguration(&mut config_ref);
if result == 0 {
Ok(config_ref)
} else {
Err(result)
}
}
}
/// Cancels a set of display configuration changes.
pub fn cancel_configuration(&self, config_ref: &CGDisplayConfigRef) -> Result<(), CGError> {
let result = unsafe { CGCancelDisplayConfiguration(*config_ref) };
if result == 0 {
Ok(())
} else {
Err(result)
}
}
/// Completes a set of display configuration changes.
pub fn complete_configuration(
&self,
config_ref: &CGDisplayConfigRef,
option: CGConfigureOption,
) -> Result<(), CGError> {
let result = unsafe { CGCompleteDisplayConfiguration(*config_ref, option) };
if result == 0 {
Ok(())
} else {
Err(result)
}
}
/// Configures the display mode of a display.
pub fn configure_display_with_display_mode(
&self,
config_ref: &CGDisplayConfigRef,
display_mode: &CGDisplayMode,
) -> Result<(), CGError> {
let result = unsafe {
CGConfigureDisplayWithDisplayMode(
*config_ref,
self.id,
display_mode.as_ptr(),
ptr::null(),
)
};
if result == 0 {
Ok(())
} else {
Err(result)
}
}
/// Configures the origin of a display in the global display coordinate space.
pub fn configure_display_origin(
&self,
config_ref: &CGDisplayConfigRef,
x: i32,
y: i32,
) -> Result<(), CGError> {
let result = unsafe { CGConfigureDisplayOrigin(*config_ref, self.id, x, y) };
if result == 0 {
Ok(())
} else {
Err(result)
}
}
/// Changes the configuration of a mirroring set.
pub fn configure_display_mirror_of_display(
&self,
config_ref: &CGDisplayConfigRef,
master: &CGDisplay,
) -> Result<(), CGError> {
let result = unsafe { CGConfigureDisplayMirrorOfDisplay(*config_ref, self.id, master.id) };
if result == 0 {
Ok(())
} else {
Err(result)
}
}
/// Returns an image containing the contents of the specified display.
#[inline]
pub fn image(&self) -> Option<CGImage> {
unsafe {
let image_ref = CGDisplayCreateImage(self.id);
if !image_ref.is_null() {
Some(CGImage::from_ptr(image_ref))
} else {
None
}
}
}
/// Returns an image containing the contents of a portion of the specified display.
#[inline]
pub fn image_for_rect(&self, bounds: CGRect) -> Option<CGImage> {
unsafe {
let image_ref = CGDisplayCreateImageForRect(self.id, bounds);
if !image_ref.is_null() {
Some(CGImage::from_ptr(image_ref))
} else {
None
}
}
}
/// Returns a composite image based on a dynamically generated list of
/// windows.
#[inline]
pub fn screenshot(
bounds: CGRect,
list_option: CGWindowListOption,
window_id: CGWindowID,
image_option: CGWindowImageOption,
) -> Option<CGImage> {
unsafe {
let image_ref = CGWindowListCreateImage(bounds, list_option, window_id, image_option);
if !image_ref.is_null() {
Some(CGImage::from_ptr(image_ref))
} else {
None
}
}
}
/// Returns a composite image of the specified windows.
#[inline]
pub fn screenshot_from_windows(
bounds: CGRect,
windows: CFArray,
image_option: CGWindowImageOption,
) -> Option<CGImage> {
unsafe {
let image_ref = CGWindowListCreateImageFromArray(
bounds,
windows.as_concrete_TypeRef(),
image_option,
);
if !image_ref.is_null() {
Some(CGImage::from_ptr(image_ref))
} else {
None
}
}
}
/// Generates and returns information about the selected windows in the
/// current user session.
pub fn window_list_info(
option: CGWindowListOption,
relative_to_window: Option<CGWindowID>,
) -> Option<CFArray> {
let relative_to_window = relative_to_window.unwrap_or(kCGNullWindowID);
let array_ref = unsafe { CGWindowListCopyWindowInfo(option, relative_to_window) };
if !array_ref.is_null() {
Some(unsafe { TCFType::wrap_under_create_rule(array_ref) })
} else {
None
}
}
/// Returns a Boolean value indicating whether a display is active.
#[inline]
pub fn is_active(&self) -> bool {
unsafe { CGDisplayIsActive(self.id) != 0 }
}
/// Returns a boolean indicating whether a display is always in a
/// mirroring set.
#[inline]
pub fn is_always_in_mirror_set(&self) -> bool {
unsafe { CGDisplayIsAlwaysInMirrorSet(self.id) != 0 }
}
/// Returns a boolean indicating whether a display is sleeping (and is
/// therefore not drawable.)
#[inline]
pub fn is_asleep(&self) -> bool {
unsafe { CGDisplayIsAsleep(self.id) != 0 }
}
/// Returns a boolean indicating whether a display is built-in, such as
/// the internal display in portable systems.
#[inline]
pub fn is_builtin(&self) -> bool {
unsafe { CGDisplayIsBuiltin(self.id) != 0 }
}
/// Returns a boolean indicating whether a display is in a hardware
/// mirroring set.
#[inline]
pub fn is_in_hw_mirror_set(&self) -> bool {
unsafe { CGDisplayIsInHWMirrorSet(self.id) != 0 }
}
/// Returns a boolean indicating whether a display is in a mirroring set.
#[inline]
pub fn is_in_mirror_set(&self) -> bool {
unsafe { CGDisplayIsInMirrorSet(self.id) != 0 }
}
/// Returns a boolean indicating whether a display is the main display.
#[inline]
pub fn is_main(&self) -> bool {
unsafe { CGDisplayIsMain(self.id) != 0 }
}
/// Returns a boolean indicating whether a display is connected or online.
#[inline]
pub fn is_online(&self) -> bool {
unsafe { CGDisplayIsOnline(self.id) != 0 }
}
/// Returns a boolean indicating whether Quartz is using OpenGL-based
/// window acceleration (Quartz Extreme) to render in a display.
#[inline]
pub fn uses_open_gl_acceleration(&self) -> bool {
unsafe { CGDisplayUsesOpenGLAcceleration(self.id) != 0 }
}
/// Returns a boolean indicating whether a display is running in a stereo
/// graphics mode.
#[inline]
pub fn is_stereo(&self) -> bool {
unsafe { CGDisplayIsStereo(self.id) != 0 }
}
/// For a secondary display in a mirroring set, returns the primary
/// display.
#[inline]
pub fn mirrors_display(&self) -> CGDirectDisplayID {
unsafe { CGDisplayMirrorsDisplay(self.id) }
}
/// Returns the primary display in a hardware mirroring set.
#[inline]
pub fn primary_display(&self) -> CGDirectDisplayID {
unsafe { CGDisplayPrimaryDisplay(self.id) }
}
/// Returns the rotation angle of a display in degrees.
#[inline]
pub fn rotation(&self) -> f64 {
unsafe { CGDisplayRotation(self.id) }
}
/// Returns the width and height of a display in millimeters.
#[inline]
pub fn screen_size(&self) -> CGSize {
unsafe { CGDisplayScreenSize(self.id) }
}
/// Returns the serial number of a display monitor.
#[inline]
pub fn serial_number(&self) -> u32 {
unsafe { CGDisplaySerialNumber(self.id) }
}
/// Returns the logical unit number of a display.
#[inline]
pub fn unit_number(&self) -> u32 {
unsafe { CGDisplayUnitNumber(self.id) }
}
/// Returns the vendor number of the specified display's monitor.
#[inline]
pub fn vendor_number(&self) -> u32 {
unsafe { CGDisplayVendorNumber(self.id) }
}
/// Returns the model number of a display monitor.
#[inline]
pub fn model_number(&self) -> u32 {
unsafe { CGDisplayModelNumber(self.id) }
}
/// Returns the display height in pixel units.
#[inline]
pub fn pixels_high(&self) -> u64 {
unsafe { CGDisplayPixelsHigh(self.id) as u64 }
}
/// Returns the display width in pixel units.
#[inline]
pub fn pixels_wide(&self) -> u64 {
unsafe { CGDisplayPixelsWide(self.id) as u64 }
}
/// Provides a list of displays that are active (or drawable).
#[inline]
pub fn active_displays() -> Result<Vec<CGDirectDisplayID>, CGError> {
let count = CGDisplay::active_display_count()?;
let mut buf: Vec<CGDirectDisplayID> = vec![0; count as usize];
let result = unsafe { CGGetActiveDisplayList(count, buf.as_mut_ptr(), ptr::null_mut()) };
if result == 0 {
Ok(buf)
} else {
Err(result)
}
}
/// Provides count of displays that are active (or drawable).
#[inline]
pub fn active_display_count() -> Result<u32, CGError> {
let mut count: u32 = 0;
let result = unsafe { CGGetActiveDisplayList(0, ptr::null_mut(), &mut count) };
if result == 0 {
Ok(count)
} else {
Err(result)
}
}
/// Hides the mouse cursor, and increments the hide cursor count.
#[inline]
pub fn hide_cursor(&self) -> Result<(), CGError> {
let result = unsafe { CGDisplayHideCursor(self.id) };
if result == 0 {
Ok(())
} else {
Err(result)
}
}
/// Decrements the hide cursor count, and shows the mouse cursor if the
/// count is 0.
#[inline]
pub fn show_cursor(&self) -> Result<(), CGError> {
let result = unsafe { CGDisplayShowCursor(self.id) };
if result == 0 {
Ok(())
} else {
Err(result)
}
}
/// Moves the mouse cursor to a specified point relative to the display
/// origin (the upper-left corner of the display).
#[inline]
pub fn move_cursor_to_point(&self, point: CGPoint) -> Result<(), CGError> {
let result = unsafe { CGDisplayMoveCursorToPoint(self.id, point) };
if result == 0 {
Ok(())
} else {
Err(result)
}
}
/// Moves the mouse cursor without generating events.
#[inline]
pub fn warp_mouse_cursor_position(point: CGPoint) -> Result<(), CGError> {
let result = unsafe { CGWarpMouseCursorPosition(point) };
if result == 0 {
Ok(())
} else {
Err(result)
}
}
/// Connects or disconnects the mouse and cursor while an application is
/// in the foreground.
#[inline]
pub fn associate_mouse_and_mouse_cursor_position(connected: bool) -> Result<(), CGError> {
let result = unsafe { CGAssociateMouseAndMouseCursorPosition(connected as boolean_t) };
if result == 0 {
Ok(())
} else {
Err(result)
}
}
}
impl CGDisplayMode {
/// Returns all display modes for the specified display id.
pub fn all_display_modes(
display_id: CGDirectDisplayID,
options: CFDictionaryRef,
) -> Option<Vec<CGDisplayMode>> {
let array_opt: Option<CFArray> = unsafe {
let array_ref = CGDisplayCopyAllDisplayModes(display_id, options);
if !array_ref.is_null() {
Some(CFArray::wrap_under_create_rule(array_ref))
} else {
None
}
};
match array_opt {
Some(modes) => {
let vec: Vec<CGDisplayMode> = modes
.into_iter()
.map(|value0| {
let x = *value0.deref() as *mut crate::sys::CGDisplayMode;
unsafe { CGDisplayMode::from_ptr(x) }
})
.collect();
Some(vec)
}
None => None,
}
}
/// Returns the height of the specified display mode.
#[inline]
pub fn height(&self) -> u64 {
unsafe { CGDisplayModeGetHeight(self.as_ptr()) as u64 }
}
/// Returns the width of the specified display mode.
#[inline]
pub fn width(&self) -> u64 {
unsafe { CGDisplayModeGetWidth(self.as_ptr()) as u64 }
}
/// Returns the pixel height of the specified display mode.
#[inline]
pub fn pixel_height(&self) -> u64 {
unsafe { CGDisplayModeGetPixelHeight(self.as_ptr()) as u64 }
}
/// Returns the pixel width of the specified display mode.
#[inline]
pub fn pixel_width(&self) -> u64 {
unsafe { CGDisplayModeGetPixelWidth(self.as_ptr()) as u64 }
}
#[inline]
pub fn refresh_rate(&self) -> f64 {
unsafe { CGDisplayModeGetRefreshRate(self.as_ptr()) }
}
/// Returns the I/O Kit flags of the specified display mode.
#[inline]
pub fn io_flags(&self) -> u32 {
unsafe { CGDisplayModeGetIOFlags(self.as_ptr()) }
}
/// Returns the pixel encoding of the specified display mode.
#[inline]
pub fn pixel_encoding(&self) -> CFString {
unsafe { CFString::wrap_under_create_rule(CGDisplayModeCopyPixelEncoding(self.as_ptr())) }
}
/// Returns the number of bits per pixel of the specified display mode.
pub fn bit_depth(&self) -> usize {
let pixel_encoding = self.pixel_encoding().to_string();
// my numerical representation for kIO16BitFloatPixels and kIO32bitFloatPixels
// are made up and possibly non-sensical
if pixel_encoding.eq_ignore_ascii_case(kIO32BitFloatPixels) {
96
} else if pixel_encoding.eq_ignore_ascii_case(kIO64BitDirectPixels) {
64
} else if pixel_encoding.eq_ignore_ascii_case(kIO16BitFloatPixels) {
48
} else if pixel_encoding.eq_ignore_ascii_case(IO32BitDirectPixels) {
32
} else if pixel_encoding.eq_ignore_ascii_case(kIO30BitDirectPixels) {
30
} else if pixel_encoding.eq_ignore_ascii_case(IO16BitDirectPixels) {
16
} else if pixel_encoding.eq_ignore_ascii_case(IO8BitIndexedPixels) {
8
} else {
0
}
}
pub fn mode_id(&self) -> i32 {
unsafe { CGDisplayModeGetIODisplayModeID(self.as_ptr()) }
}
}
#[cfg_attr(feature = "link", link(name = "CoreGraphics", kind = "framework"))]
extern "C" {
pub static CGRectNull: CGRect;
pub static CGRectInfinite: CGRect;
pub static kCGDisplayShowDuplicateLowResolutionModes: CFStringRef;
pub fn CGDisplayModeRetain(mode: crate::sys::CGDisplayModeRef);
pub fn CGDisplayModeRelease(mode: crate::sys::CGDisplayModeRef);
pub fn CGMainDisplayID() -> CGDirectDisplayID;
pub fn CGDisplayIsActive(display: CGDirectDisplayID) -> boolean_t;
pub fn CGDisplayIsAlwaysInMirrorSet(display: CGDirectDisplayID) -> boolean_t;
pub fn CGDisplayIsAsleep(display: CGDirectDisplayID) -> boolean_t;
pub fn CGDisplayIsBuiltin(display: CGDirectDisplayID) -> boolean_t;
pub fn CGDisplayIsInHWMirrorSet(display: CGDirectDisplayID) -> boolean_t;
pub fn CGDisplayIsInMirrorSet(display: CGDirectDisplayID) -> boolean_t;
pub fn CGDisplayIsMain(display: CGDirectDisplayID) -> boolean_t;
pub fn CGDisplayIsOnline(display: CGDirectDisplayID) -> boolean_t;
pub fn CGDisplayIsStereo(display: CGDirectDisplayID) -> boolean_t;
pub fn CGDisplayMirrorsDisplay(display: CGDirectDisplayID) -> CGDirectDisplayID;
pub fn CGDisplayPrimaryDisplay(display: CGDirectDisplayID) -> CGDirectDisplayID;
pub fn CGDisplayRotation(display: CGDirectDisplayID) -> libc::c_double;
pub fn CGDisplayScreenSize(display: CGDirectDisplayID) -> CGSize;
pub fn CGDisplaySerialNumber(display: CGDirectDisplayID) -> u32;
pub fn CGDisplayUnitNumber(display: CGDirectDisplayID) -> u32;
pub fn CGDisplayUsesOpenGLAcceleration(display: CGDirectDisplayID) -> boolean_t;
pub fn CGDisplayVendorNumber(display: CGDirectDisplayID) -> u32;
pub fn CGGetActiveDisplayList(
max_displays: u32,
active_displays: *mut CGDirectDisplayID,
display_count: *mut u32,
) -> CGError;
pub fn CGGetDisplaysWithRect(
rect: CGRect,
max_displays: u32,
displays: *mut CGDirectDisplayID,
matching_display_count: *mut u32,
) -> CGError;
pub fn CGDisplayModelNumber(display: CGDirectDisplayID) -> u32;
pub fn CGDisplayPixelsHigh(display: CGDirectDisplayID) -> libc::size_t;
pub fn CGDisplayPixelsWide(display: CGDirectDisplayID) -> libc::size_t;
pub fn CGDisplayBounds(display: CGDirectDisplayID) -> CGRect;
pub fn CGDisplayCreateImage(display: CGDirectDisplayID) -> crate::sys::CGImageRef;
pub fn CGDisplayCreateImageForRect(
display: CGDirectDisplayID,
rect: CGRect,
) -> crate::sys::CGImageRef;
// Capturing and Releasing Displays
pub fn CGDisplayCapture(display: CGDirectDisplayID) -> CGError;
pub fn CGDisplayRelease(display: CGDirectDisplayID) -> CGError;
pub fn CGShieldingWindowLevel() -> CGWindowLevel;
// Configuring Displays
pub fn CGBeginDisplayConfiguration(config: *mut CGDisplayConfigRef) -> CGError;
pub fn CGCancelDisplayConfiguration(config: CGDisplayConfigRef) -> CGError;
pub fn CGCompleteDisplayConfiguration(
config: CGDisplayConfigRef,
option: CGConfigureOption,
) -> CGError;
pub fn CGConfigureDisplayWithDisplayMode(
config: CGDisplayConfigRef,
display: CGDirectDisplayID,
mode: crate::sys::CGDisplayModeRef,
options: CFDictionaryRef,
) -> CGError;
pub fn CGConfigureDisplayMirrorOfDisplay(
config: CGDisplayConfigRef,
display: CGDirectDisplayID,
master: CGDirectDisplayID,
) -> CGError;
pub fn CGConfigureDisplayOrigin(
config: CGDisplayConfigRef,
display: CGDirectDisplayID,
x: i32,
y: i32,
) -> CGError;
pub fn CGRestorePermanentDisplayConfiguration();
pub fn CGDisplayCopyDisplayMode(display: CGDirectDisplayID) -> crate::sys::CGDisplayModeRef;
pub fn CGDisplayModeGetHeight(mode: crate::sys::CGDisplayModeRef) -> libc::size_t;
pub fn CGDisplayModeGetWidth(mode: crate::sys::CGDisplayModeRef) -> libc::size_t;
pub fn CGDisplayModeGetPixelHeight(mode: crate::sys::CGDisplayModeRef) -> libc::size_t;
pub fn CGDisplayModeGetPixelWidth(mode: crate::sys::CGDisplayModeRef) -> libc::size_t;
pub fn CGDisplayModeGetRefreshRate(mode: crate::sys::CGDisplayModeRef) -> libc::c_double;
pub fn CGDisplayModeGetIOFlags(mode: crate::sys::CGDisplayModeRef) -> u32;
pub fn CGDisplayModeCopyPixelEncoding(mode: crate::sys::CGDisplayModeRef) -> CFStringRef;
pub fn CGDisplayModeGetIODisplayModeID(mode: crate::sys::CGDisplayModeRef) -> i32;
pub fn CGDisplayCopyAllDisplayModes(
display: CGDirectDisplayID,
options: CFDictionaryRef,
) -> CFArrayRef;
pub fn CGDisplaySetDisplayMode(
display: CGDirectDisplayID,
mode: crate::sys::CGDisplayModeRef,
options: CFDictionaryRef,
) -> CGError;
// 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;
// Display Fade Effects
pub fn CGConfigureDisplayFadeEffect(
config: CGDisplayConfigRef,
fadeOutSeconds: CGDisplayFadeInterval,
fadeInSeconds: CGDisplayFadeInterval,
fadeRed: f32,
fadeGreen: f32,
fadeBlue: f32,
) -> CGError;
pub fn CGAcquireDisplayFadeReservation(
seconds: CGDisplayReservationInterval,
token: *mut CGDisplayFadeReservationToken,
) -> CGError;
pub fn CGDisplayFade(
token: CGDisplayFadeReservationToken,
duration: CGDisplayFadeInterval,
startBlend: CGDisplayBlendFraction,
endBlend: CGDisplayBlendFraction,
redBlend: f32,
greenBlend: f32,
blueBlend: f32,
synchronous: boolean_t,
) -> CGError;
// CGDisplayFadeOperationInProgress
pub fn CGReleaseDisplayFadeReservation(token: CGDisplayFadeReservationToken) -> CGError;
// Window Services Reference
pub fn CGWindowListCopyWindowInfo(
option: CGWindowListOption,
relativeToWindow: CGWindowID,
) -> CFArrayRef;
pub fn CGWindowListCreateImage(
screenBounds: CGRect,
listOptions: CGWindowListOption,
windowId: CGWindowID,
imageOptions: CGWindowImageOption,
) -> crate::sys::CGImageRef;
pub fn CGWindowListCreateImageFromArray(
screenBounds: CGRect,
windowArray: CFArrayRef,
imageOptions: CGWindowImageOption,
) -> crate::sys::CGImageRef;
}

825
vendor/core-graphics/src/event.rs vendored Normal file
View File

@@ -0,0 +1,825 @@
#![allow(non_upper_case_globals)]
use crate::event_source::CGEventSource;
use crate::geometry::CGPoint;
use core_foundation::{
base::{CFRelease, CFRetain, CFTypeID, TCFType},
mach_port::{CFMachPort, CFMachPortRef},
};
use foreign_types::ForeignType;
use libc::c_void;
use std::mem::ManuallyDrop;
pub type CGEventField = u32;
pub type CGKeyCode = u16;
pub type CGScrollEventUnit = u32;
bitflags! {
/// Flags for events
///
/// [Ref](http://opensource.apple.com/source/IOHIDFamily/IOHIDFamily-700/IOHIDSystem/IOKit/hidsystem/IOLLEvent.h)
#[repr(C)]
pub struct CGEventFlags: u64 {
const CGEventFlagNull = 0;
// Device-independent modifier key bits.
const CGEventFlagAlphaShift = 0x00010000;
const CGEventFlagShift = 0x00020000;
const CGEventFlagControl = 0x00040000;
const CGEventFlagAlternate = 0x00080000;
const CGEventFlagCommand = 0x00100000;
// Special key identifiers.
const CGEventFlagHelp = 0x00400000;
const CGEventFlagSecondaryFn = 0x00800000;
// Identifies key events from numeric keypad area on extended keyboards.
const CGEventFlagNumericPad = 0x00200000;
// Indicates if mouse/pen movement events are not being coalesced
const CGEventFlagNonCoalesced = 0x00000100;
}
}
/// Key codes for keys that are independent of keyboard layout.
///
/// [Ref](https://github.com/phracker/MacOSX-SDKs/blob/master/MacOSX10.13.sdk/System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/HIToolbox.framework/Versions/A/Headers/Events.h)
#[repr(C)]
pub struct KeyCode;
impl KeyCode {
pub const RETURN: CGKeyCode = 0x24;
pub const TAB: CGKeyCode = 0x30;
pub const SPACE: CGKeyCode = 0x31;
pub const DELETE: CGKeyCode = 0x33;
pub const ESCAPE: CGKeyCode = 0x35;
pub const COMMAND: CGKeyCode = 0x37;
pub const SHIFT: CGKeyCode = 0x38;
pub const CAPS_LOCK: CGKeyCode = 0x39;
pub const OPTION: CGKeyCode = 0x3A;
pub const CONTROL: CGKeyCode = 0x3B;
pub const RIGHT_COMMAND: CGKeyCode = 0x36;
pub const RIGHT_SHIFT: CGKeyCode = 0x3C;
pub const RIGHT_OPTION: CGKeyCode = 0x3D;
pub const RIGHT_CONTROL: CGKeyCode = 0x3E;
pub const FUNCTION: CGKeyCode = 0x3F;
pub const VOLUME_UP: CGKeyCode = 0x48;
pub const VOLUME_DOWN: CGKeyCode = 0x49;
pub const MUTE: CGKeyCode = 0x4A;
pub const F1: CGKeyCode = 0x7A;
pub const F2: CGKeyCode = 0x78;
pub const F3: CGKeyCode = 0x63;
pub const F4: CGKeyCode = 0x76;
pub const F5: CGKeyCode = 0x60;
pub const F6: CGKeyCode = 0x61;
pub const F7: CGKeyCode = 0x62;
pub const F8: CGKeyCode = 0x64;
pub const F9: CGKeyCode = 0x65;
pub const F10: CGKeyCode = 0x6D;
pub const F11: CGKeyCode = 0x67;
pub const F12: CGKeyCode = 0x6F;
pub const F13: CGKeyCode = 0x69;
pub const F14: CGKeyCode = 0x6B;
pub const F15: CGKeyCode = 0x71;
pub const F16: CGKeyCode = 0x6A;
pub const F17: CGKeyCode = 0x40;
pub const F18: CGKeyCode = 0x4F;
pub const F19: CGKeyCode = 0x50;
pub const F20: CGKeyCode = 0x5A;
pub const HELP: CGKeyCode = 0x72;
pub const HOME: CGKeyCode = 0x73;
pub const PAGE_UP: CGKeyCode = 0x74;
pub const FORWARD_DELETE: CGKeyCode = 0x75;
pub const END: CGKeyCode = 0x77;
pub const PAGE_DOWN: CGKeyCode = 0x79;
pub const LEFT_ARROW: CGKeyCode = 0x7B;
pub const RIGHT_ARROW: CGKeyCode = 0x7C;
pub const DOWN_ARROW: CGKeyCode = 0x7D;
pub const UP_ARROW: CGKeyCode = 0x7E;
}
#[repr(C)]
pub struct ScrollEventUnit {}
impl ScrollEventUnit {
pub const PIXEL: CGScrollEventUnit = 0;
pub const LINE: CGScrollEventUnit = 1;
}
/// Constants that specify the different types of input events.
///
/// [Ref](http://opensource.apple.com/source/IOHIDFamily/IOHIDFamily-700/IOHIDSystem/IOKit/hidsystem/IOLLEvent.h)
#[repr(u32)]
#[derive(Clone, Copy, Debug)]
pub enum CGEventType {
Null = 0,
// Mouse events.
LeftMouseDown = 1,
LeftMouseUp = 2,
RightMouseDown = 3,
RightMouseUp = 4,
MouseMoved = 5,
LeftMouseDragged = 6,
RightMouseDragged = 7,
// Keyboard events.
KeyDown = 10,
KeyUp = 11,
FlagsChanged = 12,
// Specialized control devices.
ScrollWheel = 22,
TabletPointer = 23,
TabletProximity = 24,
OtherMouseDown = 25,
OtherMouseUp = 26,
OtherMouseDragged = 27,
// Out of band event types. These are delivered to the event tap callback
// to notify it of unusual conditions that disable the event tap.
TapDisabledByTimeout = 0xFFFFFFFE,
TapDisabledByUserInput = 0xFFFFFFFF,
}
/// Constants used as keys to access specialized fields in low-level events.
///
/// [Ref](https://developer.apple.com/documentation/coregraphics/cgeventfield)
pub struct EventField;
impl EventField {
/// Key to access an integer field that contains the mouse button event
/// number. Matching mouse-down and mouse-up events will have the same
/// event number.
pub const MOUSE_EVENT_NUMBER: CGEventField = 0;
/// Key to access an integer field that contains the mouse button click
/// state. A click state of 1 represents a single click. A click state of
/// 2 represents a double-click. A click state of 3 represents a
/// triple-click.
pub const MOUSE_EVENT_CLICK_STATE: CGEventField = 1;
/// Key to access a double field that contains the mouse button pressure.
/// The pressure value may range from 0 to 1, with 0 representing the
/// mouse being up. This value is commonly set by tablet pens mimicking a
/// mouse.
pub const MOUSE_EVENT_PRESSURE: CGEventField = 2;
/// Key to access an integer field that contains the mouse button number.
pub const MOUSE_EVENT_BUTTON_NUMBER: CGEventField = 3;
/// Key to access an integer field that contains the horizontal mouse
/// delta since the last mouse movement event.
pub const MOUSE_EVENT_DELTA_X: CGEventField = 4;
/// Key to access an integer field that contains the vertical mouse delta
/// since the last mouse movement event.
pub const MOUSE_EVENT_DELTA_Y: CGEventField = 5;
/// Key to access an integer field. The value is non-zero if the event
/// should be ignored by the Inkwell subsystem.
pub const MOUSE_EVENT_INSTANT_MOUSER: CGEventField = 6;
/// Key to access an integer field that encodes the mouse event subtype as
/// a `kCFNumberIntType`.
pub const MOUSE_EVENT_SUB_TYPE: CGEventField = 7;
/// Key to access an integer field, non-zero when this is an autorepeat of
/// a key-down, and zero otherwise.
pub const KEYBOARD_EVENT_AUTOREPEAT: CGEventField = 8;
/// Key to access an integer field that contains the virtual keycode of the
/// key-down or key-up event.
pub const KEYBOARD_EVENT_KEYCODE: CGEventField = 9;
/// Key to access an integer field that contains the keyboard type
/// identifier.
pub const KEYBOARD_EVENT_KEYBOARD_TYPE: CGEventField = 10;
/// Key to access an integer field that contains scrolling data. This field
/// typically contains the change in vertical position since the last
/// scrolling event from a Mighty Mouse scroller or a single-wheel mouse
/// scroller.
pub const SCROLL_WHEEL_EVENT_DELTA_AXIS_1: CGEventField = 11;
/// Key to access an integer field that contains scrolling data. This field
/// typically contains the change in horizontal position since the last
/// scrolling event from a Mighty Mouse scroller.
pub const SCROLL_WHEEL_EVENT_DELTA_AXIS_2: CGEventField = 12;
/// Key to access a field that contains scrolling data. The scrolling data
/// represents a line-based or pixel-based change in vertical position
/// since the last scrolling event from a Mighty Mouse scroller or a
/// single-wheel mouse scroller. The scrolling data uses a fixed-point
/// 16.16 signed integer format. If this key is passed to
/// `CGEventGetDoubleValueField`, the fixed-point value is converted to a
/// double value.
pub const SCROLL_WHEEL_EVENT_FIXED_POINT_DELTA_AXIS_1: CGEventField = 93;
/// Key to access a field that contains scrolling data. The scrolling data
/// represents a line-based or pixel-based change in horizontal position
/// since the last scrolling event from a Mighty Mouse scroller. The
/// scrolling data uses a fixed-point 16.16 signed integer format. If this
/// key is passed to `CGEventGetDoubleValueField`, the fixed-point value is
/// converted to a double value.
pub const SCROLL_WHEEL_EVENT_FIXED_POINT_DELTA_AXIS_2: CGEventField = 94;
/// Key to access an integer field that contains pixel-based scrolling
/// data. The scrolling data represents the change in vertical position
/// since the last scrolling event from a Mighty Mouse scroller or a
/// single-wheel mouse scroller.
pub const SCROLL_WHEEL_EVENT_POINT_DELTA_AXIS_1: CGEventField = 96;
/// Key to access an integer field that contains pixel-based scrolling
/// data. The scrolling data represents the change in horizontal position
/// since the last scrolling event from a Mighty Mouse scroller.
pub const SCROLL_WHEEL_EVENT_POINT_DELTA_AXIS_2: CGEventField = 97;
/// Key to access an integer field that indicates whether the event should
/// be ignored by the Inkwell subsystem. If the value is non-zero, the
/// event should be ignored.
pub const SCROLL_WHEEL_EVENT_INSTANT_MOUSER: CGEventField = 14;
/// Key to access an integer field that contains the absolute X coordinate
/// in tablet space at full tablet resolution.
pub const TABLET_EVENT_POINT_X: CGEventField = 15;
/// Key to access an integer field that contains the absolute Y coordinate
/// in tablet space at full tablet resolution.
pub const TABLET_EVENT_POINT_Y: CGEventField = 16;
/// Key to access an integer field that contains the absolute Z coordinate
/// in tablet space at full tablet resolution.
pub const TABLET_EVENT_POINT_Z: CGEventField = 17;
/// Key to access an integer field that contains the tablet button state.
/// Bit 0 is the first button, and a set bit represents a closed or pressed
/// button. Up to 16 buttons are supported.
pub const TABLET_EVENT_POINT_BUTTONS: CGEventField = 18;
/// Key to access a double field that contains the tablet pen pressure. A
/// value of 0.0 represents no pressure, and 1.0 represents maximum
/// pressure.
pub const TABLET_EVENT_POINT_PRESSURE: CGEventField = 19;
/// Key to access a double field that contains the horizontal tablet pen
/// tilt. A value of 0 represents no tilt, and 1 represents maximum tilt.
pub const TABLET_EVENT_TILT_X: CGEventField = 20;
/// Key to access a double field that contains the vertical tablet pen
/// tilt. A value of 0 represents no tilt, and 1 represents maximum tilt.
pub const TABLET_EVENT_TILT_Y: CGEventField = 21;
/// Key to access a double field that contains the tablet pen rotation.
pub const TABLET_EVENT_ROTATION: CGEventField = 22;
/// Key to access a double field that contains the tangential pressure on
/// the device. A value of 0.0 represents no pressure, and 1.0 represents
/// maximum pressure.
pub const TABLET_EVENT_TANGENTIAL_PRESSURE: CGEventField = 23;
/// Key to access an integer field that contains the system-assigned unique
/// device ID.
pub const TABLET_EVENT_DEVICE_ID: CGEventField = 24;
/// Key to access an integer field that contains a vendor-specified value.
pub const TABLET_EVENT_VENDOR_1: CGEventField = 25;
/// Key to access an integer field that contains a vendor-specified value.
pub const TABLET_EVENT_VENDOR_2: CGEventField = 26;
/// Key to access an integer field that contains a vendor-specified value.
pub const TABLET_EVENT_VENDOR_3: CGEventField = 27;
/// Key to access an integer field that contains the vendor-defined ID,
/// typically the USB vendor ID.
pub const TABLET_PROXIMITY_EVENT_VENDOR_ID: CGEventField = 28;
/// Key to access an integer field that contains the vendor-defined tablet
/// ID, typically the USB product ID.
pub const TABLET_PROXIMITY_EVENT_TABLET_ID: CGEventField = 29;
/// Key to access an integer field that contains the vendor-defined ID of
/// the pointing device.
pub const TABLET_PROXIMITY_EVENT_POINTER_ID: CGEventField = 30;
/// Key to access an integer field that contains the system-assigned
/// device ID.
pub const TABLET_PROXIMITY_EVENT_DEVICE_ID: CGEventField = 31;
/// Key to access an integer field that contains the system-assigned
/// unique tablet ID.
pub const TABLET_PROXIMITY_EVENT_SYSTEM_TABLET_ID: CGEventField = 32;
/// Key to access an integer field that contains the vendor-assigned
/// pointer type.
pub const TABLET_PROXIMITY_EVENT_VENDOR_POINTER_TYPE: CGEventField = 33;
/// Key to access an integer field that contains the vendor-defined
/// pointer serial number.
pub const TABLET_PROXIMITY_EVENT_VENDOR_POINTER_SERIAL_NUMBER: CGEventField = 34;
/// Key to access an integer field that contains the vendor-defined unique
/// ID.
pub const TABLET_PROXIMITY_EVENT_VENDOR_UNIQUE_ID: CGEventField = 35;
/// Key to access an integer field that contains the device capabilities
/// mask.
pub const TABLET_PROXIMITY_EVENT_CAPABILITY_MASK: CGEventField = 36;
/// Key to access an integer field that contains the pointer type.
pub const TABLET_PROXIMITY_EVENT_POINTER_TYPE: CGEventField = 37;
/// Key to access an integer field that indicates whether the pen is in
/// proximity to the tablet. The value is non-zero if the pen is in
/// proximity to the tablet and zero when leaving the tablet.
pub const TABLET_PROXIMITY_EVENT_ENTER_PROXIMITY: CGEventField = 38;
/// Key to access a field that contains the event target process serial
/// number. The value is a 64-bit value.
pub const EVENT_TARGET_PROCESS_SERIAL_NUMBER: CGEventField = 39;
/// Key to access a field that contains the event target Unix process ID.
pub const EVENT_TARGET_UNIX_PROCESS_ID: CGEventField = 40;
/// Key to access a field that contains the event source Unix process ID.
pub const EVENT_SOURCE_UNIX_PROCESS_ID: CGEventField = 41;
/// Key to access a field that contains the event source user-supplied
/// data, up to 64 bits.
pub const EVENT_SOURCE_USER_DATA: CGEventField = 42;
/// Key to access a field that contains the event source Unix effective UID.
pub const EVENT_SOURCE_USER_ID: CGEventField = 43;
/// Key to access a field that contains the event source Unix effective
/// GID.
pub const EVENT_SOURCE_GROUP_ID: CGEventField = 44;
/// Key to access a field that contains the event source state ID used to
/// create this event.
pub const EVENT_SOURCE_STATE_ID: CGEventField = 45;
/// Key to access an integer field that indicates whether a scrolling event
/// contains continuous, pixel-based scrolling data. The value is non-zero
/// when the scrolling data is pixel-based and zero when the scrolling data
/// is line-based.
pub const SCROLL_WHEEL_EVENT_IS_CONTINUOUS: CGEventField = 88;
/// Added in 10.5; made public in 10.7.
pub const MOUSE_EVENT_WINDOW_UNDER_MOUSE_POINTER: CGEventField = 91;
pub const MOUSE_EVENT_WINDOW_UNDER_MOUSE_POINTER_THAT_CAN_HANDLE_THIS_EVENT: CGEventField = 92;
}
// Constants that specify buttons on a one, two, or three-button mouse.
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub enum CGMouseButton {
Left,
Right,
Center,
}
/// Possible tapping points for events.
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub enum CGEventTapLocation {
HID,
Session,
AnnotatedSession,
}
// The next three enums are taken from:
// [Ref](https://github.com/phracker/MacOSX-SDKs/blob/ef9fe35d5691b6dd383c8c46d867a499817a01b6/MacOSX10.15.sdk/System/Library/Frameworks/CoreGraphics.framework/Versions/A/Headers/CGEventTypes.h)
/* Constants that specify where a new event tap is inserted into the list of
active event taps. */
#[repr(u32)]
#[derive(Clone, Copy, Debug)]
pub enum CGEventTapPlacement {
HeadInsertEventTap = 0,
TailAppendEventTap,
}
/* Constants that specify whether a new event tap is an active filter or a
passive listener. */
#[repr(u32)]
#[derive(Clone, Copy, Debug)]
pub enum CGEventTapOptions {
Default = 0x00000000,
ListenOnly = 0x00000001,
}
pub type CGEventMask = u64;
/* Generate an event mask for a single type of event. */
macro_rules! CGEventMaskBit {
($eventType:expr) => {
1 << $eventType as CGEventMask
};
}
pub type CGEventTapProxy = *const c_void;
pub type CGEventTapCallBackFn<'tap_life> =
Box<dyn Fn(CGEventTapProxy, CGEventType, &CGEvent) -> Option<CGEvent> + 'tap_life>;
type CGEventTapCallBackInternal = unsafe extern "C" fn(
proxy: CGEventTapProxy,
etype: CGEventType,
event: crate::sys::CGEventRef,
user_info: *const c_void,
) -> crate::sys::CGEventRef;
unsafe extern "C" fn cg_event_tap_callback_internal(
_proxy: CGEventTapProxy,
_etype: CGEventType,
_event: crate::sys::CGEventRef,
_user_info: *const c_void,
) -> crate::sys::CGEventRef {
let callback = _user_info as *mut CGEventTapCallBackFn;
let event = CGEvent::from_ptr(_event);
let new_event = (*callback)(_proxy, _etype, &event);
let event = match new_event {
Some(new_event) => new_event,
None => event,
};
ManuallyDrop::new(event).as_ptr()
}
/// ```no_run
///extern crate core_foundation;
///use core_foundation::runloop::{kCFRunLoopCommonModes, CFRunLoop};
///use core_graphics::event::{CGEventTap, CGEventTapLocation, CGEventTapPlacement, CGEventTapOptions, CGEventType};
///let current = CFRunLoop::get_current();
///match CGEventTap::new(
/// CGEventTapLocation::HID,
/// CGEventTapPlacement::HeadInsertEventTap,
/// CGEventTapOptions::Default,
/// vec![CGEventType::MouseMoved],
/// |_a, _b, d| {
/// println!("{:?}", d.location());
/// None
/// },
/// ) {
/// Ok(tap) => unsafe {
/// let loop_source = tap
/// .mach_port
/// .create_runloop_source(0)
/// .expect("Somethings is bad ");
/// current.add_source(&loop_source, kCFRunLoopCommonModes);
/// tap.enable();
/// CFRunLoop::run_current();
/// },
/// Err(_) => (assert!(false)),
/// }
/// ```
pub struct CGEventTap<'tap_life> {
pub mach_port: CFMachPort,
pub callback_ref:
Box<dyn Fn(CGEventTapProxy, CGEventType, &CGEvent) -> Option<CGEvent> + 'tap_life>,
}
impl<'tap_life> CGEventTap<'tap_life> {
pub fn new<F: Fn(CGEventTapProxy, CGEventType, &CGEvent) -> Option<CGEvent> + 'tap_life>(
tap: CGEventTapLocation,
place: CGEventTapPlacement,
options: CGEventTapOptions,
events_of_interest: std::vec::Vec<CGEventType>,
callback: F,
) -> Result<CGEventTap<'tap_life>, ()> {
let event_mask: CGEventMask = events_of_interest
.iter()
.fold(CGEventType::Null as CGEventMask, |mask, &etype| {
mask | CGEventMaskBit!(etype)
});
let cb = Box::new(Box::new(callback) as CGEventTapCallBackFn);
let cbr = Box::into_raw(cb);
unsafe {
let event_tap_ref = CGEventTapCreate(
tap,
place,
options,
event_mask,
cg_event_tap_callback_internal,
cbr as *const c_void,
);
if !event_tap_ref.is_null() {
Ok(Self {
mach_port: (CFMachPort::wrap_under_create_rule(event_tap_ref)),
callback_ref: Box::from_raw(cbr),
})
} else {
let _ = Box::from_raw(cbr);
Err(())
}
}
}
pub fn enable(&self) {
unsafe { CGEventTapEnable(self.mach_port.as_concrete_TypeRef(), true) }
}
}
foreign_type! {
#[doc(hidden)]
pub unsafe type CGEvent {
type CType = crate::sys::CGEvent;
fn drop = |p| CFRelease(p as *mut _);
fn clone = |p| CFRetain(p as *const _) as *mut _;
}
}
impl CGEvent {
pub fn type_id() -> CFTypeID {
unsafe { CGEventGetTypeID() }
}
pub fn new(source: CGEventSource) -> Result<CGEvent, ()> {
unsafe {
let event_ref = CGEventCreate(source.as_ptr());
if !event_ref.is_null() {
Ok(Self::from_ptr(event_ref))
} else {
Err(())
}
}
}
pub fn new_keyboard_event(
source: CGEventSource,
keycode: CGKeyCode,
keydown: bool,
) -> Result<CGEvent, ()> {
unsafe {
let event_ref = CGEventCreateKeyboardEvent(source.as_ptr(), keycode, keydown);
if !event_ref.is_null() {
Ok(Self::from_ptr(event_ref))
} else {
Err(())
}
}
}
pub fn new_mouse_event(
source: CGEventSource,
mouse_type: CGEventType,
mouse_cursor_position: CGPoint,
mouse_button: CGMouseButton,
) -> Result<CGEvent, ()> {
unsafe {
let event_ref = CGEventCreateMouseEvent(
source.as_ptr(),
mouse_type,
mouse_cursor_position,
mouse_button,
);
if !event_ref.is_null() {
Ok(Self::from_ptr(event_ref))
} else {
Err(())
}
}
}
#[cfg(feature = "highsierra")]
pub fn new_scroll_event(
source: CGEventSource,
units: CGScrollEventUnit,
wheel_count: u32,
wheel1: i32,
wheel2: i32,
wheel3: i32,
) -> Result<CGEvent, ()> {
unsafe {
let event_ref = CGEventCreateScrollWheelEvent2(
source.as_ptr(),
units,
wheel_count,
wheel1,
wheel2,
wheel3,
);
if !event_ref.is_null() {
Ok(Self::from_ptr(event_ref))
} else {
Err(())
}
}
}
pub fn post(&self, tap_location: CGEventTapLocation) {
unsafe {
CGEventPost(tap_location, self.as_ptr());
}
}
pub fn post_from_tap(&self, tap_proxy: CGEventTapProxy) {
unsafe {
CGEventTapPostEvent(tap_proxy, 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) }
}
}
#[cfg_attr(feature = "link", link(name = "CoreGraphics", kind = "framework"))]
extern "C" {
/// 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: crate::sys::CGEventSourceRef) -> crate::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: crate::sys::CGEventSourceRef,
keycode: CGKeyCode,
keydown: bool,
) -> crate::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: crate::sys::CGEventSourceRef,
mouseType: CGEventType,
mouseCursorPosition: CGPoint,
mouseButton: CGMouseButton,
) -> crate::sys::CGEventRef;
/// A non-variadic variant version of CGEventCreateScrollWheelEvent.
///
/// Returns a new Quartz scrolling event.
///
/// This function allows you to create a scrolling event and customize the
/// event before posting it to the event system.
#[cfg(feature = "highsierra")]
fn CGEventCreateScrollWheelEvent2(
source: crate::sys::CGEventSourceRef,
units: CGScrollEventUnit,
wheelCount: u32,
wheel1: i32,
wheel2: i32,
wheel3: i32,
) -> crate::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: crate::sys::CGEventRef);
fn CGEventTapPostEvent(tapProxy: CGEventTapProxy, event: crate::sys::CGEventRef);
#[cfg(feature = "elcapitan")]
/// Post an event to a specified process ID
fn CGEventPostToPid(pid: libc::pid_t, event: crate::sys::CGEventRef);
/// Set the event flags of an event.
fn CGEventSetFlags(event: crate::sys::CGEventRef, flags: CGEventFlags);
/// Return the event flags of an event.
fn CGEventGetFlags(event: crate::sys::CGEventRef) -> CGEventFlags;
/// Return the location of an event in global display coordinates.
/// CGPointZero is returned if event is not a valid crate::sys::CGEventRef.
fn CGEventGetLocation(event: crate::sys::CGEventRef) -> CGPoint;
/// Set the event type of an event.
fn CGEventSetType(event: crate::sys::CGEventRef, eventType: CGEventType);
/// Return the event type of an event (left mouse down, for example).
fn CGEventGetType(event: crate::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: crate::sys::CGEventRef,
length: libc::c_ulong,
string: *const u16,
);
/// Return the integer value of a field in an event.
fn CGEventGetIntegerValueField(event: crate::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: crate::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: crate::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 fields 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: crate::sys::CGEventRef, field: CGEventField, value: f64);
// ::sys::CGEventTapRef is actually an CFMachPortRef
fn CGEventTapCreate(
tap: CGEventTapLocation,
place: CGEventTapPlacement,
options: CGEventTapOptions,
eventsOfInterest: CGEventMask,
callback: CGEventTapCallBackInternal,
userInfo: *const c_void,
) -> CFMachPortRef;
fn CGEventTapEnable(tap: CFMachPortRef, enable: bool);
}

View File

@@ -0,0 +1,46 @@
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)]
pub unsafe type CGEventSource {
type CType = crate::sys::CGEventSource;
fn drop = |p| CFRelease(p as *mut _);
fn clone = |p| CFRetain(p as *const _) as *mut _;
}
}
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(())
}
}
}
}
#[cfg_attr(feature = "link", link(name = "CoreGraphics", kind = "framework"))]
extern "C" {
/// 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) -> crate::sys::CGEventSourceRef;
}

179
vendor/core-graphics/src/font.rs vendored Normal file
View File

@@ -0,0 +1,179 @@
// 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 crate::data_provider::CGDataProvider;
use crate::geometry::CGRect;
use core_foundation::array::{CFArray, CFArrayRef};
use core_foundation::base::{CFRelease, CFRetain, CFType, CFTypeID, TCFType};
use core_foundation::data::{CFData, CFDataRef};
use core_foundation::dictionary::{CFDictionary, CFDictionaryRef};
use core_foundation::number::CFNumber;
use core_foundation::string::{CFString, CFStringRef};
use std::ptr::NonNull;
use foreign_types::ForeignType;
use libc::{c_int, size_t};
pub use core_graphics_types::base::CGGlyph;
foreign_type! {
#[doc(hidden)]
pub unsafe type CGFont: Send + Sync {
type CType = crate::sys::CGFont;
fn drop = |p| CFRelease(p as *mut _);
fn clone = |p| CFRetain(p as *const _) as *mut _;
}
}
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());
match NonNull::new(font_ref) {
Some(font_ref) => Ok(CGFont(font_ref)),
None => Err(()),
}
}
}
pub fn from_name(name: &CFString) -> Result<CGFont, ()> {
unsafe {
let font_ref = CGFontCreateWithFontName(name.as_concrete_TypeRef());
match NonNull::new(font_ref) {
Some(font_ref) => Ok(CGFont(font_ref)),
None => Err(()),
}
}
}
pub fn create_copy_from_variations(
&self,
vars: &CFDictionary<CFString, CFNumber>,
) -> Result<CGFont, ()> {
unsafe {
let font_ref =
CGFontCreateCopyWithVariations(self.as_ptr(), vars.as_concrete_TypeRef());
match NonNull::new(font_ref) {
Some(font_ref) => Ok(CGFont(font_ref)),
None => Err(()),
}
}
}
pub fn postscript_name(&self) -> CFString {
unsafe {
let string_ref = CGFontCopyPostScriptName(self.as_ptr());
TCFType::wrap_under_create_rule(string_ref)
}
}
pub fn get_glyph_b_boxes(&self, glyphs: &[CGGlyph], bboxes: &mut [CGRect]) -> bool {
unsafe {
assert!(bboxes.len() >= glyphs.len());
CGFontGetGlyphBBoxes(
self.as_ptr(),
glyphs.as_ptr(),
glyphs.len(),
bboxes.as_mut_ptr(),
)
}
}
pub fn get_glyph_advances(&self, glyphs: &[CGGlyph], advances: &mut [c_int]) -> bool {
unsafe {
assert!(advances.len() >= glyphs.len());
CGFontGetGlyphAdvances(
self.as_ptr(),
glyphs.as_ptr(),
glyphs.len(),
advances.as_mut_ptr(),
)
}
}
pub fn get_units_per_em(&self) -> c_int {
unsafe { CGFontGetUnitsPerEm(self.as_ptr()) }
}
pub fn copy_table_tags(&self) -> CFArray<u32> {
unsafe { TCFType::wrap_under_create_rule(CGFontCopyTableTags(self.as_ptr())) }
}
pub fn copy_table_for_tag(&self, tag: u32) -> Option<CFData> {
let data_ref = unsafe { CGFontCopyTableForTag(self.as_ptr(), tag) };
if !data_ref.is_null() {
Some(unsafe { TCFType::wrap_under_create_rule(data_ref) })
} else {
None
}
}
pub fn copy_variations(&self) -> Option<CFDictionary<CFString, CFNumber>> {
let variations = unsafe { CGFontCopyVariations(self.as_ptr()) };
if !variations.is_null() {
Some(unsafe { TCFType::wrap_under_create_rule(variations) })
} else {
None
}
}
pub fn copy_variation_axes(&self) -> Option<CFArray<CFDictionary<CFString, CFType>>> {
let axes = unsafe { CGFontCopyVariationAxes(self.as_ptr()) };
if !axes.is_null() {
Some(unsafe { TCFType::wrap_under_create_rule(axes) })
} else {
None
}
}
}
#[cfg_attr(feature = "link", link(name = "CoreGraphics", kind = "framework"))]
extern "C" {
// TODO: basically nothing has bindings (even commented-out) besides what we use.
fn CGFontCreateWithDataProvider(
provider: crate::sys::CGDataProviderRef,
) -> crate::sys::CGFontRef;
fn CGFontCreateWithFontName(name: CFStringRef) -> crate::sys::CGFontRef;
fn CGFontCreateCopyWithVariations(
font: crate::sys::CGFontRef,
vars: CFDictionaryRef,
) -> crate::sys::CGFontRef;
fn CGFontGetTypeID() -> CFTypeID;
fn CGFontCopyPostScriptName(font: crate::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: crate::sys::CGFontRef,
glyphs: *const CGGlyph,
count: size_t,
bboxes: *mut CGRect,
) -> bool;
fn CGFontGetGlyphAdvances(
font: crate::sys::CGFontRef,
glyphs: *const CGGlyph,
count: size_t,
advances: *mut c_int,
) -> bool;
fn CGFontGetUnitsPerEm(font: crate::sys::CGFontRef) -> c_int;
fn CGFontCopyTableTags(font: crate::sys::CGFontRef) -> CFArrayRef;
fn CGFontCopyTableForTag(font: crate::sys::CGFontRef, tag: u32) -> CFDataRef;
fn CGFontCopyVariations(font: crate::sys::CGFontRef) -> CFDictionaryRef;
fn CGFontCopyVariationAxes(font: crate::sys::CGFontRef) -> CFArrayRef;
}

10
vendor/core-graphics/src/geometry.rs vendored Normal file
View File

@@ -0,0 +1,10 @@
// Copyright 2013 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
pub use core_graphics_types::geometry::*;

88
vendor/core-graphics/src/gradient.rs vendored Normal file
View File

@@ -0,0 +1,88 @@
// 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 crate::base::CGFloat;
use crate::color::CGColor;
use crate::color_space::CGColorSpace;
use core_foundation::array::{CFArray, CFArrayRef};
use core_foundation::base::{CFRelease, CFRetain, TCFType};
use foreign_types::ForeignType;
use libc::size_t;
bitflags! {
#[repr(C)]
pub struct CGGradientDrawingOptions: u32 {
const CGGradientDrawsBeforeStartLocation = (1 << 0);
const CGGradientDrawsAfterEndLocation = (1 << 1);
}
}
foreign_type! {
#[doc(hidden)]
pub unsafe type CGGradient {
type CType = crate::sys::CGGradient;
fn drop = |p| CFRelease(p as *mut _);
fn clone = |p| CFRetain(p as *const _) as *mut _;
}
}
impl CGGradient {
pub fn create_with_color_components(
color_space: &CGColorSpace,
components: &[CGFloat],
locations: &[CGFloat],
count: usize,
) -> CGGradient {
unsafe {
let result = CGGradientCreateWithColorComponents(
color_space.as_ptr(),
components.as_ptr(),
locations.as_ptr(),
count,
);
assert!(!result.is_null());
Self::from_ptr(result)
}
}
pub fn create_with_colors(
color_space: &CGColorSpace,
colors: &CFArray<CGColor>,
locations: &[CGFloat],
) -> CGGradient {
unsafe {
let result = CGGradientCreateWithColors(
color_space.as_ptr(),
colors.as_concrete_TypeRef(),
locations.as_ptr(),
);
assert!(!result.is_null());
Self::from_ptr(result)
}
}
}
#[cfg_attr(feature = "link", link(name = "CoreGraphics", kind = "framework"))]
extern "C" {
fn CGGradientCreateWithColorComponents(
color_space: crate::sys::CGColorSpaceRef,
components: *const CGFloat,
locations: *const CGFloat,
count: size_t,
) -> crate::sys::CGGradientRef;
fn CGGradientCreateWithColors(
color_space: crate::sys::CGColorSpaceRef,
colors: CFArrayRef,
locations: *const CGFloat,
) -> crate::sys::CGGradientRef;
}

159
vendor/core-graphics/src/image.rs vendored Normal file
View File

@@ -0,0 +1,159 @@
use std::ptr;
use crate::base::CGFloat;
use crate::color_space::CGColorSpace;
use crate::data_provider::{CGDataProvider, CGDataProviderRef};
use crate::geometry::CGRect;
use core_foundation::base::{CFRetain, CFTypeID};
use core_foundation::data::CFData;
use foreign_types::{ForeignType, ForeignTypeRef};
use libc::size_t;
#[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)]
pub unsafe type CGImage {
type CType = crate::sys::CGImage;
fn drop = CGImageRelease;
fn clone = |p| CFRetain(p as *const _) as *mut _;
}
}
impl CGImage {
pub fn new(
width: size_t,
height: size_t,
bits_per_component: size_t,
bits_per_pixel: size_t,
bytes_per_row: size_t,
colorspace: &CGColorSpace,
bitmap_info: u32,
provider: &CGDataProvider,
should_interpolate: bool,
rendering_intent: u32,
) -> Self {
unsafe {
let result = CGImageCreate(
width,
height,
bits_per_component,
bits_per_pixel,
bytes_per_row,
colorspace.as_ptr(),
bitmap_info,
provider.as_ptr(),
ptr::null_mut(),
should_interpolate,
rendering_intent,
);
assert!(!result.is_null());
Self::from_ptr(result)
}
}
pub fn type_id() -> CFTypeID {
unsafe { CGImageGetTypeID() }
}
}
impl CGImageRef {
pub fn width(&self) -> size_t {
unsafe { CGImageGetWidth(self.as_ptr()) }
}
pub fn height(&self) -> size_t {
unsafe { CGImageGetHeight(self.as_ptr()) }
}
pub fn bits_per_component(&self) -> size_t {
unsafe { CGImageGetBitsPerComponent(self.as_ptr()) }
}
pub fn bits_per_pixel(&self) -> size_t {
unsafe { CGImageGetBitsPerPixel(self.as_ptr()) }
}
pub fn bytes_per_row(&self) -> size_t {
unsafe { CGImageGetBytesPerRow(self.as_ptr()) }
}
pub fn color_space(&self) -> CGColorSpace {
unsafe {
let cs = CGImageGetColorSpace(self.as_ptr());
CFRetain(cs as *mut _);
CGColorSpace::from_ptr(cs)
}
}
/// Returns the raw image bytes wrapped in `CFData`. Note, the returned `CFData` owns the
/// underlying buffer.
pub fn data(&self) -> CFData {
let data_provider =
unsafe { CGDataProviderRef::from_ptr(CGImageGetDataProvider(self.as_ptr())) };
data_provider.copy_data()
}
/// Returns a cropped image. If the `rect` specifies a rectangle which lies outside of the
/// image bounds, the `None` is returned.
pub fn cropped(&self, rect: CGRect) -> Option<CGImage> {
let image_ptr = unsafe { CGImageCreateWithImageInRect(self.as_ptr(), rect) };
if !image_ptr.is_null() {
Some(unsafe { CGImage::from_ptr(image_ptr) })
} else {
None
}
}
}
#[cfg_attr(feature = "link", link(name = "CoreGraphics", kind = "framework"))]
extern "C" {
fn CGImageGetTypeID() -> CFTypeID;
fn CGImageGetWidth(image: crate::sys::CGImageRef) -> size_t;
fn CGImageGetHeight(image: crate::sys::CGImageRef) -> size_t;
fn CGImageGetBitsPerComponent(image: crate::sys::CGImageRef) -> size_t;
fn CGImageGetBitsPerPixel(image: crate::sys::CGImageRef) -> size_t;
fn CGImageGetBytesPerRow(image: crate::sys::CGImageRef) -> size_t;
fn CGImageGetColorSpace(image: crate::sys::CGImageRef) -> crate::sys::CGColorSpaceRef;
fn CGImageGetDataProvider(image: crate::sys::CGImageRef) -> crate::sys::CGDataProviderRef;
fn CGImageRelease(image: crate::sys::CGImageRef);
fn CGImageCreate(
width: size_t,
height: size_t,
bitsPerComponent: size_t,
bitsPerPixel: size_t,
bytesPerRow: size_t,
space: crate::sys::CGColorSpaceRef,
bitmapInfo: u32,
provider: crate::sys::CGDataProviderRef,
decode: *const CGFloat,
shouldInterpolate: bool,
intent: u32,
) -> crate::sys::CGImageRef;
fn CGImageCreateWithImageInRect(
image: crate::sys::CGImageRef,
rect: CGRect,
) -> crate::sys::CGImageRef;
//fn CGImageGetAlphaInfo(image: ::sys::CGImageRef) -> CGImageAlphaInfo;
//fn CGImageCreateCopyWithColorSpace(image: ::sys::CGImageRef, space: ::sys::CGColorSpaceRef) -> ::sys::CGImageRef
}

45
vendor/core-graphics/src/lib.rs vendored Normal file
View File

@@ -0,0 +1,45 @@
// Copyright 2013 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
extern crate libc;
#[macro_use]
extern crate core_foundation;
#[macro_use]
extern crate bitflags;
#[macro_use]
extern crate foreign_types;
extern crate core_graphics_types;
#[cfg(target_os = "macos")]
pub mod access;
pub mod base;
pub mod color;
pub mod color_space;
pub mod context;
pub mod data_provider;
#[cfg(target_os = "macos")]
pub mod display;
#[cfg(target_os = "macos")]
pub mod event;
#[cfg(target_os = "macos")]
pub mod event_source;
pub mod font;
pub mod geometry;
pub mod gradient;
pub mod image;
pub mod path;
#[cfg(target_os = "macos")]
pub mod private;
pub mod sys;
#[cfg(target_os = "macos")]
pub mod window;

136
vendor/core-graphics/src/path.rs vendored Normal file
View File

@@ -0,0 +1,136 @@
// Copyright 2017 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
pub use crate::sys::CGPathRef as SysCGPathRef;
use crate::geometry::{CGAffineTransform, CGPoint, CGRect};
use core_foundation::base::{CFRelease, CFRetain, CFTypeID};
use foreign_types::ForeignType;
use libc::c_void;
use std::fmt::{self, Debug, Formatter};
use std::marker::PhantomData;
use std::ops::Deref;
use std::ptr;
use std::slice;
foreign_type! {
#[doc(hidden)]
pub unsafe type CGPath {
type CType = crate::sys::CGPath;
fn drop = |p| CFRelease(p as *mut _);
fn clone = |p| CFRetain(p as *const _) as *mut _;
}
}
impl CGPath {
pub fn from_rect(rect: CGRect, transform: Option<&CGAffineTransform>) -> CGPath {
unsafe {
let transform = match transform {
None => ptr::null(),
Some(transform) => transform as *const CGAffineTransform,
};
CGPath::from_ptr(CGPathCreateWithRect(rect, transform))
}
}
pub fn type_id() -> CFTypeID {
unsafe { CGPathGetTypeID() }
}
pub fn apply<'a, F>(&'a self, mut closure: &'a F)
where
F: FnMut(CGPathElementRef<'a>),
{
unsafe {
CGPathApply(
self.as_ptr(),
&mut closure as *mut _ as *mut c_void,
do_apply::<F>,
);
}
unsafe extern "C" fn do_apply<'a, F>(info: *mut c_void, element: *const CGPathElement)
where
F: FnMut(CGPathElementRef<'a>),
{
let closure = info as *mut *mut F;
(**closure)(CGPathElementRef::new(element))
}
}
}
#[repr(i32)]
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum CGPathElementType {
MoveToPoint = 0,
AddLineToPoint = 1,
AddQuadCurveToPoint = 2,
AddCurveToPoint = 3,
CloseSubpath = 4,
}
pub struct CGPathElementRef<'a> {
element: *const CGPathElement,
phantom: PhantomData<&'a CGPathElement>,
}
impl<'a> CGPathElementRef<'a> {
fn new<'b>(element: *const CGPathElement) -> CGPathElementRef<'b> {
CGPathElementRef {
element,
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);
#[cfg_attr(feature = "link", link(name = "CoreGraphics", kind = "framework"))]
extern "C" {
fn CGPathCreateWithRect(
rect: CGRect,
transform: *const CGAffineTransform,
) -> crate::sys::CGPathRef;
fn CGPathApply(path: crate::sys::CGPathRef, info: *mut c_void, function: CGPathApplierFunction);
fn CGPathGetTypeID() -> CFTypeID;
}

116
vendor/core-graphics/src/private.rs vendored Normal file
View File

@@ -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 crate::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 }
}
}
#[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 }
}
}
}
/// 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,
window_number,
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 crate::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;
#[cfg_attr(feature = "link", link(name = "CoreGraphics", kind = "framework"))]
extern "C" {
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;
}
}

44
vendor/core-graphics/src/sys.rs vendored Normal file
View File

@@ -0,0 +1,44 @@
use std::os::raw::c_void;
pub enum CGImage {}
pub type CGImageRef = *mut CGImage;
#[repr(C)]
pub struct __CGColor(c_void);
pub type CGColorRef = *const __CGColor;
pub enum CGColorSpace {}
pub type CGColorSpaceRef = *mut CGColorSpace;
pub enum CGPath {}
pub type CGPathRef = *mut CGPath;
pub enum CGDataProvider {}
pub type CGDataProviderRef = *mut CGDataProvider;
pub enum CGFont {}
pub type CGFontRef = *mut CGFont;
pub enum CGContext {}
pub type CGContextRef = *mut CGContext;
pub enum CGGradient {}
pub type CGGradientRef = *mut CGGradient;
#[cfg(target_os = "macos")]
mod macos {
pub enum CGEventTap {}
pub type CGEventTapRef = core_foundation::mach_port::CFMachPortRef;
pub enum CGEvent {}
pub type CGEventRef = *mut CGEvent;
pub enum CGEventSource {}
pub type CGEventSourceRef = *mut CGEventSource;
pub enum CGDisplayMode {}
pub type CGDisplayModeRef = *mut CGDisplayMode;
}
#[cfg(target_os = "macos")]
pub use self::macos::*;

165
vendor/core-graphics/src/window.rs vendored Normal file
View File

@@ -0,0 +1,165 @@
// Copyright 2018 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![allow(non_upper_case_globals)]
use core_foundation::array::{CFArray, CFArrayRef};
use core_foundation::base::{CFType, TCFType};
use core_foundation::dictionary::CFDictionary;
use core_foundation::string::{CFString, CFStringRef};
use foreign_types::ForeignType;
use crate::geometry::CGRect;
use crate::image::CGImage;
use crate::sys;
pub type CGWindowID = u32;
pub type CGWindowSharingType = u32;
pub const kCGWindowSharingNone: CGWindowSharingType = 0;
pub const kCGWindowSharingReadOnly: CGWindowSharingType = 1;
pub const kCGWindowSharingReadWrite: CGWindowSharingType = 1;
pub type CGWindowBackingType = u32;
pub const kCGWindowBackingStoreRetained: CGWindowBackingType = 0;
pub const kCGWindowBackingStoreNonretained: CGWindowBackingType = 1;
pub const kCGWindowBackingStoreBuffered: CGWindowBackingType = 2;
// https://developer.apple.com/documentation/coregraphics/quartz_window_services/window_list_option_constants?language=objc
pub type CGWindowListOption = u32;
pub const kCGWindowListOptionAll: CGWindowListOption = 0;
pub const kCGWindowListOptionOnScreenOnly: CGWindowListOption = 1 << 0;
pub const kCGWindowListOptionOnScreenAboveWindow: CGWindowListOption = 1 << 1;
pub const kCGWindowListOptionOnScreenBelowWindow: CGWindowListOption = 1 << 2;
pub const kCGWindowListOptionIncludingWindow: CGWindowListOption = 1 << 3;
pub const kCGWindowListExcludeDesktopElements: CGWindowListOption = 1 << 4;
pub type CGWindowImageOption = u32;
pub const kCGWindowImageDefault: CGWindowImageOption = 0;
pub const kCGWindowImageBoundsIgnoreFraming: CGWindowImageOption = 1 << 0;
pub const kCGWindowImageShouldBeOpaque: CGWindowImageOption = 1 << 1;
pub const kCGWindowImageOnlyShadows: CGWindowImageOption = 1 << 2;
pub const kCGWindowImageBestResolution: CGWindowImageOption = 1 << 3;
pub const kCGWindowImageNominalResolution: CGWindowImageOption = 1 << 4;
pub const kCGNullWindowID: CGWindowID = 0;
pub fn copy_window_info(
option: CGWindowListOption,
relative_to_window: CGWindowID,
) -> Option<CFArray> {
unsafe {
let array = CGWindowListCopyWindowInfo(option, relative_to_window);
if array.is_null() {
None
} else {
Some(TCFType::wrap_under_create_rule(array))
}
}
}
pub fn create_window_list(
option: CGWindowListOption,
relative_to_window: CGWindowID,
) -> Option<CFArray<CGWindowID>> {
unsafe {
let array = CGWindowListCreate(option, relative_to_window);
if array.is_null() {
None
} else {
Some(TCFType::wrap_under_create_rule(array))
}
}
}
pub fn create_description_from_array(
window_array: CFArray<CGWindowID>,
) -> Option<CFArray<CFDictionary<CFString, CFType>>> {
unsafe {
let array = CGWindowListCreateDescriptionFromArray(window_array.as_concrete_TypeRef());
if array.is_null() {
None
} else {
Some(TCFType::wrap_under_create_rule(array))
}
}
}
pub fn create_image(
screen_bounds: CGRect,
list_option: CGWindowListOption,
window_id: CGWindowID,
image_option: CGWindowImageOption,
) -> Option<CGImage> {
unsafe {
let image = CGWindowListCreateImage(screen_bounds, list_option, window_id, image_option);
if image.is_null() {
None
} else {
Some(CGImage::from_ptr(image))
}
}
}
pub fn create_image_from_array(
screen_bounds: CGRect,
window_array: CFArray,
image_option: CGWindowImageOption,
) -> Option<CGImage> {
unsafe {
let image = CGWindowListCreateImageFromArray(
screen_bounds,
window_array.as_concrete_TypeRef(),
image_option,
);
if image.is_null() {
None
} else {
Some(CGImage::from_ptr(image))
}
}
}
#[cfg_attr(feature = "link", link(name = "CoreGraphics", kind = "framework"))]
extern "C" {
pub static kCGWindowNumber: CFStringRef;
pub static kCGWindowStoreType: CFStringRef;
pub static kCGWindowLayer: CFStringRef;
pub static kCGWindowBounds: CFStringRef;
pub static kCGWindowSharingState: CFStringRef;
pub static kCGWindowAlpha: CFStringRef;
pub static kCGWindowOwnerPID: CFStringRef;
pub static kCGWindowMemoryUsage: CFStringRef;
pub static kCGWindowWorkspace: CFStringRef;
pub static kCGWindowOwnerName: CFStringRef;
pub static kCGWindowName: CFStringRef;
pub static kCGWindowIsOnscreen: CFStringRef;
pub static kCGWindowBackingLocationVideoMemory: CFStringRef;
pub fn CGWindowListCopyWindowInfo(
option: CGWindowListOption,
relativeToWindow: CGWindowID,
) -> CFArrayRef;
pub fn CGWindowListCreate(
option: CGWindowListOption,
relativeToWindow: CGWindowID,
) -> CFArrayRef;
pub fn CGWindowListCreateDescriptionFromArray(windowArray: CFArrayRef) -> CFArrayRef;
pub fn CGWindowListCreateImage(
screenBounds: CGRect,
listOption: CGWindowListOption,
windowID: CGWindowID,
imageOption: CGWindowImageOption,
) -> *mut sys::CGImage;
pub fn CGWindowListCreateImageFromArray(
screenBounds: CGRect,
windowArray: CFArrayRef,
imageOption: CGWindowImageOption,
) -> *mut sys::CGImage;
}