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