From 40ee246becf4098f6eec13cecc2f2f974093056e Mon Sep 17 00:00:00 2001 From: Kornel Date: Fri, 15 Sep 2017 00:41:43 +0100 Subject: [PATCH] Use foreign-types for CGEventSource --- src/event.rs | 16 ++++----- src/event_source.rs | 80 +++++++++------------------------------------ src/sys.rs | 3 ++ 3 files changed, 26 insertions(+), 73 deletions(-) diff --git a/src/event.rs b/src/event.rs index e064258..c3ef9bc 100644 --- a/src/event.rs +++ b/src/event.rs @@ -1,8 +1,8 @@ #![allow(non_upper_case_globals)] -use core_foundation::base::{CFRelease, CFRetain, CFTypeID, TCFType}; +use core_foundation::base::{CFRelease, CFRetain, CFTypeID}; use geometry::CGPoint; -use event_source::{CGEventSource,CGEventSourceRef}; +use event_source::CGEventSource; use libc; @@ -109,7 +109,7 @@ impl CGEvent { pub fn new(source: CGEventSource) -> Result { unsafe { - let event_ref = CGEventCreate(source.as_concrete_TypeRef()); + let event_ref = CGEventCreate(source.as_ptr()); if !event_ref.is_null() { Ok(Self::from_ptr(event_ref)) } else { @@ -124,7 +124,7 @@ impl CGEvent { keydown: bool ) -> Result { unsafe { - let event_ref = CGEventCreateKeyboardEvent(source.as_concrete_TypeRef(), keycode, keydown); + let event_ref = CGEventCreateKeyboardEvent(source.as_ptr(), keycode, keydown); if !event_ref.is_null() { Ok(Self::from_ptr(event_ref)) } else { @@ -140,7 +140,7 @@ impl CGEvent { mouse_button: CGMouseButton ) -> Result { unsafe { - let event_ref = CGEventCreateMouseEvent(source.as_concrete_TypeRef(), mouse_type, + 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)) @@ -213,7 +213,7 @@ extern { /// Return a new event using the event source `source'. If `source' is NULL, /// the default source is used. - fn CGEventCreate(source: CGEventSourceRef) -> ::sys::CGEventRef; + fn CGEventCreate(source: ::sys::CGEventSourceRef) -> ::sys::CGEventRef; /// Return a new keyboard event. /// @@ -225,7 +225,7 @@ extern { /// 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: CGEventSourceRef, keycode: CGKeyCode, + fn CGEventCreateKeyboardEvent(source: ::sys::CGEventSourceRef, keycode: CGKeyCode, keydown: bool) -> ::sys::CGEventRef; /// Return a new mouse event. @@ -241,7 +241,7 @@ extern { /// 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: CGEventSourceRef, mouseType: CGEventType, + fn CGEventCreateMouseEvent(source: ::sys::CGEventSourceRef, mouseType: CGEventType, mouseCursorPosition: CGPoint, mouseButton: CGMouseButton) -> ::sys::CGEventRef; /// Post an event into the event stream at a specified location. diff --git a/src/event_source.rs b/src/event_source.rs index c38aca9..b4e96c3 100644 --- a/src/event_source.rs +++ b/src/event_source.rs @@ -1,7 +1,5 @@ -use core_foundation::base::{CFRelease, CFRetain, CFTypeID, CFTypeRef, TCFType}; - -use std::mem; -use std::ptr; +use core_foundation::base::{CFRelease, CFRetain, CFTypeID}; +use foreign_types::ForeignType; /// Possible source states of an event source. #[repr(C)] @@ -12,75 +10,27 @@ pub enum CGEventSourceStateID { HIDSystemState = 1, } -// This is an enum due to zero-sized types warnings. -// For more details see https://github.com/rust-lang/rust/issues/27303 -pub enum __CGEventSource {} - -pub type CGEventSourceRef = *const __CGEventSource; - -pub struct CGEventSource { - obj: CGEventSourceRef, +foreign_type! { + #[doc(hidden)] + type CType = ::sys::CGEventSource; + fn drop = |p| CFRelease(p as *mut _); + fn clone = |p| CFRetain(p as *const _) as *mut _; + pub struct CGEventSource; + pub struct CGEventSourceRef; } -impl Clone for CGEventSource { - #[inline] - fn clone(&self) -> CGEventSource { - unsafe { - TCFType::wrap_under_get_rule(self.obj) - } - } -} - -impl Drop for CGEventSource { - fn drop(&mut self) { - unsafe { - let ptr = self.as_CFTypeRef(); - assert!(ptr != ptr::null()); - CFRelease(ptr); - } - } -} - -impl TCFType for CGEventSource { - #[inline] - fn as_concrete_TypeRef(&self) -> CGEventSourceRef { - self.obj - } - - #[inline] - unsafe fn wrap_under_get_rule(reference: CGEventSourceRef) -> CGEventSource { - let reference: CGEventSourceRef = mem::transmute(CFRetain(mem::transmute(reference))); - TCFType::wrap_under_create_rule(reference) - } - - #[inline] - fn as_CFTypeRef(&self) -> CFTypeRef { - unsafe { - mem::transmute(self.as_concrete_TypeRef()) - } - } - - #[inline] - unsafe fn wrap_under_create_rule(obj: CGEventSourceRef) -> CGEventSource { - CGEventSource { - obj: obj, - } - } - - #[inline] - fn type_id() -> CFTypeID { +impl CGEventSource { + pub fn type_id() -> CFTypeID { unsafe { CGEventSourceGetTypeID() } } -} -impl CGEventSource { - pub fn new(state_id: CGEventSourceStateID) -> Result { + pub fn new(state_id: CGEventSourceStateID) -> Result { unsafe { let event_source_ref = CGEventSourceCreate(state_id); - if event_source_ref != ptr::null() { - Ok(TCFType::wrap_under_create_rule(event_source_ref)) + if !event_source_ref.is_null() { + Ok(Self::from_ptr(event_source_ref)) } else { Err(()) } @@ -94,5 +44,5 @@ extern { fn CGEventSourceGetTypeID() -> CFTypeID; /// Return a Quartz event source created with a specified source state. - fn CGEventSourceCreate(stateID: CGEventSourceStateID) -> CGEventSourceRef; + fn CGEventSourceCreate(stateID: CGEventSourceStateID) -> ::sys::CGEventSourceRef; } diff --git a/src/sys.rs b/src/sys.rs index e7dd44f..513b6e9 100644 --- a/src/sys.rs +++ b/src/sys.rs @@ -13,6 +13,9 @@ pub type CGFontRef = *mut CGFont; pub enum CGEvent {} pub type CGEventRef = *mut CGEvent; +pub enum CGEventSource {} +pub type CGEventSourceRef = *mut CGEventSource; + pub enum CGContext {} pub type CGContextRef = *mut CGContext;