Browse Source

Merged default into iOS-improvements

Alex Szpakowski 11 years ago
parent
commit
b1a0bd10a2

+ 3 - 0
.hgignore

@@ -8,6 +8,9 @@ Makefile
 sdl-config
 sdl-config
 SDL2.spec
 SDL2.spec
 build
 build
+Build
+*xcuserdata*
+*xcworkspacedata*
 
 
 # for Xcode
 # for Xcode
 *.orig
 *.orig

+ 12 - 0
Xcode-iOS/SDL/SDL.xcodeproj/project.pbxproj

@@ -1274,8 +1274,14 @@
 		FD6526640DE8FCCB002AD96B /* Debug */ = {
 		FD6526640DE8FCCB002AD96B /* Debug */ = {
 			isa = XCBuildConfiguration;
 			isa = XCBuildConfiguration;
 			buildSettings = {
 			buildSettings = {
+				CLANG_ENABLE_OBJC_ARC = YES;
+				CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+				CLANG_WARN_OBJC_IMPLICIT_ATOMIC_PROPERTIES = YES;
 				COPY_PHASE_STRIP = NO;
 				COPY_PHASE_STRIP = NO;
 				IPHONEOS_DEPLOYMENT_TARGET = 5.1.1;
 				IPHONEOS_DEPLOYMENT_TARGET = 5.1.1;
+				GCC_WARN_MULTIPLE_DEFINITION_TYPES_FOR_SELECTOR = YES;
+				GCC_WARN_STRICT_SELECTOR_MATCH = YES;
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
 				PRODUCT_NAME = SDL2;
 				PRODUCT_NAME = SDL2;
 				SKIP_INSTALL = YES;
 				SKIP_INSTALL = YES;
 			};
 			};
@@ -1284,8 +1290,14 @@
 		FD6526650DE8FCCB002AD96B /* Release */ = {
 		FD6526650DE8FCCB002AD96B /* Release */ = {
 			isa = XCBuildConfiguration;
 			isa = XCBuildConfiguration;
 			buildSettings = {
 			buildSettings = {
+				CLANG_ENABLE_OBJC_ARC = YES;
+				CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+				CLANG_WARN_OBJC_IMPLICIT_ATOMIC_PROPERTIES = YES;
 				COPY_PHASE_STRIP = YES;
 				COPY_PHASE_STRIP = YES;
 				IPHONEOS_DEPLOYMENT_TARGET = 5.1.1;
 				IPHONEOS_DEPLOYMENT_TARGET = 5.1.1;
+				GCC_WARN_MULTIPLE_DEFINITION_TYPES_FOR_SELECTOR = YES;
+				GCC_WARN_STRICT_SELECTOR_MATCH = YES;
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
 				PRODUCT_NAME = SDL2;
 				PRODUCT_NAME = SDL2;
 				SKIP_INSTALL = YES;
 				SKIP_INSTALL = YES;
 			};
 			};

+ 4 - 3
include/SDL_hints.h

@@ -261,8 +261,9 @@ extern "C" {
 #define SDL_HINT_ORIENTATIONS "SDL_IOS_ORIENTATIONS"
 #define SDL_HINT_ORIENTATIONS "SDL_IOS_ORIENTATIONS"
     
     
 /**
 /**
- *  \brief  A variable controlling whether an Android built-in accelerometer should be
- *  listed as a joystick device, rather than listing actual joysticks only.
+ *  \brief  A variable controlling whether the Android / iOS built-in
+ *  accelerometer should be listed as a joystick device, rather than listing
+ *  actual joysticks only.
  *
  *
  *  This variable can be set to the following values:
  *  This variable can be set to the following values:
  *    "0"       - List only real joysticks and accept input from them
  *    "0"       - List only real joysticks and accept input from them
@@ -345,7 +346,7 @@ extern "C" {
 
 
 
 
 /**
 /**
- *  \brief If set to 1, then do not allow high-DPI windows. ("Retina" on Mac)
+ *  \brief If set to 1, then do not allow high-DPI windows. ("Retina" on Mac and iOS)
  */
  */
 #define SDL_HINT_VIDEO_HIGHDPI_DISABLED "SDL_VIDEO_HIGHDPI_DISABLED"
 #define SDL_HINT_VIDEO_HIGHDPI_DISABLED "SDL_VIDEO_HIGHDPI_DISABLED"
 
 

+ 10 - 0
include/SDL_system.h

@@ -70,6 +70,16 @@ extern DECLSPEC SDL_bool SDLCALL SDL_DXGIGetOutputInfo( int displayIndex, int *a
 extern DECLSPEC int SDLCALL SDL_iPhoneSetAnimationCallback(SDL_Window * window, int interval, void (*callback)(void*), void *callbackParam);
 extern DECLSPEC int SDLCALL SDL_iPhoneSetAnimationCallback(SDL_Window * window, int interval, void (*callback)(void*), void *callbackParam);
 extern DECLSPEC void SDLCALL SDL_iPhoneSetEventPump(SDL_bool enabled);
 extern DECLSPEC void SDLCALL SDL_iPhoneSetEventPump(SDL_bool enabled);
 
 
+/* Returns the OpenGL Renderbuffer Object associated with the window's main view.
+   The Renderbuffer must be bound when calling SDL_GL_SwapWindow.
+ */
+extern DECLSPEC Uint32 SDLCALL SDL_iPhoneGetViewRenderbuffer(SDL_Window * window);
+
+/* Returns the OpenGL Framebuffer Object associated with the window's main view.
+   The Framebuffer must be bound when rendering to the screen.
+ */
+extern DECLSPEC Uint32 SDLCALL SDL_iPhoneGetViewFramebuffer(SDL_Window * window);
+
 #endif /* __IPHONEOS__ */
 #endif /* __IPHONEOS__ */
 
 
 
 

+ 2 - 3
src/file/cocoa/SDL_rwopsbundlesupport.m

@@ -50,14 +50,13 @@ FILE* SDL_OpenFPFromBundleOrFallback(const char *file, const char *mode)
     NSString* full_path_with_file_to_try = [resource_path stringByAppendingPathComponent:ns_string_file_component];
     NSString* full_path_with_file_to_try = [resource_path stringByAppendingPathComponent:ns_string_file_component];
     if([file_manager fileExistsAtPath:full_path_with_file_to_try]) {
     if([file_manager fileExistsAtPath:full_path_with_file_to_try]) {
         fp = fopen([full_path_with_file_to_try fileSystemRepresentation], mode);
         fp = fopen([full_path_with_file_to_try fileSystemRepresentation], mode);
-    }
-    else {
+    } else {
         fp = fopen(file, mode);
         fp = fopen(file, mode);
     }
     }
 
 
     return fp;
     return fp;
 }}
 }}
 
 
-#endif /* __MACOSX__ */
+#endif /* __APPLE__ */
 
 
 /* vi: set ts=4 sw=4 expandtab: */
 /* vi: set ts=4 sw=4 expandtab: */

+ 4 - 1
src/filesystem/cocoa/SDL_sysfilesystem.m

@@ -41,6 +41,7 @@ SDL_GetBasePath(void)
     const char* baseType = [[[bundle infoDictionary] objectForKey:@"SDL_FILESYSTEM_BASE_DIR_TYPE"] UTF8String];
     const char* baseType = [[[bundle infoDictionary] objectForKey:@"SDL_FILESYSTEM_BASE_DIR_TYPE"] UTF8String];
     const char *base = NULL;
     const char *base = NULL;
     char *retval = NULL;
     char *retval = NULL;
+
     if (baseType == NULL) {
     if (baseType == NULL) {
         baseType = "resource";
         baseType = "resource";
     }
     }
@@ -52,6 +53,7 @@ SDL_GetBasePath(void)
         /* this returns the exedir for non-bundled  and the resourceDir for bundled apps */
         /* this returns the exedir for non-bundled  and the resourceDir for bundled apps */
         base = [[bundle resourcePath] fileSystemRepresentation];
         base = [[bundle resourcePath] fileSystemRepresentation];
     }
     }
+
     if (base) {
     if (base) {
         const size_t len = SDL_strlen(base) + 2;
         const size_t len = SDL_strlen(base) + 2;
         retval = (char *) SDL_malloc(len);
         retval = (char *) SDL_malloc(len);
@@ -69,9 +71,10 @@ char *
 SDL_GetPrefPath(const char *org, const char *app)
 SDL_GetPrefPath(const char *org, const char *app)
 { @autoreleasepool
 { @autoreleasepool
 {
 {
-    NSArray *array = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES);
     char *retval = NULL;
     char *retval = NULL;
 
 
+    NSArray *array = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES);
+
     if ([array count] > 0) {  /* we only want the first item in the list. */
     if ([array count] > 0) {  /* we only want the first item in the list. */
         NSString *str = [array objectAtIndex:0];
         NSString *str = [array objectAtIndex:0];
         const char *base = [str fileSystemRepresentation];
         const char *base = [str fileSystemRepresentation];

+ 31 - 16
src/joystick/iphoneos/SDL_sysjoystick.m

@@ -23,6 +23,7 @@
 /* This is the iOS implementation of the SDL joystick API */
 /* This is the iOS implementation of the SDL joystick API */
 
 
 #include "SDL_joystick.h"
 #include "SDL_joystick.h"
+#include "SDL_hints.h"
 #include "SDL_stdinc.h"
 #include "SDL_stdinc.h"
 #include "../SDL_sysjoystick.h"
 #include "../SDL_sysjoystick.h"
 #include "../SDL_joystick_c.h"
 #include "../SDL_joystick_c.h"
@@ -32,9 +33,10 @@
 /* needed for SDL_IPHONE_MAX_GFORCE macro */
 /* needed for SDL_IPHONE_MAX_GFORCE macro */
 #import "SDL_config_iphoneos.h"
 #import "SDL_config_iphoneos.h"
 
 
-const char *accelerometerName = "iOS accelerometer";
+const char *accelerometerName = "iOS Accelerometer";
 
 
 static CMMotionManager *motionManager = nil;
 static CMMotionManager *motionManager = nil;
+static int numjoysticks = 0;
 
 
 /* Function to scan the system for joysticks.
 /* Function to scan the system for joysticks.
  * This function should set SDL_numjoysticks to the number of available
  * This function should set SDL_numjoysticks to the number of available
@@ -44,12 +46,18 @@ static CMMotionManager *motionManager = nil;
 int
 int
 SDL_SYS_JoystickInit(void)
 SDL_SYS_JoystickInit(void)
 {
 {
-    return (1);
+    const char *hint = SDL_GetHint(SDL_HINT_ACCELEROMETER_AS_JOYSTICK);
+    if (!hint || SDL_atoi(hint)) {
+        /* Default behavior, accelerometer as joystick */
+        numjoysticks = 1;
+    }
+
+    return numjoysticks;
 }
 }
 
 
 int SDL_SYS_NumJoysticks()
 int SDL_SYS_NumJoysticks()
 {
 {
-    return 1;
+    return numjoysticks;
 }
 }
 
 
 void SDL_SYS_JoystickDetect()
 void SDL_SYS_JoystickDetect()
@@ -82,13 +90,15 @@ SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int device_index)
     joystick->nballs = 0;
     joystick->nballs = 0;
     joystick->nbuttons = 0;
     joystick->nbuttons = 0;
 
 
-    if (motionManager == nil) {
-        motionManager = [[CMMotionManager alloc] init];
-    }
+    @autoreleasepool {
+        if (motionManager == nil) {
+            motionManager = [[CMMotionManager alloc] init];
+        }
 
 
-    /* Shorter times between updates can significantly increase CPU usage. */
-    motionManager.accelerometerUpdateInterval = 0.1;
-    [motionManager startAccelerometerUpdates];
+        /* Shorter times between updates can significantly increase CPU usage. */
+        motionManager.accelerometerUpdateInterval = 0.1;
+        [motionManager startAccelerometerUpdates];
+    }
 
 
     return 0;
     return 0;
 }
 }
@@ -105,11 +115,13 @@ static void SDL_SYS_AccelerometerUpdate(SDL_Joystick * joystick)
     const SInt16 maxsint16 = 0x7FFF;
     const SInt16 maxsint16 = 0x7FFF;
     CMAcceleration accel;
     CMAcceleration accel;
 
 
-    if (!motionManager.accelerometerActive) {
-        return;
-    }
+    @autoreleasepool {
+        if (!motionManager.accelerometerActive) {
+            return;
+        }
 
 
-    accel = [[motionManager accelerometerData] acceleration];
+        accel = motionManager.accelerometerData.acceleration;
+    }
 
 
     /*
     /*
      Convert accelerometer data from floating point to Sint16, which is what
      Convert accelerometer data from floating point to Sint16, which is what
@@ -153,7 +165,9 @@ SDL_SYS_JoystickUpdate(SDL_Joystick * joystick)
 void
 void
 SDL_SYS_JoystickClose(SDL_Joystick * joystick)
 SDL_SYS_JoystickClose(SDL_Joystick * joystick)
 {
 {
-    [motionManager stopAccelerometerUpdates];
+    @autoreleasepool {
+        [motionManager stopAccelerometerUpdates];
+    }
     joystick->closed = 1;
     joystick->closed = 1;
 }
 }
 
 
@@ -161,10 +175,11 @@ SDL_SYS_JoystickClose(SDL_Joystick * joystick)
 void
 void
 SDL_SYS_JoystickQuit(void)
 SDL_SYS_JoystickQuit(void)
 {
 {
-    if (motionManager != nil) {
-        [motionManager release];
+    @autoreleasepool {
         motionManager = nil;
         motionManager = nil;
     }
     }
+
+    numjoysticks = 0;
 }
 }
 
 
 SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID( int device_index )
 SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID( int device_index )

+ 19 - 18
src/power/uikit/SDL_syspower.m

@@ -50,24 +50,24 @@ SDL_UIKit_UpdateBatteryMonitoring(void)
 SDL_bool
 SDL_bool
 SDL_GetPowerInfo_UIKit(SDL_PowerState * state, int *seconds, int *percent)
 SDL_GetPowerInfo_UIKit(SDL_PowerState * state, int *seconds, int *percent)
 {
 {
-    UIDevice *uidev = [UIDevice currentDevice];
+    @autoreleasepool {
+        UIDevice *uidev = [UIDevice currentDevice];
 
 
-    if (!SDL_UIKitLastPowerInfoQuery) {
-        SDL_assert([uidev isBatteryMonitoringEnabled] == NO);
-        [uidev setBatteryMonitoringEnabled:YES];
-    }
+        if (!SDL_UIKitLastPowerInfoQuery) {
+            SDL_assert(uidev.isBatteryMonitoringEnabled == NO);
+            uidev.batteryMonitoringEnabled = YES;
+        }
 
 
-    /* UIKit_GL_SwapWindow() (etc) will check this and disable the battery
-     *  monitoring if the app hasn't queried it in the last X seconds.
-     *  Apparently monitoring the battery burns battery life.  :)
-     *  Apple's docs say not to monitor the battery unless you need it.
-     */
-    SDL_UIKitLastPowerInfoQuery = SDL_GetTicks();
+        /* UIKit_GL_SwapWindow() (etc) will check this and disable the battery
+         *  monitoring if the app hasn't queried it in the last X seconds.
+         *  Apparently monitoring the battery burns battery life.  :)
+         *  Apple's docs say not to monitor the battery unless you need it.
+         */
+        SDL_UIKitLastPowerInfoQuery = SDL_GetTicks();
 
 
-    *seconds = -1;   /* no API to estimate this in UIKit. */
+        *seconds = -1;   /* no API to estimate this in UIKit. */
 
 
-    switch ([uidev batteryState])
-    {
+        switch (uidev.batteryState) {
         case UIDeviceBatteryStateCharging:
         case UIDeviceBatteryStateCharging:
             *state = SDL_POWERSTATE_CHARGING;
             *state = SDL_POWERSTATE_CHARGING;
             break;
             break;
@@ -84,11 +84,12 @@ SDL_GetPowerInfo_UIKit(SDL_PowerState * state, int *seconds, int *percent)
         default:
         default:
             *state = SDL_POWERSTATE_UNKNOWN;
             *state = SDL_POWERSTATE_UNKNOWN;
             break;
             break;
-    }
+        }
 
 
-    const float level = [uidev batteryLevel];
-    *percent = ( (level < 0.0f) ? -1 : ((int) ((level * 100) + 0.5f)) );
-    return SDL_TRUE;            /* always the definitive answer on iOS. */
+        const float level = uidev.batteryLevel;
+        *percent = ( (level < 0.0f) ? -1 : ((int) ((level * 100) + 0.5f)) );
+        return SDL_TRUE; /* always the definitive answer on iOS. */
+    }
 }
 }
 
 
 #endif /* SDL_POWER_UIKIT */
 #endif /* SDL_POWER_UIKIT */

+ 63 - 34
src/video/uikit/SDL_uikitappdelegate.m

@@ -44,7 +44,6 @@ static UIWindow *launch_window;
 int main(int argc, char **argv)
 int main(int argc, char **argv)
 {
 {
     int i;
     int i;
-    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
 
 
     /* store arguments */
     /* store arguments */
     forward_argc = argc;
     forward_argc = argc;
@@ -56,7 +55,9 @@ int main(int argc, char **argv)
     forward_argv[i] = NULL;
     forward_argv[i] = NULL;
 
 
     /* Give over control to run loop, SDLUIKitDelegate will handle most things from here */
     /* Give over control to run loop, SDLUIKitDelegate will handle most things from here */
-    UIApplicationMain(argc, argv, NULL, [SDLUIKitDelegate getAppDelegateClassName]);
+    @autoreleasepool {
+        UIApplicationMain(argc, argv, nil, [SDLUIKitDelegate getAppDelegateClassName]);
+    }
 
 
     /* free the memory we used to hold copies of argc and argv */
     /* free the memory we used to hold copies of argc and argv */
     for (i = 0; i < forward_argc; i++) {
     for (i = 0; i < forward_argc; i++) {
@@ -64,7 +65,6 @@ int main(int argc, char **argv)
     }
     }
     free(forward_argv);
     free(forward_argv);
 
 
-    [pool release];
     return exit_status;
     return exit_status;
 }
 }
 
 
@@ -75,16 +75,17 @@ SDL_IdleTimerDisabledChanged(void *userdata, const char *name, const char *oldVa
     [UIApplication sharedApplication].idleTimerDisabled = disable;
     [UIApplication sharedApplication].idleTimerDisabled = disable;
 }
 }
 
 
-@interface SDL_splashviewcontroller : UIViewController {
-    UIImageView *splash;
-    UIImage *splashPortrait;
-    UIImage *splashLandscape;
-}
+@interface SDL_splashviewcontroller : UIViewController
 
 
 - (void)updateSplashImage:(UIInterfaceOrientation)interfaceOrientation;
 - (void)updateSplashImage:(UIInterfaceOrientation)interfaceOrientation;
+
 @end
 @end
 
 
-@implementation SDL_splashviewcontroller
+@implementation SDL_splashviewcontroller {
+    UIImageView *splash;
+    UIImage *splashPortrait;
+    UIImage *splashLandscape;
+}
 
 
 - (id)init
 - (id)init
 {
 {
@@ -93,26 +94,20 @@ SDL_IdleTimerDisabledChanged(void *userdata, const char *name, const char *oldVa
         return nil;
         return nil;
     }
     }
 
 
-    self->splash = [[UIImageView alloc] init];
-    [self setView:self->splash];
+    splash = [[UIImageView alloc] init];
+    self.view = splash;
 
 
     CGSize size = [UIScreen mainScreen].bounds.size;
     CGSize size = [UIScreen mainScreen].bounds.size;
     float height = SDL_max(size.width, size.height);
     float height = SDL_max(size.width, size.height);
-    self->splashPortrait = [UIImage imageNamed:[NSString stringWithFormat:@"Default-%dh.png", (int)height]];
-    if (!self->splashPortrait) {
-        self->splashPortrait = [UIImage imageNamed:@"Default.png"];
-    }
-    self->splashLandscape = [UIImage imageNamed:@"Default-Landscape.png"];
-    if (!self->splashLandscape && self->splashPortrait) {
-        self->splashLandscape = [[UIImage alloc] initWithCGImage: self->splashPortrait.CGImage
-                                                           scale: 1.0
-                                                     orientation: UIImageOrientationRight];
-    }
-    if (self->splashPortrait) {
-        [self->splashPortrait retain];
+    splashPortrait = [UIImage imageNamed:[NSString stringWithFormat:@"Default-%dh.png", (int)height]];
+    if (!splashPortrait) {
+        splashPortrait = [UIImage imageNamed:@"Default.png"];
     }
     }
-    if (self->splashLandscape) {
-        [self->splashLandscape retain];
+    splashLandscape = [UIImage imageNamed:@"Default-Landscape.png"];
+    if (!splashLandscape && splashPortrait) {
+        splashLandscape = [[UIImage alloc] initWithCGImage: splashPortrait.CGImage
+                                                     scale: 1.0
+                                               orientation: UIImageOrientationRight];
     }
     }
 
 
     [self updateSplashImage:[[UIApplication sharedApplication] statusBarOrientation]];
     [self updateSplashImage:[[UIApplication sharedApplication] statusBarOrientation]];
@@ -147,12 +142,12 @@ SDL_IdleTimerDisabledChanged(void *userdata, const char *name, const char *oldVa
     UIImage *image;
     UIImage *image;
 
 
     if (UIInterfaceOrientationIsLandscape(interfaceOrientation)) {
     if (UIInterfaceOrientationIsLandscape(interfaceOrientation)) {
-        image = self->splashLandscape;
+        image = splashLandscape;
     } else {
     } else {
-        image = self->splashPortrait;
+        image = splashPortrait;
     }
     }
-    if (image)
-    {
+
+    if (image) {
         splash.image = image;
         splash.image = image;
     }
     }
 }
 }
@@ -165,7 +160,7 @@ SDL_IdleTimerDisabledChanged(void *userdata, const char *name, const char *oldVa
 /* convenience method */
 /* convenience method */
 + (id) sharedAppDelegate
 + (id) sharedAppDelegate
 {
 {
-    /* the delegate is set in UIApplicationMain(), which is garaunteed to be called before this method */
+    /* the delegate is set in UIApplicationMain(), which is guaranteed to be called before this method */
     return [[UIApplication sharedApplication] delegate];
     return [[UIApplication sharedApplication] delegate];
 }
 }
 
 
@@ -191,8 +186,7 @@ SDL_IdleTimerDisabledChanged(void *userdata, const char *name, const char *oldVa
 
 
     /* If we showed a splash image, clean it up */
     /* If we showed a splash image, clean it up */
     if (launch_window) {
     if (launch_window) {
-        [launch_window release];
-        launch_window = NULL;
+        launch_window = nil;
     }
     }
 
 
     /* exit, passing the return status from the user's application */
     /* exit, passing the return status from the user's application */
@@ -205,12 +199,18 @@ SDL_IdleTimerDisabledChanged(void *userdata, const char *name, const char *oldVa
 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
 {
 {
     /* Keep the launch image up until we set a video mode */
     /* Keep the launch image up until we set a video mode */
-    launch_window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
+
+    /* This is disabled temporarily because the splash viewcontroller is
+     * interfering with rotation once a regular window is created: the view's
+     * orientations are incorrect and the status bar rotates without the view.
+     * Additionally, the splash viewcontroller doesn't load the correct launch
+     * images on iOS 7 and modern devices. */
+    /*launch_window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
 
 
     UIViewController *splashViewController = [[SDL_splashviewcontroller alloc] init];
     UIViewController *splashViewController = [[SDL_splashviewcontroller alloc] init];
     launch_window.rootViewController = splashViewController;
     launch_window.rootViewController = splashViewController;
     [launch_window addSubview:splashViewController.view];
     [launch_window addSubview:splashViewController.view];
-    [launch_window makeKeyAndVisible];
+    [launch_window makeKeyAndVisible];*/
 
 
     /* Set working directory to resource path */
     /* Set working directory to resource path */
     [[NSFileManager defaultManager] changeCurrentDirectoryPath: [[NSBundle mainBundle] resourcePath]];
     [[NSFileManager defaultManager] changeCurrentDirectoryPath: [[NSBundle mainBundle] resourcePath]];
@@ -235,6 +235,35 @@ SDL_IdleTimerDisabledChanged(void *userdata, const char *name, const char *oldVa
     SDL_SendAppEvent(SDL_APP_LOWMEMORY);
     SDL_SendAppEvent(SDL_APP_LOWMEMORY);
 }
 }
 
 
+- (void)application:(UIApplication *)application didChangeStatusBarOrientation:(UIInterfaceOrientation)oldStatusBarOrientation
+{
+    BOOL isLandscape = UIInterfaceOrientationIsLandscape(application.statusBarOrientation);
+    SDL_VideoDevice *_this = SDL_GetVideoDevice();
+
+    if (_this && _this->num_displays > 0) {
+        SDL_DisplayMode *desktopmode = &_this->displays[0].desktop_mode;
+        SDL_DisplayMode *currentmode = &_this->displays[0].current_mode;
+
+        /* The desktop display mode should be kept in sync with the screen
+         * orientation so that updating a window's fullscreen state to
+         * SDL_WINDOW_FULLSCREEN_DESKTOP keeps the window dimensions in the
+         * correct orientation.
+         */
+        if (isLandscape != (desktopmode->w > desktopmode->h)) {
+            int height = desktopmode->w;
+            desktopmode->w = desktopmode->h;
+            desktopmode->h = height;
+        }
+
+        /* Same deal with the current mode + SDL_GetCurrentDisplayMode. */
+        if (isLandscape != (currentmode->w > currentmode->h)) {
+            int height = currentmode->w;
+            currentmode->w = currentmode->h;
+            currentmode->h = height;
+        }
+    }
+}
+
 - (void) applicationWillResignActive:(UIApplication*)application
 - (void) applicationWillResignActive:(UIApplication*)application
 {
 {
     SDL_VideoDevice *_this = SDL_GetVideoDevice();
     SDL_VideoDevice *_this = SDL_GetVideoDevice();

+ 2 - 1
src/video/uikit/SDL_uikitevents.m

@@ -40,8 +40,9 @@ SDL_iPhoneSetEventPump(SDL_bool enabled)
 void
 void
 UIKit_PumpEvents(_THIS)
 UIKit_PumpEvents(_THIS)
 {
 {
-    if (!UIKit_EventPumpEnabled)
+    if (!UIKit_EventPumpEnabled) {
         return;
         return;
+    }
 
 
     /* Let the run loop run for a short amount of time: long enough for
     /* Let the run loop run for a short amount of time: long enough for
        touch events to get processed (which is important to get certain
        touch events to get processed (which is important to get certain

+ 32 - 34
src/video/uikit/SDL_uikitmessagebox.m

@@ -30,17 +30,16 @@
 
 
 static SDL_bool s_showingMessageBox = SDL_FALSE;
 static SDL_bool s_showingMessageBox = SDL_FALSE;
 
 
-@interface UIKit_UIAlertViewDelegate : NSObject <UIAlertViewDelegate> {
-@private
-    int *clickedButtonIndex;
-}
+@interface UIKit_UIAlertViewDelegate : NSObject <UIAlertViewDelegate>
 
 
-- (id)initWithButtonIndex:(int *)_buttonIndex;
+- (id)initWithButtonIndex:(int *)buttonIndex;
 - (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex;
 - (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex;
 
 
 @end
 @end
 
 
-@implementation UIKit_UIAlertViewDelegate
+@implementation UIKit_UIAlertViewDelegate {
+    int *clickedButtonIndex;
+}
 
 
 - (id)initWithButtonIndex:(int *)buttonIndex
 - (id)initWithButtonIndex:(int *)buttonIndex
 {
 {
@@ -48,12 +47,13 @@ static SDL_bool s_showingMessageBox = SDL_FALSE;
     if (self == nil) {
     if (self == nil) {
         return nil;
         return nil;
     }
     }
-    self->clickedButtonIndex = buttonIndex;
+
+    clickedButtonIndex = buttonIndex;
 
 
     return self;
     return self;
 }
 }
 
 
-- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex;
+- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
 {
 {
     *clickedButtonIndex = (int)buttonIndex;
     *clickedButtonIndex = (int)buttonIndex;
 }
 }
@@ -71,40 +71,38 @@ int
 UIKit_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
 UIKit_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
 {
 {
     int clicked;
     int clicked;
+    int i;
+    const SDL_MessageBoxButtonData *buttons = messageboxdata->buttons;
 
 
-    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-
-    UIAlertView* alert = [[UIAlertView alloc] init];
-
-    alert.title = [NSString stringWithUTF8String:messageboxdata->title];
-    alert.message = [NSString stringWithUTF8String:messageboxdata->message];
-    alert.delegate = [[UIKit_UIAlertViewDelegate alloc] initWithButtonIndex:&clicked];
+    @autoreleasepool {
+        UIAlertView* alert = [[UIAlertView alloc] init];
+        UIKit_UIAlertViewDelegate *delegate = [[UIKit_UIAlertViewDelegate alloc] initWithButtonIndex:&clicked];
 
 
-    const SDL_MessageBoxButtonData *buttons = messageboxdata->buttons;
-    int i;
-    for (i = 0; i < messageboxdata->numbuttons; ++i) {
-        [alert addButtonWithTitle:[[NSString alloc] initWithUTF8String:buttons[i].text]];
-    }
+        alert.title = @(messageboxdata->title);
+        alert.message = @(messageboxdata->message);
+        alert.delegate = delegate;
 
 
-    /* Set up for showing the alert */
-    clicked = messageboxdata->numbuttons;
+        for (i = 0; i < messageboxdata->numbuttons; ++i) {
+            [alert addButtonWithTitle:@(buttons[i].text)];
+        }
 
 
-    [alert show];
+        /* Set up for showing the alert */
+        clicked = messageboxdata->numbuttons;
 
 
-    /* Run the main event loop until the alert has finished */
-    /* Note that this needs to be done on the main thread */
-    s_showingMessageBox = SDL_TRUE;
-    while (clicked == messageboxdata->numbuttons) {
-        [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
-    }
-    s_showingMessageBox = SDL_FALSE;
+        [alert show];
 
 
-    *buttonid = messageboxdata->buttons[clicked].buttonid;
+        /* Run the main event loop until the alert has finished */
+        /* Note that this needs to be done on the main thread */
+        s_showingMessageBox = SDL_TRUE;
+        while (clicked == messageboxdata->numbuttons) {
+            [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
+        }
+        s_showingMessageBox = SDL_FALSE;
 
 
-    [alert.delegate release];
-    [alert release];
+        *buttonid = messageboxdata->buttons[clicked].buttonid;
 
 
-    [pool release];
+        alert.delegate = nil;
+    }
 
 
     return 0;
     return 0;
 }
 }

+ 11 - 11
src/video/uikit/SDL_uikitmodes.h

@@ -25,17 +25,17 @@
 
 
 #include "SDL_uikitvideo.h"
 #include "SDL_uikitvideo.h"
 
 
-typedef struct
-{
-    UIScreen *uiscreen;
-    CGFloat scale;
-} SDL_DisplayData;
-
-typedef struct
-{
-    UIScreenMode *uiscreenmode;
-    CGFloat scale;
-} SDL_DisplayModeData;
+@interface SDL_DisplayData : NSObject
+
+@property (nonatomic, strong) UIScreen *uiscreen;
+
+@end
+
+@interface SDL_DisplayModeData : NSObject
+
+@property (nonatomic, strong) UIScreenMode *uiscreenmode;
+
+@end
 
 
 extern SDL_bool UIKit_IsDisplayLandscape(UIScreen *uiscreen);
 extern SDL_bool UIKit_IsDisplayLandscape(UIScreen *uiscreen);
 
 

+ 86 - 87
src/video/uikit/SDL_uikitmodes.m

@@ -25,27 +25,36 @@
 #include "SDL_assert.h"
 #include "SDL_assert.h"
 #include "SDL_uikitmodes.h"
 #include "SDL_uikitmodes.h"
 
 
+@implementation SDL_DisplayData
+
+@synthesize uiscreen;
+
+@end
+
+@implementation SDL_DisplayModeData
+
+@synthesize uiscreenmode;
+
+@end
+
 
 
 static int
 static int
 UIKit_AllocateDisplayModeData(SDL_DisplayMode * mode,
 UIKit_AllocateDisplayModeData(SDL_DisplayMode * mode,
-    UIScreenMode * uiscreenmode, CGFloat scale)
+    UIScreenMode * uiscreenmode)
 {
 {
-    SDL_DisplayModeData *data = NULL;
+    SDL_DisplayModeData *data = nil;
 
 
     if (uiscreenmode != nil) {
     if (uiscreenmode != nil) {
         /* Allocate the display mode data */
         /* Allocate the display mode data */
-        data = (SDL_DisplayModeData *) SDL_malloc(sizeof(*data));
+        data = [[SDL_DisplayModeData alloc] init];
         if (!data) {
         if (!data) {
             return SDL_OutOfMemory();
             return SDL_OutOfMemory();
         }
         }
 
 
-        data->uiscreenmode = uiscreenmode;
-        [data->uiscreenmode retain];
-
-        data->scale = scale;
+        data.uiscreenmode = uiscreenmode;
     }
     }
 
 
-    mode->driverdata = data;
+    mode->driverdata = (void *) CFBridgingRetain(data);
 
 
     return 0;
     return 0;
 }
 }
@@ -54,23 +63,21 @@ static void
 UIKit_FreeDisplayModeData(SDL_DisplayMode * mode)
 UIKit_FreeDisplayModeData(SDL_DisplayMode * mode)
 {
 {
     if (mode->driverdata != NULL) {
     if (mode->driverdata != NULL) {
-        SDL_DisplayModeData *data = (SDL_DisplayModeData *)mode->driverdata;
-        [data->uiscreenmode release];
-        SDL_free(data);
+        CFRelease(mode->driverdata);
         mode->driverdata = NULL;
         mode->driverdata = NULL;
     }
     }
 }
 }
 
 
 static int
 static int
 UIKit_AddSingleDisplayMode(SDL_VideoDisplay * display, int w, int h,
 UIKit_AddSingleDisplayMode(SDL_VideoDisplay * display, int w, int h,
-    UIScreenMode * uiscreenmode, CGFloat scale)
+    UIScreenMode * uiscreenmode)
 {
 {
     SDL_DisplayMode mode;
     SDL_DisplayMode mode;
     SDL_zero(mode);
     SDL_zero(mode);
 
 
     mode.format = SDL_PIXELFORMAT_ABGR8888;
     mode.format = SDL_PIXELFORMAT_ABGR8888;
     mode.refresh_rate = 0;
     mode.refresh_rate = 0;
-    if (UIKit_AllocateDisplayModeData(&mode, uiscreenmode, scale) < 0) {
+    if (UIKit_AllocateDisplayModeData(&mode, uiscreenmode) < 0) {
         return -1;
         return -1;
     }
     }
 
 
@@ -85,16 +92,16 @@ UIKit_AddSingleDisplayMode(SDL_VideoDisplay * display, int w, int h,
 }
 }
 
 
 static int
 static int
-UIKit_AddDisplayMode(SDL_VideoDisplay * display, int w, int h, CGFloat scale,
+UIKit_AddDisplayMode(SDL_VideoDisplay * display, int w, int h,
                      UIScreenMode * uiscreenmode, SDL_bool addRotation)
                      UIScreenMode * uiscreenmode, SDL_bool addRotation)
 {
 {
-    if (UIKit_AddSingleDisplayMode(display, w, h, uiscreenmode, scale) < 0) {
+    if (UIKit_AddSingleDisplayMode(display, w, h, uiscreenmode) < 0) {
         return -1;
         return -1;
     }
     }
 
 
     if (addRotation) {
     if (addRotation) {
         /* Add the rotated version */
         /* Add the rotated version */
-        if (UIKit_AddSingleDisplayMode(display, h, w, uiscreenmode, scale) < 0) {
+        if (UIKit_AddSingleDisplayMode(display, h, w, uiscreenmode) < 0) {
             return -1;
             return -1;
         }
         }
     }
     }
@@ -114,24 +121,16 @@ UIKit_AddDisplay(UIScreen *uiscreen)
         size.height = height;
         size.height = height;
     }
     }
 
 
-    /* When dealing with UIKit all coordinates are specified in terms of
-     * what Apple refers to as points. [UIScreen scale] indicates the
-     * relationship between points and pixels. Since SDL has no notion
-     * of points, we must compensate in all cases where dealing with such
-     * units.
-     */
-    CGFloat scale = [uiscreen scale];
-
     SDL_VideoDisplay display;
     SDL_VideoDisplay display;
     SDL_DisplayMode mode;
     SDL_DisplayMode mode;
     SDL_zero(mode);
     SDL_zero(mode);
     mode.format = SDL_PIXELFORMAT_ABGR8888;
     mode.format = SDL_PIXELFORMAT_ABGR8888;
-    mode.w = (int)(size.width * scale);
-    mode.h = (int)(size.height * scale);
+    mode.w = (int) size.width;
+    mode.h = (int) size.height;
 
 
-    UIScreenMode * uiscreenmode = [uiscreen currentMode];
+    UIScreenMode *uiscreenmode = [uiscreen currentMode];
 
 
-    if (UIKit_AllocateDisplayModeData(&mode, uiscreenmode, scale) < 0) {
+    if (UIKit_AllocateDisplayModeData(&mode, uiscreenmode) < 0) {
         return -1;
         return -1;
     }
     }
 
 
@@ -140,19 +139,18 @@ UIKit_AddDisplay(UIScreen *uiscreen)
     display.current_mode = mode;
     display.current_mode = mode;
 
 
     /* Allocate the display data */
     /* Allocate the display data */
-    SDL_DisplayData *data = (SDL_DisplayData *) SDL_malloc(sizeof(*data));
+    SDL_DisplayData *data = [[SDL_DisplayData alloc] init];
     if (!data) {
     if (!data) {
         UIKit_FreeDisplayModeData(&display.desktop_mode);
         UIKit_FreeDisplayModeData(&display.desktop_mode);
         return SDL_OutOfMemory();
         return SDL_OutOfMemory();
     }
     }
 
 
-    [uiscreen retain];
-    data->uiscreen = uiscreen;
-    data->scale = scale;
+    data.uiscreen = uiscreen;
 
 
-    display.driverdata = data;
+    display.driverdata = (void *) CFBridgingRetain(data);
     SDL_AddVideoDisplay(&display);
     SDL_AddVideoDisplay(&display);
 
 
+
     return 0;
     return 0;
 }
 }
 
 
@@ -170,9 +168,11 @@ UIKit_IsDisplayLandscape(UIScreen *uiscreen)
 int
 int
 UIKit_InitModes(_THIS)
 UIKit_InitModes(_THIS)
 {
 {
-    for (UIScreen *uiscreen in [UIScreen screens]) {
-        if (UIKit_AddDisplay(uiscreen) < 0) {
-            return -1;
+    @autoreleasepool {
+        for (UIScreen *uiscreen in [UIScreen screens]) {
+            if (UIKit_AddDisplay(uiscreen) < 0) {
+                return -1;
+            }
         }
         }
     }
     }
 
 
@@ -182,34 +182,29 @@ UIKit_InitModes(_THIS)
 void
 void
 UIKit_GetDisplayModes(_THIS, SDL_VideoDisplay * display)
 UIKit_GetDisplayModes(_THIS, SDL_VideoDisplay * display)
 {
 {
-    SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata;
-
-    SDL_bool isLandscape = UIKit_IsDisplayLandscape(data->uiscreen);
-    SDL_bool addRotation = (data->uiscreen == [UIScreen mainScreen]);
-
-    for (UIScreenMode *uimode in [data->uiscreen availableModes]) {
-        CGSize size = [uimode size];
-        int w = (int)size.width;
-        int h = (int)size.height;
-
-        /* Make sure the width/height are oriented correctly */
-        if (isLandscape != (w > h)) {
-            int tmp = w;
-            w = h;
-            h = tmp;
-        }
+    @autoreleasepool {
+        SDL_DisplayData *data = (__bridge SDL_DisplayData *) display->driverdata;
+
+        SDL_bool isLandscape = UIKit_IsDisplayLandscape(data.uiscreen);
+        SDL_bool addRotation = (data.uiscreen == [UIScreen mainScreen]);
+        CGFloat scale = data.uiscreen.scale;
+
+        for (UIScreenMode *uimode in [data.uiscreen availableModes]) {
+            /* The size of a UIScreenMode is in pixels, but we deal exclusively in
+             * points (except in SDL_GL_GetDrawableSize.) */
+            CGSize size = [uimode size];
+            int w = (int)(size.width / scale);
+            int h = (int)(size.height / scale);
+
+            /* Make sure the width/height are oriented correctly */
+            if (isLandscape != (w > h)) {
+                int tmp = w;
+                w = h;
+                h = tmp;
+            }
 
 
-        /* Add the native screen resolution. */
-        UIKit_AddDisplayMode(display, w, h, data->scale, uimode, addRotation);
-
-        if (data->scale != 1.0f) {
-            /* Add the native screen resolution divided by its scale.
-             * This is so devices capable of e.g. 640x960 also advertise 320x480.
-             */
-            UIKit_AddDisplayMode(display,
-                (int)(size.width / data->scale),
-                (int)(size.height / data->scale),
-                1.0f, uimode, addRotation);
+            /* Add the native screen resolution. */
+            UIKit_AddDisplayMode(display, w, h, uimode, addRotation);
         }
         }
     }
     }
 }
 }
@@ -217,19 +212,21 @@ UIKit_GetDisplayModes(_THIS, SDL_VideoDisplay * display)
 int
 int
 UIKit_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
 UIKit_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
 {
 {
-    SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata;
-    SDL_DisplayModeData *modedata = (SDL_DisplayModeData *)mode->driverdata;
-
-    [data->uiscreen setCurrentMode:modedata->uiscreenmode];
-
-    if (data->uiscreen == [UIScreen mainScreen]) {
-        if (mode->w > mode->h) {
-            if (!UIKit_IsDisplayLandscape(data->uiscreen)) {
-                [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight animated:NO];
-            }
-        } else if (mode->w < mode->h) {
-            if (UIKit_IsDisplayLandscape(data->uiscreen)) {
-                [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait animated:NO];
+    @autoreleasepool {
+        SDL_DisplayData *data = (__bridge SDL_DisplayData *) display->driverdata;
+        SDL_DisplayModeData *modedata = (__bridge SDL_DisplayModeData *)mode->driverdata;
+
+        [data.uiscreen setCurrentMode:modedata.uiscreenmode];
+
+        if (data.uiscreen == [UIScreen mainScreen]) {
+            if (mode->w > mode->h) {
+                if (!UIKit_IsDisplayLandscape(data.uiscreen)) {
+                    [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight animated:NO];
+                }
+            } else if (mode->w < mode->h) {
+                if (UIKit_IsDisplayLandscape(data.uiscreen)) {
+                    [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait animated:NO];
+                }
             }
             }
         }
         }
     }
     }
@@ -242,19 +239,21 @@ UIKit_QuitModes(_THIS)
 {
 {
     /* Release Objective-C objects, so higher level doesn't free() them. */
     /* Release Objective-C objects, so higher level doesn't free() them. */
     int i, j;
     int i, j;
-    for (i = 0; i < _this->num_displays; i++) {
-        SDL_VideoDisplay *display = &_this->displays[i];
+    @autoreleasepool {
+        for (i = 0; i < _this->num_displays; i++) {
+            SDL_VideoDisplay *display = &_this->displays[i];
+
+            UIKit_FreeDisplayModeData(&display->desktop_mode);
+            for (j = 0; j < display->num_display_modes; j++) {
+                SDL_DisplayMode *mode = &display->display_modes[j];
+                UIKit_FreeDisplayModeData(mode);
+            }
 
 
-        UIKit_FreeDisplayModeData(&display->desktop_mode);
-        for (j = 0; j < display->num_display_modes; j++) {
-            SDL_DisplayMode *mode = &display->display_modes[j];
-            UIKit_FreeDisplayModeData(mode);
+            if (display->driverdata != NULL) {
+                CFRelease(display->driverdata);
+                display->driverdata = NULL;
+            }
         }
         }
-
-        SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata;
-        [data->uiscreen release];
-        SDL_free(data);
-        display->driverdata = NULL;
     }
     }
 }
 }
 
 

+ 2 - 0
src/video/uikit/SDL_uikitopengles.h

@@ -25,6 +25,8 @@
 
 
 extern int UIKit_GL_MakeCurrent(_THIS, SDL_Window * window,
 extern int UIKit_GL_MakeCurrent(_THIS, SDL_Window * window,
                                 SDL_GLContext context);
                                 SDL_GLContext context);
+extern void UIKit_GL_GetDrawableSize(_THIS, SDL_Window * window,
+                                     int * w, int * h);
 extern void UIKit_GL_SwapWindow(_THIS, SDL_Window * window);
 extern void UIKit_GL_SwapWindow(_THIS, SDL_Window * window);
 extern SDL_GLContext UIKit_GL_CreateContext(_THIS, SDL_Window * window);
 extern SDL_GLContext UIKit_GL_CreateContext(_THIS, SDL_Window * window);
 extern void UIKit_GL_DeleteContext(_THIS, SDL_GLContext context);
 extern void UIKit_GL_DeleteContext(_THIS, SDL_GLContext context);

+ 150 - 90
src/video/uikit/SDL_uikitopengles.m

@@ -49,12 +49,30 @@ UIKit_GL_GetProcAddress(_THIS, const char *proc)
 /*
 /*
     note that SDL_GL_Delete context makes it current without passing the window
     note that SDL_GL_Delete context makes it current without passing the window
 */
 */
-int UIKit_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context)
+int
+UIKit_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context)
 {
 {
-    [EAGLContext setCurrentContext: context];
+    @autoreleasepool {
+        [EAGLContext setCurrentContext:(__bridge EAGLContext *)context];
+    }
     return 0;
     return 0;
 }
 }
 
 
+void UIKit_GL_GetDrawableSize(_THIS, SDL_Window * window, int * w, int * h)
+{
+    @autoreleasepool {
+        SDL_WindowData *data = (__bridge SDL_WindowData *)window->driverdata;
+
+        if (w) {
+            *w = data.view.backingWidth;
+        }
+        if (h) {
+            *h = data.view.backingHeight;
+        }
+    }
+}
+
+
 int
 int
 UIKit_GL_LoadLibrary(_THIS, const char *path)
 UIKit_GL_LoadLibrary(_THIS, const char *path)
 {
 {
@@ -71,117 +89,159 @@ UIKit_GL_LoadLibrary(_THIS, const char *path)
 
 
 void UIKit_GL_SwapWindow(_THIS, SDL_Window * window)
 void UIKit_GL_SwapWindow(_THIS, SDL_Window * window)
 {
 {
+    @autoreleasepool {
+        SDL_WindowData *data = (__bridge SDL_WindowData *)window->driverdata;
+
 #if SDL_POWER_UIKIT
 #if SDL_POWER_UIKIT
-    /* Check once a frame to see if we should turn off the battery monitor. */
-    SDL_UIKit_UpdateBatteryMonitoring();
+        /* Check once a frame to see if we should turn off the battery monitor. */
+        SDL_UIKit_UpdateBatteryMonitoring();
 #endif
 #endif
 
 
-    SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
+        if (data.view == nil) {
+            return;
+        }
+        [data.view swapBuffers];
 
 
-    if (nil == data->view) {
-        return;
+        /* You need to pump events in order for the OS to make changes visible.
+           We don't pump events here because we don't want iOS application events
+           (low memory, terminate, etc.) to happen inside low level rendering.
+         */
     }
     }
-    [data->view swapBuffers];
-
-    /* You need to pump events in order for the OS to make changes visible.
-       We don't pump events here because we don't want iOS application events
-       (low memory, terminate, etc.) to happen inside low level rendering.
-     */
 }
 }
 
 
-SDL_GLContext UIKit_GL_CreateContext(_THIS, SDL_Window * window)
+SDL_GLContext
+UIKit_GL_CreateContext(_THIS, SDL_Window * window)
 {
 {
-    SDL_uikitopenglview *view;
-    SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
-    SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
-    SDL_DisplayData *displaydata = display->driverdata;
-    SDL_DisplayModeData *displaymodedata = display->current_mode.driverdata;
-    UIWindow *uiwindow = data->uiwindow;
-    EAGLSharegroup *share_group = nil;
-
-    if (_this->gl_config.share_with_current_context) {
-        SDL_uikitopenglview *view = (SDL_uikitopenglview *) SDL_GL_GetCurrentContext();
-        share_group = [view.context sharegroup];
-    }
+    @autoreleasepool {
+        SDL_uikitopenglview *view;
+        SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata;
+        UIWindow *uiwindow = data.uiwindow;
+        CGRect frame = UIKit_ComputeViewFrame(window, uiwindow.screen);
+        EAGLSharegroup *share_group = nil;
+        CGFloat scale = 1.0;
+
+        if (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) {
+            /* Set the scale to the natural scale factor of the screen - the backing
+               dimensions of the OpenGL view will match the pixel dimensions of the
+               screen rather than the dimensions in points.
+             */
+            scale = uiwindow.screen.scale;
+        }
 
 
-    /* construct our view, passing in SDL's OpenGL configuration data */
-    CGRect frame;
-    if (window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_BORDERLESS)) {
-        frame = [displaydata->uiscreen bounds];
-    } else {
-        frame = [displaydata->uiscreen applicationFrame];
-    }
-    view = [[SDL_uikitopenglview alloc] initWithFrame: frame
-                                    scale: displaymodedata->scale
-                                    retainBacking: _this->gl_config.retained_backing
-                                    rBits: _this->gl_config.red_size
-                                    gBits: _this->gl_config.green_size
-                                    bBits: _this->gl_config.blue_size
-                                    aBits: _this->gl_config.alpha_size
-                                    depthBits: _this->gl_config.depth_size
-                                    stencilBits: _this->gl_config.stencil_size
-                                    majorVersion: _this->gl_config.major_version
-                                    shareGroup: share_group];
-    if (!view) {
-        return NULL;
-    }
+        if (_this->gl_config.share_with_current_context) {
+            EAGLContext *context = (__bridge EAGLContext *) SDL_GL_GetCurrentContext();
+            share_group = context.sharegroup;
+        }
 
 
-    data->view = view;
-    view->viewcontroller = data->viewcontroller;
-    if (view->viewcontroller != nil) {
-        [view->viewcontroller setView:view];
-        [view->viewcontroller retain];
-    }
-    [uiwindow addSubview: view];
+        /* construct our view, passing in SDL's OpenGL configuration data */
+        view = [[SDL_uikitopenglview alloc] initWithFrame: frame
+                                                    scale: scale
+                                            retainBacking: _this->gl_config.retained_backing
+                                                    rBits: _this->gl_config.red_size
+                                                    gBits: _this->gl_config.green_size
+                                                    bBits: _this->gl_config.blue_size
+                                                    aBits: _this->gl_config.alpha_size
+                                                depthBits: _this->gl_config.depth_size
+                                              stencilBits: _this->gl_config.stencil_size
+                                                     sRGB: _this->gl_config.framebuffer_srgb_capable
+                                             majorVersion: _this->gl_config.major_version
+                                               shareGroup: share_group];
+        if (!view) {
+            return NULL;
+        }
 
 
-    /* The view controller needs to be the root in order to control rotation on iOS 6.0 */
-    if (uiwindow.rootViewController == nil) {
-        uiwindow.rootViewController = view->viewcontroller;
-    }
+        data.view = view;
+        view.viewcontroller = data.viewcontroller;
+        if (view.viewcontroller != nil) {
+            view.viewcontroller.view = view;
+        }
+        [uiwindow addSubview: view];
 
 
-    EAGLContext *context = view.context;
-    if (UIKit_GL_MakeCurrent(_this, window, context) < 0) {
-        UIKit_GL_DeleteContext(_this, context);
-        return NULL;
-    }
+        /* The view controller needs to be the root in order to control rotation on iOS 6.0 */
+        if (uiwindow.rootViewController == nil) {
+            uiwindow.rootViewController = view.viewcontroller;
+        }
 
 
-    /* Make this window the current mouse focus for touch input */
-    if (displaydata->uiscreen == [UIScreen mainScreen]) {
-        SDL_SetMouseFocus(window);
-        SDL_SetKeyboardFocus(window);
-    }
+        EAGLContext *context = view.context;
+        if (UIKit_GL_MakeCurrent(_this, window, (__bridge SDL_GLContext) context) < 0) {
+            UIKit_GL_DeleteContext(_this, (SDL_GLContext) CFBridgingRetain(context));
+            return NULL;
+        }
 
 
-    return context;
+        /* Make this window the current mouse focus for touch input */
+        if (uiwindow.screen == [UIScreen mainScreen]) {
+            SDL_SetMouseFocus(window);
+            SDL_SetKeyboardFocus(window);
+        }
+
+        /* We return a +1'd context. The window's driverdata owns the view. */
+        return (SDL_GLContext) CFBridgingRetain(context);
+    }
 }
 }
 
 
-void UIKit_GL_DeleteContext(_THIS, SDL_GLContext context)
+void
+UIKit_GL_DeleteContext(_THIS, SDL_GLContext context)
 {
 {
-    SDL_Window *window;
-
-    /* Find the view associated with this context */
-    for (window = _this->windows; window; window = window->next) {
-        SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
-        SDL_uikitopenglview *view = data->view;
-        if (view.context == context) {
-            /* the delegate has retained the view, this will release him */
-            if (view->viewcontroller) {
-                UIWindow *uiwindow = (UIWindow *)view.superview;
-                if (uiwindow.rootViewController == view->viewcontroller) {
-                    uiwindow.rootViewController = nil;
+    @autoreleasepool {
+        /* Transfer ownership the +1'd context to ARC. */
+        EAGLContext *eaglcontext = (EAGLContext *) CFBridgingRelease(context);
+        SDL_Window *window;
+
+        /* Find the view associated with this context */
+        for (window = _this->windows; window; window = window->next) {
+            SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata;
+            SDL_uikitopenglview *view = data.view;
+            if (view.context == eaglcontext) {
+                /* the delegate has retained the view, this will release him */
+                if (view.viewcontroller) {
+                    UIWindow *uiwindow = (UIWindow *)view.superview;
+                    if (uiwindow.rootViewController == view.viewcontroller) {
+                        uiwindow.rootViewController = nil;
+                    }
+                    view.viewcontroller.view = nil;
+                    view.viewcontroller = nil;
                 }
                 }
-                [view->viewcontroller setView:nil];
-                [view->viewcontroller release];
+                [view removeFromSuperview];
+
+                data.view = nil;
+                return;
             }
             }
-            [view removeFromSuperview];
+        }
+    }
+}
 
 
-            /* FIXME: This doesn't actually call view dealloc - what is holding a reference to it? */
-            [view release];
-            return;
+Uint32 SDL_iPhoneGetViewRenderbuffer(SDL_Window * window)
+{
+    if (!window) {
+        SDL_SetError("Invalid window");
+        return 0;
+    }
+
+    @autoreleasepool {
+        SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata;
+        if (data.view != nil) {
+            return data.view.drawableRenderbuffer;
+        } else {
+            return 0;
         }
         }
     }
     }
+}
 
 
-    /* View not found... delete the context anyway? */
-    [(EAGLContext *)context release];
+Uint32 SDL_iPhoneGetViewFramebuffer(SDL_Window * window)
+{
+    if (!window) {
+        SDL_SetError("Invalid window");
+        return 0;
+    }
+
+    @autoreleasepool {
+        SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata;
+        if (data.view != nil) {
+            return data.view.drawableFramebuffer;
+        } else {
+            return 0;
+        }
+    }
 }
 }
 
 
 #endif /* SDL_VIDEO_DRIVER_UIKIT */
 #endif /* SDL_VIDEO_DRIVER_UIKIT */

+ 24 - 38
src/video/uikit/SDL_uikitopenglview.h

@@ -29,52 +29,38 @@
     The view content is basically an EAGL surface you render your OpenGL scene into.
     The view content is basically an EAGL surface you render your OpenGL scene into.
     Note that setting the view non-opaque will only work if the EAGL surface has an alpha channel.
     Note that setting the view non-opaque will only work if the EAGL surface has an alpha channel.
  */
  */
-@interface SDL_uikitopenglview : SDL_uikitview {
+@interface SDL_uikitopenglview : SDL_uikitview
 
 
-@private
-    /* The pixel dimensions of the backbuffer */
-    GLint backingWidth;
-    GLint backingHeight;
-
-    EAGLContext *context;
-
-    /* OpenGL names for the renderbuffer and framebuffers used to render to this view */
-    GLuint viewRenderbuffer, viewFramebuffer;
-
-    /* OpenGL name for the depth buffer that is attached to viewFramebuffer, if it exists (0 if it does not exist) */
-    GLuint depthRenderbuffer;
-
-    /* format of depthRenderbuffer */
-    GLenum depthBufferFormat;
-
-    id displayLink;
-    int animationInterval;
-    void (*animationCallback)(void*);
-    void *animationCallbackParam;
-}
-
-@property (nonatomic, retain, readonly) EAGLContext *context;
+- (id)initWithFrame:(CGRect)frame
+              scale:(CGFloat)scale
+      retainBacking:(BOOL)retained
+              rBits:(int)rBits
+              gBits:(int)gBits
+              bBits:(int)bBits
+              aBits:(int)aBits
+          depthBits:(int)depthBits
+        stencilBits:(int)stencilBits
+               sRGB:(BOOL)sRGB
+       majorVersion:(int)majorVersion
+         shareGroup:(EAGLSharegroup*)shareGroup;
+
+@property (nonatomic, strong, readonly) EAGLContext *context;
+
+/* The width and height of the drawable in pixels (as opposed to points.) */
+@property (nonatomic, readonly) int backingWidth;
+@property (nonatomic, readonly) int backingHeight;
+
+@property (nonatomic, readonly) GLuint drawableRenderbuffer;
+@property (nonatomic, readonly) GLuint drawableFramebuffer;
 
 
 - (void)swapBuffers;
 - (void)swapBuffers;
 - (void)setCurrentContext;
 - (void)setCurrentContext;
 
 
-- (id)initWithFrame:(CGRect)frame
-    scale:(CGFloat)scale
-    retainBacking:(BOOL)retained
-    rBits:(int)rBits
-    gBits:(int)gBits
-    bBits:(int)bBits
-    aBits:(int)aBits
-    depthBits:(int)depthBits
-    stencilBits:(int)stencilBits
-    majorVersion:(int)majorVersion
-    shareGroup:(EAGLSharegroup*)shareGroup;
-
 - (void)updateFrame;
 - (void)updateFrame;
 
 
 - (void)setAnimationCallback:(int)interval
 - (void)setAnimationCallback:(int)interval
-    callback:(void (*)(void*))callback
-    callbackParam:(void*)callbackParam;
+                    callback:(void (*)(void*))callback
+               callbackParam:(void*)callbackParam;
 
 
 - (void)startAnimation;
 - (void)startAnimation;
 - (void)stopAnimation;
 - (void)stopAnimation;

+ 87 - 40
src/video/uikit/SDL_uikitopenglview.m

@@ -26,42 +26,73 @@
 #include <OpenGLES/EAGLDrawable.h>
 #include <OpenGLES/EAGLDrawable.h>
 #include "SDL_uikitopenglview.h"
 #include "SDL_uikitopenglview.h"
 #include "SDL_uikitmessagebox.h"
 #include "SDL_uikitmessagebox.h"
+#include "SDL_uikitvideo.h"
 
 
 
 
-@implementation SDL_uikitopenglview
+@implementation SDL_uikitopenglview {
+
+    /* OpenGL names for the renderbuffer and framebuffers used to render to this view */
+    GLuint viewRenderbuffer, viewFramebuffer;
+
+    /* OpenGL name for the depth buffer that is attached to viewFramebuffer, if it exists (0 if it does not exist) */
+    GLuint depthRenderbuffer;
+
+    /* format of depthRenderbuffer */
+    GLenum depthBufferFormat;
+
+    id displayLink;
+    int animationInterval;
+    void (*animationCallback)(void*);
+    void *animationCallbackParam;
+
+}
 
 
 @synthesize context;
 @synthesize context;
 
 
+@synthesize backingWidth;
+@synthesize backingHeight;
+
 + (Class)layerClass
 + (Class)layerClass
 {
 {
     return [CAEAGLLayer class];
     return [CAEAGLLayer class];
 }
 }
 
 
 - (id)initWithFrame:(CGRect)frame
 - (id)initWithFrame:(CGRect)frame
-      scale:(CGFloat)scale
+              scale:(CGFloat)scale
       retainBacking:(BOOL)retained
       retainBacking:(BOOL)retained
-      rBits:(int)rBits
-      gBits:(int)gBits
-      bBits:(int)bBits
-      aBits:(int)aBits
-      depthBits:(int)depthBits
-      stencilBits:(int)stencilBits
-      majorVersion:(int)majorVersion
-      shareGroup:(EAGLSharegroup*)shareGroup
+              rBits:(int)rBits
+              gBits:(int)gBits
+              bBits:(int)bBits
+              aBits:(int)aBits
+          depthBits:(int)depthBits
+        stencilBits:(int)stencilBits
+               sRGB:(BOOL)sRGB
+       majorVersion:(int)majorVersion
+         shareGroup:(EAGLSharegroup*)shareGroup
 {
 {
-    depthBufferFormat = 0;
-
     if ((self = [super initWithFrame:frame])) {
     if ((self = [super initWithFrame:frame])) {
         const BOOL useStencilBuffer = (stencilBits != 0);
         const BOOL useStencilBuffer = (stencilBits != 0);
         const BOOL useDepthBuffer = (depthBits != 0);
         const BOOL useDepthBuffer = (depthBits != 0);
         NSString *colorFormat = nil;
         NSString *colorFormat = nil;
 
 
+        self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
+        self.autoresizesSubviews = YES;
+
         /* The EAGLRenderingAPI enum values currently map 1:1 to major GLES
         /* The EAGLRenderingAPI enum values currently map 1:1 to major GLES
            versions, and this allows us to handle future OpenGL ES versions.
            versions, and this allows us to handle future OpenGL ES versions.
          */
          */
         EAGLRenderingAPI api = majorVersion;
         EAGLRenderingAPI api = majorVersion;
 
 
-        if (rBits == 8 && gBits == 8 && bBits == 8) {
+        context = [[EAGLContext alloc] initWithAPI:api sharegroup:shareGroup];
+        if (!context || ![EAGLContext setCurrentContext:context]) {
+            SDL_SetError("OpenGL ES %d not supported", majorVersion);
+            return nil;
+        }
+
+        if (sRGB && UIKit_IsSystemVersionAtLeast(@"7.0")) {
+             /* sRGB EAGL drawable support was added in iOS 7 */
+            colorFormat = kEAGLColorFormatSRGBA8;
+        } else if (rBits >= 8 && gBits >= 8 && bBits >= 8) {
             /* if user specifically requests rbg888 or some color format higher than 16bpp */
             /* if user specifically requests rbg888 or some color format higher than 16bpp */
             colorFormat = kEAGLColorFormatRGBA8;
             colorFormat = kEAGLColorFormatRGBA8;
         } else {
         } else {
@@ -73,26 +104,28 @@
         CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer;
         CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer;
 
 
         eaglLayer.opaque = YES;
         eaglLayer.opaque = YES;
-        eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
-                                        [NSNumber numberWithBool: retained], kEAGLDrawablePropertyRetainedBacking, colorFormat, kEAGLDrawablePropertyColorFormat, nil];
-
-        context = [[EAGLContext alloc] initWithAPI:api sharegroup:shareGroup];
-        if (!context || ![EAGLContext setCurrentContext:context]) {
-            [self release];
-            SDL_SetError("OpenGL ES %d not supported", majorVersion);
-            return nil;
-        }
+        eaglLayer.drawableProperties = @{
+            kEAGLDrawablePropertyRetainedBacking: @(retained),
+            kEAGLDrawablePropertyColorFormat: colorFormat
+        };
 
 
         /* Set the appropriate scale (for retina display support) */
         /* Set the appropriate scale (for retina display support) */
         self.contentScaleFactor = scale;
         self.contentScaleFactor = scale;
 
 
-        /* create the buffers */
-        glGenFramebuffersOES(1, &viewFramebuffer);
+        /* Create the color Renderbuffer Object */
         glGenRenderbuffersOES(1, &viewRenderbuffer);
         glGenRenderbuffersOES(1, &viewRenderbuffer);
+        glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
 
 
+        if (![context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:eaglLayer]) {
+            SDL_SetError("Failed creating OpenGL ES drawable");
+            return nil;
+        }
+
+        /* Create the Framebuffer Object */
+        glGenFramebuffersOES(1, &viewFramebuffer);
         glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
         glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
-        glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
-        [context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(CAEAGLLayer*)self.layer];
+
+        /* attach the color renderbuffer to the FBO */
         glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, viewRenderbuffer);
         glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, viewRenderbuffer);
 
 
         glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
         glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
@@ -119,18 +152,26 @@
         }
         }
 
 
         if (glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES) {
         if (glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES) {
-            return NO;
+            SDL_SetError("Failed creating OpenGL ES framebuffer");
+            return nil;
         }
         }
 
 
         glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
         glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
-        /* end create buffers */
-
-        self.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
-        self.autoresizesSubviews = YES;
     }
     }
+
     return self;
     return self;
 }
 }
 
 
+- (GLuint)drawableRenderbuffer
+{
+    return viewRenderbuffer;
+}
+
+- (GLuint)drawableFramebuffer
+{
+    return viewFramebuffer;
+}
+
 - (void)updateFrame
 - (void)updateFrame
 {
 {
     glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
     glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
@@ -164,8 +205,9 @@
     animationCallback = callback;
     animationCallback = callback;
     animationCallbackParam = callbackParam;
     animationCallbackParam = callbackParam;
 
 
-    if (animationCallback)
+    if (animationCallback) {
         [self startAnimation];
         [self startAnimation];
+    }
 }
 }
 
 
 - (void)startAnimation
 - (void)startAnimation
@@ -206,18 +248,25 @@
 
 
 - (void)layoutSubviews
 - (void)layoutSubviews
 {
 {
+    [super layoutSubviews];
+
     [EAGLContext setCurrentContext:context];
     [EAGLContext setCurrentContext:context];
     [self updateFrame];
     [self updateFrame];
 }
 }
 
 
 - (void)destroyFramebuffer
 - (void)destroyFramebuffer
 {
 {
-    glDeleteFramebuffersOES(1, &viewFramebuffer);
-    viewFramebuffer = 0;
-    glDeleteRenderbuffersOES(1, &viewRenderbuffer);
-    viewRenderbuffer = 0;
+    if (viewFramebuffer != 0) {
+        glDeleteFramebuffersOES(1, &viewFramebuffer);
+        viewFramebuffer = 0;
+    }
 
 
-    if (depthRenderbuffer) {
+    if (viewRenderbuffer != 0) {
+        glDeleteRenderbuffersOES(1, &viewRenderbuffer);
+        viewRenderbuffer = 0;
+    }
+
+    if (depthRenderbuffer != 0) {
         glDeleteRenderbuffersOES(1, &depthRenderbuffer);
         glDeleteRenderbuffersOES(1, &depthRenderbuffer);
         depthRenderbuffer = 0;
         depthRenderbuffer = 0;
     }
     }
@@ -226,12 +275,10 @@
 
 
 - (void)dealloc
 - (void)dealloc
 {
 {
-    [self destroyFramebuffer];
     if ([EAGLContext currentContext] == context) {
     if ([EAGLContext currentContext] == context) {
+        [self destroyFramebuffer];
         [EAGLContext setCurrentContext:nil];
         [EAGLContext setCurrentContext:nil];
     }
     }
-    [context release];
-    [super dealloc];
 }
 }
 
 
 @end
 @end

+ 2 - 14
src/video/uikit/SDL_uikitvideo.h

@@ -25,20 +25,8 @@
 
 
 #include "../SDL_sysvideo.h"
 #include "../SDL_sysvideo.h"
 
 
-#ifndef __IPHONE_6_0
-/* This enum isn't available in older SDKs, but we use it for our own purposes on iOS 5.1 and for the system on iOS 6.0 */
-enum UIInterfaceOrientationMask
-{
-    UIInterfaceOrientationMaskPortrait = (1 << UIInterfaceOrientationPortrait),
-    UIInterfaceOrientationMaskLandscapeLeft = (1 << UIInterfaceOrientationLandscapeLeft),
-    UIInterfaceOrientationMaskLandscapeRight = (1 << UIInterfaceOrientationLandscapeRight),
-    UIInterfaceOrientationMaskPortraitUpsideDown = (1 << UIInterfaceOrientationPortraitUpsideDown),
-    UIInterfaceOrientationMaskLandscape = (UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight),
-    UIInterfaceOrientationMaskAll = (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight | UIInterfaceOrientationMaskPortraitUpsideDown),
-    UIInterfaceOrientationMaskAllButUpsideDown = (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight),
-};
-#endif /* !__IPHONE_6_0 */
-
+BOOL UIKit_IsSystemVersionAtLeast(NSString *version);
+CGRect UIKit_ComputeViewFrame(SDL_Window *window, UIScreen *screen);
 
 
 #endif /* _SDL_uikitvideo_h */
 #endif /* _SDL_uikitvideo_h */
 
 

+ 25 - 5
src/video/uikit/SDL_uikitvideo.m

@@ -78,12 +78,11 @@ UIKit_CreateDevice(int devindex)
     device->ShowWindow = UIKit_ShowWindow;
     device->ShowWindow = UIKit_ShowWindow;
     device->HideWindow = UIKit_HideWindow;
     device->HideWindow = UIKit_HideWindow;
     device->RaiseWindow = UIKit_RaiseWindow;
     device->RaiseWindow = UIKit_RaiseWindow;
+    device->SetWindowBordered = UIKit_SetWindowBordered;
     device->SetWindowFullscreen = UIKit_SetWindowFullscreen;
     device->SetWindowFullscreen = UIKit_SetWindowFullscreen;
     device->DestroyWindow = UIKit_DestroyWindow;
     device->DestroyWindow = UIKit_DestroyWindow;
     device->GetWindowWMInfo = UIKit_GetWindowWMInfo;
     device->GetWindowWMInfo = UIKit_GetWindowWMInfo;
 
 
-    /* !!! FIXME: implement SetWindowBordered */
-
 #if SDL_IPHONE_KEYBOARD
 #if SDL_IPHONE_KEYBOARD
     device->HasScreenKeyboardSupport = UIKit_HasScreenKeyboardSupport;
     device->HasScreenKeyboardSupport = UIKit_HasScreenKeyboardSupport;
     device->ShowScreenKeyboard = UIKit_ShowScreenKeyboard;
     device->ShowScreenKeyboard = UIKit_ShowScreenKeyboard;
@@ -93,12 +92,13 @@ UIKit_CreateDevice(int devindex)
 #endif
 #endif
 
 
     /* OpenGL (ES) functions */
     /* OpenGL (ES) functions */
-    device->GL_MakeCurrent        = UIKit_GL_MakeCurrent;
-    device->GL_SwapWindow        = UIKit_GL_SwapWindow;
+    device->GL_MakeCurrent      = UIKit_GL_MakeCurrent;
+    device->GL_GetDrawableSize  = UIKit_GL_GetDrawableSize;
+    device->GL_SwapWindow       = UIKit_GL_SwapWindow;
     device->GL_CreateContext    = UIKit_GL_CreateContext;
     device->GL_CreateContext    = UIKit_GL_CreateContext;
     device->GL_DeleteContext    = UIKit_GL_DeleteContext;
     device->GL_DeleteContext    = UIKit_GL_DeleteContext;
     device->GL_GetProcAddress   = UIKit_GL_GetProcAddress;
     device->GL_GetProcAddress   = UIKit_GL_GetProcAddress;
-    device->GL_LoadLibrary        = UIKit_GL_LoadLibrary;
+    device->GL_LoadLibrary      = UIKit_GL_LoadLibrary;
     device->free = UIKit_DeleteDevice;
     device->free = UIKit_DeleteDevice;
 
 
     device->gl_config.accelerated = 1;
     device->gl_config.accelerated = 1;
@@ -129,6 +129,26 @@ UIKit_VideoQuit(_THIS)
     UIKit_QuitModes(_this);
     UIKit_QuitModes(_this);
 }
 }
 
 
+BOOL
+UIKit_IsSystemVersionAtLeast(NSString *version)
+{
+    NSString *sysversion = [UIDevice currentDevice].systemVersion;
+    return [sysversion compare:version options:NSNumericSearch] != NSOrderedAscending;
+}
+
+CGRect
+UIKit_ComputeViewFrame(SDL_Window *window, UIScreen *screen)
+{
+    BOOL hasiOS7 = UIKit_IsSystemVersionAtLeast(@"7.0");
+
+    if (hasiOS7 || (window->flags & (SDL_WINDOW_BORDERLESS|SDL_WINDOW_FULLSCREEN))) {
+        /* The view should always show behind the status bar in iOS 7+. */
+        return screen.bounds;
+    } else {
+        return screen.applicationFrame;
+    }
+}
+
 /*
 /*
  * iOS log support.
  * iOS log support.
  *
  *

+ 7 - 20
src/video/uikit/SDL_uikitview.h

@@ -31,27 +31,13 @@
 #endif
 #endif
 
 
 #if SDL_IPHONE_KEYBOARD
 #if SDL_IPHONE_KEYBOARD
-@interface SDL_uikitview : UIView<UITextFieldDelegate> {
+@interface SDL_uikitview : UIView <UITextFieldDelegate>
 #else
 #else
-@interface SDL_uikitview : UIView {
+@interface SDL_uikitview : UIView
 #endif
 #endif
 
 
-    SDL_TouchID touchId;
-    UITouch *leftFingerDown;
-#ifndef IPHONE_TOUCH_EFFICIENT_DANGEROUS
-    UITouch *finger[MAX_SIMULTANEOUS_TOUCHES];
-#endif
-
-#if SDL_IPHONE_KEYBOARD
-    UITextField *textField;
-    BOOL keyboardVisible;
-    SDL_Rect textInputRect;
-    int keyboardHeight;
-#endif
+@property (nonatomic, weak) SDL_uikitviewcontroller *viewcontroller;
 
 
-@public
-    SDL_uikitviewcontroller *viewcontroller;
-}
 - (CGPoint)touchLocation:(UITouch *)touch shouldNormalize:(BOOL)normalize;
 - (CGPoint)touchLocation:(UITouch *)touch shouldNormalize:(BOOL)normalize;
 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
 - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
 - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
@@ -61,9 +47,10 @@
 - (void)showKeyboard;
 - (void)showKeyboard;
 - (void)hideKeyboard;
 - (void)hideKeyboard;
 - (void)initializeKeyboard;
 - (void)initializeKeyboard;
-@property (readonly) BOOL keyboardVisible;
-@property (nonatomic,assign) SDL_Rect textInputRect;
-@property (nonatomic,assign) int keyboardHeight;
+
+@property (nonatomic, assign, getter=isKeyboardVisible) BOOL keyboardVisible;
+@property (nonatomic, assign) SDL_Rect textInputRect;
+@property (nonatomic, assign) int keyboardHeight;
 
 
 SDL_bool UIKit_HasScreenKeyboardSupport(_THIS);
 SDL_bool UIKit_HasScreenKeyboardSupport(_THIS);
 void UIKit_ShowScreenKeyboard(_THIS, SDL_Window *window);
 void UIKit_ShowScreenKeyboard(_THIS, SDL_Window *window);

+ 68 - 80
src/video/uikit/SDL_uikitview.m

@@ -35,27 +35,36 @@
 #include "SDL_uikitmodes.h"
 #include "SDL_uikitmodes.h"
 #include "SDL_uikitwindow.h"
 #include "SDL_uikitwindow.h"
 
 
-void _uikit_keyboard_init() ;
+void _uikit_keyboard_init();
 
 
-@implementation SDL_uikitview
+@implementation SDL_uikitview {
+
+    SDL_TouchID touchId;
+    UITouch *leftFingerDown;
+#ifndef IPHONE_TOUCH_EFFICIENT_DANGEROUS
+    UITouch *finger[MAX_SIMULTANEOUS_TOUCHES];
+#endif
+
+#if SDL_IPHONE_KEYBOARD
+    UITextField *textField;
+#endif
 
 
-- (void)dealloc
-{
-    [super dealloc];
 }
 }
 
 
+@synthesize viewcontroller;
+
 - (id)initWithFrame:(CGRect)frame
 - (id)initWithFrame:(CGRect)frame
 {
 {
-    self = [super initWithFrame: frame];
-
+    if (self = [super initWithFrame: frame]) {
 #if SDL_IPHONE_KEYBOARD
 #if SDL_IPHONE_KEYBOARD
-    [self initializeKeyboard];
+        [self initializeKeyboard];
 #endif
 #endif
 
 
-    self.multipleTouchEnabled = YES;
+        self.multipleTouchEnabled = YES;
 
 
-    touchId = 1;
-    SDL_AddTouch(touchId, "");
+        touchId = 1;
+        SDL_AddTouch(touchId, "");
+    }
 
 
     return self;
     return self;
 
 
@@ -65,36 +74,26 @@ void _uikit_keyboard_init() ;
 {
 {
     CGPoint point = [touch locationInView: self];
     CGPoint point = [touch locationInView: self];
 
 
-    /* Get the display scale and apply that to the input coordinates */
-    SDL_Window *window = self->viewcontroller.window;
-    SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
-    SDL_DisplayModeData *displaymodedata = (SDL_DisplayModeData *) display->current_mode.driverdata;
-
     if (normalize) {
     if (normalize) {
-        CGRect bounds = [self bounds];
+        CGRect bounds = self.bounds;
         point.x /= bounds.size.width;
         point.x /= bounds.size.width;
         point.y /= bounds.size.height;
         point.y /= bounds.size.height;
-    } else {
-        point.x *= displaymodedata->scale;
-        point.y *= displaymodedata->scale;
     }
     }
+
     return point;
     return point;
 }
 }
 
 
 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
 {
 {
-    NSEnumerator *enumerator = [touches objectEnumerator];
-    UITouch *touch = (UITouch*)[enumerator nextObject];
-
-    while (touch) {
+    for (UITouch *touch in touches) {
         if (!leftFingerDown) {
         if (!leftFingerDown) {
             CGPoint locationInView = [self touchLocation:touch shouldNormalize:NO];
             CGPoint locationInView = [self touchLocation:touch shouldNormalize:NO];
 
 
             /* send moved event */
             /* send moved event */
-            SDL_SendMouseMotion(self->viewcontroller.window, SDL_TOUCH_MOUSEID, 0, locationInView.x, locationInView.y);
+            SDL_SendMouseMotion(self.viewcontroller.window, SDL_TOUCH_MOUSEID, 0, locationInView.x, locationInView.y);
 
 
             /* send mouse down event */
             /* send mouse down event */
-            SDL_SendMouseButton(self->viewcontroller.window, SDL_TOUCH_MOUSEID, SDL_PRESSED, SDL_BUTTON_LEFT);
+            SDL_SendMouseButton(self.viewcontroller.window, SDL_TOUCH_MOUSEID, SDL_PRESSED, SDL_BUTTON_LEFT);
 
 
             leftFingerDown = touch;
             leftFingerDown = touch;
         }
         }
@@ -118,25 +117,21 @@ void _uikit_keyboard_init() ;
             }
             }
         }
         }
 #endif
 #endif
-        touch = (UITouch*)[enumerator nextObject];
     }
     }
 }
 }
 
 
 - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
 - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
 {
 {
-    NSEnumerator *enumerator = [touches objectEnumerator];
-    UITouch *touch = (UITouch*)[enumerator nextObject];
-
-    while(touch) {
+    for (UITouch *touch in touches) {
         if (touch == leftFingerDown) {
         if (touch == leftFingerDown) {
             /* send mouse up */
             /* send mouse up */
-            SDL_SendMouseButton(self->viewcontroller.window, SDL_TOUCH_MOUSEID, SDL_RELEASED, SDL_BUTTON_LEFT);
+            SDL_SendMouseButton(self.viewcontroller.window, SDL_TOUCH_MOUSEID, SDL_RELEASED, SDL_BUTTON_LEFT);
             leftFingerDown = nil;
             leftFingerDown = nil;
         }
         }
 
 
         CGPoint locationInView = [self touchLocation:touch shouldNormalize:YES];
         CGPoint locationInView = [self touchLocation:touch shouldNormalize:YES];
 #ifdef IPHONE_TOUCH_EFFICIENT_DANGEROUS
 #ifdef IPHONE_TOUCH_EFFICIENT_DANGEROUS
-        SDL_SendTouch(touchId, (long)touch,
+        SDL_SendTouch(touchId, (SDL_FingerID)((size_t)touch),
                       SDL_FALSE, locationInView.x, locationInView.y, 1.0f);
                       SDL_FALSE, locationInView.x, locationInView.y, 1.0f);
 #else
 #else
         int i;
         int i;
@@ -149,7 +144,6 @@ void _uikit_keyboard_init() ;
             }
             }
         }
         }
 #endif
 #endif
-        touch = (UITouch*)[enumerator nextObject];
     }
     }
 }
 }
 
 
@@ -165,20 +159,17 @@ void _uikit_keyboard_init() ;
 
 
 - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
 - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
 {
 {
-    NSEnumerator *enumerator = [touches objectEnumerator];
-    UITouch *touch = (UITouch*)[enumerator nextObject];
-
-    while (touch) {
+    for (UITouch *touch in touches) {
         if (touch == leftFingerDown) {
         if (touch == leftFingerDown) {
             CGPoint locationInView = [self touchLocation:touch shouldNormalize:NO];
             CGPoint locationInView = [self touchLocation:touch shouldNormalize:NO];
 
 
             /* send moved event */
             /* send moved event */
-            SDL_SendMouseMotion(self->viewcontroller.window, SDL_TOUCH_MOUSEID, 0, locationInView.x, locationInView.y);
+            SDL_SendMouseMotion(self.viewcontroller.window, SDL_TOUCH_MOUSEID, 0, locationInView.x, locationInView.y);
         }
         }
 
 
         CGPoint locationInView = [self touchLocation:touch shouldNormalize:YES];
         CGPoint locationInView = [self touchLocation:touch shouldNormalize:YES];
 #ifdef IPHONE_TOUCH_EFFICIENT_DANGEROUS
 #ifdef IPHONE_TOUCH_EFFICIENT_DANGEROUS
-        SDL_SendTouchMotion(touchId, (long)touch,
+        SDL_SendTouchMotion(touchId, (SDL_FingerID)((size_t)touch),
                             locationInView.x, locationInView.y, 1.0f);
                             locationInView.x, locationInView.y, 1.0f);
 #else
 #else
         int i;
         int i;
@@ -190,7 +181,6 @@ void _uikit_keyboard_init() ;
             }
             }
         }
         }
 #endif
 #endif
-        touch = (UITouch*)[enumerator nextObject];
     }
     }
 }
 }
 
 
@@ -199,14 +189,9 @@ void _uikit_keyboard_init() ;
 */
 */
 #if SDL_IPHONE_KEYBOARD
 #if SDL_IPHONE_KEYBOARD
 
 
-@synthesize textInputRect = textInputRect;
-@synthesize keyboardHeight = keyboardHeight;
-
-/* Is the iPhone virtual keyboard visible onscreen? */
-- (BOOL)keyboardVisible
-{
-    return keyboardVisible;
-}
+@synthesize textInputRect;
+@synthesize keyboardHeight;
+@synthesize keyboardVisible;
 
 
 /* Set ourselves up as a UITextFieldDelegate */
 /* Set ourselves up as a UITextFieldDelegate */
 - (void)initializeKeyboard
 - (void)initializeKeyboard
@@ -229,7 +214,6 @@ void _uikit_keyboard_init() ;
     keyboardVisible = NO;
     keyboardVisible = NO;
     /* add the UITextField (hidden) to our view */
     /* add the UITextField (hidden) to our view */
     [self addSubview: textField];
     [self addSubview: textField];
-    [textField release];
     
     
     _uikit_keyboard_init();
     _uikit_keyboard_init();
 }
 }
@@ -318,8 +302,8 @@ static SDL_uikitview * getWindowView(SDL_Window * window)
         return nil;
         return nil;
     }
     }
 
 
-    SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
-    SDL_uikitview *view = data != NULL ? data->view : nil;
+    SDL_WindowData *data = (__bridge SDL_WindowData *)window->driverdata;
+    SDL_uikitview *view = data != nil ? data.view : nil;
 
 
     if (view == nil) {
     if (view == nil) {
         SDL_SetError("Window has no view");
         SDL_SetError("Window has no view");
@@ -335,44 +319,49 @@ SDL_bool UIKit_HasScreenKeyboardSupport(_THIS)
 
 
 void UIKit_ShowScreenKeyboard(_THIS, SDL_Window *window)
 void UIKit_ShowScreenKeyboard(_THIS, SDL_Window *window)
 {
 {
-    SDL_uikitview *view = getWindowView(window);
-    if (view != nil) {
-        [view showKeyboard];
+    @autoreleasepool {
+        SDL_uikitview *view = getWindowView(window);
+        if (view != nil) {
+            [view showKeyboard];
+        }
     }
     }
 }
 }
 
 
 void UIKit_HideScreenKeyboard(_THIS, SDL_Window *window)
 void UIKit_HideScreenKeyboard(_THIS, SDL_Window *window)
 {
 {
-    SDL_uikitview *view = getWindowView(window);
-    if (view != nil) {
-        [view hideKeyboard];
+    @autoreleasepool {
+        SDL_uikitview *view = getWindowView(window);
+        if (view != nil) {
+            [view hideKeyboard];
+        }
     }
     }
 }
 }
 
 
 SDL_bool UIKit_IsScreenKeyboardShown(_THIS, SDL_Window *window)
 SDL_bool UIKit_IsScreenKeyboardShown(_THIS, SDL_Window *window)
 {
 {
-    SDL_uikitview *view = getWindowView(window);
-    if (view == nil) {
-        return 0;
-    }
+    @autoreleasepool {
+        SDL_uikitview *view = getWindowView(window);
+        if (view == nil) {
+            return 0;
+        }
 
 
-    return view.keyboardVisible;
+        return view.isKeyboardVisible;
+    }
 }
 }
 
 
 
 
 void _uikit_keyboard_update() {
 void _uikit_keyboard_update() {
     SDL_Window *window = SDL_GetFocusWindow();
     SDL_Window *window = SDL_GetFocusWindow();
     if (!window) { return; }
     if (!window) { return; }
-    SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
+    SDL_WindowData *data = (__bridge SDL_WindowData *)window->driverdata;
     if (!data) { return; }
     if (!data) { return; }
-    SDL_uikitview *view = data->view;
+    SDL_uikitview *view = data.view;
     if (!view) { return; }
     if (!view) { return; }
-    
+
     SDL_Rect r = view.textInputRect;
     SDL_Rect r = view.textInputRect;
     int height = view.keyboardHeight;
     int height = view.keyboardHeight;
     int offsetx = 0;
     int offsetx = 0;
     int offsety = 0;
     int offsety = 0;
-    float scale = [UIScreen mainScreen].scale;
     if (height) {
     if (height) {
         int sw,sh;
         int sw,sh;
         SDL_GetWindowSize(window,&sw,&sh);
         SDL_GetWindowSize(window,&sw,&sh);
@@ -394,18 +383,16 @@ void _uikit_keyboard_update() {
         offsety = -offsety;
         offsety = -offsety;
     }
     }
 
 
-    offsetx /= scale;
-    offsety /= scale;
-
     view.frame = CGRectMake(offsetx,offsety,view.frame.size.width,view.frame.size.height);
     view.frame = CGRectMake(offsetx,offsety,view.frame.size.width,view.frame.size.height);
 }
 }
 
 
 void _uikit_keyboard_set_height(int height) {
 void _uikit_keyboard_set_height(int height) {
     SDL_uikitview *view = getWindowView(SDL_GetFocusWindow());
     SDL_uikitview *view = getWindowView(SDL_GetFocusWindow());
     if (view == nil) {
     if (view == nil) {
-        return ;
+        return;
     }
     }
-    
+
+    view.keyboardVisible = height > 0;
     view.keyboardHeight = height;
     view.keyboardHeight = height;
     _uikit_keyboard_update();
     _uikit_keyboard_update();
 }
 }
@@ -418,13 +405,12 @@ void _uikit_keyboard_init() {
                          queue:queue
                          queue:queue
                     usingBlock:^(NSNotification *notification) {
                     usingBlock:^(NSNotification *notification) {
                         int height = 0;
                         int height = 0;
-                        CGSize keyboardSize = [[[notification userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
+                        CGSize keyboardSize = [[notification userInfo][UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
                         height = keyboardSize.height;
                         height = keyboardSize.height;
                         UIInterfaceOrientation ui_orient = [[UIApplication sharedApplication] statusBarOrientation];
                         UIInterfaceOrientation ui_orient = [[UIApplication sharedApplication] statusBarOrientation];
                         if (ui_orient == UIInterfaceOrientationLandscapeRight || ui_orient == UIInterfaceOrientationLandscapeLeft) {
                         if (ui_orient == UIInterfaceOrientationLandscapeRight || ui_orient == UIInterfaceOrientationLandscapeLeft) {
                             height = keyboardSize.width;
                             height = keyboardSize.width;
                         }
                         }
-                        height *= [UIScreen mainScreen].scale;
                         _uikit_keyboard_set_height(height);
                         _uikit_keyboard_set_height(height);
                     }
                     }
      ];
      ];
@@ -444,13 +430,15 @@ UIKit_SetTextInputRect(_THIS, SDL_Rect *rect)
         SDL_InvalidParamError("rect");
         SDL_InvalidParamError("rect");
         return;
         return;
     }
     }
-    
-    SDL_uikitview *view = getWindowView(SDL_GetFocusWindow());
-    if (view == nil) {
-        return ;
-    }
 
 
-    view.textInputRect = *rect;
+    @autoreleasepool {
+        SDL_uikitview *view = getWindowView(SDL_GetFocusWindow());
+        if (view == nil) {
+            return;
+        }
+
+        view.textInputRect = *rect;
+    }
 }
 }
 
 
 
 

+ 3 - 5
src/video/uikit/SDL_uikitviewcontroller.h

@@ -23,12 +23,9 @@
 
 
 #include "../SDL_sysvideo.h"
 #include "../SDL_sysvideo.h"
 
 
-@interface SDL_uikitviewcontroller : UIViewController {
-@private
-    SDL_Window *window;
-}
+@interface SDL_uikitviewcontroller : UIViewController
 
 
-@property (readwrite) SDL_Window *window;
+@property (nonatomic, assign) SDL_Window *window;
 
 
 - (id)initWithSDLWindow:(SDL_Window *)_window;
 - (id)initWithSDLWindow:(SDL_Window *)_window;
 - (void)loadView;
 - (void)loadView;
@@ -36,5 +33,6 @@
 - (NSUInteger)supportedInterfaceOrientations;
 - (NSUInteger)supportedInterfaceOrientations;
 - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)orient;
 - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)orient;
 - (BOOL)prefersStatusBarHidden;
 - (BOOL)prefersStatusBarHidden;
+- (UIStatusBarStyle)preferredStatusBarStyle;
 
 
 @end
 @end

+ 23 - 28
src/video/uikit/SDL_uikitviewcontroller.m

@@ -40,12 +40,9 @@
 
 
 - (id)initWithSDLWindow:(SDL_Window *)_window
 - (id)initWithSDLWindow:(SDL_Window *)_window
 {
 {
-    self = [self init];
-    if (self == nil) {
-        return nil;
+    if (self = [super initWithNibName:nil bundle:nil]) {
+        self.window = _window;
     }
     }
-    self.window = _window;
-
     return self;
     return self;
 }
 }
 
 
@@ -56,31 +53,20 @@
 
 
 - (void)viewDidLayoutSubviews
 - (void)viewDidLayoutSubviews
 {
 {
-    if (self->window->flags & SDL_WINDOW_RESIZABLE) {
-        SDL_WindowData *data = self->window->driverdata;
-        SDL_VideoDisplay *display = SDL_GetDisplayForWindow(self->window);
-        SDL_DisplayModeData *displaymodedata = (SDL_DisplayModeData *) display->current_mode.driverdata;
-        const CGSize size = data->view.bounds.size;
-        int w, h;
-
-        w = (int)(size.width * displaymodedata->scale);
-        h = (int)(size.height * displaymodedata->scale);
+    const CGSize size = self.view.bounds.size;
+    int w = (int) size.width;
+    int h = (int) size.height;
 
 
-        SDL_SendWindowEvent(self->window, SDL_WINDOWEVENT_RESIZED, w, h);
-    }
+    SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, w, h);
 }
 }
 
 
 - (NSUInteger)supportedInterfaceOrientations
 - (NSUInteger)supportedInterfaceOrientations
 {
 {
     NSUInteger orientationMask = 0;
     NSUInteger orientationMask = 0;
+    const char *hint = SDL_GetHint(SDL_HINT_ORIENTATIONS);
 
 
-    const char *orientationsCString;
-    if ((orientationsCString = SDL_GetHint(SDL_HINT_ORIENTATIONS)) != NULL) {
-        BOOL rotate = NO;
-        NSString *orientationsNSString = [NSString stringWithCString:orientationsCString
-                                                            encoding:NSUTF8StringEncoding];
-        NSArray *orientations = [orientationsNSString componentsSeparatedByCharactersInSet:
-                                 [NSCharacterSet characterSetWithCharactersInString:@" "]];
+    if (hint != NULL) {
+        NSArray *orientations = [@(hint) componentsSeparatedByString:@" "];
 
 
         if ([orientations containsObject:@"LandscapeLeft"]) {
         if ([orientations containsObject:@"LandscapeLeft"]) {
             orientationMask |= UIInterfaceOrientationMaskLandscapeLeft;
             orientationMask |= UIInterfaceOrientationMaskLandscapeLeft;
@@ -94,14 +80,17 @@
         if ([orientations containsObject:@"PortraitUpsideDown"]) {
         if ([orientations containsObject:@"PortraitUpsideDown"]) {
             orientationMask |= UIInterfaceOrientationMaskPortraitUpsideDown;
             orientationMask |= UIInterfaceOrientationMaskPortraitUpsideDown;
         }
         }
+    }
 
 
-    } else if (self->window->flags & SDL_WINDOW_RESIZABLE) {
+    if (orientationMask == 0 && (window->flags & SDL_WINDOW_RESIZABLE)) {
         orientationMask = UIInterfaceOrientationMaskAll;  /* any orientation is okay. */
         orientationMask = UIInterfaceOrientationMaskAll;  /* any orientation is okay. */
-    } else {
-        if (self->window->w >= self->window->h) {
+    }
+
+    if (orientationMask == 0) {
+        if (window->w >= window->h) {
             orientationMask |= UIInterfaceOrientationMaskLandscape;
             orientationMask |= UIInterfaceOrientationMaskLandscape;
         }
         }
-        if (self->window->h >= self->window->w) {
+        if (window->h >= window->w) {
             orientationMask |= (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown);
             orientationMask |= (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown);
         }
         }
     }
     }
@@ -121,13 +110,19 @@
 
 
 - (BOOL)prefersStatusBarHidden
 - (BOOL)prefersStatusBarHidden
 {
 {
-    if (self->window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_BORDERLESS)) {
+    if (window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_BORDERLESS)) {
         return YES;
         return YES;
     } else {
     } else {
         return NO;
         return NO;
     }
     }
 }
 }
 
 
+- (UIStatusBarStyle)preferredStatusBarStyle
+{
+    /* We assume most games don't have a bright white background. */
+    return UIStatusBarStyleLightContent;
+}
+
 @end
 @end
 
 
 #endif /* SDL_VIDEO_DRIVER_UIKIT */
 #endif /* SDL_VIDEO_DRIVER_UIKIT */

+ 12 - 8
src/video/uikit/SDL_uikitwindow.h

@@ -26,12 +26,11 @@
 #import "SDL_uikitopenglview.h"
 #import "SDL_uikitopenglview.h"
 #import "SDL_uikitviewcontroller.h"
 #import "SDL_uikitviewcontroller.h"
 
 
-typedef struct SDL_WindowData SDL_WindowData;
-
 extern int UIKit_CreateWindow(_THIS, SDL_Window * window);
 extern int UIKit_CreateWindow(_THIS, SDL_Window * window);
 extern void UIKit_ShowWindow(_THIS, SDL_Window * window);
 extern void UIKit_ShowWindow(_THIS, SDL_Window * window);
 extern void UIKit_HideWindow(_THIS, SDL_Window * window);
 extern void UIKit_HideWindow(_THIS, SDL_Window * window);
 extern void UIKit_RaiseWindow(_THIS, SDL_Window * window);
 extern void UIKit_RaiseWindow(_THIS, SDL_Window * window);
+extern void UIKit_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered);
 extern void UIKit_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen);
 extern void UIKit_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen);
 extern void UIKit_DestroyWindow(_THIS, SDL_Window * window);
 extern void UIKit_DestroyWindow(_THIS, SDL_Window * window);
 extern SDL_bool UIKit_GetWindowWMInfo(_THIS, SDL_Window * window,
 extern SDL_bool UIKit_GetWindowWMInfo(_THIS, SDL_Window * window,
@@ -39,12 +38,17 @@ extern SDL_bool UIKit_GetWindowWMInfo(_THIS, SDL_Window * window,
 
 
 @class UIWindow;
 @class UIWindow;
 
 
-struct SDL_WindowData
-{
-    UIWindow *uiwindow;
-    SDL_uikitopenglview *view;
-    SDL_uikitviewcontroller *viewcontroller;
-};
+@interface SDL_uikitwindow : UIWindow
+
+@end
+
+@interface SDL_WindowData : NSObject
+
+@property (nonatomic, strong) SDL_uikitwindow *uiwindow;
+@property (nonatomic, strong) SDL_uikitopenglview *view;
+@property (nonatomic, strong) SDL_uikitviewcontroller *viewcontroller;
+
+@end
 
 
 #endif /* _SDL_uikitwindow_h */
 #endif /* _SDL_uikitwindow_h */
 
 

+ 177 - 147
src/video/uikit/SDL_uikitwindow.m

@@ -41,43 +41,56 @@
 
 
 #include <Foundation/Foundation.h>
 #include <Foundation/Foundation.h>
 
 
+@implementation SDL_uikitwindow
 
 
+- (void)layoutSubviews
+{
+    [super layoutSubviews];
+
+    /* This seems to be needed on iOS 8, otherwise the window's frame is put in
+     * an unexpected position when the screen or device is rotated.
+     * FIXME: is there a better solution to that problem than this ugly hack?
+     */
+    self.frame = self.screen.bounds;
+}
+
+@end
 
 
+@implementation SDL_WindowData
 
 
-static int SetupWindowData(_THIS, SDL_Window *window, UIWindow *uiwindow, SDL_bool created)
+@synthesize uiwindow;
+@synthesize view;
+@synthesize viewcontroller;
+
+@end
+
+
+static int SetupWindowData(_THIS, SDL_Window *window, SDL_uikitwindow *uiwindow, SDL_bool created)
 {
 {
     SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
     SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
-    SDL_DisplayModeData *displaymodedata = (SDL_DisplayModeData *) display->current_mode.driverdata;
-    SDL_DisplayData *displaydata = (SDL_DisplayData *) display->driverdata;
-    SDL_WindowData *data;
+    SDL_DisplayData *displaydata = (__bridge SDL_DisplayData *) display->driverdata;
 
 
     /* Allocate the window data */
     /* Allocate the window data */
-    data = (SDL_WindowData *)SDL_malloc(sizeof(*data));
+    SDL_WindowData *data = [[SDL_WindowData alloc] init];
     if (!data) {
     if (!data) {
         return SDL_OutOfMemory();
         return SDL_OutOfMemory();
     }
     }
-    data->uiwindow = uiwindow;
-    data->viewcontroller = nil;
-    data->view = nil;
+
+    data.uiwindow = uiwindow;
 
 
     /* Fill in the SDL window with the window data */
     /* Fill in the SDL window with the window data */
     {
     {
         window->x = 0;
         window->x = 0;
         window->y = 0;
         window->y = 0;
 
 
-        CGRect bounds;
-        if (window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_BORDERLESS)) {
-            bounds = [displaydata->uiscreen bounds];
-        } else {
-            bounds = [displaydata->uiscreen applicationFrame];
-        }
+        CGRect frame = UIKit_ComputeViewFrame(window, displaydata.uiscreen);
 
 
-        /* Get frame dimensions in pixels */
-        int width = (int)(bounds.size.width * displaymodedata->scale);
-        int height = (int)(bounds.size.height * displaymodedata->scale);
+        /* Get frame dimensions */
+        int width = (int) frame.size.width;
+        int height = (int) frame.size.height;
 
 
         /* Make sure the width/height are oriented correctly */
         /* Make sure the width/height are oriented correctly */
-        if (UIKit_IsDisplayLandscape(displaydata->uiscreen) != (width > height)) {
+        if (UIKit_IsDisplayLandscape(displaydata.uiscreen) != (width > height)) {
             int temp = width;
             int temp = width;
             width = height;
             width = height;
             height = temp;
             height = temp;
@@ -87,7 +100,7 @@ static int SetupWindowData(_THIS, SDL_Window *window, UIWindow *uiwindow, SDL_bo
         window->h = height;
         window->h = height;
     }
     }
 
 
-    window->driverdata = data;
+    window->driverdata = (void *) CFBridgingRetain(data);
 
 
     /* only one window on iOS, always shown */
     /* only one window on iOS, always shown */
     window->flags &= ~SDL_WINDOW_HIDDEN;
     window->flags &= ~SDL_WINDOW_HIDDEN;
@@ -96,7 +109,7 @@ static int SetupWindowData(_THIS, SDL_Window *window, UIWindow *uiwindow, SDL_bo
      * This is only set if the window is on the main screen. Other screens
      * This is only set if the window is on the main screen. Other screens
      *  just force the window to have the borderless flag.
      *  just force the window to have the borderless flag.
      */
      */
-    if (displaydata->uiscreen == [UIScreen mainScreen]) {
+    if (displaydata.uiscreen == [UIScreen mainScreen]) {
         window->flags |= SDL_WINDOW_INPUT_FOCUS;  /* always has input focus */
         window->flags |= SDL_WINDOW_INPUT_FOCUS;  /* always has input focus */
 
 
         /* This was setup earlier for our window, and in iOS 7 is controlled by the view, not the application
         /* This was setup earlier for our window, and in iOS 7 is controlled by the view, not the application
@@ -116,10 +129,8 @@ static int SetupWindowData(_THIS, SDL_Window *window, UIWindow *uiwindow, SDL_bo
      * device orientation changes. This will trigger resize events, if
      * device orientation changes. This will trigger resize events, if
      * appropriate.
      * appropriate.
      */
      */
-    SDL_uikitviewcontroller *controller;
-    controller = [SDL_uikitviewcontroller alloc];
-    data->viewcontroller = [controller initWithSDLWindow:window];
-    [data->viewcontroller setTitle:@"SDL App"];  /* !!! FIXME: hook up SDL_SetWindowTitle() */
+    data.viewcontroller = [[SDL_uikitviewcontroller alloc] initWithSDLWindow:window];
+    data.viewcontroller.title = @"SDL App";  /* !!! FIXME: hook up SDL_SetWindowTitle() */
 
 
     return 0;
     return 0;
 }
 }
@@ -127,105 +138,109 @@ static int SetupWindowData(_THIS, SDL_Window *window, UIWindow *uiwindow, SDL_bo
 int
 int
 UIKit_CreateWindow(_THIS, SDL_Window *window)
 UIKit_CreateWindow(_THIS, SDL_Window *window)
 {
 {
-    SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
-    SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata;
-    const BOOL external = ([UIScreen mainScreen] != data->uiscreen);
-    const CGSize origsize = [[data->uiscreen currentMode] size];
-
-    /* SDL currently puts this window at the start of display's linked list. We rely on this. */
-    SDL_assert(_this->windows == window);
-
-    /* We currently only handle a single window per display on iOS */
-    if (window->next != NULL) {
-        return SDL_SetError("Only one window allowed per display.");
-    }
-
-    /* If monitor has a resolution of 0x0 (hasn't been explicitly set by the
-     * user, so it's in standby), try to force the display to a resolution
-     * that most closely matches the desired window size.
-     */
-    if ((origsize.width == 0.0f) && (origsize.height == 0.0f)) {
-        if (display->num_display_modes == 0) {
-            _this->GetDisplayModes(_this, display);
+    @autoreleasepool {
+        SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
+        SDL_DisplayData *data = (__bridge SDL_DisplayData *) display->driverdata;
+        const BOOL external = ([UIScreen mainScreen] != data.uiscreen);
+        const CGSize origsize = [[data.uiscreen currentMode] size];
+
+        /* SDL currently puts this window at the start of display's linked list. We rely on this. */
+        SDL_assert(_this->windows == window);
+
+        /* We currently only handle a single window per display on iOS */
+        if (window->next != NULL) {
+            return SDL_SetError("Only one window allowed per display.");
         }
         }
 
 
-        int i;
-        const SDL_DisplayMode *bestmode = NULL;
-        for (i = display->num_display_modes; i >= 0; i--) {
-            const SDL_DisplayMode *mode = &display->display_modes[i];
-            if ((mode->w >= window->w) && (mode->h >= window->h))
-                bestmode = mode;
-        }
+        /* If monitor has a resolution of 0x0 (hasn't been explicitly set by the
+         * user, so it's in standby), try to force the display to a resolution
+         * that most closely matches the desired window size.
+         */
+        if ((origsize.width == 0.0f) && (origsize.height == 0.0f)) {
+            if (display->num_display_modes == 0) {
+                _this->GetDisplayModes(_this, display);
+            }
 
 
-        if (bestmode) {
-            SDL_DisplayModeData *modedata = (SDL_DisplayModeData *)bestmode->driverdata;
-            [data->uiscreen setCurrentMode:modedata->uiscreenmode];
+            int i;
+            const SDL_DisplayMode *bestmode = NULL;
+            for (i = display->num_display_modes; i >= 0; i--) {
+                const SDL_DisplayMode *mode = &display->display_modes[i];
+                if ((mode->w >= window->w) && (mode->h >= window->h))
+                    bestmode = mode;
+            }
 
 
-            /* desktop_mode doesn't change here (the higher level will
-             * use it to set all the screens back to their defaults
-             * upon window destruction, SDL_Quit(), etc.
-             */
-            display->current_mode = *bestmode;
-        }
-    }
+            if (bestmode) {
+                SDL_DisplayModeData *modedata = (__bridge SDL_DisplayModeData *)bestmode->driverdata;
+                [data.uiscreen setCurrentMode:modedata.uiscreenmode];
 
 
-    if (data->uiscreen == [UIScreen mainScreen]) {
-        if (window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_BORDERLESS)) {
-            [UIApplication sharedApplication].statusBarHidden = YES;
-        } else {
-            [UIApplication sharedApplication].statusBarHidden = NO;
+                /* desktop_mode doesn't change here (the higher level will
+                 * use it to set all the screens back to their defaults
+                 * upon window destruction, SDL_Quit(), etc.
+                 */
+                display->current_mode = *bestmode;
+            }
         }
         }
-    }
 
 
-    if (!(window->flags & SDL_WINDOW_RESIZABLE)) {
-        if (window->w > window->h) {
-            if (!UIKit_IsDisplayLandscape(data->uiscreen)) {
-                [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight animated:NO];
+        if (data.uiscreen == [UIScreen mainScreen]) {
+            if (window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_BORDERLESS)) {
+                [UIApplication sharedApplication].statusBarHidden = YES;
+            } else {
+                [UIApplication sharedApplication].statusBarHidden = NO;
             }
             }
-        } else if (window->w < window->h) {
-            if (UIKit_IsDisplayLandscape(data->uiscreen)) {
-                [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait animated:NO];
+        }
+
+        if (!(window->flags & SDL_WINDOW_RESIZABLE)) {
+            if (window->w > window->h) {
+                if (!UIKit_IsDisplayLandscape(data.uiscreen)) {
+                    [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight animated:NO];
+                }
+            } else if (window->w < window->h) {
+                if (UIKit_IsDisplayLandscape(data.uiscreen)) {
+                    [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait animated:NO];
+                }
             }
             }
         }
         }
-    }
 
 
-    /* ignore the size user requested, and make a fullscreen window */
-    /* !!! FIXME: can we have a smaller view? */
-    UIWindow *uiwindow = [UIWindow alloc];
-    uiwindow = [uiwindow initWithFrame:[data->uiscreen bounds]];
+        /* ignore the size user requested, and make a fullscreen window */
+        /* !!! FIXME: can we have a smaller view? */
+        SDL_uikitwindow *uiwindow = [[SDL_uikitwindow alloc] initWithFrame:data.uiscreen.bounds];
+
+        /* put the window on an external display if appropriate. This implicitly
+         * does [uiwindow setframe:[uiscreen bounds]], so don't do it on the
+         * main display, where we land by default, as that would eat the
+         * status bar real estate.
+         */
+        if (external) {
+            [uiwindow setScreen:data.uiscreen];
+        }
 
 
-    /* put the window on an external display if appropriate. This implicitly
-     * does [uiwindow setframe:[uiscreen bounds]], so don't do it on the
-     * main display, where we land by default, as that would eat the
-     * status bar real estate.
-     */
-    if (external) {
-        [uiwindow setScreen:data->uiscreen];
-    }
+        if (SetupWindowData(_this, window, uiwindow, SDL_TRUE) < 0) {
+            return -1;
+        }
 
 
-    if (SetupWindowData(_this, window, uiwindow, SDL_TRUE) < 0) {
-        [uiwindow release];
-        return -1;
     }
     }
 
 
     return 1;
     return 1;
-
 }
 }
 
 
 void
 void
 UIKit_ShowWindow(_THIS, SDL_Window * window)
 UIKit_ShowWindow(_THIS, SDL_Window * window)
 {
 {
-    UIWindow *uiwindow = ((SDL_WindowData *) window->driverdata)->uiwindow;
+    @autoreleasepool {
+        UIWindow *uiwindow = ((__bridge SDL_WindowData *) window->driverdata).uiwindow;
 
 
-    [uiwindow makeKeyAndVisible];
+        [uiwindow makeKeyAndVisible];
+    }
 }
 }
 
 
 void
 void
 UIKit_HideWindow(_THIS, SDL_Window * window)
 UIKit_HideWindow(_THIS, SDL_Window * window)
 {
 {
-    UIWindow *uiwindow = ((SDL_WindowData *) window->driverdata)->uiwindow;
+    @autoreleasepool {
+        UIWindow *uiwindow = ((__bridge SDL_WindowData *) window->driverdata).uiwindow;
 
 
-    uiwindow.hidden = YES;
+        uiwindow.hidden = YES;
+    }
 }
 }
 
 
 void
 void
@@ -239,91 +254,106 @@ UIKit_RaiseWindow(_THIS, SDL_Window * window)
     _this->GL_MakeCurrent(_this, _this->current_glwin, _this->current_glctx);
     _this->GL_MakeCurrent(_this, _this->current_glwin, _this->current_glctx);
 }
 }
 
 
-void
-UIKit_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen)
+static void
+UIKit_UpdateWindowBorder(_THIS, SDL_Window * window)
 {
 {
-    SDL_DisplayData *displaydata = (SDL_DisplayData *) display->driverdata;
-    SDL_DisplayModeData *displaymodedata = (SDL_DisplayModeData *) display->current_mode.driverdata;
-    UIWindow *uiwindow = ((SDL_WindowData *) window->driverdata)->uiwindow;
+    SDL_WindowData *windowdata = (__bridge SDL_WindowData *) window->driverdata;
+    SDL_uikitviewcontroller *viewcontroller = windowdata.viewcontroller;
+    CGRect frame;
 
 
-    if (fullscreen) {
-        [UIApplication sharedApplication].statusBarHidden = YES;
-    } else {
-        [UIApplication sharedApplication].statusBarHidden = NO;
-    }
+    if (windowdata.uiwindow.screen == [UIScreen mainScreen]) {
+        if (window->flags & (SDL_WINDOW_FULLSCREEN | SDL_WINDOW_BORDERLESS)) {
+            [UIApplication sharedApplication].statusBarHidden = YES;
+        } else {
+            [UIApplication sharedApplication].statusBarHidden = NO;
+        }
 
 
-    CGRect bounds;
-    if (fullscreen) {
-        bounds = [displaydata->uiscreen bounds];
-    } else {
-        bounds = [displaydata->uiscreen applicationFrame];
+        /* iOS 7+ won't update the status bar until we tell it to. */
+        if ([viewcontroller respondsToSelector:@selector(setNeedsStatusBarAppearanceUpdate)]) {
+            [viewcontroller setNeedsStatusBarAppearanceUpdate];
+        }
     }
     }
 
 
-    /* Get frame dimensions in pixels */
-    int width = (int)(bounds.size.width * displaymodedata->scale);
-    int height = (int)(bounds.size.height * displaymodedata->scale);
+    /* Update the view's frame to account for the status bar change. */
+    frame = UIKit_ComputeViewFrame(window, windowdata.uiwindow.screen);
+
+    windowdata.view.frame = frame;
+    [windowdata.view setNeedsLayout];
+    [windowdata.view layoutIfNeeded];
+
+    /* Get frame dimensions */
+    int width  = (int) frame.size.width;
+    int height = (int) frame.size.height;
 
 
     /* We can pick either width or height here and we'll rotate the
     /* We can pick either width or height here and we'll rotate the
-       screen to match, so we pick the closest to what we wanted.
+     screen to match, so we pick the closest to what we wanted.
      */
      */
     if (window->w >= window->h) {
     if (window->w >= window->h) {
-        if (width > height) {
-            window->w = width;
-            window->h = height;
-        } else {
-            window->w = height;
-            window->h = width;
-        }
+        SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, SDL_max(width, height), SDL_min(width, height));
     } else {
     } else {
-        if (width > height) {
-            window->w = height;
-            window->h = width;
-        } else {
-            window->w = width;
-            window->h = height;
-        }
+        SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, SDL_min(width, height), SDL_max(width, height));
     }
     }
 }
 }
 
 
 void
 void
-UIKit_DestroyWindow(_THIS, SDL_Window * window)
+UIKit_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered)
 {
 {
-    SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
+    @autoreleasepool {
+        UIKit_UpdateWindowBorder(_this, window);
+    }
+}
 
 
-    if (data) {
-        [data->viewcontroller release];
-        [data->uiwindow release];
-        SDL_free(data);
+void
+UIKit_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen)
+{
+    @autoreleasepool {
+        UIKit_UpdateWindowBorder(_this, window);
+    }
+}
+
+void
+UIKit_DestroyWindow(_THIS, SDL_Window * window)
+{
+    @autoreleasepool {
+        if (window->driverdata != NULL) {
+            CFRelease(window->driverdata);
+        }
     }
     }
+
     window->driverdata = NULL;
     window->driverdata = NULL;
 }
 }
 
 
 SDL_bool
 SDL_bool
 UIKit_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info)
 UIKit_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info)
 {
 {
-    UIWindow *uiwindow = ((SDL_WindowData *) window->driverdata)->uiwindow;
+    @autoreleasepool {
+        UIWindow *uiwindow = ((__bridge SDL_WindowData *) window->driverdata).uiwindow;
 
 
-    if (info->version.major <= SDL_MAJOR_VERSION) {
-        info->subsystem = SDL_SYSWM_UIKIT;
-        info->info.uikit.window = uiwindow;
-        return SDL_TRUE;
-    } else {
-        SDL_SetError("Application not compiled with SDL %d.%d\n",
-                     SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
-        return SDL_FALSE;
+        if (info->version.major <= SDL_MAJOR_VERSION) {
+            info->subsystem = SDL_SYSWM_UIKIT;
+            info->info.uikit.window = uiwindow;
+            return SDL_TRUE;
+        } else {
+            SDL_SetError("Application not compiled with SDL %d.%d\n",
+                         SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
+            return SDL_FALSE;
+        }
     }
     }
 }
 }
 
 
 int
 int
 SDL_iPhoneSetAnimationCallback(SDL_Window * window, int interval, void (*callback)(void*), void *callbackParam)
 SDL_iPhoneSetAnimationCallback(SDL_Window * window, int interval, void (*callback)(void*), void *callbackParam)
 {
 {
-    SDL_WindowData *data = window ? (SDL_WindowData *)window->driverdata : NULL;
+    @autoreleasepool {
+        SDL_WindowData *data = window ? (__bridge SDL_WindowData *)window->driverdata : nil;
+
+        if (!data || !data.view) {
+            return SDL_SetError("Invalid window or view not set");
+        }
 
 
-    if (!data || !data->view) {
-        return SDL_SetError("Invalid window or view not set");
+        [data.view setAnimationCallback:interval callback:callback callbackParam:callbackParam];
     }
     }
 
 
-    [data->view setAnimationCallback:interval callback:callback callbackParam:callbackParam];
     return 0;
     return 0;
 }
 }