* On iOS, fix support for the case where [UIScreen scale] is not 1.0 (retina)
authorTim Angus
Wed, 25 Jan 2012 14:29:56 +0000
changeset 6267ed2cf4669e55
parent 6266 a4be1e781020
child 6268 3aa24ec6bc39
* On iOS, fix support for the case where [UIScreen scale] is not 1.0 (retina)
* Allow selection of non-retina modes on retina devices
src/video/uikit/SDL_uikitopengles.m
src/video/uikit/SDL_uikitopenglview.h
src/video/uikit/SDL_uikitopenglview.m
src/video/uikit/SDL_uikitvideo.h
src/video/uikit/SDL_uikitvideo.m
src/video/uikit/SDL_uikitviewcontroller.m
src/video/uikit/SDL_uikitwindow.h
src/video/uikit/SDL_uikitwindow.m
     1.1 --- a/src/video/uikit/SDL_uikitopengles.m	Sun Jan 22 23:51:46 2012 -0500
     1.2 +++ b/src/video/uikit/SDL_uikitopengles.m	Wed Jan 25 14:29:56 2012 +0000
     1.3 @@ -103,10 +103,14 @@
     1.4  {
     1.5      SDL_uikitopenglview *view;
     1.6      SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
     1.7 +    SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
     1.8 +    SDL_DisplayData *displaydata = display->driverdata;
     1.9 +    SDL_DisplayModeData *displaymodedata = display->current_mode.driverdata;
    1.10      UIWindow *uiwindow = data->uiwindow;
    1.11  
    1.12      /* construct our view, passing in SDL's OpenGL configuration data */
    1.13      view = [[SDL_uikitopenglview alloc] initWithFrame: [uiwindow bounds]
    1.14 +                                    scale: displaymodedata->scale
    1.15                                      retainBacking: _this->gl_config.retained_backing
    1.16                                      rBits: _this->gl_config.red_size
    1.17                                      gBits: _this->gl_config.green_size
    1.18 @@ -135,9 +139,10 @@
    1.19      }
    1.20  
    1.21      /* Make this window the current mouse focus for touch input */
    1.22 -    /* !!! FIXME: only do this if this is the primary screen. */
    1.23 -    SDL_SetMouseFocus(window);
    1.24 -    SDL_SetKeyboardFocus(window);
    1.25 +    if (displaydata->uiscreen == [UIScreen mainScreen]) {
    1.26 +        SDL_SetMouseFocus(window);
    1.27 +        SDL_SetKeyboardFocus(window);
    1.28 +    }
    1.29  
    1.30      return view;
    1.31  }
     2.1 --- a/src/video/uikit/SDL_uikitopenglview.h	Sun Jan 22 23:51:46 2012 -0500
     2.2 +++ b/src/video/uikit/SDL_uikitopenglview.h	Wed Jan 25 14:29:56 2012 +0000
     2.3 @@ -54,6 +54,7 @@
     2.4  - (void)setCurrentContext;
     2.5  
     2.6  - (id)initWithFrame:(CGRect)frame
     2.7 +    scale:(CGFloat)scale
     2.8      retainBacking:(BOOL)retained
     2.9      rBits:(int)rBits
    2.10      gBits:(int)gBits
     3.1 --- a/src/video/uikit/SDL_uikitopenglview.m	Sun Jan 22 23:51:46 2012 -0500
     3.2 +++ b/src/video/uikit/SDL_uikitopenglview.m	Wed Jan 25 14:29:56 2012 +0000
     3.3 @@ -37,6 +37,7 @@
     3.4  }
     3.5  
     3.6  - (id)initWithFrame:(CGRect)frame
     3.7 +      scale:(CGFloat)scale
     3.8        retainBacking:(BOOL)retained
     3.9        rBits:(int)rBits
    3.10        gBits:(int)gBits
    3.11 @@ -79,10 +80,9 @@
    3.12              return nil;
    3.13          }
    3.14  
    3.15 -        // !!! FIXME: use the screen this is on!
    3.16 -        /* Use the main screen scale (for retina display support) */
    3.17 +        /* Set the appropriate scale (for retina display support) */
    3.18          if ([self respondsToSelector:@selector(contentScaleFactor)])
    3.19 -            self.contentScaleFactor = [UIScreen mainScreen].scale;
    3.20 +            self.contentScaleFactor = scale;
    3.21  
    3.22          /* create the buffers */
    3.23          glGenFramebuffersOES(1, &viewFramebuffer);
     4.1 --- a/src/video/uikit/SDL_uikitvideo.h	Sun Jan 22 23:51:46 2012 -0500
     4.2 +++ b/src/video/uikit/SDL_uikitvideo.h	Wed Jan 25 14:29:56 2012 +0000
     4.3 @@ -25,6 +25,22 @@
     4.4  
     4.5  extern BOOL SDL_UIKit_supports_multiple_displays;
     4.6  
     4.7 +typedef struct SDL_DisplayData SDL_DisplayData;
     4.8 +
     4.9 +struct SDL_DisplayData
    4.10 +{
    4.11 +    UIScreen *uiscreen;
    4.12 +    CGFloat scale;
    4.13 +};
    4.14 +
    4.15 +typedef struct SDL_DisplayModeData SDL_DisplayModeData;
    4.16 +
    4.17 +struct SDL_DisplayModeData
    4.18 +{
    4.19 +    UIScreenMode *uiscreenmode;
    4.20 +    CGFloat scale;
    4.21 +};
    4.22 +
    4.23  #endif /* _SDL_uikitvideo_h */
    4.24  
    4.25  /* vi: set ts=4 sw=4 expandtab: */
     5.1 --- a/src/video/uikit/SDL_uikitvideo.m	Sun Jan 22 23:51:46 2012 -0500
     5.2 +++ b/src/video/uikit/SDL_uikitvideo.m	Wed Jan 25 14:29:56 2012 +0000
     5.3 @@ -120,79 +120,167 @@
     5.4  
     5.5  */
     5.6  
     5.7 +static int
     5.8 +UIKit_AddSingleDisplayMode(SDL_VideoDisplay * display, int w, int h,
     5.9 +    UIScreenMode * uiscreenmode, CGFloat scale)
    5.10 +{
    5.11 +    SDL_DisplayMode mode;
    5.12 +    SDL_zero(mode);
    5.13 +    
    5.14 +    SDL_DisplayModeData *data = NULL;
    5.15 +
    5.16 +    if (uiscreenmode != nil) {
    5.17 +        /* Allocate the display mode data */
    5.18 +        data = (SDL_DisplayModeData *) SDL_malloc(sizeof(*data));
    5.19 +        if (!data) {
    5.20 +            SDL_OutOfMemory();
    5.21 +            return -1;
    5.22 +        }
    5.23 +        
    5.24 +        data->uiscreenmode = uiscreenmode;
    5.25 +        data->scale = scale;
    5.26 +    }
    5.27 +    
    5.28 +    mode.format = SDL_PIXELFORMAT_ABGR8888;
    5.29 +    mode.refresh_rate = 0;
    5.30 +    mode.driverdata = data;
    5.31 +    
    5.32 +    mode.w = w;
    5.33 +    mode.h = h;
    5.34 +    if (SDL_AddDisplayMode(display, &mode)) {
    5.35 +        if (uiscreenmode != nil) {
    5.36 +            [uiscreenmode retain];
    5.37 +        }
    5.38 +        
    5.39 +        return 0;
    5.40 +    }
    5.41 +    
    5.42 +    SDL_free(data);
    5.43 +
    5.44 +    return -1;
    5.45 +}
    5.46 +
    5.47 +static int
    5.48 +UIKit_AddDisplayMode(SDL_VideoDisplay * display, int w, int h, CGFloat scale,
    5.49 +                     UIScreenMode * uiscreenmode, BOOL rotated)
    5.50 +{
    5.51 +    if (UIKit_AddSingleDisplayMode(display, w, h, uiscreenmode, scale) < 0) {
    5.52 +        return -1;
    5.53 +    }
    5.54 +    
    5.55 +    if (rotated) {
    5.56 +        // Add the rotated version
    5.57 +        if (UIKit_AddSingleDisplayMode(display, h, w, uiscreenmode, scale) < 0) {
    5.58 +            return -1;
    5.59 +        }
    5.60 +    }
    5.61 +    
    5.62 +    return 0;
    5.63 +}
    5.64 +
    5.65  static void
    5.66  UIKit_GetDisplayModes(_THIS, SDL_VideoDisplay * display)
    5.67  {
    5.68 -    UIScreen *uiscreen = (UIScreen *) display->driverdata;
    5.69 -    SDL_DisplayMode mode;
    5.70 -    SDL_zero(mode);
    5.71 -
    5.72 -    // availableModes showed up in 3.2 (the iPad and later). We should only
    5.73 -    //  land here for at least that version of the OS.
    5.74 -    if (!SDL_UIKit_supports_multiple_displays) {
    5.75 -        const CGRect rect = [uiscreen bounds];
    5.76 -        mode.format = SDL_PIXELFORMAT_ABGR8888;
    5.77 -        mode.refresh_rate = 0;
    5.78 -        mode.driverdata = NULL;
    5.79 -
    5.80 -        mode.w = (int) rect.size.width;
    5.81 -        mode.h = (int) rect.size.height;
    5.82 -        SDL_AddDisplayMode(display, &mode);
    5.83 +    SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata;
    5.84  
    5.85 -        mode.w = (int) rect.size.height;  // swap the orientation, add again.
    5.86 -        mode.h = (int) rect.size.width;
    5.87 -        SDL_AddDisplayMode(display, &mode);
    5.88 -        return;
    5.89 -    }
    5.90 -
    5.91 -    for (UIScreenMode *uimode in [uiscreen availableModes]) {
    5.92 -        CGSize size = [uimode size];
    5.93 -        mode.format = SDL_PIXELFORMAT_ABGR8888;
    5.94 -        mode.refresh_rate = 0;
    5.95 -        mode.driverdata = uimode;
    5.96 -        mode.w = (int) size.width;
    5.97 -        mode.h = (int) size.height;
    5.98 -        if (SDL_AddDisplayMode(display, &mode))
    5.99 -            [uimode retain];        // retain is needed because of mode.driverdata
   5.100 -
   5.101 -        if (uiscreen == [UIScreen mainScreen]) {
   5.102 -            // Add the mode with swapped width/height
   5.103 -            mode.w = (int) size.height;
   5.104 -            mode.h = (int) size.width;
   5.105 -            if (SDL_AddDisplayMode(display, &mode))
   5.106 -                [uimode retain];
   5.107 +    if (SDL_UIKit_supports_multiple_displays) {
   5.108 +        // availableModes showed up in 3.2 (the iPad and later). We should only
   5.109 +        //  land here for at least that version of the OS.
   5.110 +        for (UIScreenMode *uimode in [data->uiscreen availableModes]) {
   5.111 +            BOOL mainscreen = (data->uiscreen == [UIScreen mainScreen]);
   5.112 +            CGSize size = [uimode size];
   5.113 +            int w = (int)size.width;
   5.114 +            int h = (int)size.height;
   5.115 +            
   5.116 +            // Add the native screen resolution.
   5.117 +            UIKit_AddDisplayMode(display, w, h, data->scale, uimode, mainscreen);
   5.118 +            
   5.119 +            if (data->scale != 1.0f) {
   5.120 +                // Add the native screen resolution divided by its scale.
   5.121 +                // This is so devices capable of e.g. 640x960 also advertise
   5.122 +                // 320x480.
   5.123 +                UIKit_AddDisplayMode(display,
   5.124 +                    (int)(w / data->scale), (int)(h / data->scale),
   5.125 +                    1.0f, uimode, mainscreen);
   5.126 +            }
   5.127          }
   5.128 -    }
   5.129 +    } else {
   5.130 +        const CGRect rect = [data->uiscreen bounds];
   5.131 +        UIKit_AddDisplayMode(display,
   5.132 +            (int)rect.size.width, (int)rect.size.height,
   5.133 +            1.0f, nil, YES);
   5.134 +    } 
   5.135  }
   5.136  
   5.137  
   5.138 -static void
   5.139 -UIKit_AddDisplay(UIScreen *uiscreen, int w, int h)
   5.140 +static int
   5.141 +UIKit_AddDisplay(UIScreen *uiscreen, CGSize size)
   5.142  {
   5.143 +    // When dealing with UIKit all coordinates are specified in terms of
   5.144 +    // what Apple refers to as points. On earlier devices without the
   5.145 +    // so called "Retina" display, there is a one to one mapping between
   5.146 +    // points and pixels. In other cases [UIScreen scale] indicates the
   5.147 +    // relationship between points and pixels. Since SDL has no notion
   5.148 +    // of points, we must compensate in all cases where dealing with such
   5.149 +    // units.
   5.150 +    CGFloat scale;
   5.151 +    if ([UIScreen instancesRespondToSelector:@selector(scale)]) {
   5.152 +        scale = [uiscreen scale]; // iOS >= 4.0
   5.153 +    } else {
   5.154 +        scale = 1.0f; // iOS < 4.0
   5.155 +    }
   5.156 +	
   5.157      SDL_VideoDisplay display;
   5.158      SDL_DisplayMode mode;
   5.159      SDL_zero(mode);
   5.160      mode.format = SDL_PIXELFORMAT_ABGR8888;
   5.161 -    mode.w = w;
   5.162 -    mode.h = h;
   5.163 +    mode.w = (int)(size.width * scale);
   5.164 +    mode.h = (int)(size.height * scale);
   5.165      mode.refresh_rate = 0;
   5.166  
   5.167      // UIScreenMode showed up in 3.2 (the iPad and later). We're
   5.168      //  misusing this supports_multiple_displays flag here for that.
   5.169      if (SDL_UIKit_supports_multiple_displays) {
   5.170 -        UIScreenMode *uimode = [uiscreen currentMode];
   5.171 -        [uimode retain];  // once for the desktop_mode
   5.172 -        [uimode retain];  // once for the current_mode
   5.173 -        mode.driverdata = uimode;
   5.174 +        SDL_DisplayModeData *data;
   5.175 +        
   5.176 +        /* Allocate the mode data */
   5.177 +        data = (SDL_DisplayModeData *) SDL_malloc(sizeof(*data));
   5.178 +        if (!data) {
   5.179 +            SDL_OutOfMemory();
   5.180 +            return -1;
   5.181 +        }
   5.182 +        
   5.183 +        data->uiscreenmode = [uiscreen currentMode];
   5.184 +        [data->uiscreenmode retain];  // once for the desktop_mode
   5.185 +        [data->uiscreenmode retain];  // once for the current_mode
   5.186 +        
   5.187 +        data->scale = scale;
   5.188 +
   5.189 +        mode.driverdata = data;
   5.190      }
   5.191  
   5.192      SDL_zero(display);
   5.193      display.desktop_mode = mode;
   5.194      display.current_mode = mode;
   5.195 +	
   5.196 +    SDL_DisplayData *data;
   5.197  
   5.198 +    /* Allocate the display data */
   5.199 +    data = (SDL_DisplayData *) SDL_malloc(sizeof(*data));
   5.200 +    if (!data) {
   5.201 +        SDL_free(mode.driverdata);
   5.202 +        SDL_OutOfMemory();
   5.203 +        return -1;
   5.204 +    }
   5.205 +	
   5.206      [uiscreen retain];
   5.207 -    display.driverdata = uiscreen;
   5.208 +    data->uiscreen = uiscreen;
   5.209 +    data->scale = scale;
   5.210 +	
   5.211 +    display.driverdata = data;
   5.212      SDL_AddVideoDisplay(&display);
   5.213 +    
   5.214 +    return 0;
   5.215  }
   5.216  
   5.217  
   5.218 @@ -207,7 +295,10 @@
   5.219      // Add the main screen.
   5.220      UIScreen *uiscreen = [UIScreen mainScreen];
   5.221      const CGSize size = [uiscreen bounds].size;
   5.222 -    UIKit_AddDisplay(uiscreen, (int)size.width, (int)size.height);
   5.223 +
   5.224 +    if (UIKit_AddDisplay(uiscreen, size) < 0) {
   5.225 +        return -1;
   5.226 +    }
   5.227  
   5.228      // If this is iPhoneOS < 3.2, all devices are one screen, 320x480 pixels.
   5.229      //  The iPad added both a larger main screen and the ability to use
   5.230 @@ -217,7 +308,9 @@
   5.231              // Only add the other screens
   5.232              if (uiscreen != [UIScreen mainScreen]) {
   5.233                  const CGSize size = [uiscreen bounds].size;
   5.234 -                UIKit_AddDisplay(uiscreen, (int)size.width, (int)size.height);
   5.235 +                if (UIKit_AddDisplay(uiscreen, size) < 0) {
   5.236 +                    return -1;
   5.237 +                }
   5.238              }
   5.239          }
   5.240      }
   5.241 @@ -229,15 +322,15 @@
   5.242  static int
   5.243  UIKit_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
   5.244  {
   5.245 -    UIScreen *uiscreen = (UIScreen *) display->driverdata;
   5.246 +    SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata;
   5.247      if (!SDL_UIKit_supports_multiple_displays) {
   5.248          // Not on at least iPhoneOS 3.2 (versions prior to iPad).
   5.249          SDL_assert(mode->driverdata == NULL);
   5.250      } else {
   5.251 -        UIScreenMode *uimode = (UIScreenMode *) mode->driverdata;
   5.252 -        [uiscreen setCurrentMode:uimode];
   5.253 +        SDL_DisplayModeData *modedata = (SDL_DisplayModeData *)mode->driverdata;
   5.254 +        [data->uiscreen setCurrentMode:modedata->uiscreenmode];
   5.255  
   5.256 -        CGSize size = [uimode size];
   5.257 +        CGSize size = [modedata->uiscreenmode size];
   5.258          if (size.width >= size.height) {
   5.259              [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight animated:NO];
   5.260          } else {
   5.261 @@ -255,8 +348,9 @@
   5.262          // Not on at least iPhoneOS 3.2 (versions prior to iPad).
   5.263          SDL_assert(mode->driverdata == NULL);
   5.264      } else {
   5.265 -        UIScreenMode *uimode = (UIScreenMode *) mode->driverdata;
   5.266 -        [uimode release];
   5.267 +        SDL_DisplayModeData *data = (SDL_DisplayModeData *)mode->driverdata;
   5.268 +        [data->uiscreenmode release];
   5.269 +        SDL_free(data);
   5.270          mode->driverdata = NULL;
   5.271      }
   5.272  }
   5.273 @@ -268,8 +362,9 @@
   5.274      int i, j;
   5.275      for (i = 0; i < _this->num_displays; i++) {
   5.276          SDL_VideoDisplay *display = &_this->displays[i];
   5.277 -        UIScreen *uiscreen = (UIScreen *) display->driverdata;
   5.278 -        [uiscreen release];
   5.279 +        SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata;
   5.280 +        [data->uiscreen release];
   5.281 +        SDL_free(data);
   5.282          display->driverdata = NULL;
   5.283          UIKit_ReleaseUIScreenMode(&display->desktop_mode);
   5.284          UIKit_ReleaseUIScreenMode(&display->current_mode);
     6.1 --- a/src/video/uikit/SDL_uikitviewcontroller.m	Sun Jan 22 23:51:46 2012 -0500
     6.2 +++ b/src/video/uikit/SDL_uikitviewcontroller.m	Wed Jan 25 14:29:56 2012 +0000
     6.3 @@ -113,11 +113,10 @@
     6.4      const UIInterfaceOrientation toInterfaceOrientation = [self interfaceOrientation];
     6.5      SDL_WindowData *data = self->window->driverdata;
     6.6      UIWindow *uiwindow = data->uiwindow;
     6.7 -    UIScreen *uiscreen;
     6.8 -    if (SDL_UIKit_supports_multiple_displays)
     6.9 -        uiscreen = [uiwindow screen];
    6.10 -    else
    6.11 -        uiscreen = [UIScreen mainScreen];
    6.12 +    SDL_VideoDisplay *display = SDL_GetDisplayForWindow(self->window);
    6.13 +    SDL_DisplayData *displaydata = (SDL_DisplayData *) display->driverdata;
    6.14 +    SDL_DisplayModeData *displaymodedata = (SDL_DisplayModeData *) display->current_mode.driverdata;
    6.15 +    UIScreen *uiscreen = displaydata->uiscreen;
    6.16      const int noborder = (self->window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_BORDERLESS));
    6.17      CGRect frame = noborder ? [uiscreen bounds] : [uiscreen applicationFrame];
    6.18      const CGSize size = frame.size;
    6.19 @@ -141,6 +140,9 @@
    6.20              return;
    6.21      }
    6.22  
    6.23 +    w = (int)(w * displaymodedata->scale);
    6.24 +    h = (int)(h * displaymodedata->scale);
    6.25 +
    6.26      [uiwindow setFrame:frame];
    6.27      [data->view setFrame:frame];
    6.28      [data->view updateFrame];
     7.1 --- a/src/video/uikit/SDL_uikitwindow.h	Sun Jan 22 23:51:46 2012 -0500
     7.2 +++ b/src/video/uikit/SDL_uikitwindow.h	Wed Jan 25 14:29:56 2012 +0000
     7.3 @@ -22,6 +22,7 @@
     7.4  #define _SDL_uikitwindow_h
     7.5  
     7.6  #include "../SDL_sysvideo.h"
     7.7 +#import "SDL_uikitvideo.h"
     7.8  #import "SDL_uikitopenglview.h"
     7.9  #import "SDL_uikitviewcontroller.h"
    7.10  
     8.1 --- a/src/video/uikit/SDL_uikitwindow.m	Sun Jan 22 23:51:46 2012 -0500
     8.2 +++ b/src/video/uikit/SDL_uikitwindow.m	Wed Jan 25 14:29:56 2012 +0000
     8.3 @@ -46,7 +46,8 @@
     8.4  static int SetupWindowData(_THIS, SDL_Window *window, UIWindow *uiwindow, SDL_bool created)
     8.5  {
     8.6      SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
     8.7 -    UIScreen *uiscreen = (UIScreen *) display->driverdata;
     8.8 +    SDL_DisplayModeData *displaymodedata = (SDL_DisplayModeData *) display->current_mode.driverdata;
     8.9 +    SDL_DisplayData *displaydata = (SDL_DisplayData *) display->driverdata;
    8.10      SDL_WindowData *data;
    8.11  
    8.12      /* Allocate the window data */
    8.13 @@ -64,24 +65,28 @@
    8.14          window->x = 0;
    8.15          window->y = 0;
    8.16  
    8.17 +        /* Get frame dimensions in pixels */
    8.18 +        int width = (int)(uiwindow.frame.size.width * displaymodedata->scale);
    8.19 +        int height = (int)(uiwindow.frame.size.height * displaymodedata->scale);
    8.20 +
    8.21          /* We can pick either width or height here and we'll rotate the
    8.22             screen to match, so we pick the closest to what we wanted.
    8.23           */
    8.24          if (window->w >= window->h) {
    8.25              if (uiwindow.frame.size.width > uiwindow.frame.size.height) {
    8.26 -                window->w = (int)uiwindow.frame.size.width;
    8.27 -                window->h = (int)uiwindow.frame.size.height;
    8.28 +                window->w = width;
    8.29 +                window->h = height;
    8.30              } else {
    8.31 -                window->w = (int)uiwindow.frame.size.height;
    8.32 -                window->h = (int)uiwindow.frame.size.width;
    8.33 +                window->w = height;
    8.34 +                window->h = width;
    8.35              }
    8.36          } else {
    8.37              if (uiwindow.frame.size.width > uiwindow.frame.size.height) {
    8.38 -                window->w = (int)uiwindow.frame.size.height;
    8.39 -                window->h = (int)uiwindow.frame.size.width;
    8.40 +                window->w = height;
    8.41 +                window->h = width;
    8.42              } else {
    8.43 -                window->w = (int)uiwindow.frame.size.width;
    8.44 -                window->h = (int)uiwindow.frame.size.height;
    8.45 +                window->w = width;
    8.46 +                window->h = height;
    8.47              }
    8.48          }
    8.49      }
    8.50 @@ -95,7 +100,7 @@
    8.51      // SDL_WINDOW_BORDERLESS controls whether status bar is hidden.
    8.52      // This is only set if the window is on the main screen. Other screens
    8.53      //  just force the window to have the borderless flag.
    8.54 -    if ([UIScreen mainScreen] != uiscreen) {
    8.55 +    if ([UIScreen mainScreen] != displaydata->uiscreen) {
    8.56          window->flags &= ~SDL_WINDOW_RESIZABLE;  // window is NEVER resizeable
    8.57          window->flags &= ~SDL_WINDOW_INPUT_FOCUS;  // never has input focus
    8.58          window->flags |= SDL_WINDOW_BORDERLESS;  // never has a status bar.
    8.59 @@ -131,8 +136,8 @@
    8.60  UIKit_CreateWindow(_THIS, SDL_Window *window)
    8.61  {
    8.62      SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
    8.63 -    UIScreen *uiscreen = (UIScreen *) display->driverdata;
    8.64 -    const BOOL external = ([UIScreen mainScreen] != uiscreen);
    8.65 +    SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata;
    8.66 +    const BOOL external = ([UIScreen mainScreen] != data->uiscreen);
    8.67  
    8.68      // SDL currently puts this window at the start of display's linked list. We rely on this.
    8.69      SDL_assert(_this->windows == window);
    8.70 @@ -154,7 +159,7 @@
    8.71      //  user, so it's in standby), try to force the display to a resolution
    8.72      //  that most closely matches the desired window size.
    8.73      if (SDL_UIKit_supports_multiple_displays) {
    8.74 -        const CGSize origsize = [[uiscreen currentMode] size];
    8.75 +        const CGSize origsize = [[data->uiscreen currentMode] size];
    8.76          if ((origsize.width == 0.0f) && (origsize.height == 0.0f)) {
    8.77              if (display->num_display_modes == 0) {
    8.78                  _this->GetDisplayModes(_this, display);
    8.79 @@ -169,8 +174,8 @@
    8.80              }
    8.81  
    8.82              if (bestmode) {
    8.83 -                UIScreenMode *uimode = (UIScreenMode *) bestmode->driverdata;
    8.84 -                [uiscreen setCurrentMode:uimode];
    8.85 +                SDL_DisplayModeData *modedata = (SDL_DisplayModeData *)bestmode->driverdata;
    8.86 +                [data->uiscreen setCurrentMode:modedata->uiscreenmode];
    8.87  
    8.88                  // desktop_mode doesn't change here (the higher level will
    8.89                  //  use it to set all the screens back to their defaults
    8.90 @@ -186,16 +191,16 @@
    8.91      // !!! FIXME: can we have a smaller view?
    8.92      UIWindow *uiwindow = [UIWindow alloc];
    8.93      if (window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_BORDERLESS))
    8.94 -        uiwindow = [uiwindow initWithFrame:[uiscreen bounds]];
    8.95 +        uiwindow = [uiwindow initWithFrame:[data->uiscreen bounds]];
    8.96      else
    8.97 -        uiwindow = [uiwindow initWithFrame:[uiscreen applicationFrame]];
    8.98 +        uiwindow = [uiwindow initWithFrame:[data->uiscreen applicationFrame]];
    8.99  
   8.100      // put the window on an external display if appropriate. This implicitly
   8.101      //  does [uiwindow setframe:[uiscreen bounds]], so don't do it on the
   8.102      //  main display, where we land by default, as that would eat the
   8.103      //  status bar real estate.
   8.104      if (external) {
   8.105 -        [uiwindow setScreen:uiscreen];
   8.106 +        [uiwindow setScreen:data->uiscreen];
   8.107      }
   8.108  
   8.109      if (SetupWindowData(_this, window, uiwindow, SDL_TRUE) < 0) {
   8.110 @@ -210,35 +215,40 @@
   8.111  void
   8.112  UIKit_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen)
   8.113  {
   8.114 -    UIScreen *uiscreen = (UIScreen *) display->driverdata;
   8.115 +    SDL_DisplayData *displaydata = (SDL_DisplayData *) display->driverdata;
   8.116 +    SDL_DisplayModeData *displaymodedata = (SDL_DisplayModeData *) display->current_mode.driverdata;
   8.117      UIWindow *uiwindow = ((SDL_WindowData *) window->driverdata)->uiwindow;
   8.118  
   8.119      if (fullscreen) {
   8.120          [UIApplication sharedApplication].statusBarHidden = YES;
   8.121 -        uiwindow.frame = [uiscreen bounds];
   8.122 +        uiwindow.frame = [displaydata->uiscreen bounds];
   8.123      } else {
   8.124          [UIApplication sharedApplication].statusBarHidden = NO;
   8.125 -        uiwindow.frame = [uiscreen applicationFrame];
   8.126 +        uiwindow.frame = [displaydata->uiscreen applicationFrame];
   8.127      }
   8.128  
   8.129 +    /* Get frame dimensions in pixels */
   8.130 +    int width = (int)(uiwindow.frame.size.width * displaymodedata->scale);
   8.131 +    int height = (int)(uiwindow.frame.size.height * displaymodedata->scale);
   8.132 +
   8.133      /* We can pick either width or height here and we'll rotate the
   8.134         screen to match, so we pick the closest to what we wanted.
   8.135       */
   8.136      if (window->w >= window->h) {
   8.137          if (uiwindow.frame.size.width > uiwindow.frame.size.height) {
   8.138 -            window->w = (int)uiwindow.frame.size.width;
   8.139 -            window->h = (int)uiwindow.frame.size.height;
   8.140 +            window->w = width;
   8.141 +            window->h = height;
   8.142          } else {
   8.143 -            window->w = (int)uiwindow.frame.size.height;
   8.144 -            window->h = (int)uiwindow.frame.size.width;
   8.145 +            window->w = height;
   8.146 +            window->h = width;
   8.147          }
   8.148      } else {
   8.149          if (uiwindow.frame.size.width > uiwindow.frame.size.height) {
   8.150 -            window->w = (int)uiwindow.frame.size.height;
   8.151 -            window->h = (int)uiwindow.frame.size.width;
   8.152 +            window->w = height;
   8.153 +            window->h = width;
   8.154          } else {
   8.155 -            window->w = (int)uiwindow.frame.size.width;
   8.156 -            window->h = (int)uiwindow.frame.size.height;
   8.157 +            window->w = width;
   8.158 +            window->h = height;
   8.159          }
   8.160      }
   8.161  }