Răsfoiți Sursa

Fixed orientation issue on iOS 6 by applying code from new SDL and enabling resizable window.

Lasse Öörni 13 ani în urmă
părinte
comite
208af3324d

+ 5 - 0
Engine/Graphics/OpenGL/OGLGraphics.cpp

@@ -293,6 +293,11 @@ bool Graphics::SetMode(int width, int height, bool fullscreen, bool vsync, bool
             if (fullscreen)
                 flags |= SDL_WINDOW_FULLSCREEN | SDL_WINDOW_BORDERLESS;
             
+            // On iOS window needs to be resizable to handle orientation changes properly
+            #ifdef IOS
+            flags |= SDL_WINDOW_RESIZABLE;
+            #endif
+            
             for (;;)
             {
                 if (!externalWindow_)

+ 51 - 0
ThirdParty/SDL/src/video/uikit/SDL_uikitmodes.h

@@ -0,0 +1,51 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2012 Sam Lantinga <[email protected]>
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+*/
+#include "SDL_config.h"
+
+#ifndef _SDL_uikitmodes_h
+#define _SDL_uikitmodes_h
+
+#include "SDL_uikitvideo.h"
+
+typedef struct
+{
+    UIScreen *uiscreen;
+    CGFloat scale;
+} SDL_DisplayData;
+
+typedef struct
+{
+    UIScreenMode *uiscreenmode;
+    CGFloat scale;
+} SDL_DisplayModeData;
+
+extern BOOL SDL_UIKit_supports_multiple_displays;
+
+extern SDL_bool UIKit_IsDisplayLandscape(UIScreen *uiscreen);
+
+extern int UIKit_InitModes(_THIS);
+extern void UIKit_GetDisplayModes(_THIS, SDL_VideoDisplay * display);
+extern int UIKit_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode);
+extern void UIKit_QuitModes(_THIS);
+
+#endif /* _SDL_uikitmodes_h */
+
+/* vi: set ts=4 sw=4 expandtab: */

+ 320 - 0
ThirdParty/SDL/src/video/uikit/SDL_uikitmodes.m

@@ -0,0 +1,320 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2012 Sam Lantinga <[email protected]>
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+*/
+#include "SDL_config.h"
+
+#if SDL_VIDEO_DRIVER_UIKIT
+
+#include "SDL_assert.h"
+#include "SDL_uikitmodes.h"
+
+
+BOOL SDL_UIKit_supports_multiple_displays = NO;
+
+
+static int
+UIKit_AllocateDisplayModeData(SDL_DisplayMode * mode,
+    UIScreenMode * uiscreenmode, CGFloat scale)
+{
+    SDL_DisplayModeData *data = NULL;
+    
+    if (uiscreenmode != nil) {
+        /* Allocate the display mode data */
+        data = (SDL_DisplayModeData *) SDL_malloc(sizeof(*data));
+        if (!data) {
+            SDL_OutOfMemory();
+            return -1;
+        }
+        
+        data->uiscreenmode = uiscreenmode;
+        [data->uiscreenmode retain];
+        
+        data->scale = scale;
+    }
+    
+    mode->driverdata = data;
+    
+    return 0;
+}
+
+static void
+UIKit_FreeDisplayModeData(SDL_DisplayMode * mode)
+{
+    if (!SDL_UIKit_supports_multiple_displays) {
+        // Not on at least iPhoneOS 3.2 (versions prior to iPad).
+        SDL_assert(mode->driverdata == NULL);
+    } else if (mode->driverdata != NULL) {
+        SDL_DisplayModeData *data = (SDL_DisplayModeData *)mode->driverdata;
+        [data->uiscreenmode release];
+        SDL_free(data);
+        mode->driverdata = NULL;
+    }
+}
+
+static int
+UIKit_AddSingleDisplayMode(SDL_VideoDisplay * display, int w, int h,
+    UIScreenMode * uiscreenmode, CGFloat scale)
+{
+    SDL_DisplayMode mode;
+    SDL_zero(mode);
+    
+    mode.format = SDL_PIXELFORMAT_ABGR8888;
+    mode.refresh_rate = 0;
+    if (UIKit_AllocateDisplayModeData(&mode, uiscreenmode, scale) < 0) {
+        return -1;
+    }
+    
+    mode.w = w;
+    mode.h = h;
+    if (SDL_AddDisplayMode(display, &mode)) {
+        return 0;
+    } else {
+        UIKit_FreeDisplayModeData(&mode);
+        return -1;
+    }
+}
+
+static int
+UIKit_AddDisplayMode(SDL_VideoDisplay * display, int w, int h, CGFloat scale,
+                     UIScreenMode * uiscreenmode, SDL_bool addRotation)
+{
+    if (UIKit_AddSingleDisplayMode(display, w, h, uiscreenmode, scale) < 0) {
+        return -1;
+    }
+    
+    if (addRotation) {
+        // Add the rotated version
+        if (UIKit_AddSingleDisplayMode(display, h, w, uiscreenmode, scale) < 0) {
+            return -1;
+        }
+    }
+    
+    return 0;
+}
+
+static int
+UIKit_AddDisplay(UIScreen *uiscreen)
+{
+    CGSize size = [uiscreen bounds].size;
+
+    // Make sure the width/height are oriented correctly
+    if (UIKit_IsDisplayLandscape(uiscreen) != (size.width > size.height)) {
+        CGFloat height = size.width;
+        size.width = size.height;
+        size.height = height;
+    }
+
+    // When dealing with UIKit all coordinates are specified in terms of
+    // what Apple refers to as points. On earlier devices without the
+    // so called "Retina" display, there is a one to one mapping between
+    // points and pixels. In other cases [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;
+    if ([UIScreen instancesRespondToSelector:@selector(scale)]) {
+        scale = [uiscreen scale]; // iOS >= 4.0
+    } else {
+        scale = 1.0f; // iOS < 4.0
+    }
+
+    SDL_VideoDisplay display;
+    SDL_DisplayMode mode;
+    SDL_zero(mode);
+    mode.format = SDL_PIXELFORMAT_ABGR8888;
+    mode.w = (int)(size.width * scale);
+    mode.h = (int)(size.height * scale);
+ 
+    UIScreenMode * uiscreenmode = nil;
+    // UIScreenMode showed up in 3.2 (the iPad and later). We're
+    //  misusing this supports_multiple_displays flag here for that.
+    if (SDL_UIKit_supports_multiple_displays) {
+        uiscreenmode = [uiscreen currentMode];
+    }
+    
+    if (UIKit_AllocateDisplayModeData(&mode, uiscreenmode, scale) < 0) {
+        return -1;
+    }
+
+    SDL_zero(display);
+    display.desktop_mode = mode;
+    display.current_mode = mode;
+
+    /* Allocate the display data */
+    SDL_DisplayData *data = (SDL_DisplayData *) SDL_malloc(sizeof(*data));
+    if (!data) {
+        SDL_OutOfMemory();
+        UIKit_FreeDisplayModeData(&display.desktop_mode);
+        return -1;
+    }
+	
+    [uiscreen retain];
+    data->uiscreen = uiscreen;
+    data->scale = scale;
+	
+    display.driverdata = data;
+    SDL_AddVideoDisplay(&display);
+    
+    return 0;
+}
+
+SDL_bool
+UIKit_IsDisplayLandscape(UIScreen *uiscreen)
+{
+    if (uiscreen == [UIScreen mainScreen]) {
+        return UIInterfaceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation]);
+    } else {
+        CGSize size = [uiscreen bounds].size;
+        return (size.width > size.height);
+    }
+}
+
+int
+UIKit_InitModes(_THIS)
+{
+    // this tells us whether we are running on ios >= 3.2
+    SDL_UIKit_supports_multiple_displays = [UIScreen instancesRespondToSelector:@selector(currentMode)];
+
+    // Add the main screen.
+    if (UIKit_AddDisplay([UIScreen mainScreen]) < 0) {
+        return -1;
+    }
+
+    // If this is iPhoneOS < 3.2, all devices are one screen, 320x480 pixels.
+    //  The iPad added both a larger main screen and the ability to use
+    //  external displays. So, add the other displays (screens in UI speak).
+    if (SDL_UIKit_supports_multiple_displays) {
+        for (UIScreen *uiscreen in [UIScreen screens]) {
+            // Only add the other screens
+            if (uiscreen != [UIScreen mainScreen]) {
+                if (UIKit_AddDisplay(uiscreen) < 0) {
+                    return -1;
+                }
+            }
+        }
+    }
+
+    /* We're done! */
+    return 0;
+}
+
+void
+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]);
+
+    if (SDL_UIKit_supports_multiple_displays) {
+        // availableModes showed up in 3.2 (the iPad and later). We should only
+        //  land here for at least that version of the OS.
+        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;
+            }
+
+            // 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);
+            }
+        }
+    } else {
+        const CGSize size = [data->uiscreen bounds].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;
+        }
+
+        UIKit_AddDisplayMode(display, w, h, 1.0f, nil, addRotation);
+    } 
+}
+
+int
+UIKit_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
+{
+    SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata;
+
+    if (!SDL_UIKit_supports_multiple_displays) {
+        // Not on at least iPhoneOS 3.2 (versions prior to iPad).
+        SDL_assert(mode->driverdata == NULL);
+    } else {
+        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];
+                }
+            }
+        }
+    }
+    return 0;
+}
+
+void
+UIKit_QuitModes(_THIS)
+{
+    // Release Objective-C objects, so higher level doesn't free() them.
+    int i, j;
+    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);
+        }
+
+        SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata;
+        [data->uiscreen release];
+        SDL_free(data);
+        display->driverdata = NULL;
+    }
+}
+
+#endif /* SDL_VIDEO_DRIVER_UIKIT */
+
+/* vi: set ts=4 sw=4 expandtab: */

+ 21 - 10
ThirdParty/SDL/src/video/uikit/SDL_uikitopengles.m

@@ -18,9 +18,6 @@
      misrepresented as being the original software.
   3. This notice may not be removed or altered from any source distribution.
 */
-
-// Modified by Lasse Öörni for Urho3D
-
 #include "SDL_config.h"
 
 #if SDL_VIDEO_DRIVER_UIKIT
@@ -28,9 +25,10 @@
 #include "SDL_uikitopengles.h"
 #include "SDL_uikitopenglview.h"
 #include "SDL_uikitappdelegate.h"
+#include "SDL_uikitmodes.h"
 #include "SDL_uikitwindow.h"
 #include "jumphack.h"
-#include "../../video/SDL_sysvideo.h"
+#include "../SDL_sysvideo.h"
 #include "../../events/SDL_keyboard_c.h"
 #include "../../events/SDL_mouse_c.h"
 #include "../../power/uikit/SDL_syspower.h"
@@ -93,7 +91,7 @@ void UIKit_GL_SwapWindow(_THIS, SDL_Window * window)
         return;
     }
     [data->view swapBuffers];
-    
+
     /* we need to let the event cycle run, or the OS won't update the OpenGL view! */
     SDL_PumpEvents();
 }
@@ -108,7 +106,13 @@ SDL_GLContext UIKit_GL_CreateContext(_THIS, SDL_Window * window)
     UIWindow *uiwindow = data->uiwindow;
 
     /* construct our view, passing in SDL's OpenGL configuration data */
-    view = [[SDL_uikitopenglview alloc] initWithFrame: [uiwindow bounds]
+    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
@@ -128,11 +132,14 @@ SDL_GLContext UIKit_GL_CreateContext(_THIS, SDL_Window * window)
         [view->viewcontroller setView:view];
         [view->viewcontroller retain];
     }
+    [uiwindow addSubview: view];
+    
+    // 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;
+    }
 
-    /* add the view to our window */
-    [uiwindow addSubview: view ];
-
-    if ( UIKit_GL_MakeCurrent(_this, window, view) < 0 ) {
+    if (UIKit_GL_MakeCurrent(_this, window, view) < 0) {
         UIKit_GL_DeleteContext(_this, view);
         return NULL;
     }
@@ -151,6 +158,10 @@ void UIKit_GL_DeleteContext(_THIS, SDL_GLContext context)
     /* the delegate has retained the view, this will release him */
     SDL_uikitopenglview *view = (SDL_uikitopenglview *)context;
     if (view->viewcontroller) {
+        UIWindow *uiwindow = (UIWindow *)view.superview;
+        if (uiwindow.rootViewController == view->viewcontroller) {
+            uiwindow.rootViewController = nil;
+        }
         [view->viewcontroller setView:nil];
         [view->viewcontroller release];
     }

+ 14 - 0
ThirdParty/SDL/src/video/uikit/SDL_uikitopenglview.h

@@ -46,6 +46,11 @@
 
     /* format of depthRenderbuffer */
     GLenum depthBufferFormat;
+
+    id displayLink;
+    int animationInterval;
+    void (*animationCallback)(void*);
+    void *animationCallbackParam;
 }
 
 @property (nonatomic, retain, readonly) EAGLContext *context;
@@ -66,6 +71,15 @@
 
 - (void)updateFrame;
 
+- (void)setAnimationCallback:(int)interval
+    callback:(void (*)(void*))callback
+    callbackParam:(void*)callbackParam;
+
+- (void)startAnimation;
+- (void)stopAnimation;
+
+- (void)doLoop:(id)sender;
+
 @end
 
 /* vi: set ts=4 sw=4 expandtab: */

+ 38 - 1
ThirdParty/SDL/src/video/uikit/SDL_uikitopenglview.m

@@ -121,7 +121,8 @@
         }
         /* end create buffers */
 
-        self.autoresizingMask = 0;  // don't allow autoresize, since we need to do some magic in -(void)updateFrame.
+        self.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
+        self.autoresizesSubviews = YES;
     }
     return self;
 }
@@ -147,6 +148,41 @@
     }
 }
 
+- (void)setAnimationCallback:(int)interval
+    callback:(void (*)(void*))callback
+    callbackParam:(void*)callbackParam
+{
+    [self stopAnimation];
+
+    animationInterval = interval;
+    animationCallback = callback;
+    animationCallbackParam = callbackParam;
+
+    if (animationCallback)
+        [self startAnimation];
+}
+
+- (void)startAnimation
+{
+    // CADisplayLink is API new to iPhone SDK 3.1. Compiling against earlier versions will result in a warning, but can be dismissed
+    // if the system version runtime check for CADisplayLink exists in -initWithCoder:. 
+    
+    displayLink = [NSClassFromString(@"CADisplayLink") displayLinkWithTarget:self selector:@selector(doLoop:)];
+    [displayLink setFrameInterval:animationInterval];
+    [displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
+}
+
+- (void)stopAnimation
+{
+    [displayLink invalidate];
+    displayLink = nil;
+}
+
+- (void)doLoop:(id)sender
+{
+    animationCallback(animationCallbackParam);
+}
+
 - (void)setCurrentContext
 {
     [EAGLContext setCurrentContext:context];
@@ -163,6 +199,7 @@
 - (void)layoutSubviews
 {
     [EAGLContext setCurrentContext:context];
+    [self updateFrame];
 }
 
 - (void)destroyFramebuffer

+ 12 - 13
ThirdParty/SDL/src/video/uikit/SDL_uikitvideo.h

@@ -23,23 +23,22 @@
 
 #include <UIKit/UIKit.h>
 
-extern BOOL SDL_UIKit_supports_multiple_displays;
+#include "../SDL_sysvideo.h"
 
-typedef struct SDL_DisplayData SDL_DisplayData;
-
-struct SDL_DisplayData
+#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
 {
-    UIScreen *uiscreen;
-    CGFloat scale;
+    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
 
-typedef struct SDL_DisplayModeData SDL_DisplayModeData;
-
-struct SDL_DisplayModeData
-{
-    UIScreenMode *uiscreenmode;
-    CGFloat scale;
-};
 
 #endif /* _SDL_uikitvideo_h */
 

+ 10 - 261
ThirdParty/SDL/src/video/uikit/SDL_uikitvideo.m

@@ -18,6 +18,9 @@
      misrepresented as being the original software.
   3. This notice may not be removed or altered from any source distribution.
 */
+
+// Modified by Lasse Oorni for Urho3D
+
 #include "SDL_config.h"
 
 #if SDL_VIDEO_DRIVER_UIKIT
@@ -32,22 +35,16 @@
 
 #include "SDL_uikitvideo.h"
 #include "SDL_uikitevents.h"
+#include "SDL_uikitmodes.h"
 #include "SDL_uikitwindow.h"
 #include "SDL_uikitopengles.h"
 
-#include "SDL_assert.h"
-
 #define UIKITVID_DRIVER_NAME "uikit"
 
 /* Initialization/Query functions */
 static int UIKit_VideoInit(_THIS);
-static void UIKit_GetDisplayModes(_THIS, SDL_VideoDisplay * sdl_display);
-static int UIKit_SetDisplayMode(_THIS, SDL_VideoDisplay * display,
-                                SDL_DisplayMode * mode);
 static void UIKit_VideoQuit(_THIS);
 
-BOOL SDL_UIKit_supports_multiple_displays = NO;
-
 /* DUMMY driver bootstrap functions */
 
 static int
@@ -83,10 +80,14 @@ UIKit_CreateDevice(int devindex)
     device->SetDisplayMode = UIKit_SetDisplayMode;
     device->PumpEvents = UIKit_PumpEvents;
     device->CreateWindow = UIKit_CreateWindow;
+    device->ShowWindow = UIKit_ShowWindow;
+    device->HideWindow = UIKit_HideWindow;
+    device->RaiseWindow = UIKit_RaiseWindow;
     device->SetWindowFullscreen = UIKit_SetWindowFullscreen;
     device->DestroyWindow = UIKit_DestroyWindow;
     device->GetWindowWMInfo = UIKit_GetWindowWMInfo;
 
+    /* !!! FIXME: implement SetWindowBordered */
 
     /* OpenGL (ES) functions */
     device->GL_MakeCurrent        = UIKit_GL_MakeCurrent;
@@ -108,273 +109,21 @@ VideoBootStrap UIKIT_bootstrap = {
 };
 
 
-/*
-!!! FIXME:
-
-The main screen should list a AxB mode for portrait orientation, and then
- also list BxA for landscape mode. When setting a given resolution, we should
- rotate the view's transform appropriately (extra credit if you check the
- accelerometer and rotate the display so it's never upside down).
-
-  http://iphonedevelopment.blogspot.com/2008/10/starting-in-landscape-mode-without.html
-
-*/
-
-static int
-UIKit_AllocateDisplayModeData(SDL_DisplayMode * mode,
-    UIScreenMode * uiscreenmode, CGFloat scale)
-{
-    SDL_DisplayModeData *data = NULL;
-    
-    if (uiscreenmode != nil) {
-        /* Allocate the display mode data */
-        data = (SDL_DisplayModeData *) SDL_malloc(sizeof(*data));
-        if (!data) {
-            SDL_OutOfMemory();
-            return -1;
-        }
-        
-        data->uiscreenmode = uiscreenmode;
-        [data->uiscreenmode retain];
-        
-        data->scale = scale;
-    }
-    
-    mode->driverdata = data;
-    
-    return 0;
-}
-
-static void
-UIKit_FreeDisplayModeData(SDL_DisplayMode * mode)
-{
-    if (!SDL_UIKit_supports_multiple_displays) {
-        // Not on at least iPhoneOS 3.2 (versions prior to iPad).
-        SDL_assert(mode->driverdata == NULL);
-    } else if (mode->driverdata != NULL) {
-        SDL_DisplayModeData *data = (SDL_DisplayModeData *)mode->driverdata;
-        [data->uiscreenmode release];
-        SDL_free(data);
-        mode->driverdata = NULL;
-    }
-}
-
-static int
-UIKit_AddSingleDisplayMode(SDL_VideoDisplay * display, int w, int h,
-    UIScreenMode * uiscreenmode, CGFloat scale)
-{
-    SDL_DisplayMode mode;
-    SDL_zero(mode);
-    
-    mode.format = SDL_PIXELFORMAT_ABGR8888;
-    mode.refresh_rate = 0;
-    if (UIKit_AllocateDisplayModeData(&mode, uiscreenmode, scale) < 0) {
-        return -1;
-    }
-    
-    mode.w = w;
-    mode.h = h;
-    if (SDL_AddDisplayMode(display, &mode)) {
-        return 0;
-    }
-    
-    // Failure case; free resources
-    SDL_DisplayModeData *data = (SDL_DisplayModeData *) mode.driverdata;
-    
-    if (data != NULL) {
-        [data->uiscreenmode release];
-        SDL_free(data);
-    }
-
-    return -1;
-}
-
-static int
-UIKit_AddDisplayMode(SDL_VideoDisplay * display, int w, int h, CGFloat scale,
-                     UIScreenMode * uiscreenmode, BOOL rotated)
-{
-    if (UIKit_AddSingleDisplayMode(display, w, h, uiscreenmode, scale) < 0) {
-        return -1;
-    }
-    
-    if (rotated) {
-        // Add the rotated version
-        if (UIKit_AddSingleDisplayMode(display, h, w, uiscreenmode, scale) < 0) {
-            return -1;
-        }
-    }
-    
-    return 0;
-}
-
-static void
-UIKit_GetDisplayModes(_THIS, SDL_VideoDisplay * display)
-{
-    SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata;
-
-    if (SDL_UIKit_supports_multiple_displays) {
-        // availableModes showed up in 3.2 (the iPad and later). We should only
-        //  land here for at least that version of the OS.
-        for (UIScreenMode *uimode in [data->uiscreen availableModes]) {
-            BOOL mainscreen = (data->uiscreen == [UIScreen mainScreen]);
-            CGSize size = [uimode size];
-            int w = (int)size.width;
-            int h = (int)size.height;
-            
-            // Add the native screen resolution.
-            UIKit_AddDisplayMode(display, w, h, data->scale, uimode, mainscreen);
-            
-            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)(w / data->scale), (int)(h / data->scale),
-                    1.0f, uimode, mainscreen);
-            }
-        }
-    } else {
-        const CGRect rect = [data->uiscreen bounds];
-        UIKit_AddDisplayMode(display,
-            (int)rect.size.width, (int)rect.size.height,
-            1.0f, nil, YES);
-    } 
-}
-
-
-static int
-UIKit_AddDisplay(UIScreen *uiscreen, CGSize size)
-{
-    // When dealing with UIKit all coordinates are specified in terms of
-    // what Apple refers to as points. On earlier devices without the
-    // so called "Retina" display, there is a one to one mapping between
-    // points and pixels. In other cases [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;
-    if ([UIScreen instancesRespondToSelector:@selector(scale)]) {
-        scale = [uiscreen scale]; // iOS >= 4.0
-    } else {
-        scale = 1.0f; // iOS < 4.0
-    }
-	
-    SDL_VideoDisplay display;
-    SDL_DisplayMode mode;
-    SDL_zero(mode);
-    mode.format = SDL_PIXELFORMAT_ABGR8888;
-    mode.w = (int)(size.width * scale);
-    mode.h = (int)(size.height * scale);
-    mode.refresh_rate = 0;
- 
-    UIScreenMode * uiscreenmode = nil;
-    // UIScreenMode showed up in 3.2 (the iPad and later). We're
-    //  misusing this supports_multiple_displays flag here for that.
-    if (SDL_UIKit_supports_multiple_displays) {
-        uiscreenmode = [uiscreen currentMode];
-    }
-    
-    if (UIKit_AllocateDisplayModeData(&mode, uiscreenmode, scale) < 0) {
-        return -1;
-    }
-
-    SDL_zero(display);
-    display.desktop_mode = mode;
-    display.current_mode = mode;
-
-    /* Allocate the display data */
-    SDL_DisplayData *data = (SDL_DisplayData *) SDL_malloc(sizeof(*data));
-    if (!data) {
-        SDL_OutOfMemory();
-        UIKit_FreeDisplayModeData(&display.desktop_mode);
-        return -1;
-    }
-	
-    [uiscreen retain];
-    data->uiscreen = uiscreen;
-    data->scale = scale;
-	
-    display.driverdata = data;
-    SDL_AddVideoDisplay(&display);
-    
-    return 0;
-}
-
-
 int
 UIKit_VideoInit(_THIS)
 {
     _this->gl_config.driver_loaded = 1;
 
-    // this tells us whether we are running on ios >= 3.2
-    SDL_UIKit_supports_multiple_displays = [UIScreen instancesRespondToSelector:@selector(currentMode)];
-
-    // Add the main screen.
-    UIScreen *uiscreen = [UIScreen mainScreen];
-    const CGSize size = [uiscreen bounds].size;
-
-    if (UIKit_AddDisplay(uiscreen, size) < 0) {
+    if (UIKit_InitModes(_this) < 0) {
         return -1;
     }
-
-    // If this is iPhoneOS < 3.2, all devices are one screen, 320x480 pixels.
-    //  The iPad added both a larger main screen and the ability to use
-    //  external displays. So, add the other displays (screens in UI speak).
-    if (SDL_UIKit_supports_multiple_displays) {
-        for (UIScreen *uiscreen in [UIScreen screens]) {
-            // Only add the other screens
-            if (uiscreen != [UIScreen mainScreen]) {
-                const CGSize size = [uiscreen bounds].size;
-                if (UIKit_AddDisplay(uiscreen, size) < 0) {
-                    return -1;
-                }
-            }
-        }
-    }
-
-    /* We're done! */
-    return 0;
-}
-
-static int
-UIKit_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
-{
-    SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata;
-    if (!SDL_UIKit_supports_multiple_displays) {
-        // Not on at least iPhoneOS 3.2 (versions prior to iPad).
-        SDL_assert(mode->driverdata == NULL);
-    } else {
-        SDL_DisplayModeData *modedata = (SDL_DisplayModeData *)mode->driverdata;
-        [data->uiscreen setCurrentMode:modedata->uiscreenmode];
-
-        CGSize size = [modedata->uiscreenmode size];
-        if (size.width >= size.height) {
-            [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight animated:NO];
-        } else {
-            [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait animated:NO];
-        }
-    }
-
     return 0;
 }
 
 void
 UIKit_VideoQuit(_THIS)
 {
-    // Release Objective-C objects, so higher level doesn't free() them.
-    int i, j;
-    for (i = 0; i < _this->num_displays; i++) {
-        SDL_VideoDisplay *display = &_this->displays[i];
-        SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata;
-        [data->uiscreen release];
-        SDL_free(data);
-        display->driverdata = NULL;
-        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_QuitModes(_this);
 }
 
 #endif /* SDL_VIDEO_DRIVER_UIKIT */

+ 12 - 5
ThirdParty/SDL/src/video/uikit/SDL_uikitview.h

@@ -22,8 +22,9 @@
 #import <UIKit/UIKit.h>
 #import "SDL_uikitviewcontroller.h"
 
+#include "SDL_touch.h"
+
 #define IPHONE_TOUCH_EFFICIENT_DANGEROUS
-#define FIXED_MULTITOUCH
 
 #ifndef IPHONE_TOUCH_EFFICIENT_DANGEROUS
 #define MAX_SIMULTANEOUS_TOUCHES 5
@@ -35,12 +36,11 @@
 @interface SDL_uikitview : UIView {
 #endif
 
-#ifdef FIXED_MULTITOUCH
-    long touchId;
+    SDL_TouchID touchId;
+    SDL_FingerID leftFingerDown;
 #ifndef IPHONE_TOUCH_EFFICIENT_DANGEROUS
     UITouch *finger[MAX_SIMULTANEOUS_TOUCHES];
 #endif
-#endif
 
 #if SDL_IPHONE_KEYBOARD
     UITextField *textField;
@@ -50,7 +50,7 @@
 @public
     SDL_uikitviewcontroller *viewcontroller;
 }
-- (CGPoint)touchLocation:(UITouch *)touch;
+- (CGPoint)touchLocation:(UITouch *)touch shouldNormalize:(BOOL)normalize;
 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
 - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
 - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
@@ -60,6 +60,13 @@
 - (void)hideKeyboard;
 - (void)initializeKeyboard;
 @property (readonly) BOOL keyboardVisible;
+
+SDL_bool UIKit_HasScreenKeyboardSupport(_THIS, SDL_Window *window);
+int UIKit_ShowScreenKeyboard(_THIS, SDL_Window *window);
+int UIKit_HideScreenKeyboard(_THIS, SDL_Window *window);
+int UIKit_ToggleScreenKeyboard(_THIS, SDL_Window *window);
+SDL_bool UIKit_IsScreenKeyboardShown(_THIS, SDL_Window *window);
+
 #endif
 
 @end

+ 63 - 87
ThirdParty/SDL/src/video/uikit/SDL_uikitview.m

@@ -25,17 +25,17 @@
 
 #if SDL_VIDEO_DRIVER_UIKIT
 
-#import "SDL_uikitview.h"
+#include "SDL_uikitview.h"
 
 #include "../../events/SDL_keyboard_c.h"
 #include "../../events/SDL_mouse_c.h"
 #include "../../events/SDL_touch_c.h"
 
 #if SDL_IPHONE_KEYBOARD
-#import "keyinfotable.h"
-#import "SDL_uikitappdelegate.h"
-#import "SDL_uikitkeyboard.h"
-#import "SDL_uikitwindow.h"
+#include "keyinfotable.h"
+#include "SDL_uikitappdelegate.h"
+#include "SDL_uikitmodes.h"
+#include "SDL_uikitwindow.h"
 #endif
 
 @implementation SDL_uikitview
@@ -53,7 +53,6 @@
     [self initializeKeyboard];
 #endif
 
-#ifdef FIXED_MULTITOUCH
     self.multipleTouchEnabled = YES;
 
     SDL_Touch touch;
@@ -72,22 +71,29 @@
     touch.pressure_max = 1;
     touch.native_pressureres = touch.pressure_max - touch.pressure_min;
 
-
     touchId = SDL_AddTouch(&touch, "IPHONE SCREEN");
-#endif
 
     return self;
 
 }
 
-- (CGPoint)touchLocation:(UITouch *)touch
+- (CGPoint)touchLocation:(UITouch *)touch shouldNormalize:(BOOL)normalize
 {
     CGPoint point = [touch locationInView: self];
-    CGRect frame = [self frame];
 
-    frame = CGRectApplyAffineTransform(frame, [self transform]);
-    point.x /= frame.size.width;
-    point.y /= frame.size.height;
+    // 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) {
+        CGRect bounds = [self bounds];
+        point.x /= bounds.size.width;
+        point.y /= bounds.size.height;
+    } else {
+        point.x *= displaymodedata->scale;
+        point.y *= displaymodedata->scale;
+    }
     return point;
 }
 
@@ -97,25 +103,25 @@
     UITouch *touch = (UITouch*)[enumerator nextObject];
 
     // Urho3D: do not send mouse events for touch to be consistent with Android
-    /*
-    if (touch) {
-        CGPoint locationInView = [touch locationInView: self];
+    while (touch) {
+        if (!leftFingerDown) {
+            CGPoint locationInView = [self touchLocation:touch shouldNormalize:NO];
 
-        SDL_SendMouseMotion(NULL, 0, locationInView.x, locationInView.y);
+            /* send moved event */
+            //SDL_SendMouseMotion(NULL, 0, locationInView.x, locationInView.y);
 
-        SDL_SendMouseButton(NULL, SDL_PRESSED, SDL_BUTTON_LEFT);
-    }
-    */
+            /* send mouse down event */
+            //SDL_SendMouseButton(NULL, SDL_PRESSED, SDL_BUTTON_LEFT);
 
-#ifdef FIXED_MULTITOUCH
-    while(touch) {
-        CGPoint locationInView = [self touchLocation:touch];
+            leftFingerDown = (SDL_FingerID)touch;
+        }
 
+        CGPoint locationInView = [self touchLocation:touch shouldNormalize:YES];
 #ifdef IPHONE_TOUCH_EFFICIENT_DANGEROUS
-        //FIXME: TODO: Using touch as the fingerId is potentially dangerous
-        //It is also much more efficient than storing the UITouch pointer
-        //and comparing it to the incoming event.
-        SDL_SendFingerDown(touchId, (long)touch,
+        // FIXME: TODO: Using touch as the fingerId is potentially dangerous
+        // It is also much more efficient than storing the UITouch pointer
+        // and comparing it to the incoming event.
+        SDL_SendFingerDown(touchId, (SDL_FingerID)touch,
                            SDL_TRUE, locationInView.x, locationInView.y,
                            1);
 #else
@@ -130,10 +136,8 @@
             }
         }
 #endif
-
         touch = (UITouch*)[enumerator nextObject];
     }
-#endif
 }
 
 - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
@@ -141,17 +145,14 @@
     NSEnumerator *enumerator = [touches objectEnumerator];
     UITouch *touch = (UITouch*)[enumerator nextObject];
 
-    // Urho3D: do not send mouse events for touch to be consistent with Android
-    /*
-    if (touch) {
-        SDL_SendMouseButton(NULL, SDL_RELEASED, SDL_BUTTON_LEFT);
-    }
-    */
-
-#ifdef FIXED_MULTITOUCH
     while(touch) {
-        CGPoint locationInView = [self touchLocation:touch];
+        if ((SDL_FingerID)touch == leftFingerDown) {
+            /* send mouse up */
+            //SDL_SendMouseButton(NULL, SDL_RELEASED, SDL_BUTTON_LEFT);
+            leftFingerDown = 0;
+        }
 
+        CGPoint locationInView = [self touchLocation:touch shouldNormalize:YES];
 #ifdef IPHONE_TOUCH_EFFICIENT_DANGEROUS
         SDL_SendFingerDown(touchId, (long)touch,
                            SDL_FALSE, locationInView.x, locationInView.y,
@@ -168,10 +169,8 @@
             }
         }
 #endif
-
         touch = (UITouch*)[enumerator nextObject];
     }
-#endif
 }
 
 - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
@@ -189,19 +188,15 @@
     NSEnumerator *enumerator = [touches objectEnumerator];
     UITouch *touch = (UITouch*)[enumerator nextObject];
 
-    // Urho3D: do not send mouse events for touch to be consistent with Android
-    /*
-    if (touch) {
-        CGPoint locationInView = [touch locationInView: self];
-
-        SDL_SendMouseMotion(NULL, 0, locationInView.x, locationInView.y);
-    }
-    */
+    while (touch) {
+        if ((SDL_FingerID)touch == leftFingerDown) {
+            CGPoint locationInView = [self touchLocation:touch shouldNormalize:NO];
 
-#ifdef FIXED_MULTITOUCH
-    while(touch) {
-        CGPoint locationInView = [self touchLocation:touch];
+            /* send moved event */
+            //SDL_SendMouseMotion(NULL, 0, locationInView.x, locationInView.y);
+        }
 
+        CGPoint locationInView = [self touchLocation:touch shouldNormalize:YES];
 #ifdef IPHONE_TOUCH_EFFICIENT_DANGEROUS
         SDL_SendTouchMotion(touchId, (long)touch,
                             SDL_FALSE, locationInView.x, locationInView.y,
@@ -217,10 +212,8 @@
             }
         }
 #endif
-
         touch = (UITouch*)[enumerator nextObject];
     }
-#endif
 }
 
 /*
@@ -352,7 +345,17 @@ static SDL_uikitview * getWindowView(SDL_Window * window)
     return view;
 }
 
-int SDL_iPhoneKeyboardShow(SDL_Window * window)
+SDL_bool UIKit_HasScreenKeyboardSupport(_THIS, SDL_Window *window)
+{
+    SDL_uikitview *view = getWindowView(window);
+    if (view == nil) {
+        return SDL_FALSE;
+    }
+
+    return SDL_TRUE;
+}
+
+int UIKit_ShowScreenKeyboard(_THIS, SDL_Window *window)
 {
     SDL_uikitview *view = getWindowView(window);
     if (view == nil) {
@@ -363,7 +366,7 @@ int SDL_iPhoneKeyboardShow(SDL_Window * window)
     return 0;
 }
 
-int SDL_iPhoneKeyboardHide(SDL_Window * window)
+int UIKit_HideScreenKeyboard(_THIS, SDL_Window *window)
 {
     SDL_uikitview *view = getWindowView(window);
     if (view == nil) {
@@ -374,7 +377,7 @@ int SDL_iPhoneKeyboardHide(SDL_Window * window)
     return 0;
 }
 
-SDL_bool SDL_iPhoneKeyboardIsShown(SDL_Window * window)
+SDL_bool UIKit_IsScreenKeyboardShown(_THIS, SDL_Window *window)
 {
     SDL_uikitview *view = getWindowView(window);
     if (view == nil) {
@@ -384,49 +387,22 @@ SDL_bool SDL_iPhoneKeyboardIsShown(SDL_Window * window)
     return view.keyboardVisible;
 }
 
-int SDL_iPhoneKeyboardToggle(SDL_Window * window)
+int UIKit_ToggleScreenKeyboard(_THIS, SDL_Window *window)
 {
     SDL_uikitview *view = getWindowView(window);
     if (view == nil) {
         return -1;
     }
 
-    if (SDL_iPhoneKeyboardIsShown(window)) {
-        SDL_iPhoneKeyboardHide(window);
+    if (UIKit_IsScreenKeyboardShown(_this, window)) {
+        UIKit_HideScreenKeyboard(_this, window);
     }
     else {
-        SDL_iPhoneKeyboardShow(window);
+        UIKit_ShowScreenKeyboard(_this, window);
     }
     return 0;
 }
 
-#else
-
-/* stubs, used if compiled without keyboard support */
-
-int SDL_iPhoneKeyboardShow(SDL_Window * window)
-{
-    SDL_SetError("Not compiled with keyboard support");
-    return -1;
-}
-
-int SDL_iPhoneKeyboardHide(SDL_Window * window)
-{
-    SDL_SetError("Not compiled with keyboard support");
-    return -1;
-}
-
-SDL_bool SDL_iPhoneKeyboardIsShown(SDL_Window * window)
-{
-    return 0;
-}
-
-int SDL_iPhoneKeyboardToggle(SDL_Window * window)
-{
-    SDL_SetError("Not compiled with keyboard support");
-    return -1;
-}
-
 #endif /* SDL_IPHONE_KEYBOARD */
 
 #endif /* SDL_VIDEO_DRIVER_UIKIT */

+ 3 - 2
ThirdParty/SDL/src/video/uikit/SDL_uikitviewcontroller.h

@@ -31,8 +31,9 @@
 @property (readwrite) SDL_Window *window;
 
 - (id)initWithSDLWindow:(SDL_Window *)_window;
-- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)orient;
 - (void)loadView;
-- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation;
+- (void)viewDidLayoutSubviews;
+- (NSUInteger)supportedInterfaceOrientations;
+- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)orient;
 
 @end

+ 62 - 99
ThirdParty/SDL/src/video/uikit/SDL_uikitviewcontroller.m

@@ -28,9 +28,11 @@
 #include "../SDL_sysvideo.h"
 #include "../../events/SDL_events_c.h"
 
-#include "SDL_uikitwindow.h"
 #include "SDL_uikitviewcontroller.h"
 #include "SDL_uikitvideo.h"
+#include "SDL_uikitmodes.h"
+#include "SDL_uikitwindow.h"
+
 
 @implementation SDL_uikitviewcontroller
 
@@ -43,11 +45,35 @@
         return nil;
     }
     self.window = _window;
+
     return self;
 }
 
-- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)orient
+- (void)loadView
 {
+    // do nothing.
+}
+
+- (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);
+        
+        SDL_SendWindowEvent(self->window, SDL_WINDOWEVENT_RESIZED, w, h);
+    }
+}
+
+- (NSUInteger)supportedInterfaceOrientations
+{
+    NSUInteger orientationMask = 0;
+    
     const char *orientationsCString;
     if ((orientationsCString = SDL_GetHint(SDL_HINT_ORIENTATIONS)) != NULL) {
         BOOL rotate = NO;
@@ -55,109 +81,46 @@
                                                             encoding:NSUTF8StringEncoding];
         NSArray *orientations = [orientationsNSString componentsSeparatedByCharactersInSet:
                                  [NSCharacterSet characterSetWithCharactersInString:@" "]];
-
-        switch (orient) {
-            case UIInterfaceOrientationLandscapeLeft:
-                rotate = [orientations containsObject:@"LandscapeLeft"];
-                break;
-
-            case UIInterfaceOrientationLandscapeRight:
-                rotate = [orientations containsObject:@"LandscapeRight"];
-                break;
-
-            case UIInterfaceOrientationPortrait:
-                rotate = [orientations containsObject:@"Portrait"];
-                break;
-
-            case UIInterfaceOrientationPortraitUpsideDown:
-                rotate = [orientations containsObject:@"PortraitUpsideDown"];
-                break;
-
-            default: break;
+        
+        if ([orientations containsObject:@"LandscapeLeft"]) {
+            orientationMask |= UIInterfaceOrientationMaskLandscapeLeft;
+        }
+        if ([orientations containsObject:@"LandscapeRight"]) {
+            orientationMask |= UIInterfaceOrientationMaskLandscapeRight;
+        }
+        if ([orientations containsObject:@"Portrait"]) {
+            orientationMask |= UIInterfaceOrientationMaskPortrait;
+        }
+        if ([orientations containsObject:@"PortraitUpsideDown"]) {
+            orientationMask |= UIInterfaceOrientationMaskPortraitUpsideDown;
+        }
+        
+    } else if (self->window->flags & SDL_WINDOW_RESIZABLE) {
+        orientationMask = UIInterfaceOrientationMaskAll;  // any orientation is okay.
+    } else {
+        if (self->window->w >= self->window->h) {
+            orientationMask |= UIInterfaceOrientationMaskLandscape;
+        }
+        if (self->window->h >= self->window->w) {
+            orientationMask |= (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown);
         }
-
-        return rotate;
-    }
-
-    if (self->window->flags & SDL_WINDOW_RESIZABLE) {
-        return YES;  // any orientation is okay.
     }
-
-    // If not resizable, allow device to orient to other matching sizes
-    //  (that is, let the user turn the device upside down...same screen
-    //   dimensions, but it lets the user place the device where it's most
-    //   comfortable in relation to its physical buttons, headphone jack, etc).
-    switch (orient) {
-        case UIInterfaceOrientationLandscapeLeft:
-        case UIInterfaceOrientationLandscapeRight:
-            return (self->window->w >= self->window->h);
-
-        case UIInterfaceOrientationPortrait:
-        case UIInterfaceOrientationPortraitUpsideDown:
-            return (self->window->h >= self->window->w);
-
-        default: break;
+    
+    // Don't allow upside-down orientation on the phone, so answering calls is in the natural orientation
+    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
+        orientationMask &= ~UIInterfaceOrientationMaskPortraitUpsideDown;
     }
-
-    return NO;  // Nothing else is acceptable.
+    return orientationMask;
 }
 
-- (void)loadView
+- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)orient
 {
-    // do nothing.
+    NSUInteger orientationMask = [self supportedInterfaceOrientations];
+    return (orientationMask & (1 << orient));
 }
 
-// Send a resized event when the orientation changes.
-- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
-{
-    const UIInterfaceOrientation toInterfaceOrientation = [self interfaceOrientation];
-    SDL_WindowData *data = self->window->driverdata;
-    UIWindow *uiwindow = data->uiwindow;
-    SDL_VideoDisplay *display = SDL_GetDisplayForWindow(self->window);
-    SDL_DisplayData *displaydata = (SDL_DisplayData *) display->driverdata;
-    SDL_DisplayModeData *displaymodedata = (SDL_DisplayModeData *) display->current_mode.driverdata;
-    UIScreen *uiscreen = displaydata->uiscreen;
-    const int noborder = (self->window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_BORDERLESS));
-    CGRect frame = noborder ? [uiscreen bounds] : [uiscreen applicationFrame];
-    const CGSize size = frame.size;
-    int w, h;
-    SDL_Event event;
-    event.type=SDL_SYSEVENT_ORIENTATION_CHANGED;
-    event.sysevent.data=NULL;
-
-    switch (toInterfaceOrientation) {
-        case UIInterfaceOrientationPortrait:
-        case UIInterfaceOrientationPortraitUpsideDown:
-            w = (size.width < size.height) ? size.width : size.height;
-            h = (size.width > size.height) ? size.width : size.height;
-            event.sysevent.data=(void*)SDL_ORIENTATION_PORTRAIT;
-            break;
-
-        case UIInterfaceOrientationLandscapeLeft:
-        case UIInterfaceOrientationLandscapeRight:
-            w = (size.width > size.height) ? size.width : size.height;
-            h = (size.width < size.height) ? size.width : size.height;
-            event.sysevent.data=(void*)SDL_ORIENTATION_LANDSCAPE;
-            break;
-
-        default:
-            SDL_assert(0 && "Unexpected interface orientation!");
-            return;
-    }
-
-    if (SDL_SysEventHandler)
-        SDL_SysEventHandler(&event);
-
-    w = (int)(w * displaymodedata->scale);
-    h = (int)(h * displaymodedata->scale);
-
-    [uiwindow setFrame:frame];
-    [data->view setFrame:frame];
-    [data->view updateFrame];
-    if (SDL_SysEventHandler)
-        SDL_SysEventHandler(&event);
-    else SDL_SendWindowEvent(self->window, SDL_WINDOWEVENT_RESIZED, w, h);
-}
-
-#endif /* SDL_VIDEO_DRIVER_UIKIT */
 @end
+
+#endif /* SDL_VIDEO_DRIVER_UIKIT */
+
+/* vi: set ts=4 sw=4 expandtab: */

+ 3 - 0
ThirdParty/SDL/src/video/uikit/SDL_uikitwindow.h

@@ -29,6 +29,9 @@
 typedef struct SDL_WindowData SDL_WindowData;
 
 extern int UIKit_CreateWindow(_THIS, SDL_Window * window);
+extern void UIKit_ShowWindow(_THIS, SDL_Window * window);
+extern void UIKit_HideWindow(_THIS, SDL_Window * window);
+extern void UIKit_RaiseWindow(_THIS, SDL_Window * window);
 extern void UIKit_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen);
 extern void UIKit_DestroyWindow(_THIS, SDL_Window * window);
 extern SDL_bool UIKit_GetWindowWMInfo(_THIS, SDL_Window * window,

+ 107 - 68
ThirdParty/SDL/src/video/uikit/SDL_uikitwindow.m

@@ -18,9 +18,6 @@
      misrepresented as being the original software.
   3. This notice may not be removed or altered from any source distribution.
 */
-
-// Modified by Lasse Oorni for Urho3D
-
 #include "SDL_config.h"
 
 #if SDL_VIDEO_DRIVER_UIKIT
@@ -36,6 +33,7 @@
 
 #include "SDL_uikitvideo.h"
 #include "SDL_uikitevents.h"
+#include "SDL_uikitmodes.h"
 #include "SDL_uikitwindow.h"
 #import "SDL_uikitappdelegate.h"
 
@@ -68,70 +66,58 @@ static int SetupWindowData(_THIS, SDL_Window *window, UIWindow *uiwindow, SDL_bo
         window->x = 0;
         window->y = 0;
 
-        /* Get frame dimensions in pixels */
-        int width = (int)(uiwindow.frame.size.width * displaymodedata->scale);
-        int height = (int)(uiwindow.frame.size.height * displaymodedata->scale);
-
-        /* 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.
-         */
-        if (window->w >= window->h) {
-            if (uiwindow.frame.size.width > uiwindow.frame.size.height) {
-                window->w = width;
-                window->h = height;
-            } else {
-                window->w = height;
-                window->h = width;
-            }
+        CGRect bounds;
+        if (window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_BORDERLESS)) {
+            bounds = [displaydata->uiscreen bounds];
         } else {
-            if (uiwindow.frame.size.width > uiwindow.frame.size.height) {
-                window->w = height;
-                window->h = width;
-            } else {
-                window->w = width;
-                window->h = height;
-            }
+            bounds = [displaydata->uiscreen applicationFrame];
+        }
+
+        /* Get frame dimensions in pixels */
+        int width = (int)(bounds.size.width * displaymodedata->scale);
+        int height = (int)(bounds.size.height * displaymodedata->scale);
+
+        // Make sure the width/height are oriented correctly
+        if (UIKit_IsDisplayLandscape(displaydata->uiscreen) != (width > height)) {
+            int temp = width;
+            width = height;
+            height = temp;
         }
+
+        window->w = width;
+        window->h = height;
     }
 
     window->driverdata = data;
 
     /* only one window on iOS, always shown */
     window->flags &= ~SDL_WINDOW_HIDDEN;
-    window->flags |= SDL_WINDOW_SHOWN;
 
     // SDL_WINDOW_BORDERLESS controls whether status bar is hidden.
     // This is only set if the window is on the main screen. Other screens
     //  just force the window to have the borderless flag.
-    if ([UIScreen mainScreen] != displaydata->uiscreen) {
-        window->flags &= ~SDL_WINDOW_RESIZABLE;  // window is NEVER resizeable
-        window->flags &= ~SDL_WINDOW_INPUT_FOCUS;  // never has input focus
-        window->flags |= SDL_WINDOW_BORDERLESS;  // never has a status bar.
-    } else {
+    if (displaydata->uiscreen == [UIScreen mainScreen]) {
         window->flags |= SDL_WINDOW_INPUT_FOCUS;  // always has input focus
-
-        if (window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_BORDERLESS)) {
-            [UIApplication sharedApplication].statusBarHidden = YES;
+        
+        if ([UIApplication sharedApplication].statusBarHidden) {
+            window->flags |= SDL_WINDOW_BORDERLESS;
         } else {
-            [UIApplication sharedApplication].statusBarHidden = NO;
+            window->flags &= ~SDL_WINDOW_BORDERLESS;
         }
-
-        //const UIDeviceOrientation o = [[UIDevice currentDevice] orientation];
-        //const BOOL landscape = (o == UIDeviceOrientationLandscapeLeft) ||
-        //                           (o == UIDeviceOrientationLandscapeRight);
-        //const BOOL rotate = ( ((window->w > window->h) && (!landscape)) ||
-        //                      ((window->w < window->h) && (landscape)) );
-
-        // The View Controller will handle rotating the view when the
-        //  device orientation changes. This will trigger resize events, if
-        //  appropriate.
-        SDL_uikitviewcontroller *controller;
-        controller = [SDL_uikitviewcontroller alloc];
-        data->viewcontroller = [controller initWithSDLWindow:window];
-        [data->viewcontroller setTitle:@"SDL App"];  // !!! FIXME: hook up SDL_SetWindowTitle()
-        // !!! FIXME: if (rotate), force a "resize" right at the start
+    } else {
+        window->flags &= ~SDL_WINDOW_RESIZABLE;  // window is NEVER resizeable
+        window->flags &= ~SDL_WINDOW_INPUT_FOCUS;  // never has input focus
+        window->flags |= SDL_WINDOW_BORDERLESS;  // never has a status bar.
     }
 
+    // The View Controller will handle rotating the view when the
+    //  device orientation changes. This will trigger resize events, if
+    //  appropriate.
+    SDL_uikitviewcontroller *controller;
+    controller = [SDL_uikitviewcontroller alloc];
+    data->viewcontroller = [controller initWithSDLWindow:window];
+    [data->viewcontroller setTitle:@"SDL App"];  // !!! FIXME: hook up SDL_SetWindowTitle()
+
     return 0;
 }
 
@@ -151,13 +137,6 @@ UIKit_CreateWindow(_THIS, SDL_Window *window)
         return -1;
     }
 
-    // Non-mainscreen windows must be force to borderless, as there's no
-    //  status bar there, and we want to get the right dimensions later in
-    //  this function.
-    if (external) {
-        window->flags |= SDL_WINDOW_BORDERLESS;
-    }
-
     // 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.
@@ -187,14 +166,31 @@ UIKit_CreateWindow(_THIS, SDL_Window *window)
             }
         }
     }
+    
+    if (data->uiscreen == [UIScreen mainScreen]) {
+        if (window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_BORDERLESS)) {
+            [UIApplication sharedApplication].statusBarHidden = YES;
+        } else {
+            [UIApplication sharedApplication].statusBarHidden = 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];
-    if (window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_BORDERLESS))
-        uiwindow = [uiwindow initWithFrame:[data->uiscreen bounds]];
-    else
-        uiwindow = [uiwindow initWithFrame:[data->uiscreen applicationFrame]];
+    uiwindow = [uiwindow 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
@@ -209,10 +205,34 @@ UIKit_CreateWindow(_THIS, SDL_Window *window)
         return -1;
     }
 
+    return 1;
+
+}
+
+void
+UIKit_ShowWindow(_THIS, SDL_Window * window)
+{
+    UIWindow *uiwindow = ((SDL_WindowData *) window->driverdata)->uiwindow;
+
     [uiwindow makeKeyAndVisible];
+}
 
-    return 1;
+void
+UIKit_HideWindow(_THIS, SDL_Window * window)
+{
+    UIWindow *uiwindow = ((SDL_WindowData *) window->driverdata)->uiwindow;
 
+    uiwindow.hidden = YES;
+}
+
+void
+UIKit_RaiseWindow(_THIS, SDL_Window * window)
+{
+    // We don't currently offer a concept of "raising" the SDL window, since
+    //  we only allow one per display, in the iOS fashion.
+    // However, we use this entry point to rebind the context to the view
+    //  during OnWindowRestored processing.
+    _this->GL_MakeCurrent(_this, _this->current_glwin, _this->current_glctx);
 }
 
 void
@@ -224,21 +244,26 @@ UIKit_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display
 
     if (fullscreen) {
         [UIApplication sharedApplication].statusBarHidden = YES;
-        uiwindow.frame = [displaydata->uiscreen bounds];
     } else {
         [UIApplication sharedApplication].statusBarHidden = NO;
-        uiwindow.frame = [displaydata->uiscreen applicationFrame];
+    }
+
+    CGRect bounds;
+    if (fullscreen) {
+        bounds = [displaydata->uiscreen bounds];
+    } else {
+        bounds = [displaydata->uiscreen applicationFrame];
     }
 
     /* Get frame dimensions in pixels */
-    int width = (int)(uiwindow.frame.size.width * displaymodedata->scale);
-    int height = (int)(uiwindow.frame.size.height * displaymodedata->scale);
+    int width = (int)(bounds.size.width * displaymodedata->scale);
+    int height = (int)(bounds.size.height * displaymodedata->scale);
 
     /* 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.
      */
     if (window->w >= window->h) {
-        if (uiwindow.frame.size.width > uiwindow.frame.size.height) {
+        if (width > height) {
             window->w = width;
             window->h = height;
         } else {
@@ -246,7 +271,7 @@ UIKit_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display
             window->h = width;
         }
     } else {
-        if (uiwindow.frame.size.width > uiwindow.frame.size.height) {
+        if (width > height) {
             window->w = height;
             window->h = width;
         } else {
@@ -284,6 +309,20 @@ UIKit_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info)
     }
 }
 
+int
+SDL_iPhoneSetAnimationCallback(SDL_Window * window, int interval, void (*callback)(void*), void *callbackParam)
+{
+    SDL_WindowData *data = window ? (SDL_WindowData *)window->driverdata : NULL;
+
+    if (!data || !data->view) {
+        SDL_SetError("Invalid window or view not set");
+        return -1;
+    }
+
+    [data->view setAnimationCallback:interval callback:callback callbackParam:callbackParam];
+    return 0;
+}
+
 #endif /* SDL_VIDEO_DRIVER_UIKIT */
 
 /* vi: set ts=4 sw=4 expandtab: */

+ 0 - 1
Urho3D/CMakeLists.txt

@@ -16,7 +16,6 @@ include_directories (
 if (WIN32)
     add_executable (${TARGET_NAME} WIN32 ${SOURCE_FILES})
 elseif (IOS)
-    set (MACOSX_BUNDLE_INFO_PLIST ${PROJECT_SOURCE_DIR}/iOS/Urho3DPlist.info.in)
     set (RESOURCE_DIR \${TARGET_BUILD_DIR}/\${FULL_PRODUCT_NAME})
     set (CMAKE_EXE_LINKER_FLAGS "-framework AudioToolbox -framework CoreAudio -framework CoreGraphics -framework Foundation -framework OpenGLES -framework QuartzCore -framework UIKit")
     add_executable (${TARGET_NAME} MACOSX_BUNDLE ${SOURCE_FILES})

+ 0 - 36
iOS/Urho3DInfo.plist.in

@@ -1,36 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
-	<key>CFBundleDevelopmentRegion</key>
-	<string>English</string>
-	<key>CFBundleExecutable</key>
-	<string>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string>
-	<key>CFBundleGetInfoString</key>
-	<string>${MACOSX_BUNDLE_INFO_STRING}</string>
-	<key>CFBundleIconFile</key>
-	<string>${MACOSX_BUNDLE_ICON_FILE}</string>
-	<key>CFBundleIdentifier</key>
-	<string>${MACOSX_BUNDLE_GUI_IDENTIFIER}</string>
-	<key>CFBundleInfoDictionaryVersion</key>
-	<string>6.0</string>
-	<key>CFBundleLongVersionString</key>
-	<string>${MACOSX_BUNDLE_LONG_VERSION_STRING}</string>
-	<key>CFBundleName</key>
-	<string>${MACOSX_BUNDLE_BUNDLE_NAME}</string>
-	<key>CFBundlePackageType</key>
-	<string>APPL</string>
-	<key>CFBundleShortVersionString</key>
-	<string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string>
-	<key>CFBundleSignature</key>
-	<string>????</string>
-	<key>CFBundleVersion</key>
-	<string>${MACOSX_BUNDLE_BUNDLE_VERSION}</string>
-	<key>CSResourcesFileMapped</key>
-	<true/>
-	<key>LSRequiresCarbon</key>
-	<true/>
-	<key>NSHumanReadableCopyright</key>
-	<string>${MACOSX_BUNDLE_COPYRIGHT}</string>
-</dict>
-</plist>