Added missing autorelease pool blocks in UIKit backend code. Fixes memory leak issues, especially in SDL_video.
parent
31257842ec
commit
caad673f06
|
@ -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;
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -424,12 +430,14 @@ UIKit_SetTextInputRect(_THIS, SDL_Rect *rect)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_uikitview *view = getWindowView(SDL_GetFocusWindow());
|
@autoreleasepool {
|
||||||
if (view == nil) {
|
SDL_uikitview *view = getWindowView(SDL_GetFocusWindow());
|
||||||
return ;
|
if (view == nil) {
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
view.textInputRect = *rect;
|
view.textInputRect = *rect;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue