src/video/uikit/SDL_uikitappdelegate.m
author Sam Lantinga <slouken@libsdl.org>
Sun, 14 Oct 2012 01:05:04 -0700
changeset 6587 4ef7c70295c9
parent 6557 87ba88e3f2a9
child 6885 700f1b25f77f
permissions -rw-r--r--
Implemented drop events in iOS
slouken@2765
     1
/*
slouken@5535
     2
  Simple DirectMedia Layer
slouken@6138
     3
  Copyright (C) 1997-2012 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
*/
slouken@6044
    21
#include "SDL_config.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_hints_c.h"
slouken@6556
    29
#include "SDL_system.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@6556
    34
#include "jumphack.h"
slouken@2765
    35
slouken@2765
    36
#ifdef main
slouken@2765
    37
#undef main
slouken@2765
    38
#endif
slouken@2765
    39
slouken@2765
    40
extern int SDL_main(int argc, char *argv[]);
slouken@2765
    41
static int forward_argc;
slouken@2765
    42
static char **forward_argv;
kees@6006
    43
static int exit_status;
slouken@6556
    44
static UIWindow *launch_window;
slouken@2765
    45
kees@6003
    46
int main(int argc, char **argv)
kees@6003
    47
{
slouken@5131
    48
    int i;
slouken@5131
    49
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
kees@6001
    50
slouken@5131
    51
    /* store arguments */
slouken@5131
    52
    forward_argc = argc;
slouken@5131
    53
    forward_argv = (char **)malloc((argc+1) * sizeof(char *));
kees@6003
    54
    for (i = 0; i < argc; i++) {
slouken@5131
    55
        forward_argv[i] = malloc( (strlen(argv[i])+1) * sizeof(char));
slouken@5131
    56
        strcpy(forward_argv[i], argv[i]);
slouken@5131
    57
    }
slouken@5131
    58
    forward_argv[i] = NULL;
slouken@2765
    59
slouken@5131
    60
    /* Give over control to run loop, SDLUIKitDelegate will handle most things from here */
slouken@5532
    61
    UIApplicationMain(argc, argv, NULL, [SDLUIKitDelegate getAppDelegateClassName]);
kees@6001
    62
kees@6006
    63
    /* free the memory we used to hold copies of argc and argv */
kees@6006
    64
    for (i = 0; i < forward_argc; i++) {
kees@6006
    65
        free(forward_argv[i]);
kees@6006
    66
    }
kees@6006
    67
    free(forward_argv);
kees@6006
    68
slouken@5131
    69
    [pool release];
kees@6006
    70
    return exit_status;
slouken@2765
    71
}
slouken@2765
    72
kees@6003
    73
static void SDL_IdleTimerDisabledChanged(const char *name, const char *oldValue, const char *newValue)
kees@6003
    74
{
tim@5555
    75
    SDL_assert(SDL_strcmp(name, SDL_HINT_IDLE_TIMER_DISABLED) == 0);
kees@6001
    76
tim@5555
    77
    BOOL disable = (*newValue != '0');
tim@5555
    78
    [UIApplication sharedApplication].idleTimerDisabled = disable;
tim@5555
    79
}
tim@5555
    80
slouken@6556
    81
@interface SDL_splashviewcontroller : UIViewController {
slouken@6556
    82
    UIImageView *splash;
slouken@6556
    83
    UIImage *splashPortrait;
slouken@6556
    84
    UIImage *splashLandscape;
slouken@6556
    85
}
slouken@6556
    86
slouken@6556
    87
- (void)updateSplashImage:(UIInterfaceOrientation)interfaceOrientation;
slouken@6556
    88
@end
slouken@6556
    89
slouken@6556
    90
@implementation SDL_splashviewcontroller
slouken@6556
    91
slouken@6556
    92
- (id)init
slouken@6556
    93
{
slouken@6556
    94
    self = [super init];
slouken@6556
    95
    if (self == nil) {
slouken@6556
    96
        return nil;
slouken@6556
    97
    }
slouken@6556
    98
slouken@6556
    99
    self->splash = [[UIImageView alloc] init];
slouken@6556
   100
    [self setView:self->splash];
slouken@6556
   101
slouken@6557
   102
    CGSize size = [UIScreen mainScreen].bounds.size;
slouken@6557
   103
    float height = SDL_max(size.width, size.height);
slouken@6557
   104
    self->splashPortrait = [UIImage imageNamed:[NSString stringWithFormat:@"Default-%dh.png", (int)height]];
slouken@6557
   105
    if (!self->splashPortrait) {
slouken@6557
   106
        self->splashPortrait = [UIImage imageNamed:@"Default.png"];
slouken@6557
   107
    }
slouken@6556
   108
    self->splashLandscape = [UIImage imageNamed:@"Default-Landscape.png"];
slouken@6557
   109
    if (!self->splashLandscape && self->splashPortrait) {
slouken@6556
   110
        self->splashLandscape = [[UIImage alloc] initWithCGImage: self->splashPortrait.CGImage
slouken@6556
   111
                                                           scale: 1.0
slouken@6556
   112
                                                     orientation: UIImageOrientationRight];
slouken@6556
   113
    }
slouken@6556
   114
    if (self->splashPortrait) {
slouken@6556
   115
        [self->splashPortrait retain];
slouken@6556
   116
    }
slouken@6556
   117
    if (self->splashLandscape) {
slouken@6556
   118
        [self->splashLandscape retain];
slouken@6556
   119
    }
slouken@6556
   120
 
slouken@6556
   121
    [self updateSplashImage:[[UIApplication sharedApplication] statusBarOrientation]];
slouken@6556
   122
slouken@6556
   123
    return self;
slouken@6556
   124
}
slouken@6556
   125
slouken@6556
   126
- (NSUInteger)supportedInterfaceOrientations
slouken@6556
   127
{
slouken@6556
   128
    NSUInteger orientationMask = UIInterfaceOrientationMaskAll;
slouken@6556
   129
    
slouken@6556
   130
    // Don't allow upside-down orientation on the phone, so answering calls is in the natural orientation
slouken@6556
   131
    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
slouken@6556
   132
        orientationMask &= ~UIInterfaceOrientationMaskPortraitUpsideDown;
slouken@6556
   133
    }
slouken@6556
   134
    return orientationMask;
slouken@6556
   135
}
slouken@6556
   136
slouken@6556
   137
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)orient
slouken@6556
   138
{
slouken@6556
   139
    NSUInteger orientationMask = [self supportedInterfaceOrientations];
slouken@6556
   140
    return (orientationMask & (1 << orient));
slouken@6556
   141
}
slouken@6556
   142
slouken@6556
   143
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration
slouken@6556
   144
{
slouken@6556
   145
    [self updateSplashImage:interfaceOrientation];
slouken@6556
   146
}
slouken@6556
   147
slouken@6556
   148
- (void)updateSplashImage:(UIInterfaceOrientation)interfaceOrientation
slouken@6556
   149
{
slouken@6556
   150
    UIImage *image;
slouken@6556
   151
    
slouken@6556
   152
    if (UIInterfaceOrientationIsLandscape(interfaceOrientation)) {
slouken@6556
   153
        image = self->splashLandscape;
slouken@6556
   154
    } else {
slouken@6556
   155
        image = self->splashPortrait;
slouken@6556
   156
    }
slouken@6556
   157
    if (image)
slouken@6556
   158
    {
slouken@6556
   159
        splash.image = image;
slouken@6556
   160
    }
slouken@6556
   161
}
slouken@6556
   162
slouken@6556
   163
@end
slouken@6556
   164
slouken@6556
   165
slouken@2765
   166
@implementation SDLUIKitDelegate
slouken@2765
   167
slouken@2765
   168
/* convenience method */
icculus@6090
   169
+ (id) sharedAppDelegate
kees@6003
   170
{
slouken@5131
   171
    /* the delegate is set in UIApplicationMain(), which is garaunteed to be called before this method */
icculus@6090
   172
    return [[UIApplication sharedApplication] delegate];
slouken@2765
   173
}
slouken@2765
   174
kees@6003
   175
+ (NSString *)getAppDelegateClassName
kees@6003
   176
{
slouken@5532
   177
    /* subclassing notice: when you subclass this appdelegate, make sure to add a category to override
slouken@5532
   178
       this method and return the actual name of the delegate */
slouken@5532
   179
    return @"SDLUIKitDelegate";
slouken@5532
   180
}
slouken@5532
   181
kees@6003
   182
- (id)init
kees@6003
   183
{
slouken@5131
   184
    self = [super init];
slouken@5131
   185
    return self;
slouken@2765
   186
}
slouken@2765
   187
kees@6003
   188
- (void)postFinishLaunch
kees@6003
   189
{
slouken@5131
   190
    /* run the user's application, passing argc and argv */
slouken@6346
   191
    SDL_iPhoneSetEventPump(SDL_TRUE);
kees@6006
   192
    exit_status = SDL_main(forward_argc, forward_argv);
slouken@6346
   193
    SDL_iPhoneSetEventPump(SDL_FALSE);
kees@6001
   194
slouken@6556
   195
    /* If we showed a splash image, clean it up */
slouken@6556
   196
    if (launch_window) {
slouken@6556
   197
        [launch_window release];
slouken@6556
   198
        launch_window = NULL;
slouken@6556
   199
    }
slouken@6556
   200
slouken@5131
   201
    /* exit, passing the return status from the user's application */
slouken@6342
   202
    // We don't actually exit to support applications that do setup in
slouken@6342
   203
    // their main function and then allow the Cocoa event loop to run.
kees@6006
   204
    // exit(exit_status);
slouken@3422
   205
}
slouken@3422
   206
kees@6003
   207
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
kees@6003
   208
{
slouken@6556
   209
    /* Keep the launch image up until we set a video mode */
slouken@6556
   210
    launch_window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
slouken@6556
   211
slouken@6556
   212
    UIViewController *splashViewController = [[SDL_splashviewcontroller alloc] init];
slouken@6556
   213
    launch_window.rootViewController = splashViewController;
slouken@6556
   214
    [launch_window addSubview:splashViewController.view];
slouken@6556
   215
    [launch_window makeKeyAndVisible];
slouken@6556
   216
slouken@5131
   217
    /* Set working directory to resource path */
slouken@5131
   218
    [[NSFileManager defaultManager] changeCurrentDirectoryPath: [[NSBundle mainBundle] resourcePath]];
kees@6001
   219
slouken@6349
   220
    /* register a callback for the idletimer hint */
slouken@6349
   221
    SDL_SetHint(SDL_HINT_IDLE_TIMER_DISABLED, "0");
slouken@6349
   222
    SDL_RegisterHintChangedCb(SDL_HINT_IDLE_TIMER_DISABLED, &SDL_IdleTimerDisabledChanged);
slouken@6349
   223
slouken@5532
   224
    [self performSelector:@selector(postFinishLaunch) withObject:nil afterDelay:0.0];
slouken@5487
   225
slouken@5487
   226
    return YES;
slouken@2765
   227
}
slouken@2765
   228
kees@6003
   229
- (void)applicationWillTerminate:(UIApplication *)application
kees@6003
   230
{
slouken@5131
   231
    SDL_SendQuit();
slouken@5131
   232
     /* hack to prevent automatic termination.  See SDL_uikitevents.m for details */
slouken@5131
   233
    longjmp(*(jump_env()), 1);
slouken@2765
   234
}
slouken@2765
   235
slouken@3400
   236
- (void) applicationWillResignActive:(UIApplication*)application
slouken@3400
   237
{
icculus@4446
   238
    //NSLog(@"%@", NSStringFromSelector(_cmd));
icculus@4446
   239
icculus@4446
   240
    // Send every window on every screen a MINIMIZED event.
icculus@4446
   241
    SDL_VideoDevice *_this = SDL_GetVideoDevice();
icculus@4446
   242
    if (!_this) {
icculus@4446
   243
        return;
icculus@4446
   244
    }
kees@6001
   245
slouken@5532
   246
    SDL_Window *window;
slouken@5251
   247
    for (window = _this->windows; window != nil; window = window->next) {
slouken@6191
   248
        SDL_SendWindowEvent(window, SDL_WINDOWEVENT_FOCUS_LOST, 0, 0);
slouken@5251
   249
        SDL_SendWindowEvent(window, SDL_WINDOWEVENT_MINIMIZED, 0, 0);
icculus@4446
   250
    }
slouken@3400
   251
}
slouken@3400
   252
slouken@3400
   253
- (void) applicationDidBecomeActive:(UIApplication*)application
slouken@3400
   254
{
icculus@4446
   255
    //NSLog(@"%@", NSStringFromSelector(_cmd));
slouken@3400
   256
icculus@4446
   257
    // Send every window on every screen a RESTORED event.
icculus@4446
   258
    SDL_VideoDevice *_this = SDL_GetVideoDevice();
icculus@4446
   259
    if (!_this) {
icculus@4446
   260
        return;
icculus@4446
   261
    }
kees@6001
   262
kees@5614
   263
    SDL_Window *window;
slouken@5251
   264
    for (window = _this->windows; window != nil; window = window->next) {
slouken@6191
   265
        SDL_SendWindowEvent(window, SDL_WINDOWEVENT_FOCUS_GAINED, 0, 0);
kees@5614
   266
        SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESTORED, 0, 0);
icculus@4446
   267
    }
slouken@2765
   268
}
slouken@2765
   269
slouken@6587
   270
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
slouken@6587
   271
{
slouken@6587
   272
    NSURL *fileURL = [url filePathURL];
slouken@6587
   273
    if (fileURL != nil) {
slouken@6587
   274
        SDL_SendDropFile([[fileURL path] UTF8String]);
slouken@6587
   275
    } else {
slouken@6587
   276
        SDL_SendDropFile([[url absoluteString] UTF8String]);
slouken@6587
   277
    }
slouken@6587
   278
    return YES;
slouken@6587
   279
}
slouken@6587
   280
slouken@2765
   281
@end
slouken@5132
   282
slouken@6044
   283
#endif /* SDL_VIDEO_DRIVER_UIKIT */
slouken@6044
   284
slouken@5132
   285
/* vi: set ts=4 sw=4 expandtab: */