src/video/uikit/SDL_uikitwindow.m
changeset 4446 8b03a20b320f
parent 3685 64ce267332c6
child 5056 8b7988f42fcb
equal deleted inserted replaced
4445:06becafcac89 4446:8b03a20b320f
    21 */
    21 */
    22 #include "SDL_config.h"
    22 #include "SDL_config.h"
    23 
    23 
    24 #include "SDL_video.h"
    24 #include "SDL_video.h"
    25 #include "SDL_mouse.h"
    25 #include "SDL_mouse.h"
       
    26 #include "SDL_assert.h"
    26 #include "../SDL_sysvideo.h"
    27 #include "../SDL_sysvideo.h"
    27 #include "../SDL_pixels_c.h"
    28 #include "../SDL_pixels_c.h"
    28 #include "../../events/SDL_events_c.h"
    29 #include "../../events/SDL_events_c.h"
    29 
    30 
    30 #include "SDL_uikitvideo.h"
    31 #include "SDL_uikitvideo.h"
    36 #import "SDL_renderer_sw.h"
    37 #import "SDL_renderer_sw.h"
    37 
    38 
    38 #include <UIKit/UIKit.h>
    39 #include <UIKit/UIKit.h>
    39 #include <Foundation/Foundation.h>
    40 #include <Foundation/Foundation.h>
    40 
    41 
    41 static int SetupWindowData(_THIS, SDL_Window *window, UIWindow *uiwindow, SDL_bool created) {
    42 static int SetupWindowData(_THIS, SDL_Window *window, UIWindow *uiwindow, SDL_bool created)
    42 
    43 {
       
    44     SDL_VideoDisplay *display = window->display;
       
    45     UIScreen *uiscreen = (UIScreen *) display->driverdata;
    43     SDL_WindowData *data;
    46     SDL_WindowData *data;
    44         
    47         
    45     /* Allocate the window data */
    48     /* Allocate the window data */
    46     data = (SDL_WindowData *)SDL_malloc(sizeof(*data));
    49     data = (SDL_WindowData *)SDL_malloc(sizeof(*data));
    47     if (!data) {
    50     if (!data) {
    48         SDL_OutOfMemory();
    51         SDL_OutOfMemory();
    49         return -1;
    52         return -1;
    50     }
    53     }
    51     data->window = window;
       
    52     data->uiwindow = uiwindow;
    54     data->uiwindow = uiwindow;
    53     data->view = nil;
    55     data->view = nil;
    54 
    56 
    55     /* Fill in the SDL window with the window data */
    57     /* Fill in the SDL window with the window data */
    56     {
    58     {
    66     window->flags |= SDL_WINDOW_OPENGL;            /* window is always OpenGL */
    68     window->flags |= SDL_WINDOW_OPENGL;            /* window is always OpenGL */
    67     window->flags |= SDL_WINDOW_FULLSCREEN;        /* window is always fullscreen */
    69     window->flags |= SDL_WINDOW_FULLSCREEN;        /* window is always fullscreen */
    68     window->flags |= SDL_WINDOW_SHOWN;            /* only one window on iPod touch, always shown */
    70     window->flags |= SDL_WINDOW_SHOWN;            /* only one window on iPod touch, always shown */
    69     window->flags |= SDL_WINDOW_INPUT_FOCUS;    /* always has input focus */    
    71     window->flags |= SDL_WINDOW_INPUT_FOCUS;    /* always has input focus */    
    70 
    72 
    71     /* SDL_WINDOW_BORDERLESS controls whether status bar is hidden */
    73     // SDL_WINDOW_BORDERLESS controls whether status bar is hidden.
    72     if (window->flags & SDL_WINDOW_BORDERLESS) {
    74     // This is only set if the window is on the main screen. Other screens
    73         [UIApplication sharedApplication].statusBarHidden = YES;
    75     //  just force the window to have the borderless flag.
    74     }
    76     if ([UIScreen mainScreen] == uiscreen) {
    75     else {
    77         if (window->flags & SDL_WINDOW_BORDERLESS) {
    76         [UIApplication sharedApplication].statusBarHidden = NO;
    78             [UIApplication sharedApplication].statusBarHidden = YES;
       
    79         } else {
       
    80             [UIApplication sharedApplication].statusBarHidden = NO;
       
    81         }
    77     }
    82     }
    78     
    83     
    79     return 0;
    84     return 0;
    80     
    85     
    81 }
    86 }
    82 
    87 
    83 int UIKit_CreateWindow(_THIS, SDL_Window *window) {
    88 int UIKit_CreateWindow(_THIS, SDL_Window *window) {
    84         
    89         
    85     /* We currently only handle single window applications on iPhone */
    90     SDL_VideoDisplay *display = window->display;
    86     if (nil != [SDLUIKitDelegate sharedAppDelegate].window) {
    91     UIScreen *uiscreen = (UIScreen *) display->driverdata;
    87         SDL_SetError("Window already exists, no multi-window support.");
    92 
       
    93     // SDL currently puts this window at the start of display's linked list. We rely on this.
       
    94     SDL_assert(display->windows == window);
       
    95 
       
    96     /* We currently only handle a single window per display on iPhone */
       
    97     if (window->next != NULL) {
       
    98         SDL_SetError("Only one window allowed per display.");
    88         return -1;
    99         return -1;
    89     }
   100     }
    90     
   101 
       
   102     // Non-mainscreen windows must be force to borderless, as there's no
       
   103     //  status bar there, and we want to get the right dimensions later in
       
   104     //  this function.
       
   105     if ([UIScreen mainScreen] != uiscreen) {
       
   106         window->flags |= SDL_WINDOW_BORDERLESS;
       
   107     }
       
   108 
       
   109     // If monitor has a resolution of 0x0 (hasn't been explicitly set by the
       
   110     //  user, so it's in standby), try to force the display to a resolution
       
   111     //  that most closely matches the desired window size.
       
   112     if (SDL_UIKit_supports_multiple_displays) {
       
   113         const CGSize origsize = [[uiscreen currentMode] size];
       
   114         if ((origsize.width == 0.0f) && (origsize.height == 0.0f)) {
       
   115             if (display->num_display_modes == 0) {
       
   116                 _this->GetDisplayModes(_this, display);
       
   117             }
       
   118 
       
   119             int i;
       
   120             const SDL_DisplayMode *bestmode = NULL;
       
   121             for (i = display->num_display_modes; i >= 0; i--) {
       
   122                 const SDL_DisplayMode *mode = &display->display_modes[i];
       
   123                 if ((mode->w >= window->w) && (mode->h >= window->h))
       
   124                     bestmode = mode;
       
   125             }
       
   126 
       
   127             if (bestmode) {
       
   128                 UIScreenMode *uimode = (UIScreenMode *) bestmode->driverdata;
       
   129                 [uiscreen setCurrentMode:uimode];
       
   130                 display->desktop_mode = *bestmode;
       
   131                 display->current_mode = *bestmode;
       
   132             }
       
   133         }
       
   134     }
       
   135 
    91     /* ignore the size user requested, and make a fullscreen window */
   136     /* ignore the size user requested, and make a fullscreen window */
    92     UIWindow *uiwindow = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
   137     // !!! FIXME: can we have a smaller view?
    93     
   138     UIWindow *uiwindow = [UIWindow alloc];
       
   139     if (window->flags & SDL_WINDOW_BORDERLESS)
       
   140         uiwindow = [uiwindow initWithFrame:[uiscreen bounds]];
       
   141     else
       
   142         uiwindow = [uiwindow initWithFrame:[uiscreen applicationFrame]];
       
   143 
       
   144     if (SDL_UIKit_supports_multiple_displays) {
       
   145         [uiwindow setScreen:uiscreen];
       
   146     }
       
   147 
    94     if (SetupWindowData(_this, window, uiwindow, SDL_TRUE) < 0) {
   148     if (SetupWindowData(_this, window, uiwindow, SDL_TRUE) < 0) {
    95         [uiwindow release];
   149         [uiwindow release];
    96         return -1;
   150         return -1;
    97     }    
   151     }    
    98     
       
    99     // This saves the main window in the app delegate so event callbacks can do stuff on the window.
       
   100     // This assumes a single window application design and needs to be fixed for multiple windows.
       
   101     [SDLUIKitDelegate sharedAppDelegate].window = window;
       
   102     [SDLUIKitDelegate sharedAppDelegate].uiwindow = uiwindow;
       
   103     [uiwindow release]; /* release the window (the app delegate has retained it) */
       
   104     
   152     
   105     return 1;
   153     return 1;
   106     
   154     
   107 }
   155 }
   108 
   156 
   109 void UIKit_DestroyWindow(_THIS, SDL_Window * window) {
   157 void UIKit_DestroyWindow(_THIS, SDL_Window * window) {
   110     /* don't worry, the delegate will automatically release the window */
       
   111     
       
   112     SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
   158     SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
   113     if (data) {
   159     if (data) {
   114         SDL_free( window->driverdata );
   160         [data->uiwindow release];
       
   161         SDL_free(data);
       
   162         window->driverdata = NULL;
   115     }
   163     }
   116 
       
   117     /* this will also destroy the window */
       
   118     [SDLUIKitDelegate sharedAppDelegate].window = NULL;
       
   119     [SDLUIKitDelegate sharedAppDelegate].uiwindow = nil;
       
   120 }
   164 }
   121 
   165 
   122 /* vi: set ts=4 sw=4 expandtab: */
   166 /* vi: set ts=4 sw=4 expandtab: */