From b57886be2201d0ab87561d6a585d924256de7b2d Mon Sep 17 00:00:00 2001 From: Kristian Takvam Date: Sun, 1 Feb 2015 15:00:41 -0800 Subject: [PATCH 1/3] Added support for CFURLCreateWithFileSystemPath. --- src/url.rs | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/src/url.rs b/src/url.rs index bc80a45..e21696d 100644 --- a/src/url.rs +++ b/src/url.rs @@ -11,7 +11,9 @@ #![allow(non_upper_case_globals)] -use base::{CFOptionFlags, CFRelease, CFRetain, CFTypeID, CFTypeRef, TCFType}; +use base::{CFAllocatorRef, CFIndex, CFOptionFlags, CFRelease, CFRetain}; +use base::{Boolean, CFTypeID, CFTypeRef, TCFType}; +use base::{kCFAllocatorDefault}; use string::{CFString, CFStringRef}; use std::fmt; @@ -77,8 +79,31 @@ impl fmt::Debug for CFURL { } } +impl CFURL { + pub fn from_file_system_path(filePath: CFString, pathStyle: CFURLPathStyle, isDirectory: bool) -> CFURL { + unsafe { + let url_ref = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, filePath.as_concrete_TypeRef(), pathStyle, isDirectory as u8); + TCFType::wrap_under_create_rule(url_ref) + } + } + + pub fn get_string(&self) -> CFString { + unsafe { + TCFType::wrap_under_get_rule(CFURLGetString(self.obj)) + } + } +} + type CFURLBookmarkCreationOptions = CFOptionFlags; +pub type CFURLPathStyle = CFIndex; + +/* typedef CF_ENUM(CFIndex, CFURLPathStyle) */ +pub const kCFURLPOSIXPathStyle: CFURLPathStyle = 0; +pub const kCFURLHFSPathStyle: CFURLPathStyle = 1; +pub const kCFURLWindowsPathStyle: CFURLPathStyle = 2; + + // static kCFURLBookmarkCreationPreferFileIDResolutionMask: CFURLBookmarkCreationOptions = // (1 << 8) as u32; // static kCFURLBookmarkCreationMinimalBookmarkMask: CFURLBookmarkCreationOptions = @@ -149,6 +174,7 @@ extern { //fn CFURLCreateFromFSRef //fn CFURLCreateWithBytes //fn CFURLCreateWithFileSystemPath + fn CFURLCreateWithFileSystemPath(allocator: CFAllocatorRef, filePath: CFStringRef, pathStyle: CFURLPathStyle, isDirectory: Boolean) -> CFURLRef; //fn CFURLCreateWithFileSystemPathRelativeToBase //fn CFURLCreateWithString(allocator: CFAllocatorRef, urlString: CFStringRef, // baseURL: CFURLRef) -> CFURLRef; @@ -208,3 +234,11 @@ extern { //fn CFURLStartAccessingSecurityScopedResource //fn CFURLStopAccessingSecurityScopedResource } + +#[test] +fn file_url_from_path() { + let path = "/usr/local/foo/"; + let cfstr_path = CFString::from_static_string(path); + let cfurl = CFURL::from_file_system_path(cfstr_path, kCFURLPOSIXPathStyle, true); + assert!("file:///usr/local/foo/" == cfurl.get_string().to_string().as_slice()); +} From de46d4f1a55cf10b99aac91ace946ba85042b35e Mon Sep 17 00:00:00 2001 From: Kristian Takvam Date: Tue, 3 Feb 2015 23:07:49 -0800 Subject: [PATCH 2/3] Added some CFRunLoop support. Timers work. --- src/date.rs | 16 +++ src/lib.rs | 4 + src/runloop.rs | 355 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 375 insertions(+) create mode 100644 src/date.rs create mode 100644 src/runloop.rs diff --git a/src/date.rs b/src/date.rs new file mode 100644 index 0000000..df1c818 --- /dev/null +++ b/src/date.rs @@ -0,0 +1,16 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +pub type CFTimeInterval = f64; +pub type CFAbsoluteTime = CFTimeInterval; + +#[link(name = "CoreFoundation", kind = "framework")] +extern { + pub fn CFAbsoluteTimeGetCurrent() -> CFAbsoluteTime; +} diff --git a/src/lib.rs b/src/lib.rs index 0f0c117..199d535 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -36,6 +36,10 @@ pub mod string; pub mod url; #[cfg(target_os="macos")] pub mod bundle; +#[cfg(target_os="macos")] +pub mod date; +#[cfg(target_os="macos")] +pub mod runloop; #[cfg(all(target_os="macos", test))] pub mod test { diff --git a/src/runloop.rs b/src/runloop.rs new file mode 100644 index 0000000..0c05ce7 --- /dev/null +++ b/src/runloop.rs @@ -0,0 +1,355 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use base::{CFAllocatorRef, CFIndex, CFOptionFlags, CFRelease, CFRetain}; +use base::{CFTypeID, CFTypeRef, TCFType}; +use base::{kCFAllocatorDefault}; +use base::{Boolean}; +use string::{CFString, CFStringRef}; +use date::{CFAbsoluteTime, CFTimeInterval, CFAbsoluteTimeGetCurrent}; +use libc::c_void; +use std::mem; +use std::ptr; + +#[repr(C)] +struct __CFRunLoop; + +pub type CFRunLoopRef = *const __CFRunLoop; + +/// FIXME(pcwalton): Should be a newtype struct, but that fails due to a Rust compiler bug. +pub struct CFRunLoop { + obj: CFRunLoopRef, +} + +impl Drop for CFRunLoop { + fn drop(&mut self) { + unsafe { + CFRelease(self.as_CFTypeRef()) + } + } +} + +impl TCFType for CFRunLoop { + #[inline] + fn as_concrete_TypeRef(&self) -> CFRunLoopRef { + self.obj + } + + #[inline] + unsafe fn wrap_under_get_rule(reference: CFRunLoopRef) -> CFRunLoop { + let reference: CFRunLoopRef = 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: CFRunLoopRef) -> CFRunLoop { + CFRunLoop { + obj: obj, + } + } + + #[inline] + fn type_id(_: Option) -> CFTypeID { + unsafe { + CFRunLoopGetTypeID() + } + } +} + +impl CFRunLoop { + pub fn get_current() -> CFRunLoop { + unsafe { + let run_loop_ref = CFRunLoopGetCurrent(); + TCFType::wrap_under_get_rule(run_loop_ref) + } + } + + pub fn get_main() -> CFRunLoop { + unsafe { + let run_loop_ref = CFRunLoopGetMain(); + TCFType::wrap_under_get_rule(run_loop_ref) + } + } + + pub fn run_current() { + unsafe { + CFRunLoopRun(); + } + } + + pub fn stop(&self) { + unsafe { + CFRunLoopStop(self.obj); + } + } + + pub fn current_mode(&self) -> Option { + unsafe { + let string_ref = CFRunLoopCopyCurrentMode(self.obj); + if string_ref.is_null() { + return None; + } + + let cf_string: CFString = TCFType::wrap_under_create_rule(string_ref); + Some(cf_string.to_string()) + } + } + + pub fn contains_timer(&self, timer: &CFRunLoopTimer, mode: CFStringRef) -> bool { + unsafe { + CFRunLoopContainsTimer(self.obj, timer.obj, mode) != 0 + } + } + + pub fn add_timer(&self, timer: &CFRunLoopTimer, mode: CFStringRef) { + unsafe { + CFRunLoopAddTimer(self.obj, timer.obj, mode); + } + } + +} + +//typedef struct __CFRunLoopSource * CFRunLoopSourceRef; +// +//typedef struct __CFRunLoopObserver * CFRunLoopObserverRef; +// +//typedef struct CF_BRIDGED_MUTABLE_TYPE(NSTimer) __CFRunLoopTimer * CFRunLoopTimerRef; +// +///* Reasons for CFRunLoopRunInMode() to Return */ +//enum { +// kCFRunLoopRunFinished = 1, +// kCFRunLoopRunStopped = 2, +// kCFRunLoopRunTimedOut = 3, +// kCFRunLoopRunHandledSource = 4 +//}; +// +///* Run Loop Observer Activities */ +//typedef CF_OPTIONS(CFOptionFlags, CFRunLoopActivity) { +// kCFRunLoopEntry = (1UL << 0), +// kCFRunLoopBeforeTimers = (1UL << 1), +// kCFRunLoopBeforeSources = (1UL << 2), +// kCFRunLoopBeforeWaiting = (1UL << 5), +// kCFRunLoopAfterWaiting = (1UL << 6), +// kCFRunLoopExit = (1UL << 7), +// kCFRunLoopAllActivities = 0x0FFFFFFFU +//}; +// +// +//typedef struct { +// CFIndex version; +// void * info; +// const void *(*retain)(const void *info); +// void (*release)(const void *info); +// CFStringRef (*copyDescription)(const void *info); +// Boolean (*equal)(const void *info1, const void *info2); +// CFHashCode (*hash)(const void *info); +// void (*schedule)(void *info, CFRunLoopRef rl, CFStringRef mode); +// void (*cancel)(void *info, CFRunLoopRef rl, CFStringRef mode); +// void (*perform)(void *info); +//} CFRunLoopSourceContext; +// +//typedef struct { +// CFIndex version; +// void * info; +// const void *(*retain)(const void *info); +// void (*release)(const void *info); +// CFStringRef (*copyDescription)(const void *info); +// Boolean (*equal)(const void *info1, const void *info2); +// CFHashCode (*hash)(const void *info); +//#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) || (TARGET_OS_EMBEDDED || TARGET_OS_IPHONE) +// mach_port_t (*getPort)(void *info); +// void * (*perform)(void *msg, CFIndex size, CFAllocatorRef allocator, void *info); +//#else +// void * (*getPort)(void *info); +// void (*perform)(void *info); +//#endif +//} CFRunLoopSourceContext1; +// +//typedef struct { +// CFIndex version; +// void * info; +// const void *(*retain)(const void *info); +// void (*release)(const void *info); +// CFStringRef (*copyDescription)(const void *info); +//} CFRunLoopObserverContext; +// +//typedef void (*CFRunLoopObserverCallBack)(CFRunLoopObserverRef observer, CFRunLoopActivity activity, void *info); +// + +#[repr(C)] +pub struct CFRunLoopTimerContext { + version: CFIndex, + info: *mut c_void, + retain: extern "C" fn (info: *const c_void) -> *const c_void, + release: extern "C" fn (info: *const c_void), + copyDescription: extern "C" fn (info: *const c_void) -> CFStringRef, +} + +pub type CFRunLoopTimerCallBack = extern "C" fn (timer: CFRunLoopTimerRef, info: *mut c_void); + +#[repr(C)] +struct __CFRunLoopTimer; + +pub type CFRunLoopTimerRef = *const __CFRunLoopTimer; + +/// FIXME(pcwalton): Should be a newtype struct, but that fails due to a Rust compiler bug. +pub struct CFRunLoopTimer { + obj: CFRunLoopTimerRef, +} + +impl Drop for CFRunLoopTimer { + fn drop(&mut self) { + unsafe { + CFRelease(self.as_CFTypeRef()) + } + } +} + +impl TCFType for CFRunLoopTimer { + #[inline] + fn as_concrete_TypeRef(&self) -> CFRunLoopTimerRef { + self.obj + } + + #[inline] + unsafe fn wrap_under_get_rule(reference: CFRunLoopTimerRef) -> CFRunLoopTimer { + let reference: CFRunLoopTimerRef = 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: CFRunLoopTimerRef) -> CFRunLoopTimer { + CFRunLoopTimer { + obj: obj, + } + } + + #[inline] + fn type_id(_: Option) -> CFTypeID { + unsafe { + CFRunLoopTimerGetTypeID() + } + } +} + +impl CFRunLoopTimer { + pub fn new(fireDate: CFAbsoluteTime, interval: CFTimeInterval, flags: CFOptionFlags, order: CFIndex, callout: CFRunLoopTimerCallBack, context: *mut CFRunLoopTimerContext) -> CFRunLoopTimer { + unsafe { + let timer_ref = CFRunLoopTimerCreate(kCFAllocatorDefault, fireDate, interval, flags, order, callout, context); + TCFType::wrap_under_create_rule(timer_ref) + } + } +} + + +#[link(name = "CoreFoundation", kind = "framework")] +extern { + /* + * CFRunLoop.h + */ + pub static kCFRunLoopDefaultMode: CFStringRef; + pub static kCFRunLoopCommonModes: CFStringRef; + fn CFRunLoopGetTypeID() -> CFTypeID; + fn CFRunLoopGetCurrent() -> CFRunLoopRef; + fn CFRunLoopGetMain() -> CFRunLoopRef; + fn CFRunLoopCopyCurrentMode(rl: CFRunLoopRef) -> CFStringRef; + //fn CFRunLoopCopyAllModes(rl: CFRunLoopRef) -> CFArrayRef; + //fn CFRunLoopAddCommonMode(rl: CFRunLoopRef, mode: CFStringRef); + //fn CFRunLoopGetNextTimerFireDate(rl: CFRunLoopRef, mode: CFStringRef) -> CFAbsoluteTime; + fn CFRunLoopRun(); + //fn CFRunLoopRunInMode(mode: CFStringRef, seconds: CFTimeInterval, returnAfterSourceHandled: Boolean) -> SInt32; + //fn CFRunLoopIsWaiting(rl: CFRunLoopRef) -> Boolean; + //fn CFRunLoopWakeUp(rl: CFRunLoopRef); + fn CFRunLoopStop(rl: CFRunLoopRef); + // fn CFRunLoopPerformBlock(rl: CFRunLoopRef, mode: CFTypeRef, block: void (^)(void)); + //fn CFRunLoopContainsSource(rl: CFRunLoopRef, source: CFRunLoopSourceRef, mode: CFStringRef) -> Boolean; + //fn CFRunLoopAddSource(rl: CFRunLoopRef, source: CFRunLoopSourceRef, mode: CFStringRef); + //fn CFRunLoopRemoveSource(rl: CFRunLoopRef, source: CFRunLoopSourceRef, mode: CFStringRef); + //fn CFRunLoopContainsObserver(rl: CFRunLoopRef, observer: CFRunLoopObserverRef, mode: CFStringRef) -> Boolean; + //fn CFRunLoopAddObserver(rl: CFRunLoopRef, observer: CFRunLoopObserverRef, mode: CFStringRef); + //fn CFRunLoopRemoveObserver(rl: CFRunLoopRef, observer: CFRunLoopObserverRef, mode: CFStringRef); + //fn CFRunLoopRemoveObserver(rl: CFRunLoopRef, observer: CFRunLoopObserverRef, mode: CFStringRef); + fn CFRunLoopContainsTimer(rl: CFRunLoopRef, timer: CFRunLoopTimerRef, mode: CFStringRef) -> Boolean; + fn CFRunLoopAddTimer(rl: CFRunLoopRef, timer: CFRunLoopTimerRef, mode: CFStringRef); + //fn CFRunLoopRemoveTimer(rl: CFRunLoopRef, timer: CFRunLoopTimerRef, mode: CFStringRef); + + //fn CFRunLoopSourceGetTypeID() -> CFTypeID; + //fn CFRunLoopSourceCreate(allocator: CFAllocatorRef, order: CFIndex, context: *mut CFRunLoopSourceContext) -> CFRunLoopSourceRef; + //fn CFRunLoopSourceGetOrder(source: CFRunLoopSourceRef) -> CFIndex; + //fn CFRunLoopSourceInvalidate(source: CFRunLoopSourceRef); + //fn CFRunLoopSourceIsValid(source: CFRunLoopSourceRef) -> Boolean; + //fn CFRunLoopSourceGetContext(source: CFRunLoopSourceRef, context: *mut CFRunLoopSourceContext); + //fn CFRunLoopSourceSignal(source: CFRunLoopSourceRef); + + //fn CFRunLoopObserverGetTypeID() -> CFTypeID; + //fn CFRunLoopObserverCreate(allocator: CFAllocatorRef, activities: CFOptionFlags, repeats: Boolean, order: CFIndex, callout: CFRunLoopObserverCallBack, context: *mut CFRunLoopObserverContext) -> CFRunLoopObserverRef; + // fn CFRunLoopObserverCreateWithHandler(allocator: CFAllocatorRef, activities: CFOptionFlags, repeats: Boolean, order: CFIndex, block: void (^) (CFRunLoopObserverRef observer, CFRunLoopActivity activity)) -> CFRunLoopObserverRef; + //fn CFRunLoopObserverGetActivities(observer: CFRunLoopObserverRef) -> CFOptionFlags; + //fn CFRunLoopObserverDoesRepeat(observer: CFRunLoopObserverRef) -> Boolean; + //fn CFRunLoopObserverGetOrder(observer: CFRunLoopObserverRef) -> CFIndex; + //fn CFRunLoopObserverInvalidate(observer: CFRunLoopObserverRef); + //fn CFRunLoopObserverIsValid(observer: CFRunLoopObserverRef) -> Boolean; + //fn CFRunLoopObserverGetContext(observer: CFRunLoopObserverRef, context: *mut CFRunLoopObserverContext); + + fn CFRunLoopTimerGetTypeID() -> CFTypeID; + fn CFRunLoopTimerCreate(allocator: CFAllocatorRef, fireDate: CFAbsoluteTime, interval: CFTimeInterval, flags: CFOptionFlags, order: CFIndex, callout: CFRunLoopTimerCallBack, context: *mut CFRunLoopTimerContext) -> CFRunLoopTimerRef; + // fn CFRunLoopTimerCreateWithHandler(allocator: CFAllocatorRef, fireDate: CFAbsoluteTime, interval: CFTimeInterval, flags: CFOptionFlags, order: CFIndex, block: void (^) (CFRunLoopTimerRef timer)) -> CFRunLoopTimerRef; + //fn CFRunLoopTimerGetNextFireDate(timer: CFRunLoopTimerRef) -> CFAbsoluteTime; + //fn CFRunLoopTimerSetNextFireDate(timer: CFRunLoopTimerRef, fireDate: CFAbsoluteTime); + //fn CFRunLoopTimerGetInterval(timer: CFRunLoopTimerRef) -> CFTimeInterval; + //fn CFRunLoopTimerDoesRepeat(timer: CFRunLoopTimerRef) -> Boolean; + //fn CFRunLoopTimerGetOrder(timer: CFRunLoopTimerRef) -> CFIndex; + //fn CFRunLoopTimerInvalidate(timer: CFRunLoopTimerRef); + //fn CFRunLoopTimerIsValid(timer: CFRunLoopTimerRef) -> Boolean; + //fn CFRunLoopTimerGetContext(timer: CFRunLoopTimerRef, context: *mut CFRunLoopTimerContext); + //fn CFRunLoopTimerGetTolerance(timer: CFRunLoopTimerRef) -> CFTimeInterval; + //fn CFRunLoopTimerSetTolerance(timer: CFRunLoopTimerRef, tolerance: CFTimeInterval); +} + + +#[test] +fn wait_200_milliseconds() { + let run_loop = CFRunLoop::get_current(); + let mut now = unsafe { CFAbsoluteTimeGetCurrent() }; + let mut context = unsafe { CFRunLoopTimerContext { + version: 0, + info: mem::transmute(&mut now), + retain: mem::zeroed(), + release: mem::zeroed(), + copyDescription: mem::zeroed(), + } }; + + + let run_loop_timer = CFRunLoopTimer::new(now + 0.20f64, 0f64, 0, 0, timer_popped, &mut context); + run_loop.add_timer(&run_loop_timer, kCFRunLoopDefaultMode); + + CFRunLoop::run_current(); +} + +extern "C" fn timer_popped(_timer: CFRunLoopTimerRef, _info: *mut c_void) { + let previous_now_ptr: *const CFAbsoluteTime = unsafe { mem::transmute(_info) }; + let previous_now = unsafe { *previous_now_ptr }; + let now = unsafe { CFAbsoluteTimeGetCurrent() }; + assert!(now - previous_now > 0.19 && now - previous_now < 0.21); + CFRunLoop::get_current().stop(); +} From 7780f834a99252d5f86db517f4fb3207db0d0363 Mon Sep 17 00:00:00 2001 From: Kristian Takvam Date: Wed, 4 Feb 2015 07:21:57 -0800 Subject: [PATCH 3/3] Finished converting runloop structs. --- src/base.rs | 4 +- src/runloop.rs | 226 +++++++++++++++++++++++++------------------------ 2 files changed, 117 insertions(+), 113 deletions(-) diff --git a/src/base.rs b/src/base.rs index 5e4b334..6962cd6 100644 --- a/src/base.rs +++ b/src/base.rs @@ -7,13 +7,15 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use libc::{c_long, c_ulong}; +use libc::{c_long, c_ulong, c_uint}; use std::num::Int; pub type Boolean = u8; pub type CFIndex = c_long; +pub type mach_port_t = c_uint; + pub trait CFIndexConvertible { /// Always use this method to construct a `CFIndex` value. It performs bounds checking to /// ensure the value is in range. diff --git a/src/runloop.rs b/src/runloop.rs index 0c05ce7..8287188 100644 --- a/src/runloop.rs +++ b/src/runloop.rs @@ -7,21 +7,19 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![allow(non_upper_case_globals)] + use base::{CFAllocatorRef, CFIndex, CFOptionFlags, CFRelease, CFRetain}; -use base::{CFTypeID, CFTypeRef, TCFType}; +use base::{CFTypeID, CFTypeRef, TCFType, CFHashCode, mach_port_t}; use base::{kCFAllocatorDefault}; use base::{Boolean}; +use array::{CFArrayRef}; use string::{CFString, CFStringRef}; use date::{CFAbsoluteTime, CFTimeInterval, CFAbsoluteTimeGetCurrent}; use libc::c_void; use std::mem; use std::ptr; -#[repr(C)] -struct __CFRunLoop; - -pub type CFRunLoopRef = *const __CFRunLoop; - /// FIXME(pcwalton): Should be a newtype struct, but that fails due to a Rust compiler bug. pub struct CFRunLoop { obj: CFRunLoopRef, @@ -122,72 +120,76 @@ impl CFRunLoop { } -//typedef struct __CFRunLoopSource * CFRunLoopSourceRef; -// -//typedef struct __CFRunLoopObserver * CFRunLoopObserverRef; -// -//typedef struct CF_BRIDGED_MUTABLE_TYPE(NSTimer) __CFRunLoopTimer * CFRunLoopTimerRef; -// -///* Reasons for CFRunLoopRunInMode() to Return */ -//enum { -// kCFRunLoopRunFinished = 1, -// kCFRunLoopRunStopped = 2, -// kCFRunLoopRunTimedOut = 3, -// kCFRunLoopRunHandledSource = 4 -//}; -// -///* Run Loop Observer Activities */ +#[repr(C)] +struct __CFRunLoop; + +pub type CFRunLoopRef = *const __CFRunLoop; + +#[repr(C)] +struct __CFRunLoopSource; + +pub type CFRunLoopSourceRef = *const __CFRunLoopSource; + +#[repr(C)] +struct __CFRunLoopObserver; + +pub type CFRunLoopObserverRef = *const __CFRunLoopObserver; + +// Reasons for CFRunLoopRunInMode() to Return +pub const kCFRunLoopRunFinished: i32 = 1; +pub const kCFRunLoopRunStopped: i32 = 2; +pub const kCFRunLoopRunTimedOut: i32 = 3; +pub const kCFRunLoopRunHandledSource: i32 = 4; + +// Run Loop Observer Activities //typedef CF_OPTIONS(CFOptionFlags, CFRunLoopActivity) { -// kCFRunLoopEntry = (1UL << 0), -// kCFRunLoopBeforeTimers = (1UL << 1), -// kCFRunLoopBeforeSources = (1UL << 2), -// kCFRunLoopBeforeWaiting = (1UL << 5), -// kCFRunLoopAfterWaiting = (1UL << 6), -// kCFRunLoopExit = (1UL << 7), -// kCFRunLoopAllActivities = 0x0FFFFFFFU -//}; -// -// -//typedef struct { -// CFIndex version; -// void * info; -// const void *(*retain)(const void *info); -// void (*release)(const void *info); -// CFStringRef (*copyDescription)(const void *info); -// Boolean (*equal)(const void *info1, const void *info2); -// CFHashCode (*hash)(const void *info); -// void (*schedule)(void *info, CFRunLoopRef rl, CFStringRef mode); -// void (*cancel)(void *info, CFRunLoopRef rl, CFStringRef mode); -// void (*perform)(void *info); -//} CFRunLoopSourceContext; -// -//typedef struct { -// CFIndex version; -// void * info; -// const void *(*retain)(const void *info); -// void (*release)(const void *info); -// CFStringRef (*copyDescription)(const void *info); -// Boolean (*equal)(const void *info1, const void *info2); -// CFHashCode (*hash)(const void *info); -//#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) || (TARGET_OS_EMBEDDED || TARGET_OS_IPHONE) -// mach_port_t (*getPort)(void *info); -// void * (*perform)(void *msg, CFIndex size, CFAllocatorRef allocator, void *info); -//#else -// void * (*getPort)(void *info); -// void (*perform)(void *info); -//#endif -//} CFRunLoopSourceContext1; -// -//typedef struct { -// CFIndex version; -// void * info; -// const void *(*retain)(const void *info); -// void (*release)(const void *info); -// CFStringRef (*copyDescription)(const void *info); -//} CFRunLoopObserverContext; -// -//typedef void (*CFRunLoopObserverCallBack)(CFRunLoopObserverRef observer, CFRunLoopActivity activity, void *info); -// +pub type CFRunLoopActivity = CFOptionFlags; +pub const kCFRunLoopEntry: CFOptionFlags = 1 << 0; +pub const kCFRunLoopBeforeTimers: CFOptionFlags = 1 << 1; +pub const kCFRunLoopBeforeSources: CFOptionFlags = 1 << 2; +pub const kCFRunLoopBeforeWaiting: CFOptionFlags = 1 << 5; +pub const kCFRunLoopAfterWaiting: CFOptionFlags = 1 << 6; +pub const kCFRunLoopExit: CFOptionFlags = 1 << 7; +pub const kCFRunLoopAllActivities: CFOptionFlags = 0x0FFFFFFF; + +#[repr(C)] +pub struct CFRunLoopSourceContext { + version: CFIndex, + info: *mut c_void, + retain: extern "C" fn (info: *const c_void) -> *const c_void, + release: extern "C" fn (info: *const c_void), + copyDescription: extern "C" fn (info: *const c_void) -> CFStringRef, + equal: extern "C" fn (info1: *const c_void, info2: *const c_void) -> Boolean, + hash: extern "C" fn (info: *const c_void) -> CFHashCode, + schedule: extern "C" fn (info: *const c_void, rl: CFRunLoopRef, mode: CFStringRef), + cancel: extern "C" fn (info: *const c_void, rl: CFRunLoopRef, mode: CFStringRef), + perform: extern "C" fn (info: *const c_void), +} + +#[repr(C)] +pub struct CFRunLoopSourceContext1 { + version: CFIndex, + info: *mut c_void, + retain: extern "C" fn (info: *const c_void) -> *const c_void, + release: extern "C" fn (info: *const c_void), + copyDescription: extern "C" fn (info: *const c_void) -> CFStringRef, + equal: extern "C" fn (info1: *const c_void, info2: *const c_void) -> Boolean, + hash: extern "C" fn (info: *const c_void) -> CFHashCode, + // note that the following two fields are platform dependent in the C header, the ones here are for OS X + getPort: extern "C" fn (info: *mut c_void) -> mach_port_t, + perform: extern "C" fn (msg: *mut c_void, size: CFIndex, allocator: CFAllocatorRef, info: *mut c_void) -> *mut c_void, +} + +#[repr(C)] +pub struct CFRunLoopObserverContext { + version: CFIndex, + info: *mut c_void, + retain: extern "C" fn (info: *const c_void) -> *const c_void, + release: extern "C" fn (info: *const c_void), + copyDescription: extern "C" fn (info: *const c_void) -> CFStringRef, +} + +pub type CFRunLoopObserverCallBack = extern "C" fn (observer: CFRunLoopObserverRef, activity: CFRunLoopActivity, info: *mut c_void); #[repr(C)] pub struct CFRunLoopTimerContext { @@ -262,6 +264,7 @@ impl CFRunLoopTimer { } +#[allow(dead_code)] #[link(name = "CoreFoundation", kind = "framework")] extern { /* @@ -273,57 +276,56 @@ extern { fn CFRunLoopGetCurrent() -> CFRunLoopRef; fn CFRunLoopGetMain() -> CFRunLoopRef; fn CFRunLoopCopyCurrentMode(rl: CFRunLoopRef) -> CFStringRef; - //fn CFRunLoopCopyAllModes(rl: CFRunLoopRef) -> CFArrayRef; - //fn CFRunLoopAddCommonMode(rl: CFRunLoopRef, mode: CFStringRef); - //fn CFRunLoopGetNextTimerFireDate(rl: CFRunLoopRef, mode: CFStringRef) -> CFAbsoluteTime; + fn CFRunLoopCopyAllModes(rl: CFRunLoopRef) -> CFArrayRef; + fn CFRunLoopAddCommonMode(rl: CFRunLoopRef, mode: CFStringRef); + fn CFRunLoopGetNextTimerFireDate(rl: CFRunLoopRef, mode: CFStringRef) -> CFAbsoluteTime; fn CFRunLoopRun(); - //fn CFRunLoopRunInMode(mode: CFStringRef, seconds: CFTimeInterval, returnAfterSourceHandled: Boolean) -> SInt32; - //fn CFRunLoopIsWaiting(rl: CFRunLoopRef) -> Boolean; - //fn CFRunLoopWakeUp(rl: CFRunLoopRef); + fn CFRunLoopRunInMode(mode: CFStringRef, seconds: CFTimeInterval, returnAfterSourceHandled: Boolean) -> i32; + fn CFRunLoopIsWaiting(rl: CFRunLoopRef) -> Boolean; + fn CFRunLoopWakeUp(rl: CFRunLoopRef); fn CFRunLoopStop(rl: CFRunLoopRef); // fn CFRunLoopPerformBlock(rl: CFRunLoopRef, mode: CFTypeRef, block: void (^)(void)); - //fn CFRunLoopContainsSource(rl: CFRunLoopRef, source: CFRunLoopSourceRef, mode: CFStringRef) -> Boolean; - //fn CFRunLoopAddSource(rl: CFRunLoopRef, source: CFRunLoopSourceRef, mode: CFStringRef); - //fn CFRunLoopRemoveSource(rl: CFRunLoopRef, source: CFRunLoopSourceRef, mode: CFStringRef); - //fn CFRunLoopContainsObserver(rl: CFRunLoopRef, observer: CFRunLoopObserverRef, mode: CFStringRef) -> Boolean; - //fn CFRunLoopAddObserver(rl: CFRunLoopRef, observer: CFRunLoopObserverRef, mode: CFStringRef); - //fn CFRunLoopRemoveObserver(rl: CFRunLoopRef, observer: CFRunLoopObserverRef, mode: CFStringRef); - //fn CFRunLoopRemoveObserver(rl: CFRunLoopRef, observer: CFRunLoopObserverRef, mode: CFStringRef); + fn CFRunLoopContainsSource(rl: CFRunLoopRef, source: CFRunLoopSourceRef, mode: CFStringRef) -> Boolean; + fn CFRunLoopAddSource(rl: CFRunLoopRef, source: CFRunLoopSourceRef, mode: CFStringRef); + fn CFRunLoopRemoveSource(rl: CFRunLoopRef, source: CFRunLoopSourceRef, mode: CFStringRef); + fn CFRunLoopContainsObserver(rl: CFRunLoopRef, observer: CFRunLoopObserverRef, mode: CFStringRef) -> Boolean; + fn CFRunLoopAddObserver(rl: CFRunLoopRef, observer: CFRunLoopObserverRef, mode: CFStringRef); + fn CFRunLoopRemoveObserver(rl: CFRunLoopRef, observer: CFRunLoopObserverRef, mode: CFStringRef); fn CFRunLoopContainsTimer(rl: CFRunLoopRef, timer: CFRunLoopTimerRef, mode: CFStringRef) -> Boolean; fn CFRunLoopAddTimer(rl: CFRunLoopRef, timer: CFRunLoopTimerRef, mode: CFStringRef); - //fn CFRunLoopRemoveTimer(rl: CFRunLoopRef, timer: CFRunLoopTimerRef, mode: CFStringRef); - - //fn CFRunLoopSourceGetTypeID() -> CFTypeID; - //fn CFRunLoopSourceCreate(allocator: CFAllocatorRef, order: CFIndex, context: *mut CFRunLoopSourceContext) -> CFRunLoopSourceRef; - //fn CFRunLoopSourceGetOrder(source: CFRunLoopSourceRef) -> CFIndex; - //fn CFRunLoopSourceInvalidate(source: CFRunLoopSourceRef); - //fn CFRunLoopSourceIsValid(source: CFRunLoopSourceRef) -> Boolean; - //fn CFRunLoopSourceGetContext(source: CFRunLoopSourceRef, context: *mut CFRunLoopSourceContext); - //fn CFRunLoopSourceSignal(source: CFRunLoopSourceRef); - - //fn CFRunLoopObserverGetTypeID() -> CFTypeID; - //fn CFRunLoopObserverCreate(allocator: CFAllocatorRef, activities: CFOptionFlags, repeats: Boolean, order: CFIndex, callout: CFRunLoopObserverCallBack, context: *mut CFRunLoopObserverContext) -> CFRunLoopObserverRef; + fn CFRunLoopRemoveTimer(rl: CFRunLoopRef, timer: CFRunLoopTimerRef, mode: CFStringRef); + + fn CFRunLoopSourceGetTypeID() -> CFTypeID; + fn CFRunLoopSourceCreate(allocator: CFAllocatorRef, order: CFIndex, context: *mut CFRunLoopSourceContext) -> CFRunLoopSourceRef; + fn CFRunLoopSourceGetOrder(source: CFRunLoopSourceRef) -> CFIndex; + fn CFRunLoopSourceInvalidate(source: CFRunLoopSourceRef); + fn CFRunLoopSourceIsValid(source: CFRunLoopSourceRef) -> Boolean; + fn CFRunLoopSourceGetContext(source: CFRunLoopSourceRef, context: *mut CFRunLoopSourceContext); + fn CFRunLoopSourceSignal(source: CFRunLoopSourceRef); + + fn CFRunLoopObserverGetTypeID() -> CFTypeID; + fn CFRunLoopObserverCreate(allocator: CFAllocatorRef, activities: CFOptionFlags, repeats: Boolean, order: CFIndex, callout: CFRunLoopObserverCallBack, context: *mut CFRunLoopObserverContext) -> CFRunLoopObserverRef; // fn CFRunLoopObserverCreateWithHandler(allocator: CFAllocatorRef, activities: CFOptionFlags, repeats: Boolean, order: CFIndex, block: void (^) (CFRunLoopObserverRef observer, CFRunLoopActivity activity)) -> CFRunLoopObserverRef; - //fn CFRunLoopObserverGetActivities(observer: CFRunLoopObserverRef) -> CFOptionFlags; - //fn CFRunLoopObserverDoesRepeat(observer: CFRunLoopObserverRef) -> Boolean; - //fn CFRunLoopObserverGetOrder(observer: CFRunLoopObserverRef) -> CFIndex; - //fn CFRunLoopObserverInvalidate(observer: CFRunLoopObserverRef); - //fn CFRunLoopObserverIsValid(observer: CFRunLoopObserverRef) -> Boolean; - //fn CFRunLoopObserverGetContext(observer: CFRunLoopObserverRef, context: *mut CFRunLoopObserverContext); + fn CFRunLoopObserverGetActivities(observer: CFRunLoopObserverRef) -> CFOptionFlags; + fn CFRunLoopObserverDoesRepeat(observer: CFRunLoopObserverRef) -> Boolean; + fn CFRunLoopObserverGetOrder(observer: CFRunLoopObserverRef) -> CFIndex; + fn CFRunLoopObserverInvalidate(observer: CFRunLoopObserverRef); + fn CFRunLoopObserverIsValid(observer: CFRunLoopObserverRef) -> Boolean; + fn CFRunLoopObserverGetContext(observer: CFRunLoopObserverRef, context: *mut CFRunLoopObserverContext); fn CFRunLoopTimerGetTypeID() -> CFTypeID; fn CFRunLoopTimerCreate(allocator: CFAllocatorRef, fireDate: CFAbsoluteTime, interval: CFTimeInterval, flags: CFOptionFlags, order: CFIndex, callout: CFRunLoopTimerCallBack, context: *mut CFRunLoopTimerContext) -> CFRunLoopTimerRef; // fn CFRunLoopTimerCreateWithHandler(allocator: CFAllocatorRef, fireDate: CFAbsoluteTime, interval: CFTimeInterval, flags: CFOptionFlags, order: CFIndex, block: void (^) (CFRunLoopTimerRef timer)) -> CFRunLoopTimerRef; - //fn CFRunLoopTimerGetNextFireDate(timer: CFRunLoopTimerRef) -> CFAbsoluteTime; - //fn CFRunLoopTimerSetNextFireDate(timer: CFRunLoopTimerRef, fireDate: CFAbsoluteTime); - //fn CFRunLoopTimerGetInterval(timer: CFRunLoopTimerRef) -> CFTimeInterval; - //fn CFRunLoopTimerDoesRepeat(timer: CFRunLoopTimerRef) -> Boolean; - //fn CFRunLoopTimerGetOrder(timer: CFRunLoopTimerRef) -> CFIndex; - //fn CFRunLoopTimerInvalidate(timer: CFRunLoopTimerRef); - //fn CFRunLoopTimerIsValid(timer: CFRunLoopTimerRef) -> Boolean; - //fn CFRunLoopTimerGetContext(timer: CFRunLoopTimerRef, context: *mut CFRunLoopTimerContext); - //fn CFRunLoopTimerGetTolerance(timer: CFRunLoopTimerRef) -> CFTimeInterval; - //fn CFRunLoopTimerSetTolerance(timer: CFRunLoopTimerRef, tolerance: CFTimeInterval); + fn CFRunLoopTimerGetNextFireDate(timer: CFRunLoopTimerRef) -> CFAbsoluteTime; + fn CFRunLoopTimerSetNextFireDate(timer: CFRunLoopTimerRef, fireDate: CFAbsoluteTime); + fn CFRunLoopTimerGetInterval(timer: CFRunLoopTimerRef) -> CFTimeInterval; + fn CFRunLoopTimerDoesRepeat(timer: CFRunLoopTimerRef) -> Boolean; + fn CFRunLoopTimerGetOrder(timer: CFRunLoopTimerRef) -> CFIndex; + fn CFRunLoopTimerInvalidate(timer: CFRunLoopTimerRef); + fn CFRunLoopTimerIsValid(timer: CFRunLoopTimerRef) -> Boolean; + fn CFRunLoopTimerGetContext(timer: CFRunLoopTimerRef, context: *mut CFRunLoopTimerContext); + fn CFRunLoopTimerGetTolerance(timer: CFRunLoopTimerRef) -> CFTimeInterval; + fn CFRunLoopTimerSetTolerance(timer: CFRunLoopTimerRef, tolerance: CFTimeInterval); }