From 5d0bae47d890180d697eef6cd296ece7806aef30 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sat, 29 Sep 2012 18:52:00 -0700 Subject: [PATCH] Make sure mode width/height and status bar orientation match --- src/video/uikit/SDL_uikitmodes.h | 2 + src/video/uikit/SDL_uikitmodes.m | 74 +++++++++++++++++++++++-------- src/video/uikit/SDL_uikitwindow.m | 62 ++++++++++++++------------ 3 files changed, 91 insertions(+), 47 deletions(-) diff --git a/src/video/uikit/SDL_uikitmodes.h b/src/video/uikit/SDL_uikitmodes.h index f65be0944..4831bac5a 100644 --- a/src/video/uikit/SDL_uikitmodes.h +++ b/src/video/uikit/SDL_uikitmodes.h @@ -39,6 +39,8 @@ typedef struct 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); diff --git a/src/video/uikit/SDL_uikitmodes.m b/src/video/uikit/SDL_uikitmodes.m index aba5006d1..7e1d2cfb2 100644 --- a/src/video/uikit/SDL_uikitmodes.m +++ b/src/video/uikit/SDL_uikitmodes.m @@ -93,13 +93,13 @@ static int UIKit_AddDisplayMode(SDL_VideoDisplay * display, int w, int h, CGFloat scale, - UIScreenMode * uiscreenmode, BOOL addRotated) + UIScreenMode * uiscreenmode, SDL_bool addRotation) { if (UIKit_AddSingleDisplayMode(display, w, h, uiscreenmode, scale) < 0) { return -1; } - if (addRotated) { + if (addRotation) { // Add the rotated version if (UIKit_AddSingleDisplayMode(display, h, w, uiscreenmode, scale) < 0) { return -1; @@ -114,6 +114,13 @@ { 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 @@ -127,7 +134,7 @@ } else { scale = 1.0f; // iOS < 4.0 } - + SDL_VideoDisplay display; SDL_DisplayMode mode; SDL_zero(mode); @@ -168,6 +175,16 @@ 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) @@ -203,6 +220,9 @@ { 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. @@ -210,10 +230,16 @@ CGSize size = [uimode size]; int w = (int)size.width; int h = (int)size.height; - BOOL addRotated = (data->uiscreen == [UIScreen mainScreen]); - + + // 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, addRotated); + UIKit_AddDisplayMode(display, w, h, data->scale, uimode, addRotation); if (data->scale != 1.0f) { // Add the native screen resolution divided by its scale. @@ -222,14 +248,22 @@ UIKit_AddDisplayMode(display, (int)(size.width / data->scale), (int)(size.height / data->scale), - 1.0f, uimode, addRotated); + 1.0f, uimode, addRotation); } } } else { - const CGRect rect = [data->uiscreen bounds]; - UIKit_AddDisplayMode(display, - (int)rect.size.width, (int)rect.size.height, - 1.0f, nil, YES); + 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); } } @@ -237,6 +271,7 @@ 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); @@ -244,15 +279,18 @@ SDL_DisplayModeData *modedata = (SDL_DisplayModeData *)mode->driverdata; [data->uiscreen setCurrentMode:modedata->uiscreenmode]; - if (mode->w > mode->h) { - if (!UIInterfaceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation])) - [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight animated:NO]; - } else if (mode->w < mode->h) { - if (!UIInterfaceOrientationIsPortrait([[UIApplication sharedApplication] statusBarOrientation])) - [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait animated:NO]; + 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; } diff --git a/src/video/uikit/SDL_uikitwindow.m b/src/video/uikit/SDL_uikitwindow.m index a66f915e9..ec0beda01 100644 --- a/src/video/uikit/SDL_uikitwindow.m +++ b/src/video/uikit/SDL_uikitwindow.m @@ -76,32 +76,16 @@ static int SetupWindowData(_THIS, SDL_Window *window, UIWindow *uiwindow, SDL_bo /* Get frame dimensions in pixels */ int width = (int)(bounds.size.width * displaymodedata->scale); int height = (int)(bounds.size.height * displaymodedata->scale); - - if ([UIScreen mainScreen] == displaydata->uiscreen) { - /* 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 (width > height) { - window->w = width; - window->h = height; - } else { - window->w = height; - window->h = width; - } - } else { - if (width > height) { - window->w = height; - window->h = width; - } else { - window->w = width; - window->h = height; - } - } - } else { - window->w = width; - window->h = height; + + // 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; @@ -112,13 +96,13 @@ static int SetupWindowData(_THIS, SDL_Window *window, UIWindow *uiwindow, SDL_bo // 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) { + 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; } } else { window->flags &= ~SDL_WINDOW_RESIZABLE; // window is NEVER resizeable @@ -182,6 +166,26 @@ static int SetupWindowData(_THIS, SDL_Window *window, UIWindow *uiwindow, SDL_bo } } } + + 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?