Updated SDL2 to the latest Mercurial revision.

This commit is contained in:
Alex Szpakowski
2015-08-22 14:16:20 -03:00
parent 0753e6b560
commit c47a4b56bb
916 changed files with 16588 additions and 22006 deletions
+91 -365
View File
@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2015 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@@ -24,438 +24,164 @@
#include "SDL_uikitview.h"
#include "../../events/SDL_keyboard_c.h"
#include "../../events/SDL_mouse_c.h"
#include "../../events/SDL_touch_c.h"
#include "../../events/SDL_events_c.h"
#if SDL_IPHONE_KEYBOARD
#include "keyinfotable.h"
#endif
#include "SDL_uikitappdelegate.h"
#include "SDL_uikitmodes.h"
#include "SDL_uikitwindow.h"
#import "SDL_uikitappdelegate.h"
#import "SDL_uikitmodes.h"
#import "SDL_uikitwindow.h"
void _uikit_keyboard_init() ;
@implementation SDL_uikitview {
SDL_Window *sdlwindow;
@implementation SDL_uikitview
- (void)dealloc
{
[super dealloc];
SDL_TouchID touchId;
UITouch * __weak firstFingerDown;
}
- (id)initWithFrame:(CGRect)frame
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame: frame];
if ((self = [super initWithFrame:frame])) {
self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
self.autoresizesSubviews = YES;
#if SDL_IPHONE_KEYBOARD
[self initializeKeyboard];
#endif
self.multipleTouchEnabled = YES;
self.multipleTouchEnabled = YES;
touchId = 1;
SDL_AddTouch(touchId, "");
touchId = 1;
SDL_AddTouch(touchId, "");
}
return self;
}
- (void)setSDLWindow:(SDL_Window *)window
{
SDL_WindowData *data = nil;
if (window == sdlwindow) {
return;
}
/* Remove ourself from the old window. */
if (sdlwindow) {
SDL_uikitview *view = nil;
data = (__bridge SDL_WindowData *) sdlwindow->driverdata;
[data.views removeObject:self];
[self removeFromSuperview];
/* Restore the next-oldest view in the old window. */
view = data.views.lastObject;
data.viewcontroller.view = view;
data.uiwindow.rootViewController = nil;
data.uiwindow.rootViewController = data.viewcontroller;
[data.uiwindow layoutIfNeeded];
}
/* Add ourself to the new window. */
if (window) {
data = (__bridge SDL_WindowData *) window->driverdata;
/* Make sure the SDL window has a strong reference to this view. */
[data.views addObject:self];
/* Replace the view controller's old view with this one. */
[data.viewcontroller.view removeFromSuperview];
data.viewcontroller.view = self;
/* The root view controller handles rotation and the status bar.
* Assigning it also adds the controller's view to the window. We
* explicitly re-set it to make sure the view is properly attached to
* the window. Just adding the sub-view if the root view controller is
* already correct causes orientation issues on iOS 7 and below. */
data.uiwindow.rootViewController = nil;
data.uiwindow.rootViewController = data.viewcontroller;
/* The view's bounds may not be correct until the next event cycle. That
* might happen after the current dimensions are queried, so we force a
* layout now to immediately update the bounds. */
[data.uiwindow layoutIfNeeded];
}
sdlwindow = window;
}
- (CGPoint)touchLocation:(UITouch *)touch shouldNormalize:(BOOL)normalize
{
CGPoint point = [touch locationInView: self];
/* Get the display scale and apply that to the input coordinates */
SDL_Window *window = self->viewcontroller.window;
SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
SDL_DisplayModeData *displaymodedata = (SDL_DisplayModeData *) display->current_mode.driverdata;
CGPoint point = [touch locationInView:self];
if (normalize) {
CGRect bounds = [self bounds];
CGRect bounds = self.bounds;
point.x /= bounds.size.width;
point.y /= bounds.size.height;
} else {
point.x *= displaymodedata->scale;
point.y *= displaymodedata->scale;
}
return point;
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
NSEnumerator *enumerator = [touches objectEnumerator];
UITouch *touch = (UITouch*)[enumerator nextObject];
while (touch) {
if (!leftFingerDown) {
for (UITouch *touch in touches) {
if (!firstFingerDown) {
CGPoint locationInView = [self touchLocation:touch shouldNormalize:NO];
/* send moved event */
SDL_SendMouseMotion(self->viewcontroller.window, SDL_TOUCH_MOUSEID, 0, locationInView.x, locationInView.y);
/* send mouse moved event */
SDL_SendMouseMotion(sdlwindow, SDL_TOUCH_MOUSEID, 0, locationInView.x, locationInView.y);
/* send mouse down event */
SDL_SendMouseButton(self->viewcontroller.window, SDL_TOUCH_MOUSEID, SDL_PRESSED, SDL_BUTTON_LEFT);
SDL_SendMouseButton(sdlwindow, SDL_TOUCH_MOUSEID, SDL_PRESSED, SDL_BUTTON_LEFT);
leftFingerDown = touch;
firstFingerDown = touch;
}
CGPoint locationInView = [self touchLocation:touch shouldNormalize:YES];
#ifdef IPHONE_TOUCH_EFFICIENT_DANGEROUS
/* FIXME: TODO: Using touch as the fingerId is potentially dangerous
* It is also much more efficient than storing the UITouch pointer
* and comparing it to the incoming event.
*/
SDL_SendTouch(touchId, (SDL_FingerID)((size_t)touch),
SDL_TRUE, locationInView.x, locationInView.y, 1.0f);
#else
int i;
for(i = 0; i < MAX_SIMULTANEOUS_TOUCHES; i++) {
if (finger[i] == NULL) {
finger[i] = touch;
SDL_SendTouch(touchId, i,
SDL_TRUE, locationInView.x, locationInView.y, 1.0f);
break;
}
}
#endif
touch = (UITouch*)[enumerator nextObject];
}
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
NSEnumerator *enumerator = [touches objectEnumerator];
UITouch *touch = (UITouch*)[enumerator nextObject];
while(touch) {
if (touch == leftFingerDown) {
for (UITouch *touch in touches) {
if (touch == firstFingerDown) {
/* send mouse up */
SDL_SendMouseButton(self->viewcontroller.window, SDL_TOUCH_MOUSEID, SDL_RELEASED, SDL_BUTTON_LEFT);
leftFingerDown = nil;
SDL_SendMouseButton(sdlwindow, SDL_TOUCH_MOUSEID, SDL_RELEASED, SDL_BUTTON_LEFT);
firstFingerDown = nil;
}
CGPoint locationInView = [self touchLocation:touch shouldNormalize:YES];
#ifdef IPHONE_TOUCH_EFFICIENT_DANGEROUS
SDL_SendTouch(touchId, (long)touch,
SDL_SendTouch(touchId, (SDL_FingerID)((size_t)touch),
SDL_FALSE, locationInView.x, locationInView.y, 1.0f);
#else
int i;
for (i = 0; i < MAX_SIMULTANEOUS_TOUCHES; i++) {
if (finger[i] == touch) {
SDL_SendTouch(touchId, i,
SDL_FALSE, locationInView.x, locationInView.y, 1.0f);
finger[i] = NULL;
break;
}
}
#endif
touch = (UITouch*)[enumerator nextObject];
}
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
/*
this can happen if the user puts more than 5 touches on the screen
at once, or perhaps in other circumstances. Usually (it seems)
all active touches are canceled.
*/
[self touchesEnded: touches withEvent: event];
[self touchesEnded:touches withEvent:event];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
NSEnumerator *enumerator = [touches objectEnumerator];
UITouch *touch = (UITouch*)[enumerator nextObject];
while (touch) {
if (touch == leftFingerDown) {
for (UITouch *touch in touches) {
if (touch == firstFingerDown) {
CGPoint locationInView = [self touchLocation:touch shouldNormalize:NO];
/* send moved event */
SDL_SendMouseMotion(self->viewcontroller.window, SDL_TOUCH_MOUSEID, 0, locationInView.x, locationInView.y);
SDL_SendMouseMotion(sdlwindow, SDL_TOUCH_MOUSEID, 0, locationInView.x, locationInView.y);
}
CGPoint locationInView = [self touchLocation:touch shouldNormalize:YES];
#ifdef IPHONE_TOUCH_EFFICIENT_DANGEROUS
SDL_SendTouchMotion(touchId, (long)touch,
SDL_SendTouchMotion(touchId, (SDL_FingerID)((size_t)touch),
locationInView.x, locationInView.y, 1.0f);
#else
int i;
for (i = 0; i < MAX_SIMULTANEOUS_TOUCHES; i++) {
if (finger[i] == touch) {
SDL_SendTouchMotion(touchId, i,
locationInView.x, locationInView.y, 1.0f);
break;
}
}
#endif
touch = (UITouch*)[enumerator nextObject];
}
}
/*
---- Keyboard related functionality below this line ----
*/
#if SDL_IPHONE_KEYBOARD
@synthesize textInputRect = textInputRect;
@synthesize keyboardHeight = keyboardHeight;
/* Is the iPhone virtual keyboard visible onscreen? */
- (BOOL)keyboardVisible
{
return keyboardVisible;
}
/* Set ourselves up as a UITextFieldDelegate */
- (void)initializeKeyboard
{
textField = [[UITextField alloc] initWithFrame: CGRectZero];
textField.delegate = self;
/* placeholder so there is something to delete! */
textField.text = @" ";
/* set UITextInputTrait properties, mostly to defaults */
textField.autocapitalizationType = UITextAutocapitalizationTypeNone;
textField.autocorrectionType = UITextAutocorrectionTypeNo;
textField.enablesReturnKeyAutomatically = NO;
textField.keyboardAppearance = UIKeyboardAppearanceDefault;
textField.keyboardType = UIKeyboardTypeDefault;
textField.returnKeyType = UIReturnKeyDefault;
textField.secureTextEntry = NO;
textField.hidden = YES;
keyboardVisible = NO;
/* add the UITextField (hidden) to our view */
[self addSubview: textField];
[textField release];
_uikit_keyboard_init();
}
/* reveal onscreen virtual keyboard */
- (void)showKeyboard
{
keyboardVisible = YES;
[textField becomeFirstResponder];
}
/* hide onscreen virtual keyboard */
- (void)hideKeyboard
{
keyboardVisible = NO;
[textField resignFirstResponder];
}
/* UITextFieldDelegate method. Invoked when user types something. */
- (BOOL)textField:(UITextField *)_textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if ([string length] == 0) {
/* it wants to replace text with nothing, ie a delete */
SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_BACKSPACE);
SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_BACKSPACE);
}
else {
/* go through all the characters in the string we've been sent
and convert them to key presses */
int i;
for (i = 0; i < [string length]; i++) {
unichar c = [string characterAtIndex: i];
Uint16 mod = 0;
SDL_Scancode code;
if (c < 127) {
/* figure out the SDL_Scancode and SDL_keymod for this unichar */
code = unicharToUIKeyInfoTable[c].code;
mod = unicharToUIKeyInfoTable[c].mod;
}
else {
/* we only deal with ASCII right now */
code = SDL_SCANCODE_UNKNOWN;
mod = 0;
}
if (mod & KMOD_SHIFT) {
/* If character uses shift, press shift down */
SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_LSHIFT);
}
/* send a keydown and keyup even for the character */
SDL_SendKeyboardKey(SDL_PRESSED, code);
SDL_SendKeyboardKey(SDL_RELEASED, code);
if (mod & KMOD_SHIFT) {
/* If character uses shift, press shift back up */
SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_LSHIFT);
}
}
SDL_SendKeyboardText([string UTF8String]);
}
return NO; /* don't allow the edit! (keep placeholder text there) */
}
/* Terminates the editing session */
- (BOOL)textFieldShouldReturn:(UITextField*)_textField
{
SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_RETURN);
SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_RETURN);
SDL_StopTextInput();
return YES;
}
#endif
@end
/* iPhone keyboard addition functions */
#if SDL_IPHONE_KEYBOARD
static SDL_uikitview * getWindowView(SDL_Window * window)
{
if (window == NULL) {
SDL_SetError("Window does not exist");
return nil;
}
SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
SDL_uikitview *view = data != NULL ? data->view : nil;
if (view == nil) {
SDL_SetError("Window has no view");
}
return view;
}
SDL_bool UIKit_HasScreenKeyboardSupport(_THIS)
{
return SDL_TRUE;
}
void UIKit_ShowScreenKeyboard(_THIS, SDL_Window *window)
{
SDL_uikitview *view = getWindowView(window);
if (view != nil) {
[view showKeyboard];
}
}
void UIKit_HideScreenKeyboard(_THIS, SDL_Window *window)
{
SDL_uikitview *view = getWindowView(window);
if (view != nil) {
[view hideKeyboard];
}
}
SDL_bool UIKit_IsScreenKeyboardShown(_THIS, SDL_Window *window)
{
SDL_uikitview *view = getWindowView(window);
if (view == nil) {
return 0;
}
return view.keyboardVisible;
}
void _uikit_keyboard_update() {
SDL_Window *window = SDL_GetFocusWindow();
if (!window) { return; }
SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
if (!data) { return; }
SDL_uikitview *view = data->view;
if (!view) { return; }
SDL_Rect r = view.textInputRect;
int height = view.keyboardHeight;
int offsetx = 0;
int offsety = 0;
float scale = [UIScreen mainScreen].scale;
if (height) {
int sw,sh;
SDL_GetWindowSize(window,&sw,&sh);
int bottom = (r.y + r.h);
int kbottom = sh - height;
if (kbottom < bottom) {
offsety = kbottom-bottom;
}
}
UIInterfaceOrientation ui_orient = [[UIApplication sharedApplication] statusBarOrientation];
if (ui_orient == UIInterfaceOrientationLandscapeLeft) {
int tmp = offsetx; offsetx = offsety; offsety = tmp;
}
if (ui_orient == UIInterfaceOrientationLandscapeRight) {
offsety = -offsety;
int tmp = offsetx; offsetx = offsety; offsety = tmp;
}
if (ui_orient == UIInterfaceOrientationPortraitUpsideDown) {
offsety = -offsety;
}
offsetx /= scale;
offsety /= scale;
view.frame = CGRectMake(offsetx,offsety,view.frame.size.width,view.frame.size.height);
}
void _uikit_keyboard_set_height(int height) {
SDL_uikitview *view = getWindowView(SDL_GetFocusWindow());
if (view == nil) {
return ;
}
view.keyboardHeight = height;
_uikit_keyboard_update();
}
void _uikit_keyboard_init() {
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
NSOperationQueue *queue = [NSOperationQueue mainQueue];
[center addObserverForName:UIKeyboardWillShowNotification
object:nil
queue:queue
usingBlock:^(NSNotification *notification) {
int height = 0;
CGSize keyboardSize = [[[notification userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
height = keyboardSize.height;
UIInterfaceOrientation ui_orient = [[UIApplication sharedApplication] statusBarOrientation];
if (ui_orient == UIInterfaceOrientationLandscapeRight || ui_orient == UIInterfaceOrientationLandscapeLeft) {
height = keyboardSize.width;
}
height *= [UIScreen mainScreen].scale;
_uikit_keyboard_set_height(height);
}
];
[center addObserverForName:UIKeyboardDidHideNotification
object:nil
queue:queue
usingBlock:^(NSNotification *notification) {
_uikit_keyboard_set_height(0);
}
];
}
void
UIKit_SetTextInputRect(_THIS, SDL_Rect *rect)
{
if (!rect) {
SDL_InvalidParamError("rect");
return;
}
SDL_uikitview *view = getWindowView(SDL_GetFocusWindow());
if (view == nil) {
return ;
}
view.textInputRect = *rect;
}
#endif /* SDL_IPHONE_KEYBOARD */
#endif /* SDL_VIDEO_DRIVER_UIKIT */
/* vi: set ts=4 sw=4 expandtab: */