Added missing autorelease pool blocks in UIKit backend code. Fixes memory leak issues, especially in SDL_video.

main
Alex Szpakowski 2014-07-29 00:36:12 -03:00
parent 31257842ec
commit caad673f06
6 changed files with 322 additions and 269 deletions

View File

@ -90,13 +90,15 @@ SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int device_index)
joystick->nballs = 0; joystick->nballs = 0;
joystick->nbuttons = 0; joystick->nbuttons = 0;
if (motionManager == nil) { @autoreleasepool {
motionManager = [[CMMotionManager alloc] init]; if (motionManager == nil) {
} motionManager = [[CMMotionManager alloc] init];
}
/* Shorter times between updates can significantly increase CPU usage. */ /* Shorter times between updates can significantly increase CPU usage. */
motionManager.accelerometerUpdateInterval = 0.1; motionManager.accelerometerUpdateInterval = 0.1;
[motionManager startAccelerometerUpdates]; [motionManager startAccelerometerUpdates];
}
return 0; return 0;
} }
@ -113,11 +115,13 @@ static void SDL_SYS_AccelerometerUpdate(SDL_Joystick * joystick)
const SInt16 maxsint16 = 0x7FFF; const SInt16 maxsint16 = 0x7FFF;
CMAcceleration accel; CMAcceleration accel;
if (!motionManager.accelerometerActive) { @autoreleasepool {
return; if (!motionManager.accelerometerActive) {
} return;
}
accel = [[motionManager accelerometerData] acceleration]; accel = motionManager.accelerometerData.acceleration;
}
/* /*
Convert accelerometer data from floating point to Sint16, which is what Convert accelerometer data from floating point to Sint16, which is what
@ -161,7 +165,9 @@ SDL_SYS_JoystickUpdate(SDL_Joystick * joystick)
void void
SDL_SYS_JoystickClose(SDL_Joystick * joystick) SDL_SYS_JoystickClose(SDL_Joystick * joystick)
{ {
[motionManager stopAccelerometerUpdates]; @autoreleasepool {
[motionManager stopAccelerometerUpdates];
}
joystick->closed = 1; joystick->closed = 1;
} }
@ -169,9 +175,11 @@ SDL_SYS_JoystickClose(SDL_Joystick * joystick)
void void
SDL_SYS_JoystickQuit(void) SDL_SYS_JoystickQuit(void)
{ {
if (motionManager != nil) { @autoreleasepool {
[motionManager release]; if (motionManager != nil) {
motionManager = nil; [motionManager release];
motionManager = nil;
}
} }
numjoysticks = 0; numjoysticks = 0;

View File

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

View File

@ -159,9 +159,11 @@ UIKit_IsDisplayLandscape(UIScreen *uiscreen)
int int
UIKit_InitModes(_THIS) UIKit_InitModes(_THIS)
{ {
for (UIScreen *uiscreen in [UIScreen screens]) { @autoreleasepool {
if (UIKit_AddDisplay(uiscreen) < 0) { for (UIScreen *uiscreen in [UIScreen screens]) {
return -1; if (UIKit_AddDisplay(uiscreen) < 0) {
return -1;
}
} }
} }
@ -173,26 +175,28 @@ UIKit_GetDisplayModes(_THIS, SDL_VideoDisplay * display)
{ {
SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata; SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata;
SDL_bool isLandscape = UIKit_IsDisplayLandscape(data->uiscreen); @autoreleasepool {
SDL_bool addRotation = (data->uiscreen == [UIScreen mainScreen]); SDL_bool isLandscape = UIKit_IsDisplayLandscape(data->uiscreen);
CGFloat scale = data->uiscreen.scale; SDL_bool addRotation = (data->uiscreen == [UIScreen mainScreen]);
CGFloat scale = data->uiscreen.scale;
for (UIScreenMode *uimode in [data->uiscreen availableModes]) { for (UIScreenMode *uimode in [data->uiscreen availableModes]) {
/* The size of a UIScreenMode is in pixels, but we deal exclusively in /* The size of a UIScreenMode is in pixels, but we deal exclusively in
* points (except in SDL_GL_GetDrawableSize.) */ * points (except in SDL_GL_GetDrawableSize.) */
CGSize size = [uimode size]; CGSize size = [uimode size];
int w = (int)(size.width / scale); int w = (int)(size.width / scale);
int h = (int)(size.height / scale); int h = (int)(size.height / scale);
/* Make sure the width/height are oriented correctly */ /* Make sure the width/height are oriented correctly */
if (isLandscape != (w > h)) { if (isLandscape != (w > h)) {
int tmp = w; int tmp = w;
w = h; w = h;
h = tmp; h = tmp;
}
/* Add the native screen resolution. */
UIKit_AddDisplayMode(display, w, h, uimode, addRotation);
} }
/* Add the native screen resolution. */
UIKit_AddDisplayMode(display, w, h, uimode, addRotation);
} }
} }
@ -202,16 +206,18 @@ UIKit_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata; SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata;
SDL_DisplayModeData *modedata = (SDL_DisplayModeData *)mode->driverdata; SDL_DisplayModeData *modedata = (SDL_DisplayModeData *)mode->driverdata;
[data->uiscreen setCurrentMode:modedata->uiscreenmode]; @autoreleasepool {
[data->uiscreen setCurrentMode:modedata->uiscreenmode];
if (data->uiscreen == [UIScreen mainScreen]) { if (data->uiscreen == [UIScreen mainScreen]) {
if (mode->w > mode->h) { if (mode->w > mode->h) {
if (!UIKit_IsDisplayLandscape(data->uiscreen)) { if (!UIKit_IsDisplayLandscape(data->uiscreen)) {
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight animated:NO]; [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight animated:NO];
} }
} else if (mode->w < mode->h) { } else if (mode->w < mode->h) {
if (UIKit_IsDisplayLandscape(data->uiscreen)) { if (UIKit_IsDisplayLandscape(data->uiscreen)) {
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait animated:NO]; [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait animated:NO];
}
} }
} }
} }
@ -224,19 +230,21 @@ UIKit_QuitModes(_THIS)
{ {
/* Release Objective-C objects, so higher level doesn't free() them. */ /* Release Objective-C objects, so higher level doesn't free() them. */
int i, j; int i, j;
for (i = 0; i < _this->num_displays; i++) { @autoreleasepool {
SDL_VideoDisplay *display = &_this->displays[i]; for (i = 0; i < _this->num_displays; i++) {
SDL_VideoDisplay *display = &_this->displays[i];
UIKit_FreeDisplayModeData(&display->desktop_mode); UIKit_FreeDisplayModeData(&display->desktop_mode);
for (j = 0; j < display->num_display_modes; j++) { for (j = 0; j < display->num_display_modes; j++) {
SDL_DisplayMode *mode = &display->display_modes[j]; SDL_DisplayMode *mode = &display->display_modes[j];
UIKit_FreeDisplayModeData(mode); UIKit_FreeDisplayModeData(mode);
}
SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata;
[data->uiscreen release];
SDL_free(data);
display->driverdata = NULL;
} }
SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata;
[data->uiscreen release];
SDL_free(data);
display->driverdata = NULL;
} }
} }

View File

@ -52,12 +52,14 @@ UIKit_GL_GetProcAddress(_THIS, const char *proc)
int int
UIKit_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context) UIKit_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context)
{ {
if (context) { @autoreleasepool {
SDL_WindowData *data = (SDL_WindowData *)window->driverdata; if (context) {
[data->view setCurrentContext]; SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
} [data->view setCurrentContext];
else { }
[EAGLContext setCurrentContext: nil]; else {
[EAGLContext setCurrentContext: nil];
}
} }
return 0; return 0;
@ -67,11 +69,13 @@ void UIKit_GL_GetDrawableSize(_THIS, SDL_Window * window, int * w, int * h)
{ {
SDL_WindowData *data = (SDL_WindowData *)window->driverdata; SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
if (w) { @autoreleasepool {
*w = data->view.backingWidth; if (w) {
} *w = data->view.backingWidth;
if (h) { }
*h = data->view.backingHeight; if (h) {
*h = data->view.backingHeight;
}
} }
} }
@ -92,106 +96,112 @@ UIKit_GL_LoadLibrary(_THIS, const char *path)
void UIKit_GL_SwapWindow(_THIS, SDL_Window * window) void UIKit_GL_SwapWindow(_THIS, SDL_Window * window)
{ {
@autoreleasepool {
#if SDL_POWER_UIKIT #if SDL_POWER_UIKIT
/* Check once a frame to see if we should turn off the battery monitor. */ /* Check once a frame to see if we should turn off the battery monitor. */
SDL_UIKit_UpdateBatteryMonitoring(); SDL_UIKit_UpdateBatteryMonitoring();
#endif #endif
SDL_WindowData *data = (SDL_WindowData *)window->driverdata; SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
if (nil == data->view) { if (nil == data->view) {
return; return;
}
[data->view swapBuffers];
/* You need to pump events in order for the OS to make changes visible.
We don't pump events here because we don't want iOS application events
(low memory, terminate, etc.) to happen inside low level rendering.
*/
} }
[data->view swapBuffers];
/* You need to pump events in order for the OS to make changes visible.
We don't pump events here because we don't want iOS application events
(low memory, terminate, etc.) to happen inside low level rendering.
*/
} }
SDL_GLContext SDL_GLContext
UIKit_GL_CreateContext(_THIS, SDL_Window * window) UIKit_GL_CreateContext(_THIS, SDL_Window * window)
{ {
SDL_uikitopenglview *view; @autoreleasepool {
SDL_WindowData *data = (SDL_WindowData *) window->driverdata; SDL_uikitopenglview *view;
UIWindow *uiwindow = data->uiwindow; SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
CGRect frame = UIKit_ComputeViewFrame(window, uiwindow.screen); UIWindow *uiwindow = data->uiwindow;
EAGLSharegroup *share_group = nil; CGRect frame = UIKit_ComputeViewFrame(window, uiwindow.screen);
CGFloat scale = 1.0; EAGLSharegroup *share_group = nil;
CGFloat scale = 1.0;
if (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) { if (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) {
/* Set the scale to the natural scale factor of the screen - the backing /* Set the scale to the natural scale factor of the screen - the backing
dimensions of the OpenGL view will match the pixel dimensions of the dimensions of the OpenGL view will match the pixel dimensions of the
screen rather than the dimensions in points. screen rather than the dimensions in points.
*/ */
scale = uiwindow.screen.scale; scale = uiwindow.screen.scale;
}
if (_this->gl_config.share_with_current_context) {
SDL_uikitopenglview *view = (SDL_uikitopenglview *) SDL_GL_GetCurrentContext();
share_group = [view.context sharegroup];
}
/* construct our view, passing in SDL's OpenGL configuration data */
view = [[SDL_uikitopenglview alloc] initWithFrame: frame
scale: scale
retainBacking: _this->gl_config.retained_backing
rBits: _this->gl_config.red_size
gBits: _this->gl_config.green_size
bBits: _this->gl_config.blue_size
aBits: _this->gl_config.alpha_size
depthBits: _this->gl_config.depth_size
stencilBits: _this->gl_config.stencil_size
sRGB: _this->gl_config.framebuffer_srgb_capable
majorVersion: _this->gl_config.major_version
shareGroup: share_group];
if (!view) {
return NULL;
}
data->view = view;
view->viewcontroller = data->viewcontroller;
if (view->viewcontroller != nil) {
[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;
}
if (UIKit_GL_MakeCurrent(_this, window, view) < 0) {
UIKit_GL_DeleteContext(_this, view);
return NULL;
}
/* Make this window the current mouse focus for touch input */
if (uiwindow.screen == [UIScreen mainScreen]) {
SDL_SetMouseFocus(window);
SDL_SetKeyboardFocus(window);
}
return view;
} }
if (_this->gl_config.share_with_current_context) {
SDL_uikitopenglview *view = (SDL_uikitopenglview *) SDL_GL_GetCurrentContext();
share_group = [view.context sharegroup];
}
/* construct our view, passing in SDL's OpenGL configuration data */
view = [[SDL_uikitopenglview alloc] initWithFrame: frame
scale: scale
retainBacking: _this->gl_config.retained_backing
rBits: _this->gl_config.red_size
gBits: _this->gl_config.green_size
bBits: _this->gl_config.blue_size
aBits: _this->gl_config.alpha_size
depthBits: _this->gl_config.depth_size
stencilBits: _this->gl_config.stencil_size
sRGB: _this->gl_config.framebuffer_srgb_capable
majorVersion: _this->gl_config.major_version
shareGroup: share_group];
if (!view) {
return NULL;
}
data->view = view;
view->viewcontroller = data->viewcontroller;
if (view->viewcontroller != nil) {
[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;
}
if (UIKit_GL_MakeCurrent(_this, window, view) < 0) {
UIKit_GL_DeleteContext(_this, view);
return NULL;
}
/* Make this window the current mouse focus for touch input */
if (uiwindow.screen == [UIScreen mainScreen]) {
SDL_SetMouseFocus(window);
SDL_SetKeyboardFocus(window);
}
return view;
} }
void void
UIKit_GL_DeleteContext(_THIS, SDL_GLContext context) UIKit_GL_DeleteContext(_THIS, SDL_GLContext context)
{ {
/* the delegate has retained the view, this will release him */ @autoreleasepool {
SDL_uikitopenglview *view = (SDL_uikitopenglview *)context; /* the delegate has retained the view, this will release him */
if (view->viewcontroller) { SDL_uikitopenglview *view = (SDL_uikitopenglview *)context;
UIWindow *uiwindow = (UIWindow *)view.superview; if (view->viewcontroller) {
if (uiwindow.rootViewController == view->viewcontroller) { UIWindow *uiwindow = (UIWindow *)view.superview;
uiwindow.rootViewController = nil; if (uiwindow.rootViewController == view->viewcontroller) {
uiwindow.rootViewController = nil;
}
[view->viewcontroller setView:nil];
[view->viewcontroller release];
} }
[view->viewcontroller setView:nil]; [view removeFromSuperview];
[view->viewcontroller release]; [view release];
} }
[view removeFromSuperview];
[view release];
} }
#endif /* SDL_VIDEO_DRIVER_UIKIT */ #endif /* SDL_VIDEO_DRIVER_UIKIT */

View File

@ -318,28 +318,34 @@ SDL_bool UIKit_HasScreenKeyboardSupport(_THIS)
void UIKit_ShowScreenKeyboard(_THIS, SDL_Window *window) void UIKit_ShowScreenKeyboard(_THIS, SDL_Window *window)
{ {
SDL_uikitview *view = getWindowView(window); @autoreleasepool {
if (view != nil) { SDL_uikitview *view = getWindowView(window);
[view showKeyboard]; if (view != nil) {
[view showKeyboard];
}
} }
} }
void UIKit_HideScreenKeyboard(_THIS, SDL_Window *window) void UIKit_HideScreenKeyboard(_THIS, SDL_Window *window)
{ {
SDL_uikitview *view = getWindowView(window); @autoreleasepool {
if (view != nil) { SDL_uikitview *view = getWindowView(window);
[view hideKeyboard]; if (view != nil) {
[view hideKeyboard];
}
} }
} }
SDL_bool UIKit_IsScreenKeyboardShown(_THIS, SDL_Window *window) SDL_bool UIKit_IsScreenKeyboardShown(_THIS, SDL_Window *window)
{ {
SDL_uikitview *view = getWindowView(window); @autoreleasepool {
if (view == nil) { SDL_uikitview *view = getWindowView(window);
return 0; if (view == nil) {
} return 0;
}
return view.isKeyboardVisible; return view.isKeyboardVisible;
}
} }
@ -423,13 +429,15 @@ UIKit_SetTextInputRect(_THIS, SDL_Rect *rect)
SDL_InvalidParamError("rect"); SDL_InvalidParamError("rect");
return; return;
} }
SDL_uikitview *view = getWindowView(SDL_GetFocusWindow());
if (view == nil) {
return ;
}
view.textInputRect = *rect; @autoreleasepool {
SDL_uikitview *view = getWindowView(SDL_GetFocusWindow());
if (view == nil) {
return;
}
view.textInputRect = *rect;
}
} }

View File

@ -132,84 +132,86 @@ static int SetupWindowData(_THIS, SDL_Window *window, SDL_uikitwindow *uiwindow,
int int
UIKit_CreateWindow(_THIS, SDL_Window *window) UIKit_CreateWindow(_THIS, SDL_Window *window)
{ {
SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window); @autoreleasepool {
SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata; SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
const BOOL external = ([UIScreen mainScreen] != data->uiscreen); SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata;
const CGSize origsize = [[data->uiscreen currentMode] size]; const BOOL external = ([UIScreen mainScreen] != data->uiscreen);
const CGSize origsize = [[data->uiscreen currentMode] size];
/* SDL currently puts this window at the start of display's linked list. We rely on this. */ /* SDL currently puts this window at the start of display's linked list. We rely on this. */
SDL_assert(_this->windows == window); SDL_assert(_this->windows == window);
/* We currently only handle a single window per display on iOS */ /* We currently only handle a single window per display on iOS */
if (window->next != NULL) { if (window->next != NULL) {
return SDL_SetError("Only one window allowed per display."); return SDL_SetError("Only one window allowed per display.");
}
/* If monitor has a resolution of 0x0 (hasn't been explicitly set by the
* user, so it's in standby), try to force the display to a resolution
* that most closely matches the desired window size.
*/
if ((origsize.width == 0.0f) && (origsize.height == 0.0f)) {
if (display->num_display_modes == 0) {
_this->GetDisplayModes(_this, display);
} }
int i; /* If monitor has a resolution of 0x0 (hasn't been explicitly set by the
const SDL_DisplayMode *bestmode = NULL; * user, so it's in standby), try to force the display to a resolution
for (i = display->num_display_modes; i >= 0; i--) { * that most closely matches the desired window size.
const SDL_DisplayMode *mode = &display->display_modes[i]; */
if ((mode->w >= window->w) && (mode->h >= window->h)) if ((origsize.width == 0.0f) && (origsize.height == 0.0f)) {
bestmode = mode; if (display->num_display_modes == 0) {
} _this->GetDisplayModes(_this, display);
if (bestmode) {
SDL_DisplayModeData *modedata = (SDL_DisplayModeData *)bestmode->driverdata;
[data->uiscreen setCurrentMode:modedata->uiscreenmode];
/* desktop_mode doesn't change here (the higher level will
* use it to set all the screens back to their defaults
* upon window destruction, SDL_Quit(), etc.
*/
display->current_mode = *bestmode;
}
}
if (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)) { int i;
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait animated:NO]; const SDL_DisplayMode *bestmode = NULL;
for (i = display->num_display_modes; i >= 0; i--) {
const SDL_DisplayMode *mode = &display->display_modes[i];
if ((mode->w >= window->w) && (mode->h >= window->h))
bestmode = mode;
}
if (bestmode) {
SDL_DisplayModeData *modedata = (SDL_DisplayModeData *)bestmode->driverdata;
[data->uiscreen setCurrentMode:modedata->uiscreenmode];
/* desktop_mode doesn't change here (the higher level will
* use it to set all the screens back to their defaults
* upon window destruction, SDL_Quit(), etc.
*/
display->current_mode = *bestmode;
} }
} }
}
/* ignore the size user requested, and make a fullscreen window */ if (data->uiscreen == [UIScreen mainScreen]) {
/* !!! FIXME: can we have a smaller view? */ if (window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_BORDERLESS)) {
SDL_uikitwindow *uiwindow = [[SDL_uikitwindow alloc] initWithFrame:data->uiscreen.bounds]; [UIApplication sharedApplication].statusBarHidden = YES;
} else {
[UIApplication sharedApplication].statusBarHidden = NO;
}
}
/* put the window on an external display if appropriate. This implicitly if (!(window->flags & SDL_WINDOW_RESIZABLE)) {
* does [uiwindow setframe:[uiscreen bounds]], so don't do it on the if (window->w > window->h) {
* main display, where we land by default, as that would eat the if (!UIKit_IsDisplayLandscape(data->uiscreen)) {
* status bar real estate. [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight animated:NO];
*/ }
if (external) { } else if (window->w < window->h) {
[uiwindow setScreen:data->uiscreen]; if (UIKit_IsDisplayLandscape(data->uiscreen)) {
} [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait animated:NO];
}
}
}
if (SetupWindowData(_this, window, uiwindow, SDL_TRUE) < 0) { /* ignore the size user requested, and make a fullscreen window */
[uiwindow release]; /* !!! FIXME: can we have a smaller view? */
return -1; SDL_uikitwindow *uiwindow = [[SDL_uikitwindow alloc] initWithFrame:data->uiscreen.bounds];
/* put the window on an external display if appropriate. This implicitly
* does [uiwindow setframe:[uiscreen bounds]], so don't do it on the
* main display, where we land by default, as that would eat the
* status bar real estate.
*/
if (external) {
[uiwindow setScreen:data->uiscreen];
}
if (SetupWindowData(_this, window, uiwindow, SDL_TRUE) < 0) {
[uiwindow release];
return -1;
}
} }
return 1; return 1;
@ -218,17 +220,21 @@ UIKit_CreateWindow(_THIS, SDL_Window *window)
void void
UIKit_ShowWindow(_THIS, SDL_Window * window) UIKit_ShowWindow(_THIS, SDL_Window * window)
{ {
UIWindow *uiwindow = ((SDL_WindowData *) window->driverdata)->uiwindow; @autoreleasepool {
UIWindow *uiwindow = ((SDL_WindowData *) window->driverdata)->uiwindow;
[uiwindow makeKeyAndVisible]; [uiwindow makeKeyAndVisible];
}
} }
void void
UIKit_HideWindow(_THIS, SDL_Window * window) UIKit_HideWindow(_THIS, SDL_Window * window)
{ {
UIWindow *uiwindow = ((SDL_WindowData *) window->driverdata)->uiwindow; @autoreleasepool {
UIWindow *uiwindow = ((SDL_WindowData *) window->driverdata)->uiwindow;
uiwindow.hidden = YES; uiwindow.hidden = YES;
}
} }
void void
@ -286,13 +292,17 @@ UIKit_UpdateWindowBorder(_THIS, SDL_Window * window)
void void
UIKit_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered) UIKit_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered)
{ {
UIKit_UpdateWindowBorder(_this, window); @autoreleasepool {
UIKit_UpdateWindowBorder(_this, window);
}
} }
void void
UIKit_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen) UIKit_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen)
{ {
UIKit_UpdateWindowBorder(_this, window); @autoreleasepool {
UIKit_UpdateWindowBorder(_this, window);
}
} }
void void
@ -300,27 +310,32 @@ UIKit_DestroyWindow(_THIS, SDL_Window * window)
{ {
SDL_WindowData *data = (SDL_WindowData *)window->driverdata; SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
if (data) { @autoreleasepool {
[data->viewcontroller release]; if (data) {
[data->uiwindow release]; [data->viewcontroller release];
SDL_free(data); [data->uiwindow release];
SDL_free(data);
}
} }
window->driverdata = NULL; window->driverdata = NULL;
} }
SDL_bool SDL_bool
UIKit_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info) UIKit_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info)
{ {
UIWindow *uiwindow = ((SDL_WindowData *) window->driverdata)->uiwindow; @autoreleasepool {
UIWindow *uiwindow = ((SDL_WindowData *) window->driverdata)->uiwindow;
if (info->version.major <= SDL_MAJOR_VERSION) { if (info->version.major <= SDL_MAJOR_VERSION) {
info->subsystem = SDL_SYSWM_UIKIT; info->subsystem = SDL_SYSWM_UIKIT;
info->info.uikit.window = uiwindow; info->info.uikit.window = uiwindow;
return SDL_TRUE; return SDL_TRUE;
} else { } else {
SDL_SetError("Application not compiled with SDL %d.%d\n", SDL_SetError("Application not compiled with SDL %d.%d\n",
SDL_MAJOR_VERSION, SDL_MINOR_VERSION); SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
return SDL_FALSE; return SDL_FALSE;
}
} }
} }
@ -333,7 +348,10 @@ SDL_iPhoneSetAnimationCallback(SDL_Window * window, int interval, void (*callbac
return SDL_SetError("Invalid window or view not set"); return SDL_SetError("Invalid window or view not set");
} }
[data->view setAnimationCallback:interval callback:callback callbackParam:callbackParam]; @autoreleasepool {
[data->view setAnimationCallback:interval callback:callback callbackParam:callbackParam];
}
return 0; return 0;
} }