diff --git a/Cargo.toml b/Cargo.toml index d38039e2..6ca94680 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -63,9 +63,9 @@ ndk-glue = "0.7.0" [target.'cfg(any(target_os = "ios", target_os = "macos"))'.dependencies] objc2 = "=0.3.0-beta.3" +core-foundation = "0.9.3" [target.'cfg(target_os = "macos")'.dependencies] -core-foundation = "0.9.3" core-graphics = "0.22.3" dispatch = "0.2.0" diff --git a/src/platform_impl/ios/app_state.rs b/src/platform_impl/ios/app_state.rs index ae527b0b..4972a559 100644 --- a/src/platform_impl/ios/app_state.rs +++ b/src/platform_impl/ios/app_state.rs @@ -9,6 +9,12 @@ use std::{ time::Instant, }; +use core_foundation::base::CFRelease; +use core_foundation::date::CFAbsoluteTimeGetCurrent; +use core_foundation::runloop::{ + kCFRunLoopCommonModes, CFRunLoopAddTimer, CFRunLoopGetMain, CFRunLoopRef, CFRunLoopTimerCreate, + CFRunLoopTimerInvalidate, CFRunLoopTimerRef, CFRunLoopTimerSetNextFireDate, +}; use objc2::foundation::{NSInteger, NSUInteger}; use objc2::runtime::Object; use objc2::{class, msg_send, sel}; @@ -20,12 +26,7 @@ use crate::{ event_loop::ControlFlow, platform_impl::platform::{ event_loop::{EventHandler, EventProxy, EventWrapper, Never}, - ffi::{ - id, kCFRunLoopCommonModes, CFAbsoluteTimeGetCurrent, CFRelease, CFRunLoopAddTimer, - CFRunLoopGetMain, CFRunLoopRef, CFRunLoopTimerCreate, CFRunLoopTimerInvalidate, - CFRunLoopTimerRef, CFRunLoopTimerSetNextFireDate, CGRect, CGSize, - NSOperatingSystemVersion, - }, + ffi::{id, CGRect, CGSize, NSOperatingSystemVersion}, }, window::WindowId as RootWindowId, }; diff --git a/src/platform_impl/ios/event_loop.rs b/src/platform_impl/ios/event_loop.rs index 3afcc8fc..70098105 100644 --- a/src/platform_impl/ios/event_loop.rs +++ b/src/platform_impl/ios/event_loop.rs @@ -3,10 +3,18 @@ use std::{ ffi::c_void, fmt::{self, Debug}, marker::PhantomData, - mem, ptr, + ptr, sync::mpsc::{self, Receiver, Sender}, }; +use core_foundation::base::{CFIndex, CFRelease}; +use core_foundation::runloop::{ + kCFRunLoopAfterWaiting, kCFRunLoopBeforeWaiting, kCFRunLoopCommonModes, kCFRunLoopDefaultMode, + kCFRunLoopEntry, kCFRunLoopExit, CFRunLoopActivity, CFRunLoopAddObserver, CFRunLoopAddSource, + CFRunLoopGetMain, CFRunLoopObserverCreate, CFRunLoopObserverRef, CFRunLoopSourceContext, + CFRunLoopSourceCreate, CFRunLoopSourceInvalidate, CFRunLoopSourceRef, CFRunLoopSourceSignal, + CFRunLoopWakeUp, +}; use objc2::runtime::Object; use objc2::{class, msg_send, ClassType}; use raw_window_handle::{RawDisplayHandle, UiKitDisplayHandle}; @@ -23,15 +31,7 @@ use crate::{ use crate::platform_impl::platform::{ app_state, - ffi::{ - id, kCFRunLoopAfterWaiting, kCFRunLoopBeforeWaiting, kCFRunLoopCommonModes, - kCFRunLoopDefaultMode, kCFRunLoopEntry, kCFRunLoopExit, nil, CFIndex, CFRelease, - CFRunLoopActivity, CFRunLoopAddObserver, CFRunLoopAddSource, CFRunLoopGetMain, - CFRunLoopObserverCreate, CFRunLoopObserverRef, CFRunLoopSourceContext, - CFRunLoopSourceCreate, CFRunLoopSourceInvalidate, CFRunLoopSourceRef, - CFRunLoopSourceSignal, CFRunLoopWakeUp, NSStringRust, UIApplicationMain, - UIUserInterfaceIdiom, - }, + ffi::{id, nil, NSStringRust, UIApplicationMain, UIUserInterfaceIdiom}, monitor, view, MonitorHandle, }; @@ -184,14 +184,23 @@ impl EventLoopProxy { fn new(sender: Sender) -> EventLoopProxy { unsafe { // just wake up the eventloop - extern "C" fn event_loop_proxy_handler(_: *mut c_void) {} + extern "C" fn event_loop_proxy_handler(_: *const c_void) {} // adding a Source to the main CFRunLoop lets us wake it up and // process user events through the normal OS EventLoop mechanisms. let rl = CFRunLoopGetMain(); - // we want all the members of context to be zero/null, except one - let mut context: CFRunLoopSourceContext = mem::zeroed(); - context.perform = Some(event_loop_proxy_handler); + let mut context = CFRunLoopSourceContext { + version: 0, + info: ptr::null_mut(), + retain: None, + release: None, + copyDescription: None, + equal: None, + hash: None, + schedule: None, + cancel: None, + perform: event_loop_proxy_handler, + }; let source = CFRunLoopSourceCreate(ptr::null_mut(), CFIndex::max_value() - 1, &mut context); CFRunLoopAddSource(rl, source, kCFRunLoopCommonModes); diff --git a/src/platform_impl/ios/ffi.rs b/src/platform_impl/ios/ffi.rs index 3bfbbcfc..7aef6a41 100644 --- a/src/platform_impl/ios/ffi.rs +++ b/src/platform_impl/ios/ffi.rs @@ -1,6 +1,9 @@ #![allow(non_camel_case_types, non_snake_case, non_upper_case_globals)] -use std::{convert::TryInto, ffi::CString, ops::BitOr, os::raw::*}; +use std::convert::TryInto; +use std::ffi::CString; +use std::ops::BitOr; +use std::os::raw::{c_char, c_int}; use objc2::encode::{Encode, Encoding}; use objc2::foundation::{NSInteger, NSUInteger}; @@ -280,108 +283,13 @@ impl UIScreenOverscanCompensation { } #[link(name = "UIKit", kind = "framework")] -#[link(name = "CoreFoundation", kind = "framework")] extern "C" { - pub static kCFRunLoopDefaultMode: CFRunLoopMode; - pub static kCFRunLoopCommonModes: CFRunLoopMode; - pub fn UIApplicationMain( argc: c_int, argv: *const c_char, principalClassName: id, delegateClassName: id, ) -> c_int; - - pub fn CFRunLoopGetMain() -> CFRunLoopRef; - pub fn CFRunLoopWakeUp(rl: CFRunLoopRef); - - pub fn CFRunLoopObserverCreate( - allocator: CFAllocatorRef, - activities: CFOptionFlags, - repeats: Boolean, - order: CFIndex, - callout: CFRunLoopObserverCallBack, - context: *mut CFRunLoopObserverContext, - ) -> CFRunLoopObserverRef; - pub fn CFRunLoopAddObserver( - rl: CFRunLoopRef, - observer: CFRunLoopObserverRef, - mode: CFRunLoopMode, - ); - - pub fn CFRunLoopTimerCreate( - allocator: CFAllocatorRef, - fireDate: CFAbsoluteTime, - interval: CFTimeInterval, - flags: CFOptionFlags, - order: CFIndex, - callout: CFRunLoopTimerCallBack, - context: *mut CFRunLoopTimerContext, - ) -> CFRunLoopTimerRef; - pub fn CFRunLoopAddTimer(rl: CFRunLoopRef, timer: CFRunLoopTimerRef, mode: CFRunLoopMode); - pub fn CFRunLoopTimerSetNextFireDate(timer: CFRunLoopTimerRef, fireDate: CFAbsoluteTime); - pub fn CFRunLoopTimerInvalidate(time: CFRunLoopTimerRef); - - pub fn CFRunLoopSourceCreate( - allocator: CFAllocatorRef, - order: CFIndex, - context: *mut CFRunLoopSourceContext, - ) -> CFRunLoopSourceRef; - pub fn CFRunLoopAddSource(rl: CFRunLoopRef, source: CFRunLoopSourceRef, mode: CFRunLoopMode); - pub fn CFRunLoopSourceInvalidate(source: CFRunLoopSourceRef); - pub fn CFRunLoopSourceSignal(source: CFRunLoopSourceRef); - - pub fn CFAbsoluteTimeGetCurrent() -> CFAbsoluteTime; - pub fn CFRelease(cftype: *const c_void); -} - -pub type Boolean = u8; -pub enum CFAllocator {} -pub type CFAllocatorRef = *mut CFAllocator; -pub enum CFRunLoop {} -pub type CFRunLoopRef = *mut CFRunLoop; -pub type CFRunLoopMode = CFStringRef; -pub enum CFRunLoopObserver {} -pub type CFRunLoopObserverRef = *mut CFRunLoopObserver; -pub enum CFRunLoopTimer {} -pub type CFRunLoopTimerRef = *mut CFRunLoopTimer; -pub enum CFRunLoopSource {} -pub type CFRunLoopSourceRef = *mut CFRunLoopSource; -pub enum CFString {} -pub type CFStringRef = *const CFString; - -pub type CFHashCode = c_ulong; -pub type CFIndex = c_long; -pub type CFOptionFlags = c_ulong; -pub type CFRunLoopActivity = CFOptionFlags; - -pub type CFAbsoluteTime = CFTimeInterval; -pub type CFTimeInterval = f64; - -pub const kCFRunLoopEntry: CFRunLoopActivity = 0; -pub const kCFRunLoopBeforeWaiting: CFRunLoopActivity = 1 << 5; -pub const kCFRunLoopAfterWaiting: CFRunLoopActivity = 1 << 6; -pub const kCFRunLoopExit: CFRunLoopActivity = 1 << 7; - -pub type CFRunLoopObserverCallBack = - extern "C" fn(observer: CFRunLoopObserverRef, activity: CFRunLoopActivity, info: *mut c_void); -pub type CFRunLoopTimerCallBack = extern "C" fn(timer: CFRunLoopTimerRef, info: *mut c_void); - -pub enum CFRunLoopObserverContext {} -pub enum CFRunLoopTimerContext {} - -#[repr(C)] -pub struct CFRunLoopSourceContext { - pub version: CFIndex, - pub info: *mut c_void, - pub retain: Option *const c_void>, - pub release: Option, - pub copyDescription: Option CFStringRef>, - pub equal: Option Boolean>, - pub hash: Option CFHashCode>, - pub schedule: Option, - pub cancel: Option, - pub perform: Option, } // This is named NSStringRust rather than NSString because the "Debug View Heirarchy" feature of diff --git a/src/platform_impl/macos/app_state.rs b/src/platform_impl/macos/app_state.rs index 7cfd9458..47c7a8b8 100644 --- a/src/platform_impl/macos/app_state.rs +++ b/src/platform_impl/macos/app_state.rs @@ -11,6 +11,7 @@ use std::{ time::Instant, }; +use core_foundation::runloop::{CFRunLoopGetMain, CFRunLoopWakeUp}; use objc2::foundation::{is_main_thread, NSSize}; use objc2::rc::autoreleasepool; use once_cell::sync::Lazy; @@ -24,7 +25,7 @@ use crate::{ event::{EventProxy, EventWrapper}, event_loop::PanicInfo, menu, - observer::{CFRunLoopGetMain, CFRunLoopWakeUp, EventLoopWaker}, + observer::EventLoopWaker, util::Never, window::WinitWindow, }, diff --git a/src/platform_impl/macos/event_loop.rs b/src/platform_impl/macos/event_loop.rs index cfb4d15d..f02b5ef1 100644 --- a/src/platform_impl/macos/event_loop.rs +++ b/src/platform_impl/macos/event_loop.rs @@ -11,6 +11,11 @@ use std::{ sync::mpsc, }; +use core_foundation::base::{CFIndex, CFRelease}; +use core_foundation::runloop::{ + kCFRunLoopCommonModes, CFRunLoopAddSource, CFRunLoopGetMain, CFRunLoopSourceContext, + CFRunLoopSourceCreate, CFRunLoopSourceRef, CFRunLoopSourceSignal, CFRunLoopWakeUp, +}; use objc2::foundation::is_main_thread; use objc2::rc::{autoreleasepool, Id, Shared}; use objc2::{msg_send_id, ClassType}; @@ -27,7 +32,7 @@ use crate::{ app_delegate::ApplicationDelegate, app_state::{AppState, Callback}, monitor::{self, MonitorHandle}, - observer::*, + observer::setup_control_flow_observers, }, }; @@ -278,13 +283,23 @@ impl EventLoopProxy { fn new(sender: mpsc::Sender) -> Self { unsafe { // just wake up the eventloop - extern "C" fn event_loop_proxy_handler(_: *mut c_void) {} + extern "C" fn event_loop_proxy_handler(_: *const c_void) {} // adding a Source to the main CFRunLoop lets us wake it up and // process user events through the normal OS EventLoop mechanisms. let rl = CFRunLoopGetMain(); - let mut context: CFRunLoopSourceContext = mem::zeroed(); - context.perform = Some(event_loop_proxy_handler); + let mut context = CFRunLoopSourceContext { + version: 0, + info: ptr::null_mut(), + retain: None, + release: None, + copyDescription: None, + equal: None, + hash: None, + schedule: None, + cancel: None, + perform: event_loop_proxy_handler, + }; let source = CFRunLoopSourceCreate(ptr::null_mut(), CFIndex::max_value() - 1, &mut context); CFRunLoopAddSource(rl, source, kCFRunLoopCommonModes); diff --git a/src/platform_impl/macos/observer.rs b/src/platform_impl/macos/observer.rs index a51a9d10..247f22e1 100644 --- a/src/platform_impl/macos/observer.rs +++ b/src/platform_impl/macos/observer.rs @@ -1,6 +1,6 @@ use std::{ self, - os::raw::*, + ffi::c_void, panic::{AssertUnwindSafe, UnwindSafe}, ptr, rc::Weak, @@ -12,119 +12,15 @@ use crate::platform_impl::platform::{ event_loop::{stop_app_on_panic, PanicInfo}, ffi, }; - -#[link(name = "CoreFoundation", kind = "framework")] -extern "C" { - pub static kCFRunLoopCommonModes: CFRunLoopMode; - - pub fn CFRunLoopGetMain() -> CFRunLoopRef; - pub fn CFRunLoopWakeUp(rl: CFRunLoopRef); - - pub fn CFRunLoopObserverCreate( - allocator: CFAllocatorRef, - activities: CFOptionFlags, - repeats: ffi::Boolean, - order: CFIndex, - callout: CFRunLoopObserverCallBack, - context: *mut CFRunLoopObserverContext, - ) -> CFRunLoopObserverRef; - pub fn CFRunLoopAddObserver( - rl: CFRunLoopRef, - observer: CFRunLoopObserverRef, - mode: CFRunLoopMode, - ); - - pub fn CFRunLoopTimerCreate( - allocator: CFAllocatorRef, - fireDate: CFAbsoluteTime, - interval: CFTimeInterval, - flags: CFOptionFlags, - order: CFIndex, - callout: CFRunLoopTimerCallBack, - context: *mut CFRunLoopTimerContext, - ) -> CFRunLoopTimerRef; - pub fn CFRunLoopAddTimer(rl: CFRunLoopRef, timer: CFRunLoopTimerRef, mode: CFRunLoopMode); - pub fn CFRunLoopTimerSetNextFireDate(timer: CFRunLoopTimerRef, fireDate: CFAbsoluteTime); - pub fn CFRunLoopTimerInvalidate(time: CFRunLoopTimerRef); - - pub fn CFRunLoopSourceCreate( - allocator: CFAllocatorRef, - order: CFIndex, - context: *mut CFRunLoopSourceContext, - ) -> CFRunLoopSourceRef; - pub fn CFRunLoopAddSource(rl: CFRunLoopRef, source: CFRunLoopSourceRef, mode: CFRunLoopMode); - #[allow(dead_code)] - pub fn CFRunLoopSourceInvalidate(source: CFRunLoopSourceRef); - pub fn CFRunLoopSourceSignal(source: CFRunLoopSourceRef); - - pub fn CFAbsoluteTimeGetCurrent() -> CFAbsoluteTime; - pub fn CFRelease(cftype: *const c_void); -} - -pub enum CFAllocator {} -pub type CFAllocatorRef = *mut CFAllocator; -pub enum CFRunLoop {} -pub type CFRunLoopRef = *mut CFRunLoop; -pub type CFRunLoopMode = CFStringRef; -pub enum CFRunLoopObserver {} -pub type CFRunLoopObserverRef = *mut CFRunLoopObserver; -pub enum CFRunLoopTimer {} -pub type CFRunLoopTimerRef = *mut CFRunLoopTimer; -pub enum CFRunLoopSource {} -pub type CFRunLoopSourceRef = *mut CFRunLoopSource; -pub enum CFString {} -pub type CFStringRef = *const CFString; - -pub type CFHashCode = c_ulong; -pub type CFIndex = c_long; -pub type CFOptionFlags = c_ulong; -pub type CFRunLoopActivity = CFOptionFlags; - -pub type CFAbsoluteTime = CFTimeInterval; -pub type CFTimeInterval = f64; - -#[allow(non_upper_case_globals)] -pub const kCFRunLoopEntry: CFRunLoopActivity = 0; -#[allow(non_upper_case_globals)] -pub const kCFRunLoopBeforeWaiting: CFRunLoopActivity = 1 << 5; -#[allow(non_upper_case_globals)] -pub const kCFRunLoopAfterWaiting: CFRunLoopActivity = 1 << 6; -#[allow(non_upper_case_globals)] -pub const kCFRunLoopExit: CFRunLoopActivity = 1 << 7; - -pub type CFRunLoopObserverCallBack = - extern "C" fn(observer: CFRunLoopObserverRef, activity: CFRunLoopActivity, info: *mut c_void); -pub type CFRunLoopTimerCallBack = extern "C" fn(timer: CFRunLoopTimerRef, info: *mut c_void); - -pub enum CFRunLoopTimerContext {} - -/// This mirrors the struct with the same name from Core Foundation. -/// -/// -#[allow(non_snake_case)] -#[repr(C)] -pub struct CFRunLoopObserverContext { - pub version: CFIndex, - pub info: *mut c_void, - pub retain: Option *const c_void>, - pub release: Option, - pub copyDescription: Option CFStringRef>, -} - -#[allow(non_snake_case)] -#[repr(C)] -pub struct CFRunLoopSourceContext { - pub version: CFIndex, - pub info: *mut c_void, - pub retain: Option *const c_void>, - pub release: Option, - pub copyDescription: Option CFStringRef>, - pub equal: Option ffi::Boolean>, - pub hash: Option CFHashCode>, - pub schedule: Option, - pub cancel: Option, - pub perform: Option, -} +use core_foundation::base::{CFIndex, CFOptionFlags, CFRelease}; +use core_foundation::date::CFAbsoluteTimeGetCurrent; +use core_foundation::runloop::{ + kCFRunLoopAfterWaiting, kCFRunLoopBeforeWaiting, kCFRunLoopCommonModes, kCFRunLoopEntry, + kCFRunLoopExit, CFRunLoopActivity, CFRunLoopAddObserver, CFRunLoopAddTimer, CFRunLoopGetMain, + CFRunLoopObserverCallBack, CFRunLoopObserverContext, CFRunLoopObserverCreate, + CFRunLoopObserverRef, CFRunLoopRef, CFRunLoopTimerCreate, CFRunLoopTimerInvalidate, + CFRunLoopTimerRef, CFRunLoopTimerSetNextFireDate, +}; unsafe fn control_flow_handler(panic_info: *mut c_void, f: F) where