#include "../../SDL_internal.h"
#if SDL_VIDEO_DRIVER_UIKIT
#include "../SDL_sysvideo.h"
#include "SDL_hints.h"
#include "SDL_system.h"
#include "SDL_main.h"
#import "SDL_uikitappdelegate.h"
#import "SDL_uikitmodes.h"
#import "SDL_uikitwindow.h"
#include "../../events/SDL_events_c.h"
#if !TARGET_OS_TV
#include <AvailabilityVersions.h>
# ifndef __IPHONE_13_0
# define __IPHONE_13_0 130000
# endif
#endif
#ifdef main
#undef main
#endif
static SDL_main_func forward_main;
static int forward_argc;
static char **forward_argv;
static int exit_status;
int SDL_UIKitRunApp(int argc, char *argv[], SDL_main_func mainFunction)
{
int i;
forward_main = mainFunction;
forward_argc = argc;
forward_argv = (char **)malloc((argc+1) * sizeof(char *));
for (i = 0; i < argc; i++) {
forward_argv[i] = malloc( (strlen(argv[i])+1) * sizeof(char));
strcpy(forward_argv[i], argv[i]);
}
forward_argv[i] = NULL;
@autoreleasepool {
UIApplicationMain(argc, argv, nil, [SDLUIKitDelegate getAppDelegateClassName]);
}
for (i = 0; i < forward_argc; i++) {
free(forward_argv[i]);
}
free(forward_argv);
return exit_status;
}
static void SDLCALL
SDL_IdleTimerDisabledChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
{
BOOL disable = (hint && *hint != '0');
[UIApplication sharedApplication].idleTimerDisabled = disable;
}
#if !TARGET_OS_TV
static UIImage *
SDL_LoadLaunchImageNamed(NSString *name, int screenh)
{
UIInterfaceOrientation curorient = [UIApplication sharedApplication].statusBarOrientation;
UIUserInterfaceIdiom idiom = [UIDevice currentDevice].userInterfaceIdiom;
UIImage *image = nil;
if (idiom == UIUserInterfaceIdiomPhone && screenh == 568) {
image = [UIImage imageNamed:[NSString stringWithFormat:@"%@-568h", name]];
} else if (idiom == UIUserInterfaceIdiomPad) {
if (UIInterfaceOrientationIsLandscape(curorient)) {
if (curorient == UIInterfaceOrientationLandscapeLeft) {
image = [UIImage imageNamed:[NSString stringWithFormat:@"%@-LandscapeLeft", name]];
} else {
image = [UIImage imageNamed:[NSString stringWithFormat:@"%@-LandscapeRight", name]];
}
if (!image) {
image = [UIImage imageNamed:[NSString stringWithFormat:@"%@-Landscape", name]];
}
} else {
if (curorient == UIInterfaceOrientationPortraitUpsideDown) {
image = [UIImage imageNamed:[NSString stringWithFormat:@"%@-PortraitUpsideDown", name]];
}
if (!image) {
image = [UIImage imageNamed:[NSString stringWithFormat:@"%@-Portrait", name]];
}
}
}
if (!image) {
image = [UIImage imageNamed:name];
}
return image;
}
@interface SDLLaunchStoryboardViewController : UIViewController
@property (nonatomic, strong) UIViewController *storyboardViewController;
- (instancetype)initWithStoryboardViewController:(UIViewController *)storyboardViewController;
@end
@implementation SDLLaunchStoryboardViewController
- (instancetype)initWithStoryboardViewController:(UIViewController *)storyboardViewController {
self = [super init];
self.storyboardViewController = storyboardViewController;
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
[self addChildViewController:self.storyboardViewController];
[self.view addSubview:self.storyboardViewController.view];
self.storyboardViewController.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
self.storyboardViewController.view.frame = self.view.bounds;
[self.storyboardViewController didMoveToParentViewController:self];
UIApplication.sharedApplication.statusBarHidden = self.prefersStatusBarHidden;
UIApplication.sharedApplication.statusBarStyle = self.preferredStatusBarStyle;
}
- (BOOL)prefersStatusBarHidden {
return [[NSBundle.mainBundle objectForInfoDictionaryKey:@"UIStatusBarHidden"] boolValue];
}
- (UIStatusBarStyle)preferredStatusBarStyle {
NSString *statusBarStyle = [NSBundle.mainBundle objectForInfoDictionaryKey:@"UIStatusBarStyle"];
if ([statusBarStyle isEqualToString:@"UIStatusBarStyleLightContent"]) {
return UIStatusBarStyleLightContent;
}
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_13_0
if (@available(iOS 13.0, *)) {
if ([statusBarStyle isEqualToString:@"UIStatusBarStyleDarkContent"]) {
return UIStatusBarStyleDarkContent;
}
}
#endif
return UIStatusBarStyleDefault;
}
@end
#endif
@interface SDLLaunchScreenController ()
#if !TARGET_OS_TV
- (NSUInteger)supportedInterfaceOrientations;
#endif
@end
@implementation SDLLaunchScreenController
- (instancetype)init
{
return [self initWithNibName:nil bundle:[NSBundle mainBundle]];
}
- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
if (!(self = [super initWithNibName:nil bundle:nil])) {
return nil;
}
NSString *screenname = nibNameOrNil;
NSBundle *bundle = nibBundleOrNil;
if (screenname) {
@try {
self.view = [bundle loadNibNamed:screenname owner:self options:nil][0];
}
@catch (NSException *exception) {
return nil;
}
}
if (!self.view) {
NSArray *launchimages = [bundle objectForInfoDictionaryKey:@"UILaunchImages"];
NSString *imagename = nil;
UIImage *image = nil;
int screenw = (int)([UIScreen mainScreen].bounds.size.width + 0.5);
int screenh = (int)([UIScreen mainScreen].bounds.size.height + 0.5);
#if !TARGET_OS_TV
UIInterfaceOrientation curorient = [UIApplication sharedApplication].statusBarOrientation;
if (screenw > screenh) {
int width = screenw;
screenw = screenh;
screenh = width;
}
#endif
if (launchimages) {
for (NSDictionary *dict in launchimages) {
NSString *minversion = dict[@"UILaunchImageMinimumOSVersion"];
NSString *sizestring = dict[@"UILaunchImageSize"];
if (minversion && !UIKit_IsSystemVersionAtLeast(minversion.doubleValue)) {
continue;
}
if (sizestring) {
CGSize size = CGSizeFromString(sizestring);
if ((int)(size.width + 0.5) != screenw || (int)(size.height + 0.5) != screenh) {
continue;
}
}
#if !TARGET_OS_TV
UIInterfaceOrientationMask orientmask = UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown;
NSString *orientstring = dict[@"UILaunchImageOrientation"];
if (orientstring) {
if ([orientstring isEqualToString:@"PortraitUpsideDown"]) {
orientmask = UIInterfaceOrientationMaskPortraitUpsideDown;
} else if ([orientstring isEqualToString:@"Landscape"]) {
orientmask = UIInterfaceOrientationMaskLandscape;
} else if ([orientstring isEqualToString:@"LandscapeLeft"]) {
orientmask = UIInterfaceOrientationMaskLandscapeLeft;
} else if ([orientstring isEqualToString:@"LandscapeRight"]) {
orientmask = UIInterfaceOrientationMaskLandscapeRight;
}
}
if ((orientmask & (1 << curorient)) == 0) {
continue;
}
#endif
imagename = dict[@"UILaunchImageName"];
}
if (imagename) {
image = [UIImage imageNamed:imagename];
}
}
#if !TARGET_OS_TV
else {
imagename = [bundle objectForInfoDictionaryKey:@"UILaunchImageFile"];
if (imagename) {
image = SDL_LoadLaunchImageNamed(imagename, screenh);
}
if (!image) {
image = SDL_LoadLaunchImageNamed(@"Default", screenh);
}
}
#endif
if (image) {
UIImageView *view = [[UIImageView alloc] initWithFrame:[UIScreen mainScreen].bounds];
UIImageOrientation imageorient = UIImageOrientationUp;
#if !TARGET_OS_TV
if (UIInterfaceOrientationIsLandscape(curorient)) {
if (image.size.width < image.size.height) {
if (curorient == UIInterfaceOrientationLandscapeLeft) {
imageorient = UIImageOrientationRight;
} else if (curorient == UIInterfaceOrientationLandscapeRight) {
imageorient = UIImageOrientationLeft;
}
}
}
#endif
view.image = [[UIImage alloc] initWithCGImage:image.CGImage scale:image.scale orientation:imageorient];
self.view = view;
}
}
return self;
}
- (void)loadView
{
}
#if !TARGET_OS_TV
- (BOOL)shouldAutorotate
{
return NO;
}
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskAll;
}
#endif
@end
@implementation SDLUIKitDelegate {
UIWindow *launchWindow;
}
+ (id)sharedAppDelegate
{
return [UIApplication sharedApplication].delegate;
}
+ (NSString *)getAppDelegateClassName
{
return @"SDLUIKitDelegate";
}
- (void)hideLaunchScreen
{
UIWindow *window = launchWindow;
if (!window || window.hidden) {
return;
}
launchWindow = nil;
[UIView animateWithDuration:0.2 animations:^{
window.alpha = 0.0;
} completion:^(BOOL finished) {
window.hidden = YES;
UIKit_ForceUpdateHomeIndicator();
}];
}
- (void)postFinishLaunch
{
[self performSelector:@selector(hideLaunchScreen) withObject:nil afterDelay:0.0];
SDL_iPhoneSetEventPump(SDL_TRUE);
exit_status = forward_main(forward_argc, forward_argv);
SDL_iPhoneSetEventPump(SDL_FALSE);
if (launchWindow) {
launchWindow.hidden = YES;
launchWindow = nil;
}
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSBundle *bundle = [NSBundle mainBundle];
#if SDL_IPHONE_LAUNCHSCREEN
UIViewController *vc = nil;
NSString *screenname = nil;
#if !TARGET_OS_TV
screenname = [bundle objectForInfoDictionaryKey:@"UILaunchStoryboardName"];
if (screenname) {
@try {
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:screenname bundle:bundle];
__auto_type storyboardVc = [storyboard instantiateInitialViewController];
vc = [[SDLLaunchStoryboardViewController alloc] initWithStoryboardViewController:storyboardVc];
}
@catch (NSException *exception) {
}
}
#endif
if (vc == nil) {
vc = [[SDLLaunchScreenController alloc] initWithNibName:screenname bundle:bundle];
}
if (vc.view) {
launchWindow = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
launchWindow.windowLevel = UIWindowLevelNormal + 1.0;
launchWindow.hidden = NO;
launchWindow.rootViewController = vc;
}
#endif
[[NSFileManager defaultManager] changeCurrentDirectoryPath:[bundle resourcePath]];
SDL_AddHintCallback(SDL_HINT_IDLE_TIMER_DISABLED,
SDL_IdleTimerDisabledChanged, NULL);
SDL_SetMainReady();
[self performSelector:@selector(postFinishLaunch) withObject:nil afterDelay:0.0];
return YES;
}
- (UIWindow *)window
{
SDL_VideoDevice *_this = SDL_GetVideoDevice();
if (_this) {
SDL_Window *window = NULL;
for (window = _this->windows; window != NULL; window = window->next) {
SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata;
if (data != nil) {
return data.uiwindow;
}
}
}
return nil;
}
- (void)setWindow:(UIWindow *)window
{
}
- (void)sendDropFileForURL:(NSURL *)url
{
NSURL *fileURL = url.filePathURL;
if (fileURL != nil) {
SDL_SendDropFile(NULL, fileURL.path.UTF8String);
} else {
SDL_SendDropFile(NULL, url.absoluteString.UTF8String);
}
SDL_SendDropComplete(NULL);
}
#if TARGET_OS_TV || (defined(__IPHONE_9_0) && __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_9_0)
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
{
[self sendDropFileForURL:url];
return YES;
}
#else
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
[self sendDropFileForURL:url];
return YES;
}
#endif
@end
#endif