objc2_app_kit/
application.rs

1#![cfg(feature = "NSResponder")]
2use core::ffi::{c_char, c_int};
3use core::ptr::NonNull;
4
5use objc2::rc::Retained;
6use objc2::MainThreadMarker;
7
8use crate::NSApplication;
9
10pub fn NSApp(mtm: MainThreadMarker) -> Retained<NSApplication> {
11    // TODO: Use the `NSApp` static
12    NSApplication::sharedApplication(mtm)
13}
14
15impl NSApplication {
16    /// An entry point to AppKit applications.
17    ///
18    /// See [Apple's documentation][apple-doc] for more details.
19    ///
20    /// [apple-doc]: https://developer.apple.com/documentation/appkit/nsapplicationmain(_:_:)
21    #[doc(alias = "NSApplicationMain")]
22    pub fn main(mtm: MainThreadMarker) -> ! {
23        // NSApplicationMain must be called on the main thread.
24        let _ = mtm;
25
26        #[cfg(not(feature = "gnustep-1-7"))]
27        {
28            // These functions are in crt_externs.h.
29            extern "C" {
30                fn _NSGetArgc() -> *mut c_int;
31                fn _NSGetArgv() -> *mut *mut *mut c_char;
32            }
33
34            // NOTE: `NSApplicationMain` is explicitly documented to ignore the
35            // `argc` and `argv` arguments, so we choose to not expose those in
36            // our API.
37            // We pass correct values anyhow though, just to be certain.
38            let argc = unsafe { *_NSGetArgc() };
39            let argv = unsafe { NonNull::new(*_NSGetArgv()).unwrap().cast() };
40
41            // SAFETY: `argc` and `argv` are correct.
42            // `NSApplicationMain` is safely re-entrant, just weird to do so.
43            let _ret = unsafe { Self::__main(argc, argv) };
44
45            // NSApplicationMain is documented to never return, so whatever we do
46            // here is just for show really.
47            #[cfg(feature = "std")]
48            {
49                std::process::exit(_ret as i32)
50            }
51            #[cfg(not(feature = "std"))]
52            {
53                unreachable!("NSApplicationMain should not have returned")
54            }
55        }
56        #[cfg(feature = "gnustep-1-7")]
57        {
58            unsafe { Self::__main(0, NonNull::dangling()) };
59            unreachable!()
60        }
61    }
62}