diff --git a/src/geometry.rs b/src/geometry.rs index fbe1280..e4145da 100644 --- a/src/geometry.rs +++ b/src/geometry.rs @@ -9,20 +9,76 @@ use base::CGFloat; +pub const CG_ZERO_POINT: CGPoint = CGPoint { + x: 0.0, + y: 0.0, +}; + #[repr(C)] +#[derive(Clone, Copy, Debug)] pub struct CGSize { pub width: CGFloat, pub height: CGFloat, } +impl CGSize { + #[inline] + pub fn new(width: CGFloat, height: CGFloat) -> CGSize { + CGSize { + width: width, + height: height, + } + } +} + #[repr(C)] +#[derive(Clone, Copy, Debug)] pub struct CGPoint { pub x: CGFloat, pub y: CGFloat, } +impl CGPoint { + #[inline] + pub fn new(x: CGFloat, y: CGFloat) -> CGPoint { + CGPoint { + x: x, + y: y, + } + } +} + #[repr(C)] +#[derive(Clone, Copy, Debug)] pub struct CGRect { pub origin: CGPoint, pub size: CGSize } + +impl CGRect { + #[inline] + pub fn new(origin: &CGPoint, size: &CGSize) -> CGRect { + CGRect { + origin: *origin, + size: *size, + } + } + + #[inline] + pub fn inset(&self, size: &CGSize) -> CGRect { + unsafe { + ffi::CGRectInset(*self, size.width, size.height) + } + } +} + +mod ffi { + use base::CGFloat; + use geometry::CGRect; + + #[link(name = "ApplicationServices", kind = "framework")] + extern { + pub fn CGRectInset(rect: CGRect, dx: CGFloat, dy: CGFloat) -> CGRect; + } +} + diff --git a/src/private.rs b/src/private.rs index ff9a57d..518c55c 100644 --- a/src/private.rs +++ b/src/private.rs @@ -12,10 +12,11 @@ //! These are liable to change at any time. Use with caution! use geometry::CGRect; +use libc::{c_int, c_uint}; use std::ptr; pub struct CGSRegion { - region: ffi::CGSRegion, + region: ffi::CGSRegionRef, } impl Drop for CGSRegion { @@ -37,21 +38,79 @@ impl CGSRegion { } } } + + #[inline] + pub fn from_rects(rects: &[CGRect]) -> CGSRegion { + unsafe { + let mut region = ptr::null_mut(); + assert!(ffi::CGSNewRegionWithRectList(rects.as_ptr(), + rects.len() as c_uint, + &mut region) == 0); + CGSRegion { + region: region, + } + } + } +} + +/// This should always be memory-safe; the window server rejects any invalid surface IDs. +pub struct CGSSurface { + context_id: c_uint, + window_number: c_int, + surface_id: c_uint, +} + +impl CGSSurface { + #[inline] + pub fn from_ids(context_id: c_uint, window_number: c_int, surface_id: c_uint) -> CGSSurface { + CGSSurface { + context_id: context_id, + window_number: window_number, + surface_id: surface_id, + } + } + + #[inline] + pub fn id(&self) -> c_uint { + self.surface_id + } + + #[inline] + pub fn set_shape(&self, region: &CGSRegion) { + unsafe { + assert!(ffi::CGSSetSurfaceShape(self.context_id, + self.window_number, + self.surface_id, + region.region) == 0) + } + } } mod ffi { use geometry::CGRect; + use libc::{c_int, c_uint}; // This is an enum so that we can't easily make instances of this opaque type. enum CGSRegionObject {} - pub type CGSRegion = *mut CGSRegionObject; + pub type CGError = OSStatus; + pub type CGSRegionRef = *mut CGSRegionObject; pub type OSStatus = i32; #[link(name = "ApplicationServices", kind = "framework")] extern { - pub fn CGSRegionRelease(region: CGSRegion); - pub fn CGSNewRegionWithRect(rect: *const CGRect, region: *mut CGSRegion) -> OSStatus; + 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; } }