src/video/uikit/SDL_uikitappdelegate.m
author Alex Szpakowski <slime73@gmail.com>
Wed, 23 Jul 2014 03:05:31 -0300
branchiOS-improvements
changeset 9501 574db299498f
parent 9495 76e878c8ca80
child 9504 1f3b6fc94fae
permissions -rw-r--r--
More cleanup of the iOS Objective-C code.
     1 /*
     2   Simple DirectMedia Layer
     3   Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
     4 
     5   This software is provided 'as-is', without any express or implied
     6   warranty.  In no event will the authors be held liable for any damages
     7   arising from the use of this software.
     8 
     9   Permission is granted to anyone to use this software for any purpose,
    10   including commercial applications, and to alter it and redistribute it
    11   freely, subject to the following restrictions:
    12 
    13   1. The origin of this software must not be misrepresented; you must not
    14      claim that you wrote the original software. If you use this software
    15      in a product, an acknowledgment in the product documentation would be
    16      appreciated but is not required.
    17   2. Altered source versions must be plainly marked as such, and must not be
    18      misrepresented as being the original software.
    19   3. This notice may not be removed or altered from any source distribution.
    20 */
    21 #include "../../SDL_internal.h"
    22 
    23 #if SDL_VIDEO_DRIVER_UIKIT
    24 
    25 #include "../SDL_sysvideo.h"
    26 #include "SDL_assert.h"
    27 #include "SDL_hints.h"
    28 #include "SDL_system.h"
    29 #include "SDL_main.h"
    30 
    31 #include "SDL_uikitappdelegate.h"
    32 #include "SDL_uikitmodes.h"
    33 #include "../../events/SDL_events_c.h"
    34 
    35 #ifdef main
    36 #undef main
    37 #endif
    38 
    39 static int forward_argc;
    40 static char **forward_argv;
    41 static int exit_status;
    42 static UIWindow *launch_window;
    43 
    44 int main(int argc, char **argv)
    45 {
    46     int i;
    47 
    48     /* store arguments */
    49     forward_argc = argc;
    50     forward_argv = (char **)malloc((argc+1) * sizeof(char *));
    51     for (i = 0; i < argc; i++) {
    52         forward_argv[i] = malloc( (strlen(argv[i])+1) * sizeof(char));
    53         strcpy(forward_argv[i], argv[i]);
    54     }
    55     forward_argv[i] = NULL;
    56 
    57     /* Give over control to run loop, SDLUIKitDelegate will handle most things from here */
    58     @autoreleasepool {
    59         UIApplicationMain(argc, argv, NULL, [SDLUIKitDelegate getAppDelegateClassName]);
    60     }
    61 
    62     /* free the memory we used to hold copies of argc and argv */
    63     for (i = 0; i < forward_argc; i++) {
    64         free(forward_argv[i]);
    65     }
    66     free(forward_argv);
    67 
    68     return exit_status;
    69 }
    70 
    71 static void
    72 SDL_IdleTimerDisabledChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
    73 {
    74     BOOL disable = (hint && *hint != '0');
    75     [UIApplication sharedApplication].idleTimerDisabled = disable;
    76 }
    77 
    78 @interface SDL_splashviewcontroller : UIViewController
    79 
    80 - (void)updateSplashImage:(UIInterfaceOrientation)interfaceOrientation;
    81 
    82 @end
    83 
    84 @implementation SDL_splashviewcontroller {
    85     UIImageView *splash;
    86     UIImage *splashPortrait;
    87     UIImage *splashLandscape;
    88 }
    89 
    90 - (id)init
    91 {
    92     self = [super init];
    93     if (self == nil) {
    94         return nil;
    95     }
    96 
    97     self->splash = [[UIImageView alloc] init];
    98     [self setView:self->splash];
    99 
   100     CGSize size = [UIScreen mainScreen].bounds.size;
   101     float height = SDL_max(size.width, size.height);
   102     self->splashPortrait = [UIImage imageNamed:[NSString stringWithFormat:@"Default-%dh.png", (int)height]];
   103     if (!self->splashPortrait) {
   104         self->splashPortrait = [UIImage imageNamed:@"Default.png"];
   105     }
   106     self->splashLandscape = [UIImage imageNamed:@"Default-Landscape.png"];
   107     if (!self->splashLandscape && self->splashPortrait) {
   108         self->splashLandscape = [[UIImage alloc] initWithCGImage: self->splashPortrait.CGImage
   109                                                            scale: 1.0
   110                                                      orientation: UIImageOrientationRight];
   111     }
   112     if (self->splashPortrait) {
   113         [self->splashPortrait retain];
   114     }
   115     if (self->splashLandscape) {
   116         [self->splashLandscape retain];
   117     }
   118 
   119     [self updateSplashImage:[[UIApplication sharedApplication] statusBarOrientation]];
   120 
   121     return self;
   122 }
   123 
   124 - (NSUInteger)supportedInterfaceOrientations
   125 {
   126     NSUInteger orientationMask = UIInterfaceOrientationMaskAll;
   127 
   128     /* Don't allow upside-down orientation on the phone, so answering calls is in the natural orientation */
   129     if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
   130         orientationMask &= ~UIInterfaceOrientationMaskPortraitUpsideDown;
   131     }
   132     return orientationMask;
   133 }
   134 
   135 - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)orient
   136 {
   137     NSUInteger orientationMask = [self supportedInterfaceOrientations];
   138     return (orientationMask & (1 << orient));
   139 }
   140 
   141 - (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration
   142 {
   143     [self updateSplashImage:interfaceOrientation];
   144 }
   145 
   146 - (void)updateSplashImage:(UIInterfaceOrientation)interfaceOrientation
   147 {
   148     UIImage *image;
   149 
   150     if (UIInterfaceOrientationIsLandscape(interfaceOrientation)) {
   151         image = self->splashLandscape;
   152     } else {
   153         image = self->splashPortrait;
   154     }
   155 
   156     if (image) {
   157         splash.image = image;
   158     }
   159 }
   160 
   161 @end
   162 
   163 
   164 @implementation SDLUIKitDelegate
   165 
   166 /* convenience method */
   167 + (id) sharedAppDelegate
   168 {
   169     /* the delegate is set in UIApplicationMain(), which is guaranteed to be called before this method */
   170     return [[UIApplication sharedApplication] delegate];
   171 }
   172 
   173 + (NSString *)getAppDelegateClassName
   174 {
   175     /* subclassing notice: when you subclass this appdelegate, make sure to add a category to override
   176        this method and return the actual name of the delegate */
   177     return @"SDLUIKitDelegate";
   178 }
   179 
   180 - (id)init
   181 {
   182     self = [super init];
   183     return self;
   184 }
   185 
   186 - (void)postFinishLaunch
   187 {
   188     /* run the user's application, passing argc and argv */
   189     SDL_iPhoneSetEventPump(SDL_TRUE);
   190     exit_status = SDL_main(forward_argc, forward_argv);
   191     SDL_iPhoneSetEventPump(SDL_FALSE);
   192 
   193     /* If we showed a splash image, clean it up */
   194     if (launch_window) {
   195         [launch_window release];
   196         launch_window = NULL;
   197     }
   198 
   199     /* exit, passing the return status from the user's application */
   200     /* We don't actually exit to support applications that do setup in
   201      * their main function and then allow the Cocoa event loop to run.
   202      */
   203     /* exit(exit_status); */
   204 }
   205 
   206 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
   207 {
   208     /* Keep the launch image up until we set a video mode */
   209 
   210     /* This is disabled temporarily because the splash viewcontroller is
   211      * interfering with rotation once a regular window is created: the view's
   212      * orientations are incorrect and the status bar rotates without the view.
   213      * Additionally, the splash viewcontroller doesn't load the correct launch
   214      * images on iOS 7 and modern devices. */
   215     /*launch_window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
   216 
   217     UIViewController *splashViewController = [[SDL_splashviewcontroller alloc] init];
   218     launch_window.rootViewController = splashViewController;
   219     [launch_window addSubview:splashViewController.view];
   220     [launch_window makeKeyAndVisible];*/
   221 
   222     /* Set working directory to resource path */
   223     [[NSFileManager defaultManager] changeCurrentDirectoryPath: [[NSBundle mainBundle] resourcePath]];
   224 
   225     /* register a callback for the idletimer hint */
   226     SDL_AddHintCallback(SDL_HINT_IDLE_TIMER_DISABLED,
   227                         SDL_IdleTimerDisabledChanged, NULL);
   228 
   229     SDL_SetMainReady();
   230     [self performSelector:@selector(postFinishLaunch) withObject:nil afterDelay:0.0];
   231 
   232     return YES;
   233 }
   234 
   235 - (void)applicationWillTerminate:(UIApplication *)application
   236 {
   237     SDL_SendAppEvent(SDL_APP_TERMINATING);
   238 }
   239 
   240 - (void)applicationDidReceiveMemoryWarning:(UIApplication *)application
   241 {
   242     SDL_SendAppEvent(SDL_APP_LOWMEMORY);
   243 }
   244 
   245 - (void) applicationWillResignActive:(UIApplication*)application
   246 {
   247     SDL_VideoDevice *_this = SDL_GetVideoDevice();
   248     if (_this) {
   249         SDL_Window *window;
   250         for (window = _this->windows; window != nil; window = window->next) {
   251             SDL_SendWindowEvent(window, SDL_WINDOWEVENT_FOCUS_LOST, 0, 0);
   252             SDL_SendWindowEvent(window, SDL_WINDOWEVENT_MINIMIZED, 0, 0);
   253         }
   254     }
   255     SDL_SendAppEvent(SDL_APP_WILLENTERBACKGROUND);
   256 }
   257 
   258 - (void) applicationDidEnterBackground:(UIApplication*)application
   259 {
   260     SDL_SendAppEvent(SDL_APP_DIDENTERBACKGROUND);
   261 }
   262 
   263 - (void) applicationWillEnterForeground:(UIApplication*)application
   264 {
   265     SDL_SendAppEvent(SDL_APP_WILLENTERFOREGROUND);
   266 }
   267 
   268 - (void) applicationDidBecomeActive:(UIApplication*)application
   269 {
   270     SDL_SendAppEvent(SDL_APP_DIDENTERFOREGROUND);
   271 
   272     SDL_VideoDevice *_this = SDL_GetVideoDevice();
   273     if (_this) {
   274         SDL_Window *window;
   275         for (window = _this->windows; window != nil; window = window->next) {
   276             SDL_SendWindowEvent(window, SDL_WINDOWEVENT_FOCUS_GAINED, 0, 0);
   277             SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESTORED, 0, 0);
   278         }
   279     }
   280 }
   281 
   282 - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
   283 {
   284     NSURL *fileURL = [url filePathURL];
   285     if (fileURL != nil) {
   286         SDL_SendDropFile([[fileURL path] UTF8String]);
   287     } else {
   288         SDL_SendDropFile([[url absoluteString] UTF8String]);
   289     }
   290     return YES;
   291 }
   292 
   293 @end
   294 
   295 #endif /* SDL_VIDEO_DRIVER_UIKIT */
   296 
   297 /* vi: set ts=4 sw=4 expandtab: */