src/video/uikit/SDL_uikitwindow.m
author Sam Lantinga
Fri, 27 Jan 2017 06:05:50 -0800
changeset 10856 486aa38c6a88
parent 10737 3406a0f8b041
child 10945 1300a3135d61
permissions -rw-r--r--
Added Thrustmaster Wheel FFB entry to the list of wheels
slouken@2765
     1
/*
slouken@5535
     2
  Simple DirectMedia Layer
slouken@10737
     3
  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
slouken@2765
     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@2765
     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@2765
    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@2765
    22
slouken@6044
    23
#if SDL_VIDEO_DRIVER_UIKIT
slouken@6044
    24
slouken@5056
    25
#include "SDL_syswm.h"
slouken@2765
    26
#include "SDL_video.h"
slouken@2765
    27
#include "SDL_mouse.h"
icculus@4446
    28
#include "SDL_assert.h"
tim@5554
    29
#include "SDL_hints.h"
slouken@2765
    30
#include "../SDL_sysvideo.h"
slouken@2765
    31
#include "../SDL_pixels_c.h"
slouken@2765
    32
#include "../../events/SDL_events_c.h"
slouken@2765
    33
slouken@2765
    34
#include "SDL_uikitvideo.h"
slouken@2765
    35
#include "SDL_uikitevents.h"
slouken@6518
    36
#include "SDL_uikitmodes.h"
slouken@2765
    37
#include "SDL_uikitwindow.h"
slouken@2765
    38
#import "SDL_uikitappdelegate.h"
slouken@2765
    39
slime73@9532
    40
#import "SDL_uikitview.h"
slime73@9540
    41
#import "SDL_uikitopenglview.h"
slouken@2765
    42
slouken@2765
    43
#include <Foundation/Foundation.h>
slouken@2765
    44
slime73@9510
    45
@implementation SDL_WindowData
slime73@9510
    46
slime73@9510
    47
@synthesize uiwindow;
slime73@9510
    48
@synthesize viewcontroller;
slime73@9532
    49
@synthesize views;
slime73@9532
    50
slime73@9532
    51
- (instancetype)init
slime73@9532
    52
{
slime73@9532
    53
    if ((self = [super init])) {
slime73@9532
    54
        views = [NSMutableArray new];
slime73@9532
    55
    }
slime73@9532
    56
slime73@9532
    57
    return self;
slime73@9532
    58
}
slime73@9532
    59
slime73@9532
    60
@end
slime73@9532
    61
slime73@9532
    62
@interface SDL_uikitwindow : UIWindow
slime73@9532
    63
slime73@9532
    64
- (void)layoutSubviews;
slime73@9532
    65
slime73@9532
    66
@end
slime73@9532
    67
slime73@9532
    68
@implementation SDL_uikitwindow
slime73@9532
    69
slime73@9532
    70
- (void)layoutSubviews
slime73@9532
    71
{
slime73@9532
    72
    /* Workaround to fix window orientation issues in iOS 8+. */
slime73@9532
    73
    self.frame = self.screen.bounds;
slime73@9532
    74
    [super layoutSubviews];
slime73@9532
    75
}
slime73@9510
    76
slime73@9510
    77
@end
slime73@9510
    78
slime73@9505
    79
slime73@9528
    80
static int SetupWindowData(_THIS, SDL_Window *window, UIWindow *uiwindow, SDL_bool created)
icculus@4446
    81
{
slouken@5246
    82
    SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
slime73@9510
    83
    SDL_DisplayData *displaydata = (__bridge SDL_DisplayData *) display->driverdata;
slime73@9532
    84
    SDL_uikitview *view;
slime73@9532
    85
slime73@9532
    86
    CGRect frame = UIKit_ComputeViewFrame(window, displaydata.uiscreen);
slime73@9532
    87
    int width  = (int) frame.size.width;
slime73@9532
    88
    int height = (int) frame.size.height;
kees@6001
    89
slime73@9510
    90
    SDL_WindowData *data = [[SDL_WindowData alloc] init];
slouken@2765
    91
    if (!data) {
icculus@7037
    92
        return SDL_OutOfMemory();
slouken@2765
    93
    }
slime73@9510
    94
slime73@9532
    95
    window->driverdata = (void *) CFBridgingRetain(data);
slouken@6520
    96
slime73@9532
    97
    data.uiwindow = uiwindow;
icculus@5520
    98
slouken@6262
    99
    /* only one window on iOS, always shown */
slouken@6262
   100
    window->flags &= ~SDL_WINDOW_HIDDEN;
slouken@2765
   101
slime73@10367
   102
    if (displaydata.uiscreen != [UIScreen mainScreen]) {
slime73@9532
   103
        window->flags &= ~SDL_WINDOW_RESIZABLE;  /* window is NEVER resizable */
slouken@7191
   104
        window->flags &= ~SDL_WINDOW_INPUT_FOCUS;  /* never has input focus */
slouken@7191
   105
        window->flags |= SDL_WINDOW_BORDERLESS;  /* never has a status bar. */
slouken@6511
   106
    }
icculus@5518
   107
slime73@10340
   108
#if !TARGET_OS_TV
slime73@9532
   109
    if (displaydata.uiscreen == [UIScreen mainScreen]) {
slime73@9532
   110
        NSUInteger orients = UIKit_GetSupportedOrientations(window);
slime73@9532
   111
        BOOL supportsLandscape = (orients & UIInterfaceOrientationMaskLandscape) != 0;
slime73@9532
   112
        BOOL supportsPortrait = (orients & (UIInterfaceOrientationMaskPortrait|UIInterfaceOrientationMaskPortraitUpsideDown)) != 0;
slime73@9532
   113
slime73@9532
   114
        /* Make sure the width/height are oriented correctly */
slime73@9532
   115
        if ((width > height && !supportsLandscape) || (height > width && !supportsPortrait)) {
slime73@9532
   116
            int temp = width;
slime73@9532
   117
            width = height;
slime73@9532
   118
            height = temp;
slime73@9532
   119
        }
slime73@9532
   120
    }
slime73@10340
   121
#endif /* !TARGET_OS_TV */
slime73@9532
   122
slime73@9532
   123
    window->x = 0;
slime73@9532
   124
    window->y = 0;
slime73@9532
   125
    window->w = width;
slime73@9532
   126
    window->h = height;
slime73@9532
   127
slime73@9532
   128
    /* The View Controller will handle rotating the view when the device
slime73@9532
   129
     * orientation changes. This will trigger resize events, if appropriate. */
slime73@9510
   130
    data.viewcontroller = [[SDL_uikitviewcontroller alloc] initWithSDLWindow:window];
slime73@9532
   131
slime73@9532
   132
    /* The window will initially contain a generic view so resizes, touch events,
slime73@9532
   133
     * etc. can be handled without an active OpenGL view/context. */
slime73@9532
   134
    view = [[SDL_uikitview alloc] initWithFrame:frame];
slime73@9532
   135
slime73@9532
   136
    /* Sets this view as the controller's view, and adds the view to the window
slime73@9532
   137
     * heirarchy. */
slime73@9532
   138
    [view setSDLWindow:window];
slime73@9532
   139
slime73@9532
   140
    /* Make this window the current mouse focus for touch input */
slime73@9532
   141
    if (displaydata.uiscreen == [UIScreen mainScreen]) {
slime73@9532
   142
        SDL_SetMouseFocus(window);
slime73@9532
   143
        SDL_SetKeyboardFocus(window);
slime73@9532
   144
    }
icculus@5518
   145
slouken@2765
   146
    return 0;
slouken@2765
   147
}
slouken@2765
   148
slouken@5056
   149
int
slouken@5246
   150
UIKit_CreateWindow(_THIS, SDL_Window *window)
slouken@5246
   151
{
slime73@9506
   152
    @autoreleasepool {
slime73@9506
   153
        SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
slime73@9510
   154
        SDL_DisplayData *data = (__bridge SDL_DisplayData *) display->driverdata;
icculus@4446
   155
slime73@9506
   156
        /* SDL currently puts this window at the start of display's linked list. We rely on this. */
slime73@9506
   157
        SDL_assert(_this->windows == window);
icculus@4446
   158
slime73@9506
   159
        /* We currently only handle a single window per display on iOS */
slime73@9506
   160
        if (window->next != NULL) {
slime73@9506
   161
            return SDL_SetError("Only one window allowed per display.");
slouken@8891
   162
        }
icculus@4446
   163
slime73@9506
   164
        /* If monitor has a resolution of 0x0 (hasn't been explicitly set by the
slime73@9506
   165
         * user, so it's in standby), try to force the display to a resolution
slime73@9532
   166
         * that most closely matches the desired window size. */
slime73@10340
   167
#if !TARGET_OS_TV
slime73@10340
   168
        const CGSize origsize = data.uiscreen.currentMode.size;
slime73@9506
   169
        if ((origsize.width == 0.0f) && (origsize.height == 0.0f)) {
slime73@9506
   170
            if (display->num_display_modes == 0) {
slime73@9506
   171
                _this->GetDisplayModes(_this, display);
slime73@9506
   172
            }
slouken@7191
   173
slime73@9506
   174
            int i;
slime73@9506
   175
            const SDL_DisplayMode *bestmode = NULL;
slime73@9506
   176
            for (i = display->num_display_modes; i >= 0; i--) {
slime73@9506
   177
                const SDL_DisplayMode *mode = &display->display_modes[i];
slime73@9532
   178
                if ((mode->w >= window->w) && (mode->h >= window->h)) {
slime73@9506
   179
                    bestmode = mode;
slime73@9532
   180
                }
slime73@9506
   181
            }
slouken@7191
   182
slime73@9506
   183
            if (bestmode) {
slime73@9510
   184
                SDL_DisplayModeData *modedata = (__bridge SDL_DisplayModeData *)bestmode->driverdata;
slime73@9510
   185
                [data.uiscreen setCurrentMode:modedata.uiscreenmode];
slime73@9506
   186
slime73@9506
   187
                /* desktop_mode doesn't change here (the higher level will
slime73@9506
   188
                 * use it to set all the screens back to their defaults
slime73@9532
   189
                 * upon window destruction, SDL_Quit(), etc. */
slime73@9506
   190
                display->current_mode = *bestmode;
slouken@6520
   191
            }
slouken@6520
   192
        }
icculus@4446
   193
slime73@9510
   194
        if (data.uiscreen == [UIScreen mainScreen]) {
slime73@9506
   195
            if (window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_BORDERLESS)) {
slime73@9584
   196
                [UIApplication sharedApplication].statusBarHidden = YES;
slime73@9506
   197
            } else {
slime73@9584
   198
                [UIApplication sharedApplication].statusBarHidden = NO;
slime73@9506
   199
            }
slime73@9506
   200
        }
slime73@10340
   201
#endif /* !TARGET_OS_TV */
icculus@4446
   202
slime73@9506
   203
        /* ignore the size user requested, and make a fullscreen window */
slime73@9506
   204
        /* !!! FIXME: can we have a smaller view? */
slime73@9532
   205
        UIWindow *uiwindow = [[SDL_uikitwindow alloc] initWithFrame:data.uiscreen.bounds];
slime73@9506
   206
slime73@9532
   207
        /* put the window on an external display if appropriate. */
slime73@9532
   208
        if (data.uiscreen != [UIScreen mainScreen]) {
slime73@9510
   209
            [uiwindow setScreen:data.uiscreen];
slime73@9506
   210
        }
slime73@9506
   211
slime73@9506
   212
        if (SetupWindowData(_this, window, uiwindow, SDL_TRUE) < 0) {
slime73@9506
   213
            return -1;
slime73@9506
   214
        }
kees@6001
   215
    }
kees@6001
   216
slouken@3685
   217
    return 1;
slouken@2765
   218
}
slouken@2765
   219
slouken@5056
   220
void
slime73@9529
   221
UIKit_SetWindowTitle(_THIS, SDL_Window * window)
slime73@9529
   222
{
slime73@9529
   223
    @autoreleasepool {
slime73@9532
   224
        SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata;
slime73@9537
   225
        data.viewcontroller.title = @(window->title);
slime73@9529
   226
    }
slime73@9529
   227
}
slime73@9529
   228
slime73@9529
   229
void
slouken@6379
   230
UIKit_ShowWindow(_THIS, SDL_Window * window)
slouken@6379
   231
{
slime73@9506
   232
    @autoreleasepool {
slime73@9532
   233
        SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata;
slime73@9532
   234
        [data.uiwindow makeKeyAndVisible];
slime73@9506
   235
    }
slouken@6379
   236
}
slouken@6379
   237
slouken@6379
   238
void
slouken@6379
   239
UIKit_HideWindow(_THIS, SDL_Window * window)
slouken@6379
   240
{
slime73@9506
   241
    @autoreleasepool {
slime73@9532
   242
        SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata;
slime73@9532
   243
        data.uiwindow.hidden = YES;
slime73@9506
   244
    }
slouken@6379
   245
}
slouken@6379
   246
slouken@6379
   247
void
icculus@6419
   248
UIKit_RaiseWindow(_THIS, SDL_Window * window)
icculus@6419
   249
{
slouken@7191
   250
    /* We don't currently offer a concept of "raising" the SDL window, since
slime73@9532
   251
     * we only allow one per display, in the iOS fashion.
slouken@7191
   252
     * However, we use this entry point to rebind the context to the view
slime73@9532
   253
     * during OnWindowRestored processing. */
icculus@6419
   254
    _this->GL_MakeCurrent(_this, _this->current_glwin, _this->current_glctx);
icculus@6419
   255
}
icculus@6419
   256
slime73@9505
   257
static void
slime73@9505
   258
UIKit_UpdateWindowBorder(_THIS, SDL_Window * window)
slouken@6073
   259
{
slime73@9532
   260
    SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata;
slime73@9532
   261
    SDL_uikitviewcontroller *viewcontroller = data.viewcontroller;
slouken@6073
   262
slime73@10340
   263
#if !TARGET_OS_TV
slime73@9532
   264
    if (data.uiwindow.screen == [UIScreen mainScreen]) {
slime73@9505
   265
        if (window->flags & (SDL_WINDOW_FULLSCREEN | SDL_WINDOW_BORDERLESS)) {
slime73@9505
   266
            [UIApplication sharedApplication].statusBarHidden = YES;
slime73@9505
   267
        } else {
slime73@9505
   268
            [UIApplication sharedApplication].statusBarHidden = NO;
slime73@9505
   269
        }
slouken@6437
   270
slime73@9505
   271
        /* iOS 7+ won't update the status bar until we tell it to. */
slime73@9505
   272
        if ([viewcontroller respondsToSelector:@selector(setNeedsStatusBarAppearanceUpdate)]) {
slime73@9505
   273
            [viewcontroller setNeedsStatusBarAppearanceUpdate];
slime73@9505
   274
        }
slime73@9491
   275
    }
slime73@9491
   276
slime73@9497
   277
    /* Update the view's frame to account for the status bar change. */
slime73@9532
   278
    viewcontroller.view.frame = UIKit_ComputeViewFrame(window, data.uiwindow.screen);
slime73@10340
   279
#endif /* !TARGET_OS_TV */
slime73@9585
   280
slime73@9585
   281
#ifdef SDL_IPHONE_KEYBOARD
slime73@9585
   282
    /* Make sure the view is offset correctly when the keyboard is visible. */
slime73@9585
   283
    [viewcontroller updateKeyboard];
slime73@9585
   284
#endif
slime73@9585
   285
slime73@9532
   286
    [viewcontroller.view setNeedsLayout];
slime73@9532
   287
    [viewcontroller.view layoutIfNeeded];
slouken@6073
   288
}
slouken@6073
   289
slouken@6073
   290
void
slime73@9505
   291
UIKit_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered)
slime73@9505
   292
{
slime73@9506
   293
    @autoreleasepool {
slime73@9506
   294
        UIKit_UpdateWindowBorder(_this, window);
slime73@9506
   295
    }
slime73@9505
   296
}
slime73@9505
   297
slime73@9505
   298
void
slime73@9505
   299
UIKit_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen)
slime73@9505
   300
{
slime73@9506
   301
    @autoreleasepool {
slime73@9506
   302
        UIKit_UpdateWindowBorder(_this, window);
slime73@9506
   303
    }
slime73@9505
   304
}
slime73@9505
   305
slime73@9505
   306
void
kees@6003
   307
UIKit_DestroyWindow(_THIS, SDL_Window * window)
kees@6003
   308
{
slime73@9506
   309
    @autoreleasepool {
slime73@9510
   310
        if (window->driverdata != NULL) {
slime73@9532
   311
            SDL_WindowData *data = (SDL_WindowData *) CFBridgingRelease(window->driverdata);
slime73@9727
   312
            NSArray *views = nil;
slime73@9727
   313
slime73@9532
   314
            [data.viewcontroller stopAnimation];
slime73@9727
   315
slime73@9727
   316
            /* Detach all views from this window. We use a copy of the array
slime73@9727
   317
             * because setSDLWindow will remove the object from the original
slime73@9727
   318
             * array, which would be undesirable if we were iterating over it. */
slime73@9727
   319
            views = [data.views copy];
slime73@9727
   320
            for (SDL_uikitview *view in views) {
slime73@9727
   321
                [view setSDLWindow:NULL];
slime73@9727
   322
            }
slime73@9911
   323
slime73@9912
   324
            /* iOS may still hold a reference to the window after we release it.
slime73@9912
   325
             * We want to make sure the SDL view controller isn't accessed in
slime73@9912
   326
             * that case, because it would contain an invalid pointer to the old
slime73@9912
   327
             * SDL window. */
slime73@9911
   328
            data.uiwindow.rootViewController = nil;
slime73@9911
   329
            data.uiwindow.hidden = YES;
slime73@9506
   330
        }
slouken@3685
   331
    }
slouken@8978
   332
    window->driverdata = NULL;
slouken@2765
   333
}
slouken@2765
   334
slouken@5056
   335
SDL_bool
slouken@5056
   336
UIKit_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info)
slouken@5056
   337
{
slime73@9506
   338
    @autoreleasepool {
slime73@9532
   339
        SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata;
slouken@5056
   340
slime73@9506
   341
        if (info->version.major <= SDL_MAJOR_VERSION) {
slime73@9540
   342
            int versionnum = SDL_VERSIONNUM(info->version.major, info->version.minor, info->version.patch);
slime73@9540
   343
slime73@9506
   344
            info->subsystem = SDL_SYSWM_UIKIT;
slime73@9532
   345
            info->info.uikit.window = data.uiwindow;
slime73@9540
   346
slime73@9540
   347
            /* These struct members were added in SDL 2.0.4. */
slime73@9540
   348
            if (versionnum >= SDL_VERSIONNUM(2,0,4)) {
slime73@9540
   349
                if ([data.viewcontroller.view isKindOfClass:[SDL_uikitopenglview class]]) {
slime73@9540
   350
                    SDL_uikitopenglview *glview = (SDL_uikitopenglview *)data.viewcontroller.view;
slime73@9540
   351
                    info->info.uikit.framebuffer = glview.drawableFramebuffer;
slime73@9540
   352
                    info->info.uikit.colorbuffer = glview.drawableRenderbuffer;
slime73@9810
   353
                    info->info.uikit.resolveFramebuffer = glview.msaaResolveFramebuffer;
slime73@9540
   354
                } else {
slime73@9540
   355
                    info->info.uikit.framebuffer = 0;
slime73@9540
   356
                    info->info.uikit.colorbuffer = 0;
slime73@9810
   357
                    info->info.uikit.resolveFramebuffer = 0;
slime73@9540
   358
                }
slime73@9540
   359
            }
slime73@9540
   360
slime73@9506
   361
            return SDL_TRUE;
slime73@9506
   362
        } else {
slime73@9506
   363
            SDL_SetError("Application not compiled with SDL %d.%d\n",
slime73@9506
   364
                         SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
slime73@9506
   365
            return SDL_FALSE;
slime73@9506
   366
        }
slouken@5056
   367
    }
slouken@5056
   368
}
slouken@5056
   369
slime73@10340
   370
#if !TARGET_OS_TV
slime73@9523
   371
NSUInteger
slime73@9523
   372
UIKit_GetSupportedOrientations(SDL_Window * window)
slime73@9523
   373
{
slime73@9523
   374
    const char *hint = SDL_GetHint(SDL_HINT_ORIENTATIONS);
slime73@9584
   375
    NSUInteger validOrientations = UIInterfaceOrientationMaskAll;
slime73@9523
   376
    NSUInteger orientationMask = 0;
slime73@9523
   377
slime73@9523
   378
    @autoreleasepool {
slime73@9584
   379
        SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata;
slime73@9584
   380
        UIApplication *app = [UIApplication sharedApplication];
slime73@9584
   381
slime73@9584
   382
        /* Get all possible valid orientations. If the app delegate doesn't tell
slime73@9584
   383
         * us, we get the orientations from Info.plist via UIApplication. */
slime73@9584
   384
        if ([app.delegate respondsToSelector:@selector(application:supportedInterfaceOrientationsForWindow:)]) {
slime73@9584
   385
            validOrientations = [app.delegate application:app supportedInterfaceOrientationsForWindow:data.uiwindow];
slime73@9584
   386
        } else if ([app respondsToSelector:@selector(supportedInterfaceOrientationsForWindow:)]) {
slime73@9584
   387
            validOrientations = [app supportedInterfaceOrientationsForWindow:data.uiwindow];
slime73@9584
   388
        }
slime73@9584
   389
slime73@9523
   390
        if (hint != NULL) {
slime73@9523
   391
            NSArray *orientations = [@(hint) componentsSeparatedByString:@" "];
slime73@9523
   392
slime73@9523
   393
            if ([orientations containsObject:@"LandscapeLeft"]) {
slime73@9523
   394
                orientationMask |= UIInterfaceOrientationMaskLandscapeLeft;
slime73@9523
   395
            }
slime73@9523
   396
            if ([orientations containsObject:@"LandscapeRight"]) {
slime73@9523
   397
                orientationMask |= UIInterfaceOrientationMaskLandscapeRight;
slime73@9523
   398
            }
slime73@9523
   399
            if ([orientations containsObject:@"Portrait"]) {
slime73@9523
   400
                orientationMask |= UIInterfaceOrientationMaskPortrait;
slime73@9523
   401
            }
slime73@9523
   402
            if ([orientations containsObject:@"PortraitUpsideDown"]) {
slime73@9523
   403
                orientationMask |= UIInterfaceOrientationMaskPortraitUpsideDown;
slime73@9523
   404
            }
slime73@9523
   405
        }
slime73@9523
   406
slime73@9523
   407
        if (orientationMask == 0 && (window->flags & SDL_WINDOW_RESIZABLE)) {
slime73@9523
   408
            /* any orientation is okay. */
slime73@9523
   409
            orientationMask = UIInterfaceOrientationMaskAll;
slime73@9523
   410
        }
slime73@9523
   411
slime73@9523
   412
        if (orientationMask == 0) {
slime73@9523
   413
            if (window->w >= window->h) {
slime73@9523
   414
                orientationMask |= UIInterfaceOrientationMaskLandscape;
slime73@9523
   415
            }
slime73@9523
   416
            if (window->h >= window->w) {
slime73@9523
   417
                orientationMask |= (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown);
slime73@9523
   418
            }
slime73@9523
   419
        }
slime73@9523
   420
slime73@9584
   421
        /* Don't allow upside-down orientation on phones, so answering calls is in the natural orientation */
slime73@9532
   422
        if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone) {
slime73@9523
   423
            orientationMask &= ~UIInterfaceOrientationMaskPortraitUpsideDown;
slime73@9523
   424
        }
slime73@9584
   425
slime73@9584
   426
        /* If none of the specified orientations are actually supported by the
slime73@9584
   427
         * app, we'll revert to what the app supports. An exception would be
slime73@9584
   428
         * thrown by the system otherwise. */
slime73@9584
   429
        if ((validOrientations & orientationMask) == 0) {
slime73@9584
   430
            orientationMask = validOrientations;
slime73@9584
   431
        }
slime73@9523
   432
    }
slime73@9523
   433
slime73@9523
   434
    return orientationMask;
slime73@9523
   435
}
slime73@10340
   436
#endif /* !TARGET_OS_TV */
slime73@9523
   437
slouken@6342
   438
int
slouken@6342
   439
SDL_iPhoneSetAnimationCallback(SDL_Window * window, int interval, void (*callback)(void*), void *callbackParam)
slouken@6342
   440
{
slime73@9532
   441
    if (!window || !window->driverdata) {
slime73@9532
   442
        return SDL_SetError("Invalid window");
slime73@9532
   443
    }
slouken@6342
   444
slime73@9532
   445
    @autoreleasepool {
slime73@9532
   446
        SDL_WindowData *data = (__bridge SDL_WindowData *)window->driverdata;
slime73@9532
   447
        [data.viewcontroller setAnimationCallback:interval
slime73@9532
   448
                                         callback:callback
slime73@9532
   449
                                    callbackParam:callbackParam];
slime73@9506
   450
    }
slime73@9506
   451
slouken@6342
   452
    return 0;
slouken@6342
   453
}
slouken@6342
   454
slouken@6044
   455
#endif /* SDL_VIDEO_DRIVER_UIKIT */
slouken@6044
   456
slouken@2765
   457
/* vi: set ts=4 sw=4 expandtab: */