Updated the iOS backend code to use Objective-C's automatic reference counting (ARC).

This commit is contained in:
Alex Szpakowski 2014-08-06 03:24:16 -03:00
parent 362899776e
commit f5543f93b3
15 changed files with 181 additions and 176 deletions

View file

@ -1274,8 +1274,14 @@
FD6526640DE8FCCB002AD96B /* Debug */ = { FD6526640DE8FCCB002AD96B /* Debug */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_OBJC_IMPLICIT_ATOMIC_PROPERTIES = YES;
COPY_PHASE_STRIP = NO; COPY_PHASE_STRIP = NO;
IPHONEOS_DEPLOYMENT_TARGET = 5.1.1; IPHONEOS_DEPLOYMENT_TARGET = 5.1.1;
GCC_WARN_MULTIPLE_DEFINITION_TYPES_FOR_SELECTOR = YES;
GCC_WARN_STRICT_SELECTOR_MATCH = YES;
GCC_WARN_UNDECLARED_SELECTOR = YES;
PRODUCT_NAME = SDL2; PRODUCT_NAME = SDL2;
SKIP_INSTALL = YES; SKIP_INSTALL = YES;
}; };
@ -1284,8 +1290,14 @@
FD6526650DE8FCCB002AD96B /* Release */ = { FD6526650DE8FCCB002AD96B /* Release */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_OBJC_IMPLICIT_ATOMIC_PROPERTIES = YES;
COPY_PHASE_STRIP = YES; COPY_PHASE_STRIP = YES;
IPHONEOS_DEPLOYMENT_TARGET = 5.1.1; IPHONEOS_DEPLOYMENT_TARGET = 5.1.1;
GCC_WARN_MULTIPLE_DEFINITION_TYPES_FOR_SELECTOR = YES;
GCC_WARN_STRICT_SELECTOR_MATCH = YES;
GCC_WARN_UNDECLARED_SELECTOR = YES;
PRODUCT_NAME = SDL2; PRODUCT_NAME = SDL2;
SKIP_INSTALL = YES; SKIP_INSTALL = YES;
}; };

View file

@ -209,9 +209,9 @@ struct SDL_SysWMinfo
struct struct
{ {
#if defined(__OBJC__) && __has_feature(objc_arc) #if defined(__OBJC__) && __has_feature(objc_arc)
NSWindow __unsafe_unretained *window; /* The Cocoa window */ NSWindow * __unsafe_unretained window; /* The Cocoa window */
#else #else
NSWindow *window; /* The Cocoa window */ NSWindow *window; /* The Cocoa window */
#endif #endif
} cocoa; } cocoa;
#endif #endif
@ -219,9 +219,9 @@ struct SDL_SysWMinfo
struct struct
{ {
#if defined(__OBJC__) && __has_feature(objc_arc) #if defined(__OBJC__) && __has_feature(objc_arc)
UIWindow __unsafe_unretained *window; /* The UIKit window */ UIWindow * __unsafe_unretained window; /* The UIKit window */
#else #else
UIWindow *window; /* The UIKit window */ UIWindow *window; /* The UIKit window */
#endif #endif
} uikit; } uikit;
#endif #endif

View file

@ -50,8 +50,7 @@ FILE* SDL_OpenFPFromBundleOrFallback(const char *file, const char *mode)
NSString* full_path_with_file_to_try = [resource_path stringByAppendingPathComponent:ns_string_file_component]; NSString* full_path_with_file_to_try = [resource_path stringByAppendingPathComponent:ns_string_file_component];
if([file_manager fileExistsAtPath:full_path_with_file_to_try]) { if([file_manager fileExistsAtPath:full_path_with_file_to_try]) {
fp = fopen([full_path_with_file_to_try fileSystemRepresentation], mode); fp = fopen([full_path_with_file_to_try fileSystemRepresentation], mode);
} } else {
else {
fp = fopen(file, mode); fp = fopen(file, mode);
} }
} }

View file

@ -176,10 +176,7 @@ void
SDL_SYS_JoystickQuit(void) SDL_SYS_JoystickQuit(void)
{ {
@autoreleasepool { @autoreleasepool {
if (motionManager != nil) { motionManager = nil;
[motionManager release];
motionManager = nil;
}
} }
numjoysticks = 0; numjoysticks = 0;

View file

@ -56,7 +56,7 @@ int main(int argc, char **argv)
/* Give over control to run loop, SDLUIKitDelegate will handle most things from here */ /* Give over control to run loop, SDLUIKitDelegate will handle most things from here */
@autoreleasepool { @autoreleasepool {
UIApplicationMain(argc, argv, NULL, [SDLUIKitDelegate getAppDelegateClassName]); UIApplicationMain(argc, argv, nil, [SDLUIKitDelegate getAppDelegateClassName]);
} }
/* free the memory we used to hold copies of argc and argv */ /* free the memory we used to hold copies of argc and argv */
@ -94,26 +94,20 @@ SDL_IdleTimerDisabledChanged(void *userdata, const char *name, const char *oldVa
return nil; return nil;
} }
self->splash = [[UIImageView alloc] init]; splash = [[UIImageView alloc] init];
[self setView:self->splash]; self.view = splash;
CGSize size = [UIScreen mainScreen].bounds.size; CGSize size = [UIScreen mainScreen].bounds.size;
float height = SDL_max(size.width, size.height); float height = SDL_max(size.width, size.height);
self->splashPortrait = [UIImage imageNamed:[NSString stringWithFormat:@"Default-%dh.png", (int)height]]; splashPortrait = [UIImage imageNamed:[NSString stringWithFormat:@"Default-%dh.png", (int)height]];
if (!self->splashPortrait) { if (!splashPortrait) {
self->splashPortrait = [UIImage imageNamed:@"Default.png"]; splashPortrait = [UIImage imageNamed:@"Default.png"];
} }
self->splashLandscape = [UIImage imageNamed:@"Default-Landscape.png"]; splashLandscape = [UIImage imageNamed:@"Default-Landscape.png"];
if (!self->splashLandscape && self->splashPortrait) { if (!splashLandscape && splashPortrait) {
self->splashLandscape = [[UIImage alloc] initWithCGImage: self->splashPortrait.CGImage splashLandscape = [[UIImage alloc] initWithCGImage: splashPortrait.CGImage
scale: 1.0 scale: 1.0
orientation: UIImageOrientationRight]; orientation: UIImageOrientationRight];
}
if (self->splashPortrait) {
[self->splashPortrait retain];
}
if (self->splashLandscape) {
[self->splashLandscape retain];
} }
[self updateSplashImage:[[UIApplication sharedApplication] statusBarOrientation]]; [self updateSplashImage:[[UIApplication sharedApplication] statusBarOrientation]];
@ -148,9 +142,9 @@ SDL_IdleTimerDisabledChanged(void *userdata, const char *name, const char *oldVa
UIImage *image; UIImage *image;
if (UIInterfaceOrientationIsLandscape(interfaceOrientation)) { if (UIInterfaceOrientationIsLandscape(interfaceOrientation)) {
image = self->splashLandscape; image = splashLandscape;
} else { } else {
image = self->splashPortrait; image = splashPortrait;
} }
if (image) { if (image) {
@ -192,8 +186,7 @@ SDL_IdleTimerDisabledChanged(void *userdata, const char *name, const char *oldVa
/* If we showed a splash image, clean it up */ /* If we showed a splash image, clean it up */
if (launch_window) { if (launch_window) {
[launch_window release]; launch_window = nil;
launch_window = NULL;
} }
/* exit, passing the return status from the user's application */ /* exit, passing the return status from the user's application */

View file

@ -76,13 +76,14 @@ UIKit_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
@autoreleasepool { @autoreleasepool {
UIAlertView* alert = [[UIAlertView alloc] init]; UIAlertView* alert = [[UIAlertView alloc] init];
UIKit_UIAlertViewDelegate *delegate = [[UIKit_UIAlertViewDelegate alloc] initWithButtonIndex:&clicked];
alert.title = @(messageboxdata->title); alert.title = @(messageboxdata->title);
alert.message = @(messageboxdata->message); alert.message = @(messageboxdata->message);
alert.delegate = [[UIKit_UIAlertViewDelegate alloc] initWithButtonIndex:&clicked]; alert.delegate = delegate;
for (i = 0; i < messageboxdata->numbuttons; ++i) { for (i = 0; i < messageboxdata->numbuttons; ++i) {
[alert addButtonWithTitle:[[NSString alloc] initWithUTF8String:buttons[i].text]]; [alert addButtonWithTitle:@(buttons[i].text)];
} }
/* Set up for showing the alert */ /* Set up for showing the alert */
@ -100,8 +101,7 @@ UIKit_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
*buttonid = messageboxdata->buttons[clicked].buttonid; *buttonid = messageboxdata->buttons[clicked].buttonid;
[alert.delegate release]; alert.delegate = nil;
[alert release];
} }
return 0; return 0;

View file

@ -25,15 +25,17 @@
#include "SDL_uikitvideo.h" #include "SDL_uikitvideo.h"
typedef struct @interface SDL_DisplayData : NSObject
{
UIScreen *uiscreen;
} SDL_DisplayData;
typedef struct @property (nonatomic, strong) UIScreen *uiscreen;
{
UIScreenMode *uiscreenmode; @end
} SDL_DisplayModeData;
@interface SDL_DisplayModeData : NSObject
@property (nonatomic, strong) UIScreenMode *uiscreenmode;
@end
extern SDL_bool UIKit_IsDisplayLandscape(UIScreen *uiscreen); extern SDL_bool UIKit_IsDisplayLandscape(UIScreen *uiscreen);

View file

@ -25,25 +25,36 @@
#include "SDL_assert.h" #include "SDL_assert.h"
#include "SDL_uikitmodes.h" #include "SDL_uikitmodes.h"
@implementation SDL_DisplayData
@synthesize uiscreen;
@end
@implementation SDL_DisplayModeData
@synthesize uiscreenmode;
@end
static int static int
UIKit_AllocateDisplayModeData(SDL_DisplayMode * mode, UIKit_AllocateDisplayModeData(SDL_DisplayMode * mode,
UIScreenMode * uiscreenmode) UIScreenMode * uiscreenmode)
{ {
SDL_DisplayModeData *data = NULL; SDL_DisplayModeData *data = nil;
if (uiscreenmode != nil) { if (uiscreenmode != nil) {
/* Allocate the display mode data */ /* Allocate the display mode data */
data = (SDL_DisplayModeData *) SDL_malloc(sizeof(*data)); data = [[SDL_DisplayModeData alloc] init];
if (!data) { if (!data) {
return SDL_OutOfMemory(); return SDL_OutOfMemory();
} }
data->uiscreenmode = uiscreenmode; data.uiscreenmode = uiscreenmode;
[data->uiscreenmode retain];
} }
mode->driverdata = data; mode->driverdata = (void *) CFBridgingRetain(data);
return 0; return 0;
} }
@ -52,9 +63,7 @@ static void
UIKit_FreeDisplayModeData(SDL_DisplayMode * mode) UIKit_FreeDisplayModeData(SDL_DisplayMode * mode)
{ {
if (mode->driverdata != NULL) { if (mode->driverdata != NULL) {
SDL_DisplayModeData *data = (SDL_DisplayModeData *)mode->driverdata; CFRelease(mode->driverdata);
[data->uiscreenmode release];
SDL_free(data);
mode->driverdata = NULL; mode->driverdata = NULL;
} }
} }
@ -130,18 +139,18 @@ UIKit_AddDisplay(UIScreen *uiscreen)
display.current_mode = mode; display.current_mode = mode;
/* Allocate the display data */ /* Allocate the display data */
SDL_DisplayData *data = (SDL_DisplayData *) SDL_malloc(sizeof(*data)); SDL_DisplayData *data = [[SDL_DisplayData alloc] init];
if (!data) { if (!data) {
UIKit_FreeDisplayModeData(&display.desktop_mode); UIKit_FreeDisplayModeData(&display.desktop_mode);
return SDL_OutOfMemory(); return SDL_OutOfMemory();
} }
[uiscreen retain]; data.uiscreen = uiscreen;
data->uiscreen = uiscreen;
display.driverdata = data; display.driverdata = (void *) CFBridgingRetain(data);
SDL_AddVideoDisplay(&display); SDL_AddVideoDisplay(&display);
return 0; return 0;
} }
@ -173,14 +182,14 @@ UIKit_InitModes(_THIS)
void void
UIKit_GetDisplayModes(_THIS, SDL_VideoDisplay * display) UIKit_GetDisplayModes(_THIS, SDL_VideoDisplay * display)
{ {
SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata;
@autoreleasepool { @autoreleasepool {
SDL_bool isLandscape = UIKit_IsDisplayLandscape(data->uiscreen); SDL_DisplayData *data = (__bridge SDL_DisplayData *) display->driverdata;
SDL_bool addRotation = (data->uiscreen == [UIScreen mainScreen]);
CGFloat scale = data->uiscreen.scale;
for (UIScreenMode *uimode in [data->uiscreen availableModes]) { SDL_bool isLandscape = UIKit_IsDisplayLandscape(data.uiscreen);
SDL_bool addRotation = (data.uiscreen == [UIScreen mainScreen]);
CGFloat scale = data.uiscreen.scale;
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];
@ -203,19 +212,19 @@ UIKit_GetDisplayModes(_THIS, SDL_VideoDisplay * display)
int int
UIKit_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode) UIKit_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
{ {
SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata;
SDL_DisplayModeData *modedata = (SDL_DisplayModeData *)mode->driverdata;
@autoreleasepool { @autoreleasepool {
[data->uiscreen setCurrentMode:modedata->uiscreenmode]; SDL_DisplayData *data = (__bridge SDL_DisplayData *) display->driverdata;
SDL_DisplayModeData *modedata = (__bridge SDL_DisplayModeData *)mode->driverdata;
if (data->uiscreen == [UIScreen mainScreen]) { [data.uiscreen setCurrentMode:modedata.uiscreenmode];
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];
} }
} }
@ -240,10 +249,10 @@ UIKit_QuitModes(_THIS)
UIKit_FreeDisplayModeData(mode); UIKit_FreeDisplayModeData(mode);
} }
SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata; if (display->driverdata != NULL) {
[data->uiscreen release]; CFRelease(display->driverdata);
SDL_free(data); display->driverdata = NULL;
display->driverdata = NULL; }
} }
} }
} }

View file

@ -54,8 +54,8 @@ UIKit_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context)
{ {
@autoreleasepool { @autoreleasepool {
if (context) { if (context) {
SDL_WindowData *data = (SDL_WindowData *)window->driverdata; SDL_WindowData *data = (__bridge SDL_WindowData *)window->driverdata;
[data->view setCurrentContext]; [data.view setCurrentContext];
} }
else { else {
[EAGLContext setCurrentContext: nil]; [EAGLContext setCurrentContext: nil];
@ -67,14 +67,14 @@ UIKit_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context)
void UIKit_GL_GetDrawableSize(_THIS, SDL_Window * window, int * w, int * h) void UIKit_GL_GetDrawableSize(_THIS, SDL_Window * window, int * w, int * h)
{ {
SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
@autoreleasepool { @autoreleasepool {
SDL_WindowData *data = (__bridge SDL_WindowData *)window->driverdata;
if (w) { if (w) {
*w = data->view.backingWidth; *w = data.view.backingWidth;
} }
if (h) { if (h) {
*h = data->view.backingHeight; *h = data.view.backingHeight;
} }
} }
} }
@ -97,17 +97,17 @@ UIKit_GL_LoadLibrary(_THIS, const char *path)
void UIKit_GL_SwapWindow(_THIS, SDL_Window * window) void UIKit_GL_SwapWindow(_THIS, SDL_Window * window)
{ {
@autoreleasepool { @autoreleasepool {
SDL_WindowData *data = (__bridge SDL_WindowData *)window->driverdata;
#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; if (data.view == nil) {
if (nil == data->view) {
return; return;
} }
[data->view swapBuffers]; [data.view swapBuffers];
/* You need to pump events in order for the OS to make changes visible. /* 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 We don't pump events here because we don't want iOS application events
@ -121,8 +121,8 @@ UIKit_GL_CreateContext(_THIS, SDL_Window * window)
{ {
@autoreleasepool { @autoreleasepool {
SDL_uikitopenglview *view; SDL_uikitopenglview *view;
SDL_WindowData *data = (SDL_WindowData *) window->driverdata; SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata;
UIWindow *uiwindow = data->uiwindow; UIWindow *uiwindow = data.uiwindow;
CGRect frame = UIKit_ComputeViewFrame(window, uiwindow.screen); CGRect frame = UIKit_ComputeViewFrame(window, uiwindow.screen);
EAGLSharegroup *share_group = nil; EAGLSharegroup *share_group = nil;
CGFloat scale = 1.0; CGFloat scale = 1.0;
@ -136,7 +136,7 @@ UIKit_GL_CreateContext(_THIS, SDL_Window * window)
} }
if (_this->gl_config.share_with_current_context) { if (_this->gl_config.share_with_current_context) {
SDL_uikitopenglview *view = (SDL_uikitopenglview *) SDL_GL_GetCurrentContext(); SDL_uikitopenglview *view = (__bridge SDL_uikitopenglview *) SDL_GL_GetCurrentContext();
share_group = [view.context sharegroup]; share_group = [view.context sharegroup];
} }
@ -157,21 +157,20 @@ UIKit_GL_CreateContext(_THIS, SDL_Window * window)
return NULL; return NULL;
} }
data->view = view; data.view = view;
view->viewcontroller = data->viewcontroller; view.viewcontroller = data.viewcontroller;
if (view->viewcontroller != nil) { if (view.viewcontroller != nil) {
[view->viewcontroller setView:view]; view.viewcontroller.view = view;
[view->viewcontroller retain];
} }
[uiwindow addSubview: view]; [uiwindow addSubview: view];
/* The view controller needs to be the root in order to control rotation on iOS 6.0 */ /* The view controller needs to be the root in order to control rotation on iOS 6.0 */
if (uiwindow.rootViewController == nil) { if (uiwindow.rootViewController == nil) {
uiwindow.rootViewController = view->viewcontroller; uiwindow.rootViewController = view.viewcontroller;
} }
if (UIKit_GL_MakeCurrent(_this, window, view) < 0) { if (UIKit_GL_MakeCurrent(_this, window, (__bridge SDL_GLContext)(view)) < 0) {
UIKit_GL_DeleteContext(_this, view); UIKit_GL_DeleteContext(_this, (SDL_GLContext) CFBridgingRetain(view));
return NULL; return NULL;
} }
@ -181,7 +180,7 @@ UIKit_GL_CreateContext(_THIS, SDL_Window * window)
SDL_SetKeyboardFocus(window); SDL_SetKeyboardFocus(window);
} }
return view; return (SDL_GLContext) CFBridgingRetain(view);
} }
} }
@ -190,17 +189,15 @@ UIKit_GL_DeleteContext(_THIS, SDL_GLContext context)
{ {
@autoreleasepool { @autoreleasepool {
/* the delegate has retained the view, this will release him */ /* the delegate has retained the view, this will release him */
SDL_uikitopenglview *view = (SDL_uikitopenglview *)context; SDL_uikitopenglview *view = (SDL_uikitopenglview *)CFBridgingRelease(context);
if (view->viewcontroller) { if (view.viewcontroller) {
UIWindow *uiwindow = (UIWindow *)view.superview; UIWindow *uiwindow = (UIWindow *)view.superview;
if (uiwindow.rootViewController == view->viewcontroller) { if (uiwindow.rootViewController == view.viewcontroller) {
uiwindow.rootViewController = nil; uiwindow.rootViewController = nil;
} }
[view->viewcontroller setView:nil]; view.viewcontroller.view = nil;
[view->viewcontroller release];
} }
[view removeFromSuperview]; [view removeFromSuperview];
[view release];
} }
} }

View file

@ -44,7 +44,7 @@
majorVersion:(int)majorVersion majorVersion:(int)majorVersion
shareGroup:(EAGLSharegroup*)shareGroup; shareGroup:(EAGLSharegroup*)shareGroup;
@property (nonatomic, retain, readonly) EAGLContext *context; @property (nonatomic, strong, readonly) EAGLContext *context;
/* The width and height of the drawable in pixels (as opposed to points.) */ /* The width and height of the drawable in pixels (as opposed to points.) */
@property (nonatomic, readonly) int backingWidth; @property (nonatomic, readonly) int backingWidth;

View file

@ -85,7 +85,6 @@
context = [[EAGLContext alloc] initWithAPI:api sharegroup:shareGroup]; context = [[EAGLContext alloc] initWithAPI:api sharegroup:shareGroup];
if (!context || ![EAGLContext setCurrentContext:context]) { if (!context || ![EAGLContext setCurrentContext:context]) {
[self release];
SDL_SetError("OpenGL ES %d not supported", majorVersion); SDL_SetError("OpenGL ES %d not supported", majorVersion);
return nil; return nil;
} }
@ -118,7 +117,6 @@
glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer); glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
if (![context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:eaglLayer]) { if (![context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:eaglLayer]) {
[self release];
SDL_SetError("Failed creating OpenGL ES drawable"); SDL_SetError("Failed creating OpenGL ES drawable");
return nil; return nil;
} }
@ -154,7 +152,6 @@
} }
if (glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES) { if (glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES) {
[self release];
SDL_SetError("Failed creating OpenGL ES framebuffer"); SDL_SetError("Failed creating OpenGL ES framebuffer");
return nil; return nil;
} }
@ -268,12 +265,10 @@
- (void)dealloc - (void)dealloc
{ {
[self destroyFramebuffer];
if ([EAGLContext currentContext] == context) { if ([EAGLContext currentContext] == context) {
[self destroyFramebuffer];
[EAGLContext setCurrentContext:nil]; [EAGLContext setCurrentContext:nil];
} }
[context release];
[super dealloc];
} }
@end @end

View file

@ -31,13 +31,12 @@
#endif #endif
#if SDL_IPHONE_KEYBOARD #if SDL_IPHONE_KEYBOARD
@interface SDL_uikitview : UIView<UITextFieldDelegate> { @interface SDL_uikitview : UIView <UITextFieldDelegate>
#else #else
@interface SDL_uikitview : UIView { @interface SDL_uikitview : UIView
#endif #endif
@public
SDL_uikitviewcontroller *viewcontroller; @property (nonatomic, weak) SDL_uikitviewcontroller *viewcontroller;
}
- (CGPoint)touchLocation:(UITouch *)touch shouldNormalize:(BOOL)normalize; - (CGPoint)touchLocation:(UITouch *)touch shouldNormalize:(BOOL)normalize;
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event; - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;

View file

@ -51,6 +51,8 @@ void _uikit_keyboard_init();
} }
@synthesize viewcontroller;
- (id)initWithFrame:(CGRect)frame - (id)initWithFrame:(CGRect)frame
{ {
if (self = [super initWithFrame: frame]) { if (self = [super initWithFrame: frame]) {
@ -88,10 +90,10 @@ void _uikit_keyboard_init();
CGPoint locationInView = [self touchLocation:touch shouldNormalize:NO]; CGPoint locationInView = [self touchLocation:touch shouldNormalize:NO];
/* send moved event */ /* send moved event */
SDL_SendMouseMotion(viewcontroller.window, SDL_TOUCH_MOUSEID, 0, locationInView.x, locationInView.y); SDL_SendMouseMotion(self.viewcontroller.window, SDL_TOUCH_MOUSEID, 0, locationInView.x, locationInView.y);
/* send mouse down event */ /* send mouse down event */
SDL_SendMouseButton(viewcontroller.window, SDL_TOUCH_MOUSEID, SDL_PRESSED, SDL_BUTTON_LEFT); SDL_SendMouseButton(self.viewcontroller.window, SDL_TOUCH_MOUSEID, SDL_PRESSED, SDL_BUTTON_LEFT);
leftFingerDown = touch; leftFingerDown = touch;
} }
@ -123,7 +125,7 @@ void _uikit_keyboard_init();
for (UITouch *touch in touches) { for (UITouch *touch in touches) {
if (touch == leftFingerDown) { if (touch == leftFingerDown) {
/* send mouse up */ /* send mouse up */
SDL_SendMouseButton(viewcontroller.window, SDL_TOUCH_MOUSEID, SDL_RELEASED, SDL_BUTTON_LEFT); SDL_SendMouseButton(self.viewcontroller.window, SDL_TOUCH_MOUSEID, SDL_RELEASED, SDL_BUTTON_LEFT);
leftFingerDown = nil; leftFingerDown = nil;
} }
@ -162,7 +164,7 @@ void _uikit_keyboard_init();
CGPoint locationInView = [self touchLocation:touch shouldNormalize:NO]; CGPoint locationInView = [self touchLocation:touch shouldNormalize:NO];
/* send moved event */ /* send moved event */
SDL_SendMouseMotion(viewcontroller.window, SDL_TOUCH_MOUSEID, 0, locationInView.x, locationInView.y); SDL_SendMouseMotion(self.viewcontroller.window, SDL_TOUCH_MOUSEID, 0, locationInView.x, locationInView.y);
} }
CGPoint locationInView = [self touchLocation:touch shouldNormalize:YES]; CGPoint locationInView = [self touchLocation:touch shouldNormalize:YES];
@ -212,7 +214,6 @@ void _uikit_keyboard_init();
keyboardVisible = NO; keyboardVisible = NO;
/* add the UITextField (hidden) to our view */ /* add the UITextField (hidden) to our view */
[self addSubview: textField]; [self addSubview: textField];
[textField release];
_uikit_keyboard_init(); _uikit_keyboard_init();
} }
@ -301,8 +302,8 @@ static SDL_uikitview * getWindowView(SDL_Window * window)
return nil; return nil;
} }
SDL_WindowData *data = (SDL_WindowData *)window->driverdata; SDL_WindowData *data = (__bridge SDL_WindowData *)window->driverdata;
SDL_uikitview *view = data != NULL ? data->view : nil; SDL_uikitview *view = data != nil ? data.view : nil;
if (view == nil) { if (view == nil) {
SDL_SetError("Window has no view"); SDL_SetError("Window has no view");
@ -352,9 +353,9 @@ SDL_bool UIKit_IsScreenKeyboardShown(_THIS, SDL_Window *window)
void _uikit_keyboard_update() { void _uikit_keyboard_update() {
SDL_Window *window = SDL_GetFocusWindow(); SDL_Window *window = SDL_GetFocusWindow();
if (!window) { return; } if (!window) { return; }
SDL_WindowData *data = (SDL_WindowData *)window->driverdata; SDL_WindowData *data = (__bridge SDL_WindowData *)window->driverdata;
if (!data) { return; } if (!data) { return; }
SDL_uikitview *view = data->view; SDL_uikitview *view = data.view;
if (!view) { return; } if (!view) { return; }
SDL_Rect r = view.textInputRect; SDL_Rect r = view.textInputRect;

View file

@ -26,8 +26,6 @@
#import "SDL_uikitopenglview.h" #import "SDL_uikitopenglview.h"
#import "SDL_uikitviewcontroller.h" #import "SDL_uikitviewcontroller.h"
typedef struct SDL_WindowData SDL_WindowData;
extern int UIKit_CreateWindow(_THIS, SDL_Window * window); extern int UIKit_CreateWindow(_THIS, SDL_Window * window);
extern void UIKit_ShowWindow(_THIS, SDL_Window * window); extern void UIKit_ShowWindow(_THIS, SDL_Window * window);
extern void UIKit_HideWindow(_THIS, SDL_Window * window); extern void UIKit_HideWindow(_THIS, SDL_Window * window);
@ -44,12 +42,13 @@ extern SDL_bool UIKit_GetWindowWMInfo(_THIS, SDL_Window * window,
@end @end
struct SDL_WindowData @interface SDL_WindowData : NSObject
{
SDL_uikitwindow *uiwindow; @property (nonatomic, strong) SDL_uikitwindow *uiwindow;
SDL_uikitopenglview *view; @property (nonatomic, strong) SDL_uikitopenglview *view;
SDL_uikitviewcontroller *viewcontroller; @property (nonatomic, strong) SDL_uikitviewcontroller *viewcontroller;
};
@end
#endif /* _SDL_uikitwindow_h */ #endif /* _SDL_uikitwindow_h */

View file

@ -56,35 +56,41 @@
@end @end
@implementation SDL_WindowData
@synthesize uiwindow;
@synthesize view;
@synthesize viewcontroller;
@end
static int SetupWindowData(_THIS, SDL_Window *window, SDL_uikitwindow *uiwindow, SDL_bool created) static int SetupWindowData(_THIS, SDL_Window *window, SDL_uikitwindow *uiwindow, SDL_bool created)
{ {
SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window); SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
SDL_DisplayData *displaydata = (SDL_DisplayData *) display->driverdata; SDL_DisplayData *displaydata = (__bridge SDL_DisplayData *) display->driverdata;
SDL_WindowData *data;
/* Allocate the window data */ /* Allocate the window data */
data = (SDL_WindowData *)SDL_malloc(sizeof(*data)); SDL_WindowData *data = [[SDL_WindowData alloc] init];
if (!data) { if (!data) {
return SDL_OutOfMemory(); return SDL_OutOfMemory();
} }
data->uiwindow = uiwindow;
data->viewcontroller = nil; data.uiwindow = uiwindow;
data->view = nil;
/* Fill in the SDL window with the window data */ /* Fill in the SDL window with the window data */
{ {
window->x = 0; window->x = 0;
window->y = 0; window->y = 0;
CGRect frame = UIKit_ComputeViewFrame(window, displaydata->uiscreen); CGRect frame = UIKit_ComputeViewFrame(window, displaydata.uiscreen);
/* Get frame dimensions */ /* Get frame dimensions */
int width = (int) frame.size.width; int width = (int) frame.size.width;
int height = (int) frame.size.height; int height = (int) frame.size.height;
/* Make sure the width/height are oriented correctly */ /* Make sure the width/height are oriented correctly */
if (UIKit_IsDisplayLandscape(displaydata->uiscreen) != (width > height)) { if (UIKit_IsDisplayLandscape(displaydata.uiscreen) != (width > height)) {
int temp = width; int temp = width;
width = height; width = height;
height = temp; height = temp;
@ -94,7 +100,7 @@ static int SetupWindowData(_THIS, SDL_Window *window, SDL_uikitwindow *uiwindow,
window->h = height; window->h = height;
} }
window->driverdata = data; window->driverdata = (void *) CFBridgingRetain(data);
/* only one window on iOS, always shown */ /* only one window on iOS, always shown */
window->flags &= ~SDL_WINDOW_HIDDEN; window->flags &= ~SDL_WINDOW_HIDDEN;
@ -103,7 +109,7 @@ static int SetupWindowData(_THIS, SDL_Window *window, SDL_uikitwindow *uiwindow,
* This is only set if the window is on the main screen. Other screens * This is only set if the window is on the main screen. Other screens
* just force the window to have the borderless flag. * just force the window to have the borderless flag.
*/ */
if (displaydata->uiscreen == [UIScreen mainScreen]) { if (displaydata.uiscreen == [UIScreen mainScreen]) {
window->flags |= SDL_WINDOW_INPUT_FOCUS; /* always has input focus */ window->flags |= SDL_WINDOW_INPUT_FOCUS; /* always has input focus */
/* This was setup earlier for our window, and in iOS 7 is controlled by the view, not the application /* This was setup earlier for our window, and in iOS 7 is controlled by the view, not the application
@ -123,8 +129,8 @@ static int SetupWindowData(_THIS, SDL_Window *window, SDL_uikitwindow *uiwindow,
* device orientation changes. This will trigger resize events, if * device orientation changes. This will trigger resize events, if
* appropriate. * appropriate.
*/ */
data->viewcontroller = [[SDL_uikitviewcontroller alloc] initWithSDLWindow:window]; data.viewcontroller = [[SDL_uikitviewcontroller alloc] initWithSDLWindow:window];
[data->viewcontroller setTitle:@"SDL App"]; /* !!! FIXME: hook up SDL_SetWindowTitle() */ data.viewcontroller.title = @"SDL App"; /* !!! FIXME: hook up SDL_SetWindowTitle() */
return 0; return 0;
} }
@ -134,9 +140,9 @@ UIKit_CreateWindow(_THIS, SDL_Window *window)
{ {
@autoreleasepool { @autoreleasepool {
SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window); SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata; SDL_DisplayData *data = (__bridge SDL_DisplayData *) display->driverdata;
const BOOL external = ([UIScreen mainScreen] != data->uiscreen); const BOOL external = ([UIScreen mainScreen] != data.uiscreen);
const CGSize origsize = [[data->uiscreen currentMode] size]; 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);
@ -164,8 +170,8 @@ UIKit_CreateWindow(_THIS, SDL_Window *window)
} }
if (bestmode) { if (bestmode) {
SDL_DisplayModeData *modedata = (SDL_DisplayModeData *)bestmode->driverdata; SDL_DisplayModeData *modedata = (__bridge SDL_DisplayModeData *)bestmode->driverdata;
[data->uiscreen setCurrentMode:modedata->uiscreenmode]; [data.uiscreen setCurrentMode:modedata.uiscreenmode];
/* desktop_mode doesn't change here (the higher level will /* desktop_mode doesn't change here (the higher level will
* use it to set all the screens back to their defaults * use it to set all the screens back to their defaults
@ -175,7 +181,7 @@ UIKit_CreateWindow(_THIS, SDL_Window *window)
} }
} }
if (data->uiscreen == [UIScreen mainScreen]) { if (data.uiscreen == [UIScreen mainScreen]) {
if (window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_BORDERLESS)) { if (window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_BORDERLESS)) {
[UIApplication sharedApplication].statusBarHidden = YES; [UIApplication sharedApplication].statusBarHidden = YES;
} else { } else {
@ -185,11 +191,11 @@ UIKit_CreateWindow(_THIS, SDL_Window *window)
if (!(window->flags & SDL_WINDOW_RESIZABLE)) { if (!(window->flags & SDL_WINDOW_RESIZABLE)) {
if (window->w > window->h) { if (window->w > window->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 (window->w < window->h) { } else if (window->w < window->h) {
if (UIKit_IsDisplayLandscape(data->uiscreen)) { if (UIKit_IsDisplayLandscape(data.uiscreen)) {
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait animated:NO]; [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait animated:NO];
} }
} }
@ -197,7 +203,7 @@ UIKit_CreateWindow(_THIS, SDL_Window *window)
/* ignore the size user requested, and make a fullscreen window */ /* ignore the size user requested, and make a fullscreen window */
/* !!! FIXME: can we have a smaller view? */ /* !!! FIXME: can we have a smaller view? */
SDL_uikitwindow *uiwindow = [[SDL_uikitwindow alloc] initWithFrame:data->uiscreen.bounds]; SDL_uikitwindow *uiwindow = [[SDL_uikitwindow alloc] initWithFrame:data.uiscreen.bounds];
/* put the window on an external display if appropriate. This implicitly /* put the window on an external display if appropriate. This implicitly
* does [uiwindow setframe:[uiscreen bounds]], so don't do it on the * does [uiwindow setframe:[uiscreen bounds]], so don't do it on the
@ -205,13 +211,13 @@ UIKit_CreateWindow(_THIS, SDL_Window *window)
* status bar real estate. * status bar real estate.
*/ */
if (external) { if (external) {
[uiwindow setScreen:data->uiscreen]; [uiwindow setScreen:data.uiscreen];
} }
if (SetupWindowData(_this, window, uiwindow, SDL_TRUE) < 0) { if (SetupWindowData(_this, window, uiwindow, SDL_TRUE) < 0) {
[uiwindow release];
return -1; return -1;
} }
} }
return 1; return 1;
@ -221,7 +227,7 @@ void
UIKit_ShowWindow(_THIS, SDL_Window * window) UIKit_ShowWindow(_THIS, SDL_Window * window)
{ {
@autoreleasepool { @autoreleasepool {
UIWindow *uiwindow = ((SDL_WindowData *) window->driverdata)->uiwindow; UIWindow *uiwindow = ((__bridge SDL_WindowData *) window->driverdata).uiwindow;
[uiwindow makeKeyAndVisible]; [uiwindow makeKeyAndVisible];
} }
@ -231,7 +237,7 @@ void
UIKit_HideWindow(_THIS, SDL_Window * window) UIKit_HideWindow(_THIS, SDL_Window * window)
{ {
@autoreleasepool { @autoreleasepool {
UIWindow *uiwindow = ((SDL_WindowData *) window->driverdata)->uiwindow; UIWindow *uiwindow = ((__bridge SDL_WindowData *) window->driverdata).uiwindow;
uiwindow.hidden = YES; uiwindow.hidden = YES;
} }
@ -251,11 +257,11 @@ UIKit_RaiseWindow(_THIS, SDL_Window * window)
static void static void
UIKit_UpdateWindowBorder(_THIS, SDL_Window * window) UIKit_UpdateWindowBorder(_THIS, SDL_Window * window)
{ {
SDL_WindowData *windowdata = (SDL_WindowData *) window->driverdata; SDL_WindowData *windowdata = (__bridge SDL_WindowData *) window->driverdata;
SDL_uikitviewcontroller *viewcontroller = windowdata->viewcontroller; SDL_uikitviewcontroller *viewcontroller = windowdata.viewcontroller;
CGRect frame; CGRect frame;
if (windowdata->uiwindow.screen == [UIScreen mainScreen]) { if (windowdata.uiwindow.screen == [UIScreen mainScreen]) {
if (window->flags & (SDL_WINDOW_FULLSCREEN | SDL_WINDOW_BORDERLESS)) { if (window->flags & (SDL_WINDOW_FULLSCREEN | SDL_WINDOW_BORDERLESS)) {
[UIApplication sharedApplication].statusBarHidden = YES; [UIApplication sharedApplication].statusBarHidden = YES;
} else { } else {
@ -269,11 +275,11 @@ UIKit_UpdateWindowBorder(_THIS, SDL_Window * window)
} }
/* Update the view's frame to account for the status bar change. */ /* Update the view's frame to account for the status bar change. */
frame = UIKit_ComputeViewFrame(window, windowdata->uiwindow.screen); frame = UIKit_ComputeViewFrame(window, windowdata.uiwindow.screen);
windowdata->view.frame = frame; windowdata.view.frame = frame;
[windowdata->view setNeedsLayout]; [windowdata.view setNeedsLayout];
[windowdata->view layoutIfNeeded]; [windowdata.view layoutIfNeeded];
/* Get frame dimensions */ /* Get frame dimensions */
int width = (int) frame.size.width; int width = (int) frame.size.width;
@ -308,13 +314,9 @@ UIKit_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display
void void
UIKit_DestroyWindow(_THIS, SDL_Window * window) UIKit_DestroyWindow(_THIS, SDL_Window * window)
{ {
SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
@autoreleasepool { @autoreleasepool {
if (data) { if (window->driverdata != NULL) {
[data->viewcontroller release]; CFRelease(window->driverdata);
[data->uiwindow release];
SDL_free(data);
} }
} }
@ -325,7 +327,7 @@ SDL_bool
UIKit_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info) UIKit_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info)
{ {
@autoreleasepool { @autoreleasepool {
UIWindow *uiwindow = ((SDL_WindowData *) window->driverdata)->uiwindow; UIWindow *uiwindow = ((__bridge 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;
@ -342,14 +344,14 @@ UIKit_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info)
int int
SDL_iPhoneSetAnimationCallback(SDL_Window * window, int interval, void (*callback)(void*), void *callbackParam) SDL_iPhoneSetAnimationCallback(SDL_Window * window, int interval, void (*callback)(void*), void *callbackParam)
{ {
SDL_WindowData *data = window ? (SDL_WindowData *)window->driverdata : NULL;
if (!data || !data->view) {
return SDL_SetError("Invalid window or view not set");
}
@autoreleasepool { @autoreleasepool {
[data->view setAnimationCallback:interval callback:callback callbackParam:callbackParam]; SDL_WindowData *data = window ? (__bridge SDL_WindowData *)window->driverdata : nil;
if (!data || !data.view) {
return SDL_SetError("Invalid window or view not set");
}
[data.view setAnimationCallback:interval callback:callback callbackParam:callbackParam];
} }
return 0; return 0;