summaryrefslogtreecommitdiff
path: root/source/3rd-party/SDL2/src/video/uikit
diff options
context:
space:
mode:
Diffstat (limited to 'source/3rd-party/SDL2/src/video/uikit')
-rw-r--r--source/3rd-party/SDL2/src/video/uikit/SDL_uikitappdelegate.h47
-rw-r--r--source/3rd-party/SDL2/src/video/uikit/SDL_uikitappdelegate.m516
-rw-r--r--source/3rd-party/SDL2/src/video/uikit/SDL_uikitclipboard.h35
-rw-r--r--source/3rd-party/SDL2/src/video/uikit/SDL_uikitclipboard.m111
-rw-r--r--source/3rd-party/SDL2/src/video/uikit/SDL_uikitevents.h30
-rw-r--r--source/3rd-party/SDL2/src/video/uikit/SDL_uikitevents.m73
-rw-r--r--source/3rd-party/SDL2/src/video/uikit/SDL_uikitmessagebox.h31
-rw-r--r--source/3rd-party/SDL2/src/video/uikit/SDL_uikitmessagebox.m208
-rw-r--r--source/3rd-party/SDL2/src/video/uikit/SDL_uikitmetalview.h58
-rw-r--r--source/3rd-party/SDL2/src/video/uikit/SDL_uikitmetalview.m132
-rw-r--r--source/3rd-party/SDL2/src/video/uikit/SDL_uikitmodes.h54
-rw-r--r--source/3rd-party/SDL2/src/video/uikit/SDL_uikitmodes.m380
-rw-r--r--source/3rd-party/SDL2/src/video/uikit/SDL_uikitopengles.h40
-rw-r--r--source/3rd-party/SDL2/src/video/uikit/SDL_uikitopengles.m250
-rw-r--r--source/3rd-party/SDL2/src/video/uikit/SDL_uikitopenglview.h60
-rw-r--r--source/3rd-party/SDL2/src/video/uikit/SDL_uikitopenglview.m384
-rw-r--r--source/3rd-party/SDL2/src/video/uikit/SDL_uikitvideo.h46
-rw-r--r--source/3rd-party/SDL2/src/video/uikit/SDL_uikitvideo.m249
-rw-r--r--source/3rd-party/SDL2/src/video/uikit/SDL_uikitview.h41
-rw-r--r--source/3rd-party/SDL2/src/video/uikit/SDL_uikitview.m328
-rw-r--r--source/3rd-party/SDL2/src/video/uikit/SDL_uikitviewcontroller.h91
-rw-r--r--source/3rd-party/SDL2/src/video/uikit/SDL_uikitviewcontroller.m553
-rw-r--r--source/3rd-party/SDL2/src/video/uikit/SDL_uikitvulkan.h54
-rw-r--r--source/3rd-party/SDL2/src/video/uikit/SDL_uikitvulkan.m222
-rw-r--r--source/3rd-party/SDL2/src/video/uikit/SDL_uikitwindow.h56
-rw-r--r--source/3rd-party/SDL2/src/video/uikit/SDL_uikitwindow.m465
-rw-r--r--source/3rd-party/SDL2/src/video/uikit/keyinfotable.h174
27 files changed, 4688 insertions, 0 deletions
diff --git a/source/3rd-party/SDL2/src/video/uikit/SDL_uikitappdelegate.h b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitappdelegate.h
new file mode 100644
index 0000000..34b0138
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitappdelegate.h
@@ -0,0 +1,47 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 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
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#import <UIKit/UIKit.h>
+
+@interface SDLLaunchScreenController : UIViewController
+
+- (instancetype)init;
+- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil;
+- (void)loadView;
+
+@end
+
+@interface SDLUIKitDelegate : NSObject<UIApplicationDelegate>
+
++ (id)sharedAppDelegate;
++ (NSString *)getAppDelegateClassName;
+
+- (void)hideLaunchScreen;
+
+/* This property is marked as optional, and is only intended to be used when
+ * the app's UI is storyboard-based. SDL is not storyboard-based, however
+ * several major third-party ad APIs (e.g. Google admob) incorrectly assume this
+ * property always exists, and will crash if it doesn't. */
+@property (nonatomic) UIWindow *window;
+
+@end
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/uikit/SDL_uikitappdelegate.m b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitappdelegate.m
new file mode 100644
index 0000000..15762d2
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitappdelegate.m
@@ -0,0 +1,516 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 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
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_UIKIT
+
+#include "../SDL_sysvideo.h"
+#include "SDL_assert.h"
+#include "SDL_hints.h"
+#include "SDL_system.h"
+#include "SDL_main.h"
+
+#import "SDL_uikitappdelegate.h"
+#import "SDL_uikitmodes.h"
+#import "SDL_uikitwindow.h"
+
+#include "../../events/SDL_events_c.h"
+
+#ifdef main
+#undef main
+#endif
+
+static int forward_argc;
+static char **forward_argv;
+static int exit_status;
+
+int main(int argc, char **argv)
+{
+ int i;
+
+ /* store arguments */
+ forward_argc = argc;
+ forward_argv = (char **)malloc((argc+1) * sizeof(char *));
+ for (i = 0; i < argc; i++) {
+ forward_argv[i] = malloc( (strlen(argv[i])+1) * sizeof(char));
+ strcpy(forward_argv[i], argv[i]);
+ }
+ forward_argv[i] = NULL;
+
+ /* Give over control to run loop, SDLUIKitDelegate will handle most things from here */
+ @autoreleasepool {
+ UIApplicationMain(argc, argv, nil, [SDLUIKitDelegate getAppDelegateClassName]);
+ }
+
+ /* free the memory we used to hold copies of argc and argv */
+ for (i = 0; i < forward_argc; i++) {
+ free(forward_argv[i]);
+ }
+ free(forward_argv);
+
+ return exit_status;
+}
+
+static void SDLCALL
+SDL_IdleTimerDisabledChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
+{
+ BOOL disable = (hint && *hint != '0');
+ [UIApplication sharedApplication].idleTimerDisabled = disable;
+}
+
+#if !TARGET_OS_TV
+/* Load a launch image using the old UILaunchImageFile-era naming rules. */
+static UIImage *
+SDL_LoadLaunchImageNamed(NSString *name, int screenh)
+{
+ UIInterfaceOrientation curorient = [UIApplication sharedApplication].statusBarOrientation;
+ UIUserInterfaceIdiom idiom = [UIDevice currentDevice].userInterfaceIdiom;
+ UIImage *image = nil;
+
+ if (idiom == UIUserInterfaceIdiomPhone && screenh == 568) {
+ /* The image name for the iPhone 5 uses its height as a suffix. */
+ image = [UIImage imageNamed:[NSString stringWithFormat:@"%@-568h", name]];
+ } else if (idiom == UIUserInterfaceIdiomPad) {
+ /* iPad apps can launch in any orientation. */
+ if (UIInterfaceOrientationIsLandscape(curorient)) {
+ if (curorient == UIInterfaceOrientationLandscapeLeft) {
+ image = [UIImage imageNamed:[NSString stringWithFormat:@"%@-LandscapeLeft", name]];
+ } else {
+ image = [UIImage imageNamed:[NSString stringWithFormat:@"%@-LandscapeRight", name]];
+ }
+ if (!image) {
+ image = [UIImage imageNamed:[NSString stringWithFormat:@"%@-Landscape", name]];
+ }
+ } else {
+ if (curorient == UIInterfaceOrientationPortraitUpsideDown) {
+ image = [UIImage imageNamed:[NSString stringWithFormat:@"%@-PortraitUpsideDown", name]];
+ }
+ if (!image) {
+ image = [UIImage imageNamed:[NSString stringWithFormat:@"%@-Portrait", name]];
+ }
+ }
+ }
+
+ if (!image) {
+ image = [UIImage imageNamed:name];
+ }
+
+ return image;
+}
+#endif /* !TARGET_OS_TV */
+
+@interface SDLLaunchScreenController ()
+
+#if !TARGET_OS_TV
+- (NSUInteger)supportedInterfaceOrientations;
+#endif
+
+@end
+
+@implementation SDLLaunchScreenController
+
+- (instancetype)init
+{
+ return [self initWithNibName:nil bundle:[NSBundle mainBundle]];
+}
+
+- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
+{
+ if (!(self = [super initWithNibName:nil bundle:nil])) {
+ return nil;
+ }
+
+ NSString *screenname = nibNameOrNil;
+ NSBundle *bundle = nibBundleOrNil;
+ BOOL atleastiOS8 = UIKit_IsSystemVersionAtLeast(8.0);
+
+ /* Launch screens were added in iOS 8. Otherwise we use launch images. */
+ if (screenname && atleastiOS8) {
+ @try {
+ self.view = [bundle loadNibNamed:screenname owner:self options:nil][0];
+ }
+ @catch (NSException *exception) {
+ /* If a launch screen name is specified but it fails to load, iOS
+ * displays a blank screen rather than falling back to an image. */
+ return nil;
+ }
+ }
+
+ if (!self.view) {
+ NSArray *launchimages = [bundle objectForInfoDictionaryKey:@"UILaunchImages"];
+ NSString *imagename = nil;
+ UIImage *image = nil;
+
+ int screenw = (int)([UIScreen mainScreen].bounds.size.width + 0.5);
+ int screenh = (int)([UIScreen mainScreen].bounds.size.height + 0.5);
+
+#if !TARGET_OS_TV
+ UIInterfaceOrientation curorient = [UIApplication sharedApplication].statusBarOrientation;
+
+ /* We always want portrait-oriented size, to match UILaunchImageSize. */
+ if (screenw > screenh) {
+ int width = screenw;
+ screenw = screenh;
+ screenh = width;
+ }
+#endif
+
+ /* Xcode 5 introduced a dictionary of launch images in Info.plist. */
+ if (launchimages) {
+ for (NSDictionary *dict in launchimages) {
+ NSString *minversion = dict[@"UILaunchImageMinimumOSVersion"];
+ NSString *sizestring = dict[@"UILaunchImageSize"];
+
+ /* Ignore this image if the current version is too low. */
+ if (minversion && !UIKit_IsSystemVersionAtLeast(minversion.doubleValue)) {
+ continue;
+ }
+
+ /* Ignore this image if the size doesn't match. */
+ if (sizestring) {
+ CGSize size = CGSizeFromString(sizestring);
+ if ((int)(size.width + 0.5) != screenw || (int)(size.height + 0.5) != screenh) {
+ continue;
+ }
+ }
+
+#if !TARGET_OS_TV
+ UIInterfaceOrientationMask orientmask = UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown;
+ NSString *orientstring = dict[@"UILaunchImageOrientation"];
+
+ if (orientstring) {
+ if ([orientstring isEqualToString:@"PortraitUpsideDown"]) {
+ orientmask = UIInterfaceOrientationMaskPortraitUpsideDown;
+ } else if ([orientstring isEqualToString:@"Landscape"]) {
+ orientmask = UIInterfaceOrientationMaskLandscape;
+ } else if ([orientstring isEqualToString:@"LandscapeLeft"]) {
+ orientmask = UIInterfaceOrientationMaskLandscapeLeft;
+ } else if ([orientstring isEqualToString:@"LandscapeRight"]) {
+ orientmask = UIInterfaceOrientationMaskLandscapeRight;
+ }
+ }
+
+ /* Ignore this image if the orientation doesn't match. */
+ if ((orientmask & (1 << curorient)) == 0) {
+ continue;
+ }
+#endif
+
+ imagename = dict[@"UILaunchImageName"];
+ }
+
+ if (imagename) {
+ image = [UIImage imageNamed:imagename];
+ }
+ }
+#if !TARGET_OS_TV
+ else {
+ imagename = [bundle objectForInfoDictionaryKey:@"UILaunchImageFile"];
+
+ if (imagename) {
+ image = SDL_LoadLaunchImageNamed(imagename, screenh);
+ }
+
+ if (!image) {
+ image = SDL_LoadLaunchImageNamed(@"Default", screenh);
+ }
+ }
+#endif
+
+ if (image) {
+ UIImageView *view = [[UIImageView alloc] initWithFrame:[UIScreen mainScreen].bounds];
+ UIImageOrientation imageorient = UIImageOrientationUp;
+
+#if !TARGET_OS_TV
+ /* Bugs observed / workaround tested in iOS 8.3, 7.1, and 6.1. */
+ if (UIInterfaceOrientationIsLandscape(curorient)) {
+ if (atleastiOS8 && image.size.width < image.size.height) {
+ /* On iOS 8, portrait launch images displayed in forced-
+ * landscape mode (e.g. a standard Default.png on an iPhone
+ * when Info.plist only supports landscape orientations) need
+ * to be rotated to display in the expected orientation. */
+ if (curorient == UIInterfaceOrientationLandscapeLeft) {
+ imageorient = UIImageOrientationRight;
+ } else if (curorient == UIInterfaceOrientationLandscapeRight) {
+ imageorient = UIImageOrientationLeft;
+ }
+ } else if (!atleastiOS8 && image.size.width > image.size.height) {
+ /* On iOS 7 and below, landscape launch images displayed in
+ * landscape mode (e.g. landscape iPad launch images) need
+ * to be rotated to display in the expected orientation. */
+ if (curorient == UIInterfaceOrientationLandscapeLeft) {
+ imageorient = UIImageOrientationLeft;
+ } else if (curorient == UIInterfaceOrientationLandscapeRight) {
+ imageorient = UIImageOrientationRight;
+ }
+ }
+ }
+#endif
+
+ /* Create the properly oriented image. */
+ view.image = [[UIImage alloc] initWithCGImage:image.CGImage scale:image.scale orientation:imageorient];
+
+ self.view = view;
+ }
+ }
+
+ return self;
+}
+
+- (void)loadView
+{
+ /* Do nothing. */
+}
+
+#if !TARGET_OS_TV
+- (BOOL)shouldAutorotate
+{
+ /* If YES, the launch image will be incorrectly rotated in some cases. */
+ return NO;
+}
+
+- (NSUInteger)supportedInterfaceOrientations
+{
+ /* We keep the supported orientations unrestricted to avoid the case where
+ * there are no common orientations between the ones set in Info.plist and
+ * the ones set here (it will cause an exception in that case.) */
+ return UIInterfaceOrientationMaskAll;
+}
+#endif /* !TARGET_OS_TV */
+
+@end
+
+@implementation SDLUIKitDelegate {
+ UIWindow *launchWindow;
+}
+
+/* convenience method */
++ (id)sharedAppDelegate
+{
+ /* the delegate is set in UIApplicationMain(), which is guaranteed to be
+ * called before this method */
+ return [UIApplication sharedApplication].delegate;
+}
+
++ (NSString *)getAppDelegateClassName
+{
+ /* subclassing notice: when you subclass this appdelegate, make sure to add
+ * a category to override this method and return the actual name of the
+ * delegate */
+ return @"SDLUIKitDelegate";
+}
+
+- (void)hideLaunchScreen
+{
+ UIWindow *window = launchWindow;
+
+ if (!window || window.hidden) {
+ return;
+ }
+
+ launchWindow = nil;
+
+ /* Do a nice animated fade-out (roughly matches the real launch behavior.) */
+ [UIView animateWithDuration:0.2 animations:^{
+ window.alpha = 0.0;
+ } completion:^(BOOL finished) {
+ window.hidden = YES;
+ }];
+}
+
+- (void)postFinishLaunch
+{
+ /* Hide the launch screen the next time the run loop is run. SDL apps will
+ * have a chance to load resources while the launch screen is still up. */
+ [self performSelector:@selector(hideLaunchScreen) withObject:nil afterDelay:0.0];
+
+ /* run the user's application, passing argc and argv */
+ SDL_iPhoneSetEventPump(SDL_TRUE);
+ exit_status = SDL_main(forward_argc, forward_argv);
+ SDL_iPhoneSetEventPump(SDL_FALSE);
+
+ if (launchWindow) {
+ launchWindow.hidden = YES;
+ launchWindow = nil;
+ }
+
+ /* exit, passing the return status from the user's application */
+ /* We don't actually exit to support applications that do setup in their
+ * main function and then allow the Cocoa event loop to run. */
+ /* exit(exit_status); */
+}
+
+- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
+{
+ NSBundle *bundle = [NSBundle mainBundle];
+
+#if SDL_IPHONE_LAUNCHSCREEN
+ /* The normal launch screen is displayed until didFinishLaunching returns,
+ * but SDL_main is called after that happens and there may be a noticeable
+ * delay between the start of SDL_main and when the first real frame is
+ * displayed (e.g. if resources are loaded before SDL_GL_SwapWindow is
+ * called), so we show the launch screen programmatically until the first
+ * time events are pumped. */
+ UIViewController *vc = nil;
+ NSString *screenname = nil;
+
+ /* tvOS only uses a plain launch image. */
+#if !TARGET_OS_TV
+ screenname = [bundle objectForInfoDictionaryKey:@"UILaunchStoryboardName"];
+
+ if (screenname && UIKit_IsSystemVersionAtLeast(8.0)) {
+ @try {
+ /* The launch storyboard is actually a nib in some older versions of
+ * Xcode. We'll try to load it as a storyboard first, as it's more
+ * modern. */
+ UIStoryboard *storyboard = [UIStoryboard storyboardWithName:screenname bundle:bundle];
+ vc = [storyboard instantiateInitialViewController];
+ }
+ @catch (NSException *exception) {
+ /* Do nothing (there's more code to execute below). */
+ }
+ }
+#endif
+
+ if (vc == nil) {
+ vc = [[SDLLaunchScreenController alloc] initWithNibName:screenname bundle:bundle];
+ }
+
+ if (vc.view) {
+ launchWindow = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
+
+ /* We don't want the launch window immediately hidden when a real SDL
+ * window is shown - we fade it out ourselves when we're ready. */
+ launchWindow.windowLevel = UIWindowLevelNormal + 1.0;
+
+ /* Show the window but don't make it key. Events should always go to
+ * other windows when possible. */
+ launchWindow.hidden = NO;
+
+ launchWindow.rootViewController = vc;
+ }
+#endif
+
+ /* Set working directory to resource path */
+ [[NSFileManager defaultManager] changeCurrentDirectoryPath:[bundle resourcePath]];
+
+ /* register a callback for the idletimer hint */
+ SDL_AddHintCallback(SDL_HINT_IDLE_TIMER_DISABLED,
+ SDL_IdleTimerDisabledChanged, NULL);
+
+ SDL_SetMainReady();
+ [self performSelector:@selector(postFinishLaunch) withObject:nil afterDelay:0.0];
+
+ return YES;
+}
+
+- (UIWindow *)window
+{
+ SDL_VideoDevice *_this = SDL_GetVideoDevice();
+ if (_this) {
+ SDL_Window *window = NULL;
+ for (window = _this->windows; window != NULL; window = window->next) {
+ SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata;
+ if (data != nil) {
+ return data.uiwindow;
+ }
+ }
+ }
+ return nil;
+}
+
+- (void)setWindow:(UIWindow *)window
+{
+ /* Do nothing. */
+}
+
+#if !TARGET_OS_TV
+- (void)application:(UIApplication *)application didChangeStatusBarOrientation:(UIInterfaceOrientation)oldStatusBarOrientation
+{
+ SDL_OnApplicationDidChangeStatusBarOrientation();
+}
+#endif
+
+- (void)applicationWillTerminate:(UIApplication *)application
+{
+ SDL_OnApplicationWillTerminate();
+}
+
+- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application
+{
+ SDL_OnApplicationDidReceiveMemoryWarning();
+}
+
+- (void)applicationWillResignActive:(UIApplication*)application
+{
+ SDL_OnApplicationWillResignActive();
+}
+
+- (void)applicationDidEnterBackground:(UIApplication*)application
+{
+ SDL_OnApplicationDidEnterBackground();
+}
+
+- (void)applicationWillEnterForeground:(UIApplication*)application
+{
+ SDL_OnApplicationWillEnterForeground();
+}
+
+- (void)applicationDidBecomeActive:(UIApplication*)application
+{
+ SDL_OnApplicationDidBecomeActive();
+}
+
+- (void)sendDropFileForURL:(NSURL *)url
+{
+ NSURL *fileURL = url.filePathURL;
+ if (fileURL != nil) {
+ SDL_SendDropFile(NULL, fileURL.path.UTF8String);
+ } else {
+ SDL_SendDropFile(NULL, url.absoluteString.UTF8String);
+ }
+ SDL_SendDropComplete(NULL);
+}
+
+#if TARGET_OS_TV || (defined(__IPHONE_9_0) && __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_9_0)
+
+- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
+{
+ /* TODO: Handle options */
+ [self sendDropFileForURL:url];
+ return YES;
+}
+
+#else
+
+- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
+{
+ [self sendDropFileForURL:url];
+ return YES;
+}
+
+#endif
+
+@end
+
+#endif /* SDL_VIDEO_DRIVER_UIKIT */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/uikit/SDL_uikitclipboard.h b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitclipboard.h
new file mode 100644
index 0000000..c4b689d
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitclipboard.h
@@ -0,0 +1,35 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 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
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#ifndef SDL_uikitclipboard_h_
+#define SDL_uikitclipboard_h_
+
+#include "../SDL_sysvideo.h"
+
+extern int UIKit_SetClipboardText(_THIS, const char *text);
+extern char *UIKit_GetClipboardText(_THIS);
+extern SDL_bool UIKit_HasClipboardText(_THIS);
+
+extern void UIKit_InitClipboard(_THIS);
+extern void UIKit_QuitClipboard(_THIS);
+
+#endif /* SDL_uikitclipboard_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/uikit/SDL_uikitclipboard.m b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitclipboard.m
new file mode 100644
index 0000000..b1d4f6d
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitclipboard.m
@@ -0,0 +1,111 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 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
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_UIKIT
+
+#include "SDL_uikitvideo.h"
+#include "../../events/SDL_clipboardevents_c.h"
+
+#import <UIKit/UIPasteboard.h>
+
+int
+UIKit_SetClipboardText(_THIS, const char *text)
+{
+#if TARGET_OS_TV
+ return SDL_SetError("The clipboard is not available on tvOS");
+#else
+ @autoreleasepool {
+ [UIPasteboard generalPasteboard].string = @(text);
+ return 0;
+ }
+#endif
+}
+
+char *
+UIKit_GetClipboardText(_THIS)
+{
+#if TARGET_OS_TV
+ return SDL_strdup(""); // Unsupported.
+#else
+ @autoreleasepool {
+ UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
+ NSString *string = pasteboard.string;
+
+ if (string != nil) {
+ return SDL_strdup(string.UTF8String);
+ } else {
+ return SDL_strdup("");
+ }
+ }
+#endif
+}
+
+SDL_bool
+UIKit_HasClipboardText(_THIS)
+{
+ @autoreleasepool {
+#if !TARGET_OS_TV
+ if ([UIPasteboard generalPasteboard].string != nil) {
+ return SDL_TRUE;
+ }
+#endif
+ return SDL_FALSE;
+ }
+}
+
+void
+UIKit_InitClipboard(_THIS)
+{
+#if !TARGET_OS_TV
+ @autoreleasepool {
+ SDL_VideoData *data = (__bridge SDL_VideoData *) _this->driverdata;
+ NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
+
+ id observer = [center addObserverForName:UIPasteboardChangedNotification
+ object:nil
+ queue:nil
+ usingBlock:^(NSNotification *note) {
+ SDL_SendClipboardUpdate();
+ }];
+
+ data.pasteboardObserver = observer;
+ }
+#endif
+}
+
+void
+UIKit_QuitClipboard(_THIS)
+{
+ @autoreleasepool {
+ SDL_VideoData *data = (__bridge SDL_VideoData *) _this->driverdata;
+
+ if (data.pasteboardObserver != nil) {
+ [[NSNotificationCenter defaultCenter] removeObserver:data.pasteboardObserver];
+ }
+
+ data.pasteboardObserver = nil;
+ }
+}
+
+#endif /* SDL_VIDEO_DRIVER_UIKIT */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/uikit/SDL_uikitevents.h b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitevents.h
new file mode 100644
index 0000000..0c48829
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitevents.h
@@ -0,0 +1,30 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 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
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#ifndef SDL_uikitevents_h_
+#define SDL_uikitevents_h_
+
+#include "../SDL_sysvideo.h"
+
+extern void UIKit_PumpEvents(_THIS);
+
+#endif /* SDL_uikitevents_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/uikit/SDL_uikitevents.m b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitevents.m
new file mode 100644
index 0000000..d64e330
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitevents.m
@@ -0,0 +1,73 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 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
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_UIKIT
+
+#include "../../events/SDL_events_c.h"
+
+#include "SDL_uikitvideo.h"
+#include "SDL_uikitevents.h"
+#include "SDL_uikitopengles.h"
+
+#import <Foundation/Foundation.h>
+
+static BOOL UIKit_EventPumpEnabled = YES;
+
+void
+SDL_iPhoneSetEventPump(SDL_bool enabled)
+{
+ UIKit_EventPumpEnabled = enabled;
+}
+
+void
+UIKit_PumpEvents(_THIS)
+{
+ if (!UIKit_EventPumpEnabled) {
+ return;
+ }
+
+ /* Let the run loop run for a short amount of time: long enough for
+ touch events to get processed (which is important to get certain
+ elements of Game Center's GKLeaderboardViewController to respond
+ to touch input), but not long enough to introduce a significant
+ delay in the rest of the app.
+ */
+ const CFTimeInterval seconds = 0.000002;
+
+ /* Pump most event types. */
+ SInt32 result;
+ do {
+ result = CFRunLoopRunInMode(kCFRunLoopDefaultMode, seconds, TRUE);
+ } while (result == kCFRunLoopRunHandledSource);
+
+ /* Make sure UIScrollView objects scroll properly. */
+ do {
+ result = CFRunLoopRunInMode((CFStringRef)UITrackingRunLoopMode, seconds, TRUE);
+ } while(result == kCFRunLoopRunHandledSource);
+
+ /* See the comment in the function definition. */
+ UIKit_GL_RestoreCurrentContext();
+}
+
+#endif /* SDL_VIDEO_DRIVER_UIKIT */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/uikit/SDL_uikitmessagebox.h b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitmessagebox.h
new file mode 100644
index 0000000..a766b57
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitmessagebox.h
@@ -0,0 +1,31 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 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
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_UIKIT
+
+extern SDL_bool UIKit_ShowingMessageBox(void);
+
+extern int UIKit_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid);
+
+#endif /* SDL_VIDEO_DRIVER_UIKIT */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/uikit/SDL_uikitmessagebox.m b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitmessagebox.m
new file mode 100644
index 0000000..cf2a8f3
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitmessagebox.m
@@ -0,0 +1,208 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 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
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_UIKIT
+
+#include "SDL.h"
+#include "SDL_uikitvideo.h"
+#include "SDL_uikitwindow.h"
+
+/* Display a UIKit message box */
+
+static SDL_bool s_showingMessageBox = SDL_FALSE;
+
+SDL_bool
+UIKit_ShowingMessageBox(void)
+{
+ return s_showingMessageBox;
+}
+
+static void
+UIKit_WaitUntilMessageBoxClosed(const SDL_MessageBoxData *messageboxdata, int *clickedindex)
+{
+ *clickedindex = messageboxdata->numbuttons;
+
+ @autoreleasepool {
+ /* Run the main event loop until the alert has finished */
+ /* Note that this needs to be done on the main thread */
+ s_showingMessageBox = SDL_TRUE;
+ while ((*clickedindex) == messageboxdata->numbuttons) {
+ [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
+ }
+ s_showingMessageBox = SDL_FALSE;
+ }
+}
+
+static BOOL
+UIKit_ShowMessageBoxAlertController(const SDL_MessageBoxData *messageboxdata, int *buttonid)
+{
+#ifdef __IPHONE_8_0
+ int i;
+ int __block clickedindex = messageboxdata->numbuttons;
+ const SDL_MessageBoxButtonData *buttons = messageboxdata->buttons;
+ UIWindow *window = nil;
+ UIWindow *alertwindow = nil;
+
+ if (![UIAlertController class]) {
+ return NO;
+ }
+
+ UIAlertController *alert;
+ alert = [UIAlertController alertControllerWithTitle:@(messageboxdata->title)
+ message:@(messageboxdata->message)
+ preferredStyle:UIAlertControllerStyleAlert];
+
+ for (i = 0; i < messageboxdata->numbuttons; i++) {
+ UIAlertAction *action;
+ UIAlertActionStyle style = UIAlertActionStyleDefault;
+
+ if (buttons[i].flags & SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT) {
+ style = UIAlertActionStyleCancel;
+ }
+
+ action = [UIAlertAction actionWithTitle:@(buttons[i].text)
+ style:style
+ handler:^(UIAlertAction *action) {
+ clickedindex = i;
+ }];
+ [alert addAction:action];
+ }
+
+ if (messageboxdata->window) {
+ SDL_WindowData *data = (__bridge SDL_WindowData *) messageboxdata->window->driverdata;
+ window = data.uiwindow;
+ }
+
+ if (window == nil || window.rootViewController == nil) {
+ alertwindow = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
+ alertwindow.rootViewController = [UIViewController new];
+ alertwindow.windowLevel = UIWindowLevelAlert;
+
+ window = alertwindow;
+
+ [alertwindow makeKeyAndVisible];
+ }
+
+ [window.rootViewController presentViewController:alert animated:YES completion:nil];
+ UIKit_WaitUntilMessageBoxClosed(messageboxdata, &clickedindex);
+
+ if (alertwindow) {
+ alertwindow.hidden = YES;
+ }
+
+#if !TARGET_OS_TV
+ /* Force the main SDL window to re-evaluate home indicator state */
+ SDL_Window *focus = SDL_GetFocusWindow();
+ if (focus) {
+ SDL_WindowData *data = (__bridge SDL_WindowData *) focus->driverdata;
+ if (data != nil) {
+ if (@available(iOS 11.0, *)) {
+ [data.viewcontroller performSelectorOnMainThread:@selector(setNeedsUpdateOfHomeIndicatorAutoHidden) withObject:nil waitUntilDone:NO];
+ [data.viewcontroller performSelectorOnMainThread:@selector(setNeedsUpdateOfScreenEdgesDeferringSystemGestures) withObject:nil waitUntilDone:NO];
+ }
+ }
+ }
+#endif /* !TARGET_OS_TV */
+
+ *buttonid = messageboxdata->buttons[clickedindex].buttonid;
+ return YES;
+#else
+ return NO;
+#endif /* __IPHONE_8_0 */
+}
+
+/* UIAlertView is deprecated in iOS 8+ in favor of UIAlertController. */
+#if __IPHONE_OS_VERSION_MIN_REQUIRED < 80000
+@interface SDLAlertViewDelegate : NSObject <UIAlertViewDelegate>
+
+@property (nonatomic, assign) int *clickedIndex;
+
+@end
+
+@implementation SDLAlertViewDelegate
+
+- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
+{
+ if (_clickedIndex != NULL) {
+ *_clickedIndex = (int) buttonIndex;
+ }
+}
+
+@end
+#endif /* __IPHONE_OS_VERSION_MIN_REQUIRED < 80000 */
+
+static BOOL
+UIKit_ShowMessageBoxAlertView(const SDL_MessageBoxData *messageboxdata, int *buttonid)
+{
+ /* UIAlertView is deprecated in iOS 8+ in favor of UIAlertController. */
+#if __IPHONE_OS_VERSION_MIN_REQUIRED < 80000
+ int i;
+ int clickedindex = messageboxdata->numbuttons;
+ const SDL_MessageBoxButtonData *buttons = messageboxdata->buttons;
+ UIAlertView *alert = [[UIAlertView alloc] init];
+ SDLAlertViewDelegate *delegate = [[SDLAlertViewDelegate alloc] init];
+
+ alert.delegate = delegate;
+ alert.title = @(messageboxdata->title);
+ alert.message = @(messageboxdata->message);
+
+ for (i = 0; i < messageboxdata->numbuttons; i++) {
+ [alert addButtonWithTitle:@(buttons[i].text)];
+ }
+
+ delegate.clickedIndex = &clickedindex;
+
+ [alert show];
+
+ UIKit_WaitUntilMessageBoxClosed(messageboxdata, &clickedindex);
+
+ alert.delegate = nil;
+
+ *buttonid = messageboxdata->buttons[clickedindex].buttonid;
+ return YES;
+#else
+ return NO;
+#endif /* __IPHONE_OS_VERSION_MIN_REQUIRED < 80000 */
+}
+
+int
+UIKit_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
+{
+ BOOL success = NO;
+
+ @autoreleasepool {
+ success = UIKit_ShowMessageBoxAlertController(messageboxdata, buttonid);
+ if (!success) {
+ success = UIKit_ShowMessageBoxAlertView(messageboxdata, buttonid);
+ }
+ }
+
+ if (!success) {
+ return SDL_SetError("Could not show message box.");
+ }
+
+ return 0;
+}
+
+#endif /* SDL_VIDEO_DRIVER_UIKIT */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/uikit/SDL_uikitmetalview.h b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitmetalview.h
new file mode 100644
index 0000000..bc97778
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitmetalview.h
@@ -0,0 +1,58 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 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
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+ */
+
+/*
+ * @author Mark Callow, www.edgewise-consulting.com.
+ *
+ * Thanks to Alex Szpakowski, @slime73 on GitHub, for his gist showing
+ * how to add a CAMetalLayer backed view.
+ */
+
+#ifndef SDL_uikitmetalview_h_
+#define SDL_uikitmetalview_h_
+
+#import "../SDL_sysvideo.h"
+#import "SDL_uikitwindow.h"
+
+#if SDL_VIDEO_DRIVER_UIKIT && (SDL_VIDEO_RENDER_METAL || SDL_VIDEO_VULKAN)
+
+#import <UIKit/UIKit.h>
+#import <Metal/Metal.h>
+#import <QuartzCore/CAMetalLayer.h>
+
+#define METALVIEW_TAG 255
+
+@interface SDL_uikitmetalview : SDL_uikitview
+
+- (instancetype)initWithFrame:(CGRect)frame
+ scale:(CGFloat)scale;
+
+@end
+
+SDL_uikitmetalview* UIKit_Mtl_AddMetalView(SDL_Window* window);
+
+void UIKit_Mtl_GetDrawableSize(SDL_Window * window, int * w, int * h);
+
+#endif /* SDL_VIDEO_DRIVER_UIKIT && (SDL_VIDEO_RENDER_METAL || SDL_VIDEO_VULKAN) */
+
+#endif /* SDL_uikitmetalview_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/uikit/SDL_uikitmetalview.m b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitmetalview.m
new file mode 100644
index 0000000..436e742
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitmetalview.m
@@ -0,0 +1,132 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 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
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+ */
+
+/*
+ * @author Mark Callow, www.edgewise-consulting.com.
+ *
+ * Thanks to Alex Szpakowski, @slime73 on GitHub, for his gist showing
+ * how to add a CAMetalLayer backed view.
+ */
+
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_UIKIT && (SDL_VIDEO_RENDER_METAL || SDL_VIDEO_VULKAN)
+
+#import "../SDL_sysvideo.h"
+#import "SDL_uikitwindow.h"
+#import "SDL_uikitmetalview.h"
+
+#include "SDL_assert.h"
+
+@implementation SDL_uikitmetalview
+
+/* Returns a Metal-compatible layer. */
++ (Class)layerClass
+{
+ return [CAMetalLayer class];
+}
+
+- (instancetype)initWithFrame:(CGRect)frame
+ scale:(CGFloat)scale
+{
+ if ((self = [super initWithFrame:frame])) {
+ self.tag = METALVIEW_TAG;
+ self.layer.contentsScale = scale;
+ [self updateDrawableSize];
+ }
+
+ return self;
+}
+
+/* Set the size of the metal drawables when the view is resized. */
+- (void)layoutSubviews
+{
+ [super layoutSubviews];
+ [self updateDrawableSize];
+}
+
+- (void)updateDrawableSize
+{
+ CGSize size = self.bounds.size;
+ size.width *= self.layer.contentsScale;
+ size.height *= self.layer.contentsScale;
+ ((CAMetalLayer *)self.layer).drawableSize = size;
+}
+
+@end
+
+SDL_uikitmetalview*
+UIKit_Mtl_AddMetalView(SDL_Window* window)
+{
+ SDL_WindowData *data = (__bridge SDL_WindowData *)window->driverdata;
+ SDL_uikitview *view = (SDL_uikitview*)data.uiwindow.rootViewController.view;
+ CGFloat scale = 1.0;
+
+ if ([view isKindOfClass:[SDL_uikitmetalview class]]) {
+ return (SDL_uikitmetalview *)view;
+ }
+
+ if (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) {
+ /* Set the scale to the natural scale factor of the screen - then
+ * the backing dimensions of the Metal view will match the pixel
+ * dimensions of the screen rather than the dimensions in points
+ * yielding high resolution on retine displays.
+ */
+#ifdef __IPHONE_8_0
+ if ([data.uiwindow.screen respondsToSelector:@selector(nativeScale)]) {
+ scale = data.uiwindow.screen.nativeScale;
+ } else
+#endif
+ {
+ scale = data.uiwindow.screen.scale;
+ }
+ }
+ SDL_uikitmetalview *metalview
+ = [[SDL_uikitmetalview alloc] initWithFrame:view.frame
+ scale:scale];
+ [metalview setSDLWindow:window];
+
+ return metalview;
+}
+
+void
+UIKit_Mtl_GetDrawableSize(SDL_Window * window, int * w, int * h)
+{
+ @autoreleasepool {
+ SDL_WindowData *data = (__bridge SDL_WindowData *)window->driverdata;
+ SDL_uikitview *view = (SDL_uikitview*)data.uiwindow.rootViewController.view;
+ SDL_uikitmetalview* metalview = [view viewWithTag:METALVIEW_TAG];
+ if (metalview) {
+ CAMetalLayer *layer = (CAMetalLayer*)metalview.layer;
+ assert(layer != NULL);
+ if (w) {
+ *w = layer.drawableSize.width;
+ }
+ if (h) {
+ *h = layer.drawableSize.height;
+ }
+ } else {
+ SDL_GetWindowSize(window, w, h);
+ }
+ }
+}
+
+#endif /* SDL_VIDEO_DRIVER_UIKIT && (SDL_VIDEO_RENDER_METAL || SDL_VIDEO_VULKAN) */
diff --git a/source/3rd-party/SDL2/src/video/uikit/SDL_uikitmodes.h b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitmodes.h
new file mode 100644
index 0000000..b5c0c65
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitmodes.h
@@ -0,0 +1,54 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 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
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#ifndef SDL_uikitmodes_h_
+#define SDL_uikitmodes_h_
+
+#include "SDL_uikitvideo.h"
+
+@interface SDL_DisplayData : NSObject
+
+@property (nonatomic, strong) UIScreen *uiscreen;
+
+@end
+
+@interface SDL_DisplayModeData : NSObject
+
+@property (nonatomic, strong) UIScreenMode *uiscreenmode;
+
+@end
+
+extern SDL_bool UIKit_IsDisplayLandscape(UIScreen *uiscreen);
+
+extern int UIKit_InitModes(_THIS);
+extern void UIKit_GetDisplayModes(_THIS, SDL_VideoDisplay * display);
+extern int UIKit_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode);
+extern void UIKit_QuitModes(_THIS);
+extern int UIKit_GetDisplayUsableBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect * rect);
+
+#if !TARGET_OS_TV
+extern void SDL_OnApplicationDidChangeStatusBarOrientation(void);
+#endif
+
+#endif /* SDL_uikitmodes_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/uikit/SDL_uikitmodes.m b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitmodes.m
new file mode 100644
index 0000000..7ddf107
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitmodes.m
@@ -0,0 +1,380 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 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
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_UIKIT
+
+#include "SDL_assert.h"
+#include "SDL_uikitmodes.h"
+
+#include "../../events/SDL_events_c.h"
+
+@implementation SDL_DisplayData
+
+@synthesize uiscreen;
+
+@end
+
+@implementation SDL_DisplayModeData
+
+@synthesize uiscreenmode;
+
+@end
+
+
+static int
+UIKit_AllocateDisplayModeData(SDL_DisplayMode * mode,
+ UIScreenMode * uiscreenmode)
+{
+ SDL_DisplayModeData *data = nil;
+
+ if (uiscreenmode != nil) {
+ /* Allocate the display mode data */
+ data = [[SDL_DisplayModeData alloc] init];
+ if (!data) {
+ return SDL_OutOfMemory();
+ }
+
+ data.uiscreenmode = uiscreenmode;
+ }
+
+ mode->driverdata = (void *) CFBridgingRetain(data);
+
+ return 0;
+}
+
+static void
+UIKit_FreeDisplayModeData(SDL_DisplayMode * mode)
+{
+ if (mode->driverdata != NULL) {
+ CFRelease(mode->driverdata);
+ mode->driverdata = NULL;
+ }
+}
+
+static NSUInteger
+UIKit_GetDisplayModeRefreshRate(UIScreen *uiscreen)
+{
+#ifdef __IPHONE_10_3
+ if ([uiscreen respondsToSelector:@selector(maximumFramesPerSecond)]) {
+ return uiscreen.maximumFramesPerSecond;
+ }
+#endif
+ return 0;
+}
+
+static int
+UIKit_AddSingleDisplayMode(SDL_VideoDisplay * display, int w, int h,
+ UIScreen * uiscreen, UIScreenMode * uiscreenmode)
+{
+ SDL_DisplayMode mode;
+ SDL_zero(mode);
+
+ if (UIKit_AllocateDisplayModeData(&mode, uiscreenmode) < 0) {
+ return -1;
+ }
+
+ mode.format = SDL_PIXELFORMAT_ABGR8888;
+ mode.refresh_rate = (int) UIKit_GetDisplayModeRefreshRate(uiscreen);
+ mode.w = w;
+ mode.h = h;
+
+ if (SDL_AddDisplayMode(display, &mode)) {
+ return 0;
+ } else {
+ UIKit_FreeDisplayModeData(&mode);
+ return -1;
+ }
+}
+
+static int
+UIKit_AddDisplayMode(SDL_VideoDisplay * display, int w, int h, UIScreen * uiscreen,
+ UIScreenMode * uiscreenmode, SDL_bool addRotation)
+{
+ if (UIKit_AddSingleDisplayMode(display, w, h, uiscreen, uiscreenmode) < 0) {
+ return -1;
+ }
+
+ if (addRotation) {
+ /* Add the rotated version */
+ if (UIKit_AddSingleDisplayMode(display, h, w, uiscreen, uiscreenmode) < 0) {
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+static int
+UIKit_AddDisplay(UIScreen *uiscreen)
+{
+ UIScreenMode *uiscreenmode = uiscreen.currentMode;
+ CGSize size = uiscreen.bounds.size;
+ SDL_VideoDisplay display;
+ SDL_DisplayMode mode;
+ SDL_zero(mode);
+
+ /* Make sure the width/height are oriented correctly */
+ if (UIKit_IsDisplayLandscape(uiscreen) != (size.width > size.height)) {
+ CGFloat height = size.width;
+ size.width = size.height;
+ size.height = height;
+ }
+
+ mode.format = SDL_PIXELFORMAT_ABGR8888;
+ mode.refresh_rate = (int) UIKit_GetDisplayModeRefreshRate(uiscreen);
+ mode.w = (int) size.width;
+ mode.h = (int) size.height;
+
+ if (UIKit_AllocateDisplayModeData(&mode, uiscreenmode) < 0) {
+ return -1;
+ }
+
+ SDL_zero(display);
+ display.desktop_mode = mode;
+ display.current_mode = mode;
+
+ /* Allocate the display data */
+ SDL_DisplayData *data = [[SDL_DisplayData alloc] init];
+ if (!data) {
+ UIKit_FreeDisplayModeData(&display.desktop_mode);
+ return SDL_OutOfMemory();
+ }
+
+ data.uiscreen = uiscreen;
+
+ display.driverdata = (void *) CFBridgingRetain(data);
+ SDL_AddVideoDisplay(&display);
+
+ return 0;
+}
+
+SDL_bool
+UIKit_IsDisplayLandscape(UIScreen *uiscreen)
+{
+#if !TARGET_OS_TV
+ if (uiscreen == [UIScreen mainScreen]) {
+ return UIInterfaceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation);
+ } else
+#endif /* !TARGET_OS_TV */
+ {
+ CGSize size = uiscreen.bounds.size;
+ return (size.width > size.height);
+ }
+}
+
+int
+UIKit_InitModes(_THIS)
+{
+ @autoreleasepool {
+ for (UIScreen *uiscreen in [UIScreen screens]) {
+ if (UIKit_AddDisplay(uiscreen) < 0) {
+ return -1;
+ }
+ }
+#if !TARGET_OS_TV
+ SDL_OnApplicationDidChangeStatusBarOrientation();
+#endif
+ }
+
+ return 0;
+}
+
+void
+UIKit_GetDisplayModes(_THIS, SDL_VideoDisplay * display)
+{
+ @autoreleasepool {
+ SDL_DisplayData *data = (__bridge SDL_DisplayData *) display->driverdata;
+
+ SDL_bool isLandscape = UIKit_IsDisplayLandscape(data.uiscreen);
+ SDL_bool addRotation = (data.uiscreen == [UIScreen mainScreen]);
+ CGFloat scale = data.uiscreen.scale;
+ NSArray *availableModes = nil;
+
+#if TARGET_OS_TV
+ addRotation = SDL_FALSE;
+ availableModes = @[data.uiscreen.currentMode];
+#else
+ availableModes = data.uiscreen.availableModes;
+#endif
+
+#ifdef __IPHONE_8_0
+ /* The UIScreenMode of an iPhone 6 Plus should be 1080x1920 rather than
+ * 1242x2208 (414x736@3x), so we should use the native scale. */
+ if ([data.uiscreen respondsToSelector:@selector(nativeScale)]) {
+ scale = data.uiscreen.nativeScale;
+ }
+#endif
+
+ for (UIScreenMode *uimode in availableModes) {
+ /* The size of a UIScreenMode is in pixels, but we deal exclusively
+ * in points (except in SDL_GL_GetDrawableSize.) */
+ int w = (int)(uimode.size.width / scale);
+ int h = (int)(uimode.size.height / scale);
+
+ /* Make sure the width/height are oriented correctly */
+ if (isLandscape != (w > h)) {
+ int tmp = w;
+ w = h;
+ h = tmp;
+ }
+
+ UIKit_AddDisplayMode(display, w, h, data.uiscreen, uimode, addRotation);
+ }
+ }
+}
+
+int
+UIKit_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
+{
+ @autoreleasepool {
+ SDL_DisplayData *data = (__bridge SDL_DisplayData *) display->driverdata;
+
+#if !TARGET_OS_TV
+ SDL_DisplayModeData *modedata = (__bridge SDL_DisplayModeData *)mode->driverdata;
+ [data.uiscreen setCurrentMode:modedata.uiscreenmode];
+#endif
+
+ if (data.uiscreen == [UIScreen mainScreen]) {
+ /* [UIApplication setStatusBarOrientation:] no longer works reliably
+ * in recent iOS versions, so we can't rotate the screen when setting
+ * the display mode. */
+ if (mode->w > mode->h) {
+ if (!UIKit_IsDisplayLandscape(data.uiscreen)) {
+ return SDL_SetError("Screen orientation does not match display mode size");
+ }
+ } else if (mode->w < mode->h) {
+ if (UIKit_IsDisplayLandscape(data.uiscreen)) {
+ return SDL_SetError("Screen orientation does not match display mode size");
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+
+int
+UIKit_GetDisplayUsableBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect * rect)
+{
+ @autoreleasepool {
+ int displayIndex = (int) (display - _this->displays);
+ SDL_DisplayData *data = (__bridge SDL_DisplayData *) display->driverdata;
+ CGRect frame = data.uiscreen.bounds;
+
+ /* the default function iterates displays to make a fake offset,
+ as if all the displays were side-by-side, which is fine for iOS. */
+ if (SDL_GetDisplayBounds(displayIndex, rect) < 0) {
+ return -1;
+ }
+
+#if !TARGET_OS_TV && __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_7_0
+ if (!UIKit_IsSystemVersionAtLeast(7.0)) {
+ frame = [data.uiscreen applicationFrame];
+ }
+#endif
+
+ rect->x += frame.origin.x;
+ rect->y += frame.origin.y;
+ rect->w = frame.size.width;
+ rect->h = frame.size.height;
+ }
+
+ return 0;
+}
+
+void
+UIKit_QuitModes(_THIS)
+{
+ /* Release Objective-C objects, so higher level doesn't free() them. */
+ int i, j;
+ @autoreleasepool {
+ for (i = 0; i < _this->num_displays; i++) {
+ SDL_VideoDisplay *display = &_this->displays[i];
+
+ UIKit_FreeDisplayModeData(&display->desktop_mode);
+ for (j = 0; j < display->num_display_modes; j++) {
+ SDL_DisplayMode *mode = &display->display_modes[j];
+ UIKit_FreeDisplayModeData(mode);
+ }
+
+ if (display->driverdata != NULL) {
+ CFRelease(display->driverdata);
+ display->driverdata = NULL;
+ }
+ }
+ }
+}
+
+#if !TARGET_OS_TV
+void SDL_OnApplicationDidChangeStatusBarOrientation()
+{
+ BOOL isLandscape = UIInterfaceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation);
+ SDL_VideoDisplay *display = SDL_GetDisplay(0);
+
+ if (display) {
+ SDL_DisplayMode *desktopmode = &display->desktop_mode;
+ SDL_DisplayMode *currentmode = &display->current_mode;
+ SDL_DisplayOrientation orientation = SDL_ORIENTATION_UNKNOWN;
+
+ /* The desktop display mode should be kept in sync with the screen
+ * orientation so that updating a window's fullscreen state to
+ * SDL_WINDOW_FULLSCREEN_DESKTOP keeps the window dimensions in the
+ * correct orientation. */
+ if (isLandscape != (desktopmode->w > desktopmode->h)) {
+ int height = desktopmode->w;
+ desktopmode->w = desktopmode->h;
+ desktopmode->h = height;
+ }
+
+ /* Same deal with the current mode + SDL_GetCurrentDisplayMode. */
+ if (isLandscape != (currentmode->w > currentmode->h)) {
+ int height = currentmode->w;
+ currentmode->w = currentmode->h;
+ currentmode->h = height;
+ }
+
+ switch ([UIApplication sharedApplication].statusBarOrientation) {
+ case UIInterfaceOrientationPortrait:
+ orientation = SDL_ORIENTATION_PORTRAIT;
+ break;
+ case UIInterfaceOrientationPortraitUpsideDown:
+ orientation = SDL_ORIENTATION_PORTRAIT_FLIPPED;
+ break;
+ case UIInterfaceOrientationLandscapeLeft:
+ /* Bug: UIInterfaceOrientationLandscapeLeft/Right are reversed - http://openradar.appspot.com/7216046 */
+ orientation = SDL_ORIENTATION_LANDSCAPE_FLIPPED;
+ break;
+ case UIInterfaceOrientationLandscapeRight:
+ /* Bug: UIInterfaceOrientationLandscapeLeft/Right are reversed - http://openradar.appspot.com/7216046 */
+ orientation = SDL_ORIENTATION_LANDSCAPE;
+ break;
+ default:
+ break;
+ }
+ SDL_SendDisplayEvent(display, SDL_DISPLAYEVENT_ORIENTATION, orientation);
+ }
+}
+#endif /* !TARGET_OS_TV */
+
+#endif /* SDL_VIDEO_DRIVER_UIKIT */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/uikit/SDL_uikitopengles.h b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitopengles.h
new file mode 100644
index 0000000..6b57289
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitopengles.h
@@ -0,0 +1,40 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 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
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#ifndef SDL_uikitopengles_
+#define SDL_uikitopengles_
+
+#include "../SDL_sysvideo.h"
+
+extern int UIKit_GL_MakeCurrent(_THIS, SDL_Window * window,
+ SDL_GLContext context);
+extern void UIKit_GL_GetDrawableSize(_THIS, SDL_Window * window,
+ int * w, int * h);
+extern int UIKit_GL_SwapWindow(_THIS, SDL_Window * window);
+extern SDL_GLContext UIKit_GL_CreateContext(_THIS, SDL_Window * window);
+extern void UIKit_GL_DeleteContext(_THIS, SDL_GLContext context);
+extern void *UIKit_GL_GetProcAddress(_THIS, const char *proc);
+extern int UIKit_GL_LoadLibrary(_THIS, const char *path);
+
+extern void UIKit_GL_RestoreCurrentContext(void);
+
+#endif /* SDL_uikitopengles_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/uikit/SDL_uikitopengles.m b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitopengles.m
new file mode 100644
index 0000000..2f6dec4
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitopengles.m
@@ -0,0 +1,250 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 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
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_UIKIT
+
+#include "SDL_uikitopengles.h"
+#import "SDL_uikitopenglview.h"
+#include "SDL_uikitmodes.h"
+#include "SDL_uikitwindow.h"
+#include "SDL_uikitevents.h"
+#include "../SDL_sysvideo.h"
+#include "../../events/SDL_keyboard_c.h"
+#include "../../events/SDL_mouse_c.h"
+#include "../../power/uikit/SDL_syspower.h"
+#include "SDL_loadso.h"
+#include <dlfcn.h>
+
+@interface SDLEAGLContext : EAGLContext
+
+/* The OpenGL ES context owns a view / drawable. */
+@property (nonatomic, strong) SDL_uikitopenglview *sdlView;
+
+@end
+
+@implementation SDLEAGLContext
+
+- (void)dealloc
+{
+ /* When the context is deallocated, its view should be removed from any
+ * SDL window that it's attached to. */
+ [self.sdlView setSDLWindow:NULL];
+}
+
+@end
+
+void *
+UIKit_GL_GetProcAddress(_THIS, const char *proc)
+{
+ /* Look through all SO's for the proc symbol. Here's why:
+ * -Looking for the path to the OpenGL Library seems not to work in the iOS Simulator.
+ * -We don't know that the path won't change in the future. */
+ return dlsym(RTLD_DEFAULT, proc);
+}
+
+/*
+ note that SDL_GL_DeleteContext makes it current without passing the window
+*/
+int
+UIKit_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context)
+{
+ @autoreleasepool {
+ SDLEAGLContext *eaglcontext = (__bridge SDLEAGLContext *) context;
+
+ if (![EAGLContext setCurrentContext:eaglcontext]) {
+ return SDL_SetError("Could not make EAGL context current");
+ }
+
+ if (eaglcontext) {
+ [eaglcontext.sdlView setSDLWindow:window];
+ }
+ }
+
+ return 0;
+}
+
+void
+UIKit_GL_GetDrawableSize(_THIS, SDL_Window * window, int * w, int * h)
+{
+ @autoreleasepool {
+ SDL_WindowData *data = (__bridge SDL_WindowData *)window->driverdata;
+ UIView *view = data.viewcontroller.view;
+ if ([view isKindOfClass:[SDL_uikitopenglview class]]) {
+ SDL_uikitopenglview *glview = (SDL_uikitopenglview *) view;
+ if (w) {
+ *w = glview.backingWidth;
+ }
+ if (h) {
+ *h = glview.backingHeight;
+ }
+ }
+ }
+}
+
+int
+UIKit_GL_LoadLibrary(_THIS, const char *path)
+{
+ /* We shouldn't pass a path to this function, since we've already loaded the
+ * library. */
+ if (path != NULL) {
+ return SDL_SetError("iOS GL Load Library just here for compatibility");
+ }
+ return 0;
+}
+
+int UIKit_GL_SwapWindow(_THIS, SDL_Window * window)
+{
+ @autoreleasepool {
+ SDLEAGLContext *context = (__bridge SDLEAGLContext *) SDL_GL_GetCurrentContext();
+
+#if SDL_POWER_UIKIT
+ /* Check once a frame to see if we should turn off the battery monitor. */
+ SDL_UIKit_UpdateBatteryMonitoring();
+#endif
+
+ [context.sdlView 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. */
+ }
+ return 0;
+}
+
+SDL_GLContext
+UIKit_GL_CreateContext(_THIS, SDL_Window * window)
+{
+ @autoreleasepool {
+ SDLEAGLContext *context = nil;
+ SDL_uikitopenglview *view;
+ SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata;
+ CGRect frame = UIKit_ComputeViewFrame(window, data.uiwindow.screen);
+ EAGLSharegroup *sharegroup = nil;
+ CGFloat scale = 1.0;
+ int samples = 0;
+ int major = _this->gl_config.major_version;
+ int minor = _this->gl_config.minor_version;
+
+ /* The EAGLRenderingAPI enum values currently map 1:1 to major GLES
+ * versions. */
+ EAGLRenderingAPI api = major;
+
+ /* iOS currently doesn't support GLES >3.0. iOS 6 also only supports up
+ * to GLES 2.0. */
+ if (major > 3 || (major == 3 && (minor > 0 || !UIKit_IsSystemVersionAtLeast(7.0)))) {
+ SDL_SetError("OpenGL ES %d.%d context could not be created", major, minor);
+ return NULL;
+ }
+
+ if (_this->gl_config.multisamplebuffers > 0) {
+ samples = _this->gl_config.multisamplesamples;
+ }
+
+ if (_this->gl_config.share_with_current_context) {
+ EAGLContext *context = (__bridge EAGLContext *) SDL_GL_GetCurrentContext();
+ sharegroup = context.sharegroup;
+ }
+
+ if (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) {
+ /* 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 screen rather than the dimensions in points. */
+#ifdef __IPHONE_8_0
+ if ([data.uiwindow.screen respondsToSelector:@selector(nativeScale)]) {
+ scale = data.uiwindow.screen.nativeScale;
+ } else
+#endif
+ {
+ scale = data.uiwindow.screen.scale;
+ }
+ }
+
+ context = [[SDLEAGLContext alloc] initWithAPI:api sharegroup:sharegroup];
+ if (!context) {
+ SDL_SetError("OpenGL ES %d context could not be created", _this->gl_config.major_version);
+ return NULL;
+ }
+
+ /* 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
+ multisamples:samples
+ context:context];
+
+ if (!view) {
+ return NULL;
+ }
+
+ /* The context owns the view / drawable. */
+ context.sdlView = view;
+
+ if (UIKit_GL_MakeCurrent(_this, window, (__bridge SDL_GLContext) context) < 0) {
+ UIKit_GL_DeleteContext(_this, (SDL_GLContext) CFBridgingRetain(context));
+ return NULL;
+ }
+
+ /* We return a +1'd context. The window's driverdata owns the view (via
+ * MakeCurrent.) */
+ return (SDL_GLContext) CFBridgingRetain(context);
+ }
+}
+
+void
+UIKit_GL_DeleteContext(_THIS, SDL_GLContext context)
+{
+ @autoreleasepool {
+ /* The context was retained in SDL_GL_CreateContext, so we release it
+ * here. The context's view will be detached from its window when the
+ * context is deallocated. */
+ CFRelease(context);
+ }
+}
+
+void
+UIKit_GL_RestoreCurrentContext(void)
+{
+ @autoreleasepool {
+ /* Some iOS system functionality (such as Dictation on the on-screen
+ keyboard) uses its own OpenGL ES context but doesn't restore the
+ previous one when it's done. This is a workaround to make sure the
+ expected SDL-created OpenGL ES context is active after the OS is
+ finished running its own code for the frame. If this isn't done, the
+ app may crash or have other nasty symptoms when Dictation is used.
+ */
+ EAGLContext *context = (__bridge EAGLContext *) SDL_GL_GetCurrentContext();
+ if (context != NULL && [EAGLContext currentContext] != context) {
+ [EAGLContext setCurrentContext:context];
+ }
+ }
+}
+
+#endif /* SDL_VIDEO_DRIVER_UIKIT */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/uikit/SDL_uikitopenglview.h b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitopenglview.h
new file mode 100644
index 0000000..8d12c9f
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitopenglview.h
@@ -0,0 +1,60 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 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
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#import <UIKit/UIKit.h>
+#import <OpenGLES/EAGL.h>
+#import <OpenGLES/ES3/gl.h>
+
+#import "SDL_uikitview.h"
+#include "SDL_uikitvideo.h"
+
+@interface SDL_uikitopenglview : SDL_uikitview
+
+- (instancetype)initWithFrame:(CGRect)frame
+ scale:(CGFloat)scale
+ retainBacking:(BOOL)retained
+ rBits:(int)rBits
+ gBits:(int)gBits
+ bBits:(int)bBits
+ aBits:(int)aBits
+ depthBits:(int)depthBits
+ stencilBits:(int)stencilBits
+ sRGB:(BOOL)sRGB
+ multisamples:(int)multisamples
+ context:(EAGLContext *)glcontext;
+
+@property (nonatomic, readonly, weak) EAGLContext *context;
+
+/* The width and height of the drawable in pixels (as opposed to points.) */
+@property (nonatomic, readonly) int backingWidth;
+@property (nonatomic, readonly) int backingHeight;
+
+@property (nonatomic, readonly) GLuint drawableRenderbuffer;
+@property (nonatomic, readonly) GLuint drawableFramebuffer;
+@property (nonatomic, readonly) GLuint msaaResolveFramebuffer;
+
+- (void)swapBuffers;
+
+- (void)updateFrame;
+
+@end
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/uikit/SDL_uikitopenglview.m b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitopenglview.m
new file mode 100644
index 0000000..9024376
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitopenglview.m
@@ -0,0 +1,384 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 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
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_UIKIT
+
+#include <OpenGLES/EAGLDrawable.h>
+#include <OpenGLES/ES2/glext.h>
+#import "SDL_uikitopenglview.h"
+#include "SDL_uikitwindow.h"
+
+@implementation SDL_uikitopenglview {
+ /* The renderbuffer and framebuffer used to render to this layer. */
+ GLuint viewRenderbuffer, viewFramebuffer;
+
+ /* The depth buffer that is attached to viewFramebuffer, if it exists. */
+ GLuint depthRenderbuffer;
+
+ GLenum colorBufferFormat;
+
+ /* format of depthRenderbuffer */
+ GLenum depthBufferFormat;
+
+ /* The framebuffer and renderbuffer used for rendering with MSAA. */
+ GLuint msaaFramebuffer, msaaRenderbuffer;
+
+ /* The number of MSAA samples. */
+ int samples;
+
+ BOOL retainedBacking;
+}
+
+@synthesize context;
+@synthesize backingWidth;
+@synthesize backingHeight;
+
++ (Class)layerClass
+{
+ return [CAEAGLLayer class];
+}
+
+- (instancetype)initWithFrame:(CGRect)frame
+ scale:(CGFloat)scale
+ retainBacking:(BOOL)retained
+ rBits:(int)rBits
+ gBits:(int)gBits
+ bBits:(int)bBits
+ aBits:(int)aBits
+ depthBits:(int)depthBits
+ stencilBits:(int)stencilBits
+ sRGB:(BOOL)sRGB
+ multisamples:(int)multisamples
+ context:(EAGLContext *)glcontext
+{
+ if ((self = [super initWithFrame:frame])) {
+ const BOOL useStencilBuffer = (stencilBits != 0);
+ const BOOL useDepthBuffer = (depthBits != 0);
+ NSString *colorFormat = nil;
+
+ context = glcontext;
+ samples = multisamples;
+ retainedBacking = retained;
+
+ if (!context || ![EAGLContext setCurrentContext:context]) {
+ SDL_SetError("Could not create OpenGL ES drawable (could not make context current)");
+ return nil;
+ }
+
+ if (samples > 0) {
+ GLint maxsamples = 0;
+ glGetIntegerv(GL_MAX_SAMPLES, &maxsamples);
+
+ /* Clamp the samples to the max supported count. */
+ samples = MIN(samples, maxsamples);
+ }
+
+ if (sRGB) {
+ /* sRGB EAGL drawable support was added in iOS 7. */
+ if (UIKit_IsSystemVersionAtLeast(7.0)) {
+ colorFormat = kEAGLColorFormatSRGBA8;
+ colorBufferFormat = GL_SRGB8_ALPHA8;
+ } else {
+ SDL_SetError("sRGB drawables are not supported.");
+ return nil;
+ }
+ } else if (rBits >= 8 || gBits >= 8 || bBits >= 8 || aBits > 0) {
+ /* if user specifically requests rbg888 or some color format higher than 16bpp */
+ colorFormat = kEAGLColorFormatRGBA8;
+ colorBufferFormat = GL_RGBA8;
+ } else {
+ /* default case (potentially faster) */
+ colorFormat = kEAGLColorFormatRGB565;
+ colorBufferFormat = GL_RGB565;
+ }
+
+ CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer;
+
+ eaglLayer.opaque = YES;
+ eaglLayer.drawableProperties = @{
+ kEAGLDrawablePropertyRetainedBacking:@(retained),
+ kEAGLDrawablePropertyColorFormat:colorFormat
+ };
+
+ /* Set the appropriate scale (for retina display support) */
+ self.contentScaleFactor = scale;
+
+ /* Create the color Renderbuffer Object */
+ glGenRenderbuffers(1, &viewRenderbuffer);
+ glBindRenderbuffer(GL_RENDERBUFFER, viewRenderbuffer);
+
+ if (![context renderbufferStorage:GL_RENDERBUFFER fromDrawable:eaglLayer]) {
+ SDL_SetError("Failed to create OpenGL ES drawable");
+ return nil;
+ }
+
+ /* Create the Framebuffer Object */
+ glGenFramebuffers(1, &viewFramebuffer);
+ glBindFramebuffer(GL_FRAMEBUFFER, viewFramebuffer);
+
+ /* attach the color renderbuffer to the FBO */
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, viewRenderbuffer);
+
+ glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &backingWidth);
+ glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &backingHeight);
+
+ if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
+ SDL_SetError("Failed creating OpenGL ES framebuffer");
+ return nil;
+ }
+
+ /* When MSAA is used we'll use a separate framebuffer for rendering to,
+ * since we'll need to do an explicit MSAA resolve before presenting. */
+ if (samples > 0) {
+ glGenFramebuffers(1, &msaaFramebuffer);
+ glBindFramebuffer(GL_FRAMEBUFFER, msaaFramebuffer);
+
+ glGenRenderbuffers(1, &msaaRenderbuffer);
+ glBindRenderbuffer(GL_RENDERBUFFER, msaaRenderbuffer);
+
+ glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, colorBufferFormat, backingWidth, backingHeight);
+
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, msaaRenderbuffer);
+ }
+
+ if (useDepthBuffer || useStencilBuffer) {
+ if (useStencilBuffer) {
+ /* Apparently you need to pack stencil and depth into one buffer. */
+ depthBufferFormat = GL_DEPTH24_STENCIL8_OES;
+ } else if (useDepthBuffer) {
+ /* iOS only uses 32-bit float (exposed as fixed point 24-bit)
+ * depth buffers. */
+ depthBufferFormat = GL_DEPTH_COMPONENT24_OES;
+ }
+
+ glGenRenderbuffers(1, &depthRenderbuffer);
+ glBindRenderbuffer(GL_RENDERBUFFER, depthRenderbuffer);
+
+ if (samples > 0) {
+ glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, depthBufferFormat, backingWidth, backingHeight);
+ } else {
+ glRenderbufferStorage(GL_RENDERBUFFER, depthBufferFormat, backingWidth, backingHeight);
+ }
+
+ if (useDepthBuffer) {
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthRenderbuffer);
+ }
+ if (useStencilBuffer) {
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthRenderbuffer);
+ }
+ }
+
+ if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
+ SDL_SetError("Failed creating OpenGL ES framebuffer");
+ return nil;
+ }
+
+ glBindRenderbuffer(GL_RENDERBUFFER, viewRenderbuffer);
+
+ [self setDebugLabels];
+ }
+
+ return self;
+}
+
+- (GLuint)drawableRenderbuffer
+{
+ return viewRenderbuffer;
+}
+
+- (GLuint)drawableFramebuffer
+{
+ /* When MSAA is used, the MSAA draw framebuffer is used for drawing. */
+ if (msaaFramebuffer) {
+ return msaaFramebuffer;
+ } else {
+ return viewFramebuffer;
+ }
+}
+
+- (GLuint)msaaResolveFramebuffer
+{
+ /* When MSAA is used, the MSAA draw framebuffer is used for drawing and the
+ * view framebuffer is used as a MSAA resolve framebuffer. */
+ if (msaaFramebuffer) {
+ return viewFramebuffer;
+ } else {
+ return 0;
+ }
+}
+
+- (void)updateFrame
+{
+ GLint prevRenderbuffer = 0;
+ glGetIntegerv(GL_RENDERBUFFER_BINDING, &prevRenderbuffer);
+
+ glBindRenderbuffer(GL_RENDERBUFFER, viewRenderbuffer);
+ [context renderbufferStorage:GL_RENDERBUFFER fromDrawable:(CAEAGLLayer *)self.layer];
+
+ glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &backingWidth);
+ glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &backingHeight);
+
+ if (msaaRenderbuffer != 0) {
+ glBindRenderbuffer(GL_RENDERBUFFER, msaaRenderbuffer);
+ glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, colorBufferFormat, backingWidth, backingHeight);
+ }
+
+ if (depthRenderbuffer != 0) {
+ glBindRenderbuffer(GL_RENDERBUFFER, depthRenderbuffer);
+
+ if (samples > 0) {
+ glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, depthBufferFormat, backingWidth, backingHeight);
+ } else {
+ glRenderbufferStorage(GL_RENDERBUFFER, depthBufferFormat, backingWidth, backingHeight);
+ }
+ }
+
+ glBindRenderbuffer(GL_RENDERBUFFER, prevRenderbuffer);
+}
+
+- (void)setDebugLabels
+{
+ if (viewFramebuffer != 0) {
+ glLabelObjectEXT(GL_FRAMEBUFFER, viewFramebuffer, 0, "context FBO");
+ }
+
+ if (viewRenderbuffer != 0) {
+ glLabelObjectEXT(GL_RENDERBUFFER, viewRenderbuffer, 0, "context color buffer");
+ }
+
+ if (depthRenderbuffer != 0) {
+ if (depthBufferFormat == GL_DEPTH24_STENCIL8_OES) {
+ glLabelObjectEXT(GL_RENDERBUFFER, depthRenderbuffer, 0, "context depth-stencil buffer");
+ } else {
+ glLabelObjectEXT(GL_RENDERBUFFER, depthRenderbuffer, 0, "context depth buffer");
+ }
+ }
+
+ if (msaaFramebuffer != 0) {
+ glLabelObjectEXT(GL_FRAMEBUFFER, msaaFramebuffer, 0, "context MSAA FBO");
+ }
+
+ if (msaaRenderbuffer != 0) {
+ glLabelObjectEXT(GL_RENDERBUFFER, msaaRenderbuffer, 0, "context MSAA renderbuffer");
+ }
+}
+
+- (void)swapBuffers
+{
+ if (msaaFramebuffer) {
+ const GLenum attachments[] = {GL_COLOR_ATTACHMENT0};
+
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, viewFramebuffer);
+
+ /* OpenGL ES 3+ provides explicit MSAA resolves via glBlitFramebuffer.
+ * In OpenGL ES 1 and 2, MSAA resolves must be done via an extension. */
+ if (context.API >= kEAGLRenderingAPIOpenGLES3) {
+ int w = backingWidth;
+ int h = backingHeight;
+ glBlitFramebuffer(0, 0, w, h, 0, 0, w, h, GL_COLOR_BUFFER_BIT, GL_NEAREST);
+
+ if (!retainedBacking) {
+ /* Discard the contents of the MSAA drawable color buffer. */
+ glInvalidateFramebuffer(GL_READ_FRAMEBUFFER, 1, attachments);
+ }
+ } else {
+ glResolveMultisampleFramebufferAPPLE();
+
+ if (!retainedBacking) {
+ glDiscardFramebufferEXT(GL_READ_FRAMEBUFFER, 1, attachments);
+ }
+ }
+
+ /* We assume the "drawable framebuffer" (MSAA draw framebuffer) was
+ * previously bound... */
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, msaaFramebuffer);
+ }
+
+ /* viewRenderbuffer should always be bound here. Code that binds something
+ * else is responsible for rebinding viewRenderbuffer, to reduce duplicate
+ * state changes. */
+ [context presentRenderbuffer:GL_RENDERBUFFER];
+}
+
+- (void)layoutSubviews
+{
+ [super layoutSubviews];
+
+ int width = (int) (self.bounds.size.width * self.contentScaleFactor);
+ int height = (int) (self.bounds.size.height * self.contentScaleFactor);
+
+ /* Update the color and depth buffer storage if the layer size has changed. */
+ if (width != backingWidth || height != backingHeight) {
+ EAGLContext *prevContext = [EAGLContext currentContext];
+ if (prevContext != context) {
+ [EAGLContext setCurrentContext:context];
+ }
+
+ [self updateFrame];
+
+ if (prevContext != context) {
+ [EAGLContext setCurrentContext:prevContext];
+ }
+ }
+}
+
+- (void)destroyFramebuffer
+{
+ if (viewFramebuffer != 0) {
+ glDeleteFramebuffers(1, &viewFramebuffer);
+ viewFramebuffer = 0;
+ }
+
+ if (viewRenderbuffer != 0) {
+ glDeleteRenderbuffers(1, &viewRenderbuffer);
+ viewRenderbuffer = 0;
+ }
+
+ if (depthRenderbuffer != 0) {
+ glDeleteRenderbuffers(1, &depthRenderbuffer);
+ depthRenderbuffer = 0;
+ }
+
+ if (msaaFramebuffer != 0) {
+ glDeleteFramebuffers(1, &msaaFramebuffer);
+ msaaFramebuffer = 0;
+ }
+
+ if (msaaRenderbuffer != 0) {
+ glDeleteRenderbuffers(1, &msaaRenderbuffer);
+ msaaRenderbuffer = 0;
+ }
+}
+
+- (void)dealloc
+{
+ if (context && context == [EAGLContext currentContext]) {
+ [self destroyFramebuffer];
+ [EAGLContext setCurrentContext:nil];
+ }
+}
+
+@end
+
+#endif /* SDL_VIDEO_DRIVER_UIKIT */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/uikit/SDL_uikitvideo.h b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitvideo.h
new file mode 100644
index 0000000..e24183a
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitvideo.h
@@ -0,0 +1,46 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 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
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#ifndef SDL_uikitvideo_h_
+#define SDL_uikitvideo_h_
+
+#include "../SDL_sysvideo.h"
+
+#ifdef __OBJC__
+
+#include <UIKit/UIKit.h>
+
+@interface SDL_VideoData : NSObject
+
+@property (nonatomic, assign) id pasteboardObserver;
+
+@end
+
+CGRect UIKit_ComputeViewFrame(SDL_Window *window, UIScreen *screen);
+
+#endif /* __OBJC__ */
+
+void UIKit_SuspendScreenSaver(_THIS);
+
+SDL_bool UIKit_IsSystemVersionAtLeast(double version);
+
+#endif /* SDL_uikitvideo_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/uikit/SDL_uikitvideo.m b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitvideo.m
new file mode 100644
index 0000000..10d1dde
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitvideo.m
@@ -0,0 +1,249 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 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
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_UIKIT
+
+#import <UIKit/UIKit.h>
+
+#include "SDL_video.h"
+#include "SDL_mouse.h"
+#include "SDL_hints.h"
+#include "../SDL_sysvideo.h"
+#include "../SDL_pixels_c.h"
+#include "../../events/SDL_events_c.h"
+
+#include "SDL_uikitvideo.h"
+#include "SDL_uikitevents.h"
+#include "SDL_uikitmodes.h"
+#include "SDL_uikitwindow.h"
+#include "SDL_uikitopengles.h"
+#include "SDL_uikitclipboard.h"
+#include "SDL_uikitvulkan.h"
+
+#define UIKITVID_DRIVER_NAME "uikit"
+
+@implementation SDL_VideoData
+
+@end
+
+/* Initialization/Query functions */
+static int UIKit_VideoInit(_THIS);
+static void UIKit_VideoQuit(_THIS);
+
+/* DUMMY driver bootstrap functions */
+
+static int
+UIKit_Available(void)
+{
+ return 1;
+}
+
+static void UIKit_DeleteDevice(SDL_VideoDevice * device)
+{
+ @autoreleasepool {
+ CFRelease(device->driverdata);
+ SDL_free(device);
+ }
+}
+
+static SDL_VideoDevice *
+UIKit_CreateDevice(int devindex)
+{
+ @autoreleasepool {
+ SDL_VideoDevice *device;
+ SDL_VideoData *data;
+
+ /* Initialize all variables that we clean on shutdown */
+ device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice));
+ if (device) {
+ data = [SDL_VideoData new];
+ } else {
+ SDL_free(device);
+ SDL_OutOfMemory();
+ return (0);
+ }
+
+ device->driverdata = (void *) CFBridgingRetain(data);
+
+ /* Set the function pointers */
+ device->VideoInit = UIKit_VideoInit;
+ device->VideoQuit = UIKit_VideoQuit;
+ device->GetDisplayModes = UIKit_GetDisplayModes;
+ device->SetDisplayMode = UIKit_SetDisplayMode;
+ device->PumpEvents = UIKit_PumpEvents;
+ device->SuspendScreenSaver = UIKit_SuspendScreenSaver;
+ device->CreateSDLWindow = UIKit_CreateWindow;
+ device->SetWindowTitle = UIKit_SetWindowTitle;
+ device->ShowWindow = UIKit_ShowWindow;
+ device->HideWindow = UIKit_HideWindow;
+ device->RaiseWindow = UIKit_RaiseWindow;
+ device->SetWindowBordered = UIKit_SetWindowBordered;
+ device->SetWindowFullscreen = UIKit_SetWindowFullscreen;
+ device->DestroyWindow = UIKit_DestroyWindow;
+ device->GetWindowWMInfo = UIKit_GetWindowWMInfo;
+ device->GetDisplayUsableBounds = UIKit_GetDisplayUsableBounds;
+
+#if SDL_IPHONE_KEYBOARD
+ device->HasScreenKeyboardSupport = UIKit_HasScreenKeyboardSupport;
+ device->ShowScreenKeyboard = UIKit_ShowScreenKeyboard;
+ device->HideScreenKeyboard = UIKit_HideScreenKeyboard;
+ device->IsScreenKeyboardShown = UIKit_IsScreenKeyboardShown;
+ device->SetTextInputRect = UIKit_SetTextInputRect;
+#endif
+
+ device->SetClipboardText = UIKit_SetClipboardText;
+ device->GetClipboardText = UIKit_GetClipboardText;
+ device->HasClipboardText = UIKit_HasClipboardText;
+
+ /* OpenGL (ES) functions */
+ device->GL_MakeCurrent = UIKit_GL_MakeCurrent;
+ device->GL_GetDrawableSize = UIKit_GL_GetDrawableSize;
+ device->GL_SwapWindow = UIKit_GL_SwapWindow;
+ device->GL_CreateContext = UIKit_GL_CreateContext;
+ device->GL_DeleteContext = UIKit_GL_DeleteContext;
+ device->GL_GetProcAddress = UIKit_GL_GetProcAddress;
+ device->GL_LoadLibrary = UIKit_GL_LoadLibrary;
+ device->free = UIKit_DeleteDevice;
+
+#if SDL_VIDEO_VULKAN
+ device->Vulkan_LoadLibrary = UIKit_Vulkan_LoadLibrary;
+ device->Vulkan_UnloadLibrary = UIKit_Vulkan_UnloadLibrary;
+ device->Vulkan_GetInstanceExtensions
+ = UIKit_Vulkan_GetInstanceExtensions;
+ device->Vulkan_CreateSurface = UIKit_Vulkan_CreateSurface;
+ device->Vulkan_GetDrawableSize = UIKit_Vulkan_GetDrawableSize;
+#endif
+
+ device->gl_config.accelerated = 1;
+
+ return device;
+ }
+}
+
+VideoBootStrap UIKIT_bootstrap = {
+ UIKITVID_DRIVER_NAME, "SDL UIKit video driver",
+ UIKit_Available, UIKit_CreateDevice
+};
+
+
+int
+UIKit_VideoInit(_THIS)
+{
+ _this->gl_config.driver_loaded = 1;
+
+ if (UIKit_InitModes(_this) < 0) {
+ return -1;
+ }
+ return 0;
+}
+
+void
+UIKit_VideoQuit(_THIS)
+{
+ UIKit_QuitModes(_this);
+}
+
+void
+UIKit_SuspendScreenSaver(_THIS)
+{
+ @autoreleasepool {
+ /* Ignore ScreenSaver API calls if the idle timer hint has been set. */
+ /* FIXME: The idle timer hint should be deprecated for SDL 2.1. */
+ if (!SDL_GetHintBoolean(SDL_HINT_IDLE_TIMER_DISABLED, SDL_FALSE)) {
+ UIApplication *app = [UIApplication sharedApplication];
+
+ /* Prevent the display from dimming and going to sleep. */
+ app.idleTimerDisabled = (_this->suspend_screensaver != SDL_FALSE);
+ }
+ }
+}
+
+SDL_bool
+UIKit_IsSystemVersionAtLeast(double version)
+{
+ return [[UIDevice currentDevice].systemVersion doubleValue] >= version;
+}
+
+CGRect
+UIKit_ComputeViewFrame(SDL_Window *window, UIScreen *screen)
+{
+ CGRect frame = screen.bounds;
+
+#if !TARGET_OS_TV && (__IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_7_0)
+ BOOL hasiOS7 = UIKit_IsSystemVersionAtLeast(7.0);
+
+ /* The view should always show behind the status bar in iOS 7+. */
+ if (!hasiOS7 && !(window->flags & (SDL_WINDOW_BORDERLESS|SDL_WINDOW_FULLSCREEN))) {
+ frame = screen.applicationFrame;
+ }
+#endif
+
+#if !TARGET_OS_TV
+ /* iOS 10 seems to have a bug where, in certain conditions, putting the
+ * device to sleep with the a landscape-only app open, re-orienting the
+ * device to portrait, and turning it back on will result in the screen
+ * bounds returning portrait orientation despite the app being in landscape.
+ * This is a workaround until a better solution can be found.
+ * https://bugzilla.libsdl.org/show_bug.cgi?id=3505
+ * https://bugzilla.libsdl.org/show_bug.cgi?id=3465
+ * https://forums.developer.apple.com/thread/65337 */
+ if (UIKit_IsSystemVersionAtLeast(8.0)) {
+ UIInterfaceOrientation orient = [UIApplication sharedApplication].statusBarOrientation;
+ BOOL isLandscape = UIInterfaceOrientationIsLandscape(orient);
+
+ if (isLandscape != (frame.size.width > frame.size.height)) {
+ float height = frame.size.width;
+ frame.size.width = frame.size.height;
+ frame.size.height = height;
+ }
+ }
+#endif
+
+ return frame;
+}
+
+/*
+ * iOS log support.
+ *
+ * This doesn't really have aything to do with the interfaces of the SDL video
+ * subsystem, but we need to stuff this into an Objective-C source code file.
+ */
+
+void SDL_NSLog(const char *text)
+{
+ NSLog(@"%s", text);
+}
+
+/*
+ * iOS Tablet detection
+ *
+ * This doesn't really have aything to do with the interfaces of the SDL video
+ * subsystem, but we need to stuff this into an Objective-C source code file.
+ */
+SDL_bool SDL_IsIPad(void)
+{
+ return (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad);
+}
+
+#endif /* SDL_VIDEO_DRIVER_UIKIT */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/uikit/SDL_uikitview.h b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitview.h
new file mode 100644
index 0000000..4457f6c
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitview.h
@@ -0,0 +1,41 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 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
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#import <UIKit/UIKit.h>
+
+#include "../SDL_sysvideo.h"
+
+#include "SDL_touch.h"
+
+@interface SDL_uikitview : UIView
+
+- (instancetype)initWithFrame:(CGRect)frame;
+
+- (void)setSDLWindow:(SDL_Window *)window;
+
+- (CGPoint)touchLocation:(UITouch *)touch shouldNormalize:(BOOL)normalize;
+- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
+- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
+- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
+
+@end
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/uikit/SDL_uikitview.m b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitview.m
new file mode 100644
index 0000000..caabfac
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitview.m
@@ -0,0 +1,328 @@
+ /*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 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
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_UIKIT
+
+#include "SDL_uikitview.h"
+
+#include "SDL_hints.h"
+#include "../../events/SDL_mouse_c.h"
+#include "../../events/SDL_touch_c.h"
+#include "../../events/SDL_events_c.h"
+
+#import "SDL_uikitappdelegate.h"
+#import "SDL_uikitmodes.h"
+#import "SDL_uikitwindow.h"
+
+/* This is defined in SDL_sysjoystick.m */
+extern int SDL_AppleTVRemoteOpenedAsJoystick;
+
+@implementation SDL_uikitview {
+ SDL_Window *sdlwindow;
+
+ SDL_TouchID touchId;
+ UITouch * __weak firstFingerDown;
+}
+
+- (instancetype)initWithFrame:(CGRect)frame
+{
+ if ((self = [super initWithFrame:frame])) {
+#if TARGET_OS_TV
+ /* Apple TV Remote touchpad swipe gestures. */
+ UISwipeGestureRecognizer *swipeUp = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeGesture:)];
+ swipeUp.direction = UISwipeGestureRecognizerDirectionUp;
+ [self addGestureRecognizer:swipeUp];
+
+ UISwipeGestureRecognizer *swipeDown = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeGesture:)];
+ swipeDown.direction = UISwipeGestureRecognizerDirectionDown;
+ [self addGestureRecognizer:swipeDown];
+
+ UISwipeGestureRecognizer *swipeLeft = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeGesture:)];
+ swipeLeft.direction = UISwipeGestureRecognizerDirectionLeft;
+ [self addGestureRecognizer:swipeLeft];
+
+ UISwipeGestureRecognizer *swipeRight = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeGesture:)];
+ swipeRight.direction = UISwipeGestureRecognizerDirectionRight;
+ [self addGestureRecognizer:swipeRight];
+#endif
+
+ self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
+ self.autoresizesSubviews = YES;
+
+#if !TARGET_OS_TV
+ self.multipleTouchEnabled = YES;
+#endif
+
+ 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];
+
+ if (normalize) {
+ CGRect bounds = self.bounds;
+ point.x /= bounds.size.width;
+ point.y /= bounds.size.height;
+ }
+
+ return point;
+}
+
+- (float)pressureForTouch:(UITouch *)touch
+{
+#ifdef __IPHONE_9_0
+ if ([touch respondsToSelector:@selector(force)]) {
+ return (float) touch.force;
+ }
+#endif
+
+ return 1.0f;
+}
+
+- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
+{
+ for (UITouch *touch in touches) {
+ float pressure = [self pressureForTouch:touch];
+
+ if (!firstFingerDown) {
+ CGPoint locationInView = [self touchLocation:touch shouldNormalize:NO];
+ int clicks = (int) touch.tapCount;
+
+ /* send mouse moved event */
+ SDL_SendMouseMotion(sdlwindow, SDL_TOUCH_MOUSEID, 0, locationInView.x, locationInView.y);
+
+ /* send mouse down event */
+ SDL_SendMouseButtonClicks(sdlwindow, SDL_TOUCH_MOUSEID, SDL_PRESSED, SDL_BUTTON_LEFT, clicks);
+
+ firstFingerDown = touch;
+ }
+
+ CGPoint locationInView = [self touchLocation:touch shouldNormalize:YES];
+ SDL_SendTouch(touchId, (SDL_FingerID)((size_t)touch),
+ SDL_TRUE, locationInView.x, locationInView.y, pressure);
+ }
+}
+
+- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
+{
+ for (UITouch *touch in touches) {
+ float pressure = [self pressureForTouch:touch];
+
+ if (touch == firstFingerDown) {
+ /* send mouse up */
+ int clicks = (int) touch.tapCount;
+ SDL_SendMouseButtonClicks(sdlwindow, SDL_TOUCH_MOUSEID, SDL_RELEASED, SDL_BUTTON_LEFT, clicks);
+ firstFingerDown = nil;
+ }
+
+ CGPoint locationInView = [self touchLocation:touch shouldNormalize:YES];
+ SDL_SendTouch(touchId, (SDL_FingerID)((size_t)touch),
+ SDL_FALSE, locationInView.x, locationInView.y, pressure);
+ }
+}
+
+- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
+{
+ [self touchesEnded:touches withEvent:event];
+}
+
+- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
+{
+ for (UITouch *touch in touches) {
+ float pressure = [self pressureForTouch:touch];
+
+ if (touch == firstFingerDown) {
+ CGPoint locationInView = [self touchLocation:touch shouldNormalize:NO];
+
+ /* send moved event */
+ SDL_SendMouseMotion(sdlwindow, SDL_TOUCH_MOUSEID, 0, locationInView.x, locationInView.y);
+ }
+
+ CGPoint locationInView = [self touchLocation:touch shouldNormalize:YES];
+ SDL_SendTouchMotion(touchId, (SDL_FingerID)((size_t)touch),
+ locationInView.x, locationInView.y, pressure);
+ }
+}
+
+#if TARGET_OS_TV || defined(__IPHONE_9_1)
+- (SDL_Scancode)scancodeFromPressType:(UIPressType)presstype
+{
+ switch (presstype) {
+ case UIPressTypeUpArrow:
+ return SDL_SCANCODE_UP;
+ case UIPressTypeDownArrow:
+ return SDL_SCANCODE_DOWN;
+ case UIPressTypeLeftArrow:
+ return SDL_SCANCODE_LEFT;
+ case UIPressTypeRightArrow:
+ return SDL_SCANCODE_RIGHT;
+ case UIPressTypeSelect:
+ /* HIG says: "primary button behavior" */
+ return SDL_SCANCODE_RETURN;
+ case UIPressTypeMenu:
+ /* HIG says: "returns to previous screen" */
+ return SDL_SCANCODE_ESCAPE;
+ case UIPressTypePlayPause:
+ /* HIG says: "secondary button behavior" */
+ return SDL_SCANCODE_PAUSE;
+ default:
+ return SDL_SCANCODE_UNKNOWN;
+ }
+}
+
+- (void)pressesBegan:(NSSet<UIPress *> *)presses withEvent:(UIPressesEvent *)event
+{
+ if (!SDL_AppleTVRemoteOpenedAsJoystick) {
+ for (UIPress *press in presses) {
+ SDL_Scancode scancode = [self scancodeFromPressType:press.type];
+ SDL_SendKeyboardKey(SDL_PRESSED, scancode);
+ }
+ }
+ [super pressesBegan:presses withEvent:event];
+}
+
+- (void)pressesEnded:(NSSet<UIPress *> *)presses withEvent:(UIPressesEvent *)event
+{
+ if (!SDL_AppleTVRemoteOpenedAsJoystick) {
+ for (UIPress *press in presses) {
+ SDL_Scancode scancode = [self scancodeFromPressType:press.type];
+ SDL_SendKeyboardKey(SDL_RELEASED, scancode);
+ }
+ }
+ [super pressesEnded:presses withEvent:event];
+}
+
+- (void)pressesCancelled:(NSSet<UIPress *> *)presses withEvent:(UIPressesEvent *)event
+{
+ if (!SDL_AppleTVRemoteOpenedAsJoystick) {
+ for (UIPress *press in presses) {
+ SDL_Scancode scancode = [self scancodeFromPressType:press.type];
+ SDL_SendKeyboardKey(SDL_RELEASED, scancode);
+ }
+ }
+ [super pressesCancelled:presses withEvent:event];
+}
+
+- (void)pressesChanged:(NSSet<UIPress *> *)presses withEvent:(UIPressesEvent *)event
+{
+ /* This is only called when the force of a press changes. */
+ [super pressesChanged:presses withEvent:event];
+}
+#endif /* TARGET_OS_TV || defined(__IPHONE_9_1) */
+
+#if TARGET_OS_TV
+-(void)swipeGesture:(UISwipeGestureRecognizer *)gesture
+{
+ /* Swipe gestures don't trigger begin states. */
+ if (gesture.state == UIGestureRecognizerStateEnded) {
+ if (!SDL_AppleTVRemoteOpenedAsJoystick) {
+ /* Send arrow key presses for now, as we don't have an external API
+ * which better maps to swipe gestures. */
+ switch (gesture.direction) {
+ case UISwipeGestureRecognizerDirectionUp:
+ SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_UP);
+ SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_UP);
+ break;
+ case UISwipeGestureRecognizerDirectionDown:
+ SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_DOWN);
+ SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_DOWN);
+ break;
+ case UISwipeGestureRecognizerDirectionLeft:
+ SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_LEFT);
+ SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_LEFT);
+ break;
+ case UISwipeGestureRecognizerDirectionRight:
+ SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_RIGHT);
+ SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_RIGHT);
+ break;
+ }
+ }
+ }
+}
+#endif /* TARGET_OS_TV */
+
+@end
+
+#endif /* SDL_VIDEO_DRIVER_UIKIT */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/uikit/SDL_uikitviewcontroller.h b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitviewcontroller.h
new file mode 100644
index 0000000..fffb142
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitviewcontroller.h
@@ -0,0 +1,91 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 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
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#import <UIKit/UIKit.h>
+
+#include "../SDL_sysvideo.h"
+
+#include "SDL_touch.h"
+
+#if TARGET_OS_TV
+#import <GameController/GameController.h>
+#define SDLRootViewController GCEventViewController
+#else
+#define SDLRootViewController UIViewController
+#endif
+
+#if SDL_IPHONE_KEYBOARD
+@interface SDL_uikitviewcontroller : SDLRootViewController <UITextFieldDelegate>
+#else
+@interface SDL_uikitviewcontroller : SDLRootViewController
+#endif
+
+@property (nonatomic, assign) SDL_Window *window;
+
+- (instancetype)initWithSDLWindow:(SDL_Window *)_window;
+
+- (void)setAnimationCallback:(int)interval
+ callback:(void (*)(void*))callback
+ callbackParam:(void*)callbackParam;
+
+- (void)startAnimation;
+- (void)stopAnimation;
+
+- (void)doLoop:(CADisplayLink*)sender;
+
+- (void)loadView;
+- (void)viewDidLayoutSubviews;
+
+#if !TARGET_OS_TV
+- (NSUInteger)supportedInterfaceOrientations;
+- (BOOL)prefersStatusBarHidden;
+- (BOOL)prefersHomeIndicatorAutoHidden;
+- (UIRectEdge)preferredScreenEdgesDeferringSystemGestures;
+
+@property (nonatomic, assign) int homeIndicatorHidden;
+#endif
+
+#if SDL_IPHONE_KEYBOARD
+- (void)showKeyboard;
+- (void)hideKeyboard;
+- (void)initKeyboard;
+- (void)deinitKeyboard;
+
+- (void)keyboardWillShow:(NSNotification *)notification;
+- (void)keyboardWillHide:(NSNotification *)notification;
+
+- (void)updateKeyboard;
+
+@property (nonatomic, assign, getter=isKeyboardVisible) BOOL keyboardVisible;
+@property (nonatomic, assign) SDL_Rect textInputRect;
+@property (nonatomic, assign) int keyboardHeight;
+#endif
+
+@end
+
+#if SDL_IPHONE_KEYBOARD
+SDL_bool UIKit_HasScreenKeyboardSupport(_THIS);
+void UIKit_ShowScreenKeyboard(_THIS, SDL_Window *window);
+void UIKit_HideScreenKeyboard(_THIS, SDL_Window *window);
+SDL_bool UIKit_IsScreenKeyboardShown(_THIS, SDL_Window *window);
+void UIKit_SetTextInputRect(_THIS, SDL_Rect *rect);
+#endif
diff --git a/source/3rd-party/SDL2/src/video/uikit/SDL_uikitviewcontroller.m b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitviewcontroller.m
new file mode 100644
index 0000000..49a39b6
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitviewcontroller.m
@@ -0,0 +1,553 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 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
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_UIKIT
+
+#include "SDL_video.h"
+#include "SDL_assert.h"
+#include "SDL_hints.h"
+#include "../SDL_sysvideo.h"
+#include "../../events/SDL_events_c.h"
+
+#import "SDL_uikitviewcontroller.h"
+#import "SDL_uikitmessagebox.h"
+#include "SDL_uikitvideo.h"
+#include "SDL_uikitmodes.h"
+#include "SDL_uikitwindow.h"
+#include "SDL_uikitopengles.h"
+
+#if SDL_IPHONE_KEYBOARD
+#include "keyinfotable.h"
+#endif
+
+#if TARGET_OS_TV
+static void SDLCALL
+SDL_AppleTVControllerUIHintChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
+{
+ @autoreleasepool {
+ SDL_uikitviewcontroller *viewcontroller = (__bridge SDL_uikitviewcontroller *) userdata;
+ viewcontroller.controllerUserInteractionEnabled = hint && (*hint != '0');
+ }
+}
+#endif
+
+#if !TARGET_OS_TV
+static void SDLCALL
+SDL_HideHomeIndicatorHintChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
+{
+ @autoreleasepool {
+ SDL_uikitviewcontroller *viewcontroller = (__bridge SDL_uikitviewcontroller *) userdata;
+ viewcontroller.homeIndicatorHidden = (hint && *hint) ? SDL_atoi(hint) : -1;
+ if (@available(iOS 11.0, *)) {
+ [viewcontroller setNeedsUpdateOfHomeIndicatorAutoHidden];
+ [viewcontroller setNeedsUpdateOfScreenEdgesDeferringSystemGestures];
+ }
+ }
+}
+#endif
+
+@implementation SDL_uikitviewcontroller {
+ CADisplayLink *displayLink;
+ int animationInterval;
+ void (*animationCallback)(void*);
+ void *animationCallbackParam;
+
+#if SDL_IPHONE_KEYBOARD
+ UITextField *textField;
+ BOOL rotatingOrientation;
+ NSString *changeText;
+ NSString *obligateForBackspace;
+#endif
+}
+
+@synthesize window;
+
+- (instancetype)initWithSDLWindow:(SDL_Window *)_window
+{
+ if (self = [super initWithNibName:nil bundle:nil]) {
+ self.window = _window;
+
+#if SDL_IPHONE_KEYBOARD
+ [self initKeyboard];
+ rotatingOrientation = FALSE;
+#endif
+
+#if TARGET_OS_TV
+ SDL_AddHintCallback(SDL_HINT_APPLE_TV_CONTROLLER_UI_EVENTS,
+ SDL_AppleTVControllerUIHintChanged,
+ (__bridge void *) self);
+#endif
+
+#if !TARGET_OS_TV
+ SDL_AddHintCallback(SDL_HINT_IOS_HIDE_HOME_INDICATOR,
+ SDL_HideHomeIndicatorHintChanged,
+ (__bridge void *) self);
+#endif
+ }
+ return self;
+}
+
+- (void)dealloc
+{
+#if SDL_IPHONE_KEYBOARD
+ [self deinitKeyboard];
+#endif
+
+#if TARGET_OS_TV
+ SDL_DelHintCallback(SDL_HINT_APPLE_TV_CONTROLLER_UI_EVENTS,
+ SDL_AppleTVControllerUIHintChanged,
+ (__bridge void *) self);
+#endif
+
+#if !TARGET_OS_TV
+ SDL_DelHintCallback(SDL_HINT_IOS_HIDE_HOME_INDICATOR,
+ SDL_HideHomeIndicatorHintChanged,
+ (__bridge void *) self);
+#endif
+}
+
+- (void)setAnimationCallback:(int)interval
+ callback:(void (*)(void*))callback
+ callbackParam:(void*)callbackParam
+{
+ [self stopAnimation];
+
+ animationInterval = interval;
+ animationCallback = callback;
+ animationCallbackParam = callbackParam;
+
+ if (animationCallback) {
+ [self startAnimation];
+ }
+}
+
+- (void)startAnimation
+{
+ displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(doLoop:)];
+
+#ifdef __IPHONE_10_3
+ SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata;
+
+ if ([displayLink respondsToSelector:@selector(preferredFramesPerSecond)]
+ && data != nil && data.uiwindow != nil
+ && [data.uiwindow.screen respondsToSelector:@selector(maximumFramesPerSecond)]) {
+ displayLink.preferredFramesPerSecond = data.uiwindow.screen.maximumFramesPerSecond / animationInterval;
+ } else
+#endif
+ {
+#if __IPHONE_OS_VERSION_MIN_REQUIRED < 100300
+ [displayLink setFrameInterval:animationInterval];
+#endif
+ }
+
+ [displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
+}
+
+- (void)stopAnimation
+{
+ [displayLink invalidate];
+ displayLink = nil;
+}
+
+- (void)doLoop:(CADisplayLink*)sender
+{
+ /* Don't run the game loop while a messagebox is up */
+ if (!UIKit_ShowingMessageBox()) {
+ /* See the comment in the function definition. */
+ UIKit_GL_RestoreCurrentContext();
+
+ animationCallback(animationCallbackParam);
+ }
+}
+
+- (void)loadView
+{
+ /* Do nothing. */
+}
+
+- (void)viewDidLayoutSubviews
+{
+ const CGSize size = self.view.bounds.size;
+ int w = (int) size.width;
+ int h = (int) size.height;
+
+ SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, w, h);
+}
+
+#if !TARGET_OS_TV
+- (NSUInteger)supportedInterfaceOrientations
+{
+ return UIKit_GetSupportedOrientations(window);
+}
+
+#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_7_0
+- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)orient
+{
+ return ([self supportedInterfaceOrientations] & (1 << orient)) != 0;
+}
+#endif
+
+- (BOOL)prefersStatusBarHidden
+{
+ BOOL hidden = (window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_BORDERLESS)) != 0;
+ return hidden;
+}
+
+- (BOOL)prefersHomeIndicatorAutoHidden
+{
+ BOOL hidden = NO;
+ if (self.homeIndicatorHidden == 1) {
+ hidden = YES;
+ }
+ return hidden;
+}
+
+- (UIRectEdge)preferredScreenEdgesDeferringSystemGestures
+{
+ if (self.homeIndicatorHidden >= 0) {
+ if (self.homeIndicatorHidden == 2) {
+ return UIRectEdgeAll;
+ } else {
+ return UIRectEdgeNone;
+ }
+ }
+
+ /* By default, fullscreen and borderless windows get all screen gestures */
+ if ((window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_BORDERLESS)) != 0) {
+ return UIRectEdgeAll;
+ } else {
+ return UIRectEdgeNone;
+ }
+}
+#endif
+
+/*
+ ---- Keyboard related functionality below this line ----
+ */
+#if SDL_IPHONE_KEYBOARD
+
+@synthesize textInputRect;
+@synthesize keyboardHeight;
+@synthesize keyboardVisible;
+
+/* Set ourselves up as a UITextFieldDelegate */
+- (void)initKeyboard
+{
+ changeText = nil;
+ obligateForBackspace = @" "; /* 64 space */
+ textField = [[UITextField alloc] initWithFrame:CGRectZero];
+ textField.delegate = self;
+ /* placeholder so there is something to delete! */
+ textField.text = obligateForBackspace;
+
+ /* 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;
+
+ NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
+#if !TARGET_OS_TV
+ [center addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
+ [center addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
+#endif
+ [center addObserver:self selector:@selector(textFieldTextDidChange:) name:UITextFieldTextDidChangeNotification object:nil];
+}
+
+- (void)setView:(UIView *)view
+{
+ [super setView:view];
+
+ [view addSubview:textField];
+
+ if (keyboardVisible) {
+ [self showKeyboard];
+ }
+}
+
+/* willRotateToInterfaceOrientation and didRotateFromInterfaceOrientation are deprecated in iOS 8+ in favor of viewWillTransitionToSize */
+#if TARGET_OS_TV || __IPHONE_OS_VERSION_MIN_REQUIRED >= 80000
+- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
+{
+ [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
+ rotatingOrientation = TRUE;
+ [coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context) {}
+ completion:^(id<UIViewControllerTransitionCoordinatorContext> context) {
+ rotatingOrientation = FALSE;
+ }];
+}
+#else
+- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
+ [super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
+ rotatingOrientation = TRUE;
+}
+
+- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
+ [super didRotateFromInterfaceOrientation:fromInterfaceOrientation];
+ rotatingOrientation = FALSE;
+}
+#endif /* TARGET_OS_TV || __IPHONE_OS_VERSION_MIN_REQUIRED >= 80000 */
+
+- (void)deinitKeyboard
+{
+ NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
+#if !TARGET_OS_TV
+ [center removeObserver:self name:UIKeyboardWillShowNotification object:nil];
+ [center removeObserver:self name:UIKeyboardWillHideNotification object:nil];
+#endif
+ [center removeObserver:self name:UITextFieldTextDidChangeNotification object:nil];
+}
+
+/* reveal onscreen virtual keyboard */
+- (void)showKeyboard
+{
+ keyboardVisible = YES;
+ if (textField.window) {
+ [textField becomeFirstResponder];
+ }
+}
+
+/* hide onscreen virtual keyboard */
+- (void)hideKeyboard
+{
+ keyboardVisible = NO;
+ [textField resignFirstResponder];
+}
+
+- (void)keyboardWillShow:(NSNotification *)notification
+{
+#if !TARGET_OS_TV
+ CGRect kbrect = [[notification userInfo][UIKeyboardFrameEndUserInfoKey] CGRectValue];
+
+ /* The keyboard rect is in the coordinate space of the screen/window, but we
+ * want its height in the coordinate space of the view. */
+ kbrect = [self.view convertRect:kbrect fromView:nil];
+
+ [self setKeyboardHeight:(int)kbrect.size.height];
+#endif
+}
+
+- (void)keyboardWillHide:(NSNotification *)notification
+{
+ if (!rotatingOrientation) {
+ SDL_StopTextInput();
+ }
+ [self setKeyboardHeight:0];
+}
+
+- (void)textFieldTextDidChange:(NSNotification *)notification
+{
+ if (changeText!=nil && textField.markedTextRange == nil)
+ {
+ NSUInteger len = changeText.length;
+ if (len > 0) {
+ /* Go through all the characters in the string we've been sent and
+ * convert them to key presses */
+ int i;
+ for (i = 0; i < len; i++) {
+ unichar c = [changeText characterAtIndex:i];
+ SDL_Scancode code;
+ Uint16 mod;
+
+ 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([changeText UTF8String]);
+ }
+ changeText = nil;
+ }
+}
+
+- (void)updateKeyboard
+{
+ CGAffineTransform t = self.view.transform;
+ CGPoint offset = CGPointMake(0.0, 0.0);
+ CGRect frame = UIKit_ComputeViewFrame(window, self.view.window.screen);
+
+ if (self.keyboardHeight) {
+ int rectbottom = self.textInputRect.y + self.textInputRect.h;
+ int keybottom = self.view.bounds.size.height - self.keyboardHeight;
+ if (keybottom < rectbottom) {
+ offset.y = keybottom - rectbottom;
+ }
+ }
+
+ /* Apply this view's transform (except any translation) to the offset, in
+ * order to orient it correctly relative to the frame's coordinate space. */
+ t.tx = 0.0;
+ t.ty = 0.0;
+ offset = CGPointApplyAffineTransform(offset, t);
+
+ /* Apply the updated offset to the view's frame. */
+ frame.origin.x += offset.x;
+ frame.origin.y += offset.y;
+
+ self.view.frame = frame;
+}
+
+- (void)setKeyboardHeight:(int)height
+{
+ keyboardVisible = height > 0;
+ keyboardHeight = height;
+ [self updateKeyboard];
+}
+
+/* UITextFieldDelegate method. Invoked when user types something. */
+- (BOOL)textField:(UITextField *)_textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
+{
+ NSUInteger len = string.length;
+ if (len == 0) {
+ changeText = nil;
+ if (textField.markedTextRange == nil) {
+ /* it wants to replace text with nothing, ie a delete */
+ SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_BACKSPACE);
+ SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_BACKSPACE);
+ }
+ if (textField.text.length < 16) {
+ textField.text = obligateForBackspace;
+ }
+ } else {
+ changeText = string;
+ }
+ return YES;
+}
+
+/* Terminates the editing session */
+- (BOOL)textFieldShouldReturn:(UITextField*)_textField
+{
+ SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_RETURN);
+ SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_RETURN);
+ if (SDL_GetHintBoolean(SDL_HINT_RETURN_KEY_HIDES_IME, SDL_FALSE)) {
+ SDL_StopTextInput();
+ }
+ return YES;
+}
+
+#endif
+
+@end
+
+/* iPhone keyboard addition functions */
+#if SDL_IPHONE_KEYBOARD
+
+static SDL_uikitviewcontroller *
+GetWindowViewController(SDL_Window * window)
+{
+ if (!window || !window->driverdata) {
+ SDL_SetError("Invalid window");
+ return nil;
+ }
+
+ SDL_WindowData *data = (__bridge SDL_WindowData *)window->driverdata;
+
+ return data.viewcontroller;
+}
+
+SDL_bool
+UIKit_HasScreenKeyboardSupport(_THIS)
+{
+ return SDL_TRUE;
+}
+
+void
+UIKit_ShowScreenKeyboard(_THIS, SDL_Window *window)
+{
+ @autoreleasepool {
+ SDL_uikitviewcontroller *vc = GetWindowViewController(window);
+ [vc showKeyboard];
+ }
+}
+
+void
+UIKit_HideScreenKeyboard(_THIS, SDL_Window *window)
+{
+ @autoreleasepool {
+ SDL_uikitviewcontroller *vc = GetWindowViewController(window);
+ [vc hideKeyboard];
+ }
+}
+
+SDL_bool
+UIKit_IsScreenKeyboardShown(_THIS, SDL_Window *window)
+{
+ @autoreleasepool {
+ SDL_uikitviewcontroller *vc = GetWindowViewController(window);
+ if (vc != nil) {
+ return vc.keyboardVisible;
+ }
+ return SDL_FALSE;
+ }
+}
+
+void
+UIKit_SetTextInputRect(_THIS, SDL_Rect *rect)
+{
+ if (!rect) {
+ SDL_InvalidParamError("rect");
+ return;
+ }
+
+ @autoreleasepool {
+ SDL_uikitviewcontroller *vc = GetWindowViewController(SDL_GetFocusWindow());
+ if (vc != nil) {
+ vc.textInputRect = *rect;
+
+ if (vc.keyboardVisible) {
+ [vc updateKeyboard];
+ }
+ }
+ }
+}
+
+
+#endif /* SDL_IPHONE_KEYBOARD */
+
+#endif /* SDL_VIDEO_DRIVER_UIKIT */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/uikit/SDL_uikitvulkan.h b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitvulkan.h
new file mode 100644
index 0000000..e3ec350
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitvulkan.h
@@ -0,0 +1,54 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 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
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+/*
+ * @author Mark Callow, www.edgewise-consulting.com. Based on Jacob Lifshay's
+ * SDL_x11vulkan.h.
+ */
+
+#include "../../SDL_internal.h"
+
+#ifndef SDL_uikitvulkan_h_
+#define SDL_uikitvulkan_h_
+
+#include "../SDL_vulkan_internal.h"
+#include "../SDL_sysvideo.h"
+
+#if SDL_VIDEO_VULKAN && SDL_VIDEO_DRIVER_UIKIT
+
+int UIKit_Vulkan_LoadLibrary(_THIS, const char *path);
+void UIKit_Vulkan_UnloadLibrary(_THIS);
+SDL_bool UIKit_Vulkan_GetInstanceExtensions(_THIS,
+ SDL_Window *window,
+ unsigned *count,
+ const char **names);
+SDL_bool UIKit_Vulkan_CreateSurface(_THIS,
+ SDL_Window *window,
+ VkInstance instance,
+ VkSurfaceKHR *surface);
+
+void UIKit_Vulkan_GetDrawableSize(_THIS, SDL_Window *window, int *w, int *h);
+
+#endif
+
+#endif /* SDL_uikitvulkan_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/uikit/SDL_uikitvulkan.m b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitvulkan.m
new file mode 100644
index 0000000..771c7a4
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitvulkan.m
@@ -0,0 +1,222 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 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
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+/*
+ * @author Mark Callow, www.edgewise-consulting.com. Based on Jacob Lifshay's
+ * SDL_x11vulkan.c.
+ */
+
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_VULKAN && SDL_VIDEO_DRIVER_UIKIT
+
+#include "SDL_uikitvideo.h"
+#include "SDL_uikitwindow.h"
+#include "SDL_assert.h"
+
+#include "SDL_loadso.h"
+#include "SDL_uikitvulkan.h"
+#include "SDL_uikitmetalview.h"
+#include "SDL_syswm.h"
+
+#include <dlfcn.h>
+
+#define DEFAULT_MOLTENVK "libMoltenVK.dylib"
+/* Since libSDL is static, could use RTLD_SELF. Using RTLD_DEFAULT is future
+ * proofing. */
+#define DEFAULT_HANDLE RTLD_DEFAULT
+
+int UIKit_Vulkan_LoadLibrary(_THIS, const char *path)
+{
+ VkExtensionProperties *extensions = NULL;
+ Uint32 extensionCount = 0;
+ SDL_bool hasSurfaceExtension = SDL_FALSE;
+ SDL_bool hasIOSSurfaceExtension = SDL_FALSE;
+ PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = NULL;
+
+ if (_this->vulkan_config.loader_handle) {
+ return SDL_SetError("MoltenVK/Vulkan already loaded");
+ }
+
+ /* Load the Vulkan loader library */
+ if (!path) {
+ path = SDL_getenv("SDL_VULKAN_LIBRARY");
+ }
+
+ if (!path) {
+ /* MoltenVK framework, currently, v0.17.0, has a static library and is
+ * the recommended way to use the package. There is likely no object to
+ * load. */
+ vkGetInstanceProcAddr =
+ (PFN_vkGetInstanceProcAddr)dlsym(DEFAULT_HANDLE,
+ "vkGetInstanceProcAddr");
+ }
+
+ if (vkGetInstanceProcAddr) {
+ _this->vulkan_config.loader_handle = DEFAULT_HANDLE;
+ } else {
+ if (!path) {
+ /* Look for the .dylib packaged with the application instead. */
+ path = DEFAULT_MOLTENVK;
+ }
+
+ _this->vulkan_config.loader_handle = SDL_LoadObject(path);
+ if (!_this->vulkan_config.loader_handle) {
+ return -1;
+ }
+ SDL_strlcpy(_this->vulkan_config.loader_path, path,
+ SDL_arraysize(_this->vulkan_config.loader_path));
+ vkGetInstanceProcAddr =
+ (PFN_vkGetInstanceProcAddr)SDL_LoadFunction(
+ _this->vulkan_config.loader_handle,
+ "vkGetInstanceProcAddr");
+ }
+
+ if (!vkGetInstanceProcAddr) {
+ SDL_SetError("Failed to find %s in either executable or %s: %s",
+ "vkGetInstanceProcAddr",
+ DEFAULT_MOLTENVK,
+ (const char *) dlerror());
+ goto fail;
+ }
+
+ _this->vulkan_config.vkGetInstanceProcAddr = (void *)vkGetInstanceProcAddr;
+ _this->vulkan_config.vkEnumerateInstanceExtensionProperties =
+ (void *)((PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr)(
+ VK_NULL_HANDLE, "vkEnumerateInstanceExtensionProperties");
+
+ if (!_this->vulkan_config.vkEnumerateInstanceExtensionProperties) {
+ SDL_SetError("No vkEnumerateInstanceExtensionProperties found.");
+ goto fail;
+ }
+
+ extensions = SDL_Vulkan_CreateInstanceExtensionsList(
+ (PFN_vkEnumerateInstanceExtensionProperties)
+ _this->vulkan_config.vkEnumerateInstanceExtensionProperties,
+ &extensionCount);
+
+ if (!extensions) {
+ goto fail;
+ }
+
+ for (Uint32 i = 0; i < extensionCount; i++) {
+ if (SDL_strcmp(VK_KHR_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0) {
+ hasSurfaceExtension = SDL_TRUE;
+ } else if (SDL_strcmp(VK_MVK_IOS_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0) {
+ hasIOSSurfaceExtension = SDL_TRUE;
+ }
+ }
+
+ SDL_free(extensions);
+
+ if (!hasSurfaceExtension) {
+ SDL_SetError("Installed MoltenVK/Vulkan doesn't implement the "
+ VK_KHR_SURFACE_EXTENSION_NAME " extension");
+ goto fail;
+ } else if (!hasIOSSurfaceExtension) {
+ SDL_SetError("Installed MoltenVK/Vulkan doesn't implement the "
+ VK_MVK_IOS_SURFACE_EXTENSION_NAME "extension");
+ goto fail;
+ }
+
+ return 0;
+
+fail:
+ _this->vulkan_config.loader_handle = NULL;
+ return -1;
+}
+
+void UIKit_Vulkan_UnloadLibrary(_THIS)
+{
+ if (_this->vulkan_config.loader_handle) {
+ if (_this->vulkan_config.loader_handle != DEFAULT_HANDLE) {
+ SDL_UnloadObject(_this->vulkan_config.loader_handle);
+ }
+ _this->vulkan_config.loader_handle = NULL;
+ }
+}
+
+SDL_bool UIKit_Vulkan_GetInstanceExtensions(_THIS,
+ SDL_Window *window,
+ unsigned *count,
+ const char **names)
+{
+ static const char *const extensionsForUIKit[] = {
+ VK_KHR_SURFACE_EXTENSION_NAME, VK_MVK_IOS_SURFACE_EXTENSION_NAME
+ };
+ if (!_this->vulkan_config.loader_handle) {
+ SDL_SetError("Vulkan is not loaded");
+ return SDL_FALSE;
+ }
+
+ return SDL_Vulkan_GetInstanceExtensions_Helper(
+ count, names, SDL_arraysize(extensionsForUIKit),
+ extensionsForUIKit);
+}
+
+SDL_bool UIKit_Vulkan_CreateSurface(_THIS,
+ SDL_Window *window,
+ VkInstance instance,
+ VkSurfaceKHR *surface)
+{
+ PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr =
+ (PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr;
+ PFN_vkCreateIOSSurfaceMVK vkCreateIOSSurfaceMVK =
+ (PFN_vkCreateIOSSurfaceMVK)vkGetInstanceProcAddr(
+ (VkInstance)instance,
+ "vkCreateIOSSurfaceMVK");
+ VkIOSSurfaceCreateInfoMVK createInfo = {};
+ VkResult result;
+
+ if (!_this->vulkan_config.loader_handle) {
+ SDL_SetError("Vulkan is not loaded");
+ return SDL_FALSE;
+ }
+
+ if (!vkCreateIOSSurfaceMVK) {
+ SDL_SetError(VK_MVK_IOS_SURFACE_EXTENSION_NAME
+ " extension is not enabled in the Vulkan instance.");
+ return SDL_FALSE;
+ }
+
+ createInfo.sType = VK_STRUCTURE_TYPE_IOS_SURFACE_CREATE_INFO_MVK;
+ createInfo.pNext = NULL;
+ createInfo.flags = 0;
+ createInfo.pView = (__bridge void *)UIKit_Mtl_AddMetalView(window);
+ result = vkCreateIOSSurfaceMVK(instance, &createInfo,
+ NULL, surface);
+ if (result != VK_SUCCESS) {
+ SDL_SetError("vkCreateIOSSurfaceMVK failed: %s",
+ SDL_Vulkan_GetResultString(result));
+ return SDL_FALSE;
+ }
+
+ return SDL_TRUE;
+}
+
+void UIKit_Vulkan_GetDrawableSize(_THIS, SDL_Window *window, int *w, int *h)
+{
+ UIKit_Mtl_GetDrawableSize(window, w, h);
+}
+
+#endif
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/uikit/SDL_uikitwindow.h b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitwindow.h
new file mode 100644
index 0000000..46073ee
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitwindow.h
@@ -0,0 +1,56 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 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
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#ifndef SDL_uikitwindow_h_
+#define SDL_uikitwindow_h_
+
+#include "../SDL_sysvideo.h"
+#import "SDL_uikitvideo.h"
+#import "SDL_uikitview.h"
+#import "SDL_uikitviewcontroller.h"
+
+extern int UIKit_CreateWindow(_THIS, SDL_Window * window);
+extern void UIKit_SetWindowTitle(_THIS, SDL_Window * window);
+extern void UIKit_ShowWindow(_THIS, SDL_Window * window);
+extern void UIKit_HideWindow(_THIS, SDL_Window * window);
+extern void UIKit_RaiseWindow(_THIS, SDL_Window * window);
+extern void UIKit_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered);
+extern void UIKit_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen);
+extern void UIKit_DestroyWindow(_THIS, SDL_Window * window);
+extern SDL_bool UIKit_GetWindowWMInfo(_THIS, SDL_Window * window,
+ struct SDL_SysWMinfo * info);
+
+extern NSUInteger UIKit_GetSupportedOrientations(SDL_Window * window);
+
+@class UIWindow;
+
+@interface SDL_WindowData : NSObject
+
+@property (nonatomic, strong) UIWindow *uiwindow;
+@property (nonatomic, strong) SDL_uikitviewcontroller *viewcontroller;
+
+/* Array of SDL_uikitviews owned by this window. */
+@property (nonatomic, copy) NSMutableArray *views;
+
+@end
+
+#endif /* SDL_uikitwindow_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/uikit/SDL_uikitwindow.m b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitwindow.m
new file mode 100644
index 0000000..d01cff3
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/uikit/SDL_uikitwindow.m
@@ -0,0 +1,465 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 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
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_UIKIT
+
+#include "SDL_syswm.h"
+#include "SDL_video.h"
+#include "SDL_mouse.h"
+#include "SDL_assert.h"
+#include "SDL_hints.h"
+#include "../SDL_sysvideo.h"
+#include "../SDL_pixels_c.h"
+#include "../../events/SDL_events_c.h"
+
+#include "SDL_uikitvideo.h"
+#include "SDL_uikitevents.h"
+#include "SDL_uikitmodes.h"
+#include "SDL_uikitwindow.h"
+#import "SDL_uikitappdelegate.h"
+
+#import "SDL_uikitview.h"
+#import "SDL_uikitopenglview.h"
+
+#include <Foundation/Foundation.h>
+
+@implementation SDL_WindowData
+
+@synthesize uiwindow;
+@synthesize viewcontroller;
+@synthesize views;
+
+- (instancetype)init
+{
+ if ((self = [super init])) {
+ views = [NSMutableArray new];
+ }
+
+ return self;
+}
+
+@end
+
+@interface SDL_uikitwindow : UIWindow
+
+- (void)layoutSubviews;
+
+@end
+
+@implementation SDL_uikitwindow
+
+- (void)layoutSubviews
+{
+ /* Workaround to fix window orientation issues in iOS 8+. */
+ self.frame = self.screen.bounds;
+ [super layoutSubviews];
+}
+
+@end
+
+
+static int SetupWindowData(_THIS, SDL_Window *window, UIWindow *uiwindow, SDL_bool created)
+{
+ SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
+ SDL_DisplayData *displaydata = (__bridge SDL_DisplayData *) display->driverdata;
+ SDL_uikitview *view;
+
+ CGRect frame = UIKit_ComputeViewFrame(window, displaydata.uiscreen);
+ int width = (int) frame.size.width;
+ int height = (int) frame.size.height;
+
+ SDL_WindowData *data = [[SDL_WindowData alloc] init];
+ if (!data) {
+ return SDL_OutOfMemory();
+ }
+
+ window->driverdata = (void *) CFBridgingRetain(data);
+
+ data.uiwindow = uiwindow;
+
+ /* only one window on iOS, always shown */
+ window->flags &= ~SDL_WINDOW_HIDDEN;
+
+ if (displaydata.uiscreen != [UIScreen mainScreen]) {
+ window->flags &= ~SDL_WINDOW_RESIZABLE; /* window is NEVER resizable */
+ window->flags &= ~SDL_WINDOW_INPUT_FOCUS; /* never has input focus */
+ window->flags |= SDL_WINDOW_BORDERLESS; /* never has a status bar. */
+ }
+
+#if !TARGET_OS_TV
+ if (displaydata.uiscreen == [UIScreen mainScreen]) {
+ /* SDL_CreateWindow sets the window w&h to the display's bounds if the
+ * fullscreen flag is set. But the display bounds orientation might not
+ * match what we want, and GetSupportedOrientations call below uses the
+ * window w&h. They're overridden below anyway, so we'll just set them
+ * to the requested size for the purposes of determining orientation. */
+ window->w = window->windowed.w;
+ window->h = window->windowed.h;
+
+ NSUInteger orients = UIKit_GetSupportedOrientations(window);
+ BOOL supportsLandscape = (orients & UIInterfaceOrientationMaskLandscape) != 0;
+ BOOL supportsPortrait = (orients & (UIInterfaceOrientationMaskPortrait|UIInterfaceOrientationMaskPortraitUpsideDown)) != 0;
+
+ /* Make sure the width/height are oriented correctly */
+ if ((width > height && !supportsLandscape) || (height > width && !supportsPortrait)) {
+ int temp = width;
+ width = height;
+ height = temp;
+ }
+ }
+#endif /* !TARGET_OS_TV */
+
+ window->x = 0;
+ window->y = 0;
+ window->w = width;
+ window->h = height;
+
+ /* The View Controller will handle rotating the view when the device
+ * orientation changes. This will trigger resize events, if appropriate. */
+ data.viewcontroller = [[SDL_uikitviewcontroller alloc] initWithSDLWindow:window];
+
+ /* The window will initially contain a generic view so resizes, touch events,
+ * etc. can be handled without an active OpenGL view/context. */
+ view = [[SDL_uikitview alloc] initWithFrame:frame];
+
+ /* Sets this view as the controller's view, and adds the view to the window
+ * heirarchy. */
+ [view setSDLWindow:window];
+
+ /* Make this window the current mouse focus for touch input */
+ if (displaydata.uiscreen == [UIScreen mainScreen]) {
+ SDL_SetMouseFocus(window);
+ SDL_SetKeyboardFocus(window);
+ }
+
+ return 0;
+}
+
+int
+UIKit_CreateWindow(_THIS, SDL_Window *window)
+{
+ @autoreleasepool {
+ SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
+ SDL_DisplayData *data = (__bridge SDL_DisplayData *) display->driverdata;
+
+ /* SDL currently puts this window at the start of display's linked list. We rely on this. */
+ SDL_assert(_this->windows == window);
+
+ /* We currently only handle a single window per display on iOS */
+ if (window->next != NULL) {
+ 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 !TARGET_OS_TV
+ const CGSize origsize = data.uiscreen.currentMode.size;
+ if ((origsize.width == 0.0f) && (origsize.height == 0.0f)) {
+ if (display->num_display_modes == 0) {
+ _this->GetDisplayModes(_this, display);
+ }
+
+ int i;
+ 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 = (__bridge 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;
+ }
+ }
+#endif /* !TARGET_OS_TV */
+
+ /* ignore the size user requested, and make a fullscreen window */
+ /* !!! FIXME: can we have a smaller view? */
+ UIWindow *uiwindow = [[SDL_uikitwindow alloc] initWithFrame:data.uiscreen.bounds];
+
+ /* put the window on an external display if appropriate. */
+ if (data.uiscreen != [UIScreen mainScreen]) {
+ [uiwindow setScreen:data.uiscreen];
+ }
+
+ if (SetupWindowData(_this, window, uiwindow, SDL_TRUE) < 0) {
+ return -1;
+ }
+ }
+
+ return 1;
+}
+
+void
+UIKit_SetWindowTitle(_THIS, SDL_Window * window)
+{
+ @autoreleasepool {
+ SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata;
+ data.viewcontroller.title = @(window->title);
+ }
+}
+
+void
+UIKit_ShowWindow(_THIS, SDL_Window * window)
+{
+ @autoreleasepool {
+ SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata;
+ [data.uiwindow makeKeyAndVisible];
+ }
+}
+
+void
+UIKit_HideWindow(_THIS, SDL_Window * window)
+{
+ @autoreleasepool {
+ SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata;
+ data.uiwindow.hidden = YES;
+ }
+}
+
+void
+UIKit_RaiseWindow(_THIS, SDL_Window * window)
+{
+ /* We don't currently offer a concept of "raising" the SDL window, since
+ * we only allow one per display, in the iOS fashion.
+ * However, we use this entry point to rebind the context to the view
+ * during OnWindowRestored processing. */
+ _this->GL_MakeCurrent(_this, _this->current_glwin, _this->current_glctx);
+}
+
+static void
+UIKit_UpdateWindowBorder(_THIS, SDL_Window * window)
+{
+ SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata;
+ SDL_uikitviewcontroller *viewcontroller = data.viewcontroller;
+
+#if !TARGET_OS_TV
+ if (data.uiwindow.screen == [UIScreen mainScreen]) {
+ if (window->flags & (SDL_WINDOW_FULLSCREEN | SDL_WINDOW_BORDERLESS)) {
+ [UIApplication sharedApplication].statusBarHidden = YES;
+ } else {
+ [UIApplication sharedApplication].statusBarHidden = NO;
+ }
+
+ /* iOS 7+ won't update the status bar until we tell it to. */
+ if ([viewcontroller respondsToSelector:@selector(setNeedsStatusBarAppearanceUpdate)]) {
+ [viewcontroller setNeedsStatusBarAppearanceUpdate];
+ }
+ }
+
+ /* Update the view's frame to account for the status bar change. */
+ viewcontroller.view.frame = UIKit_ComputeViewFrame(window, data.uiwindow.screen);
+#endif /* !TARGET_OS_TV */
+
+#ifdef SDL_IPHONE_KEYBOARD
+ /* Make sure the view is offset correctly when the keyboard is visible. */
+ [viewcontroller updateKeyboard];
+#endif
+
+ [viewcontroller.view setNeedsLayout];
+ [viewcontroller.view layoutIfNeeded];
+}
+
+void
+UIKit_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered)
+{
+ @autoreleasepool {
+ UIKit_UpdateWindowBorder(_this, window);
+ }
+}
+
+void
+UIKit_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen)
+{
+ @autoreleasepool {
+ UIKit_UpdateWindowBorder(_this, window);
+ }
+}
+
+void
+UIKit_DestroyWindow(_THIS, SDL_Window * window)
+{
+ @autoreleasepool {
+ if (window->driverdata != NULL) {
+ SDL_WindowData *data = (SDL_WindowData *) CFBridgingRelease(window->driverdata);
+ NSArray *views = nil;
+
+ [data.viewcontroller stopAnimation];
+
+ /* Detach all views from this window. We use a copy of the array
+ * because setSDLWindow will remove the object from the original
+ * array, which would be undesirable if we were iterating over it. */
+ views = [data.views copy];
+ for (SDL_uikitview *view in views) {
+ [view setSDLWindow:NULL];
+ }
+
+ /* iOS may still hold a reference to the window after we release it.
+ * We want to make sure the SDL view controller isn't accessed in
+ * that case, because it would contain an invalid pointer to the old
+ * SDL window. */
+ data.uiwindow.rootViewController = nil;
+ data.uiwindow.hidden = YES;
+ }
+ }
+ window->driverdata = NULL;
+}
+
+SDL_bool
+UIKit_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info)
+{
+ @autoreleasepool {
+ SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata;
+
+ if (info->version.major <= SDL_MAJOR_VERSION) {
+ int versionnum = SDL_VERSIONNUM(info->version.major, info->version.minor, info->version.patch);
+
+ info->subsystem = SDL_SYSWM_UIKIT;
+ info->info.uikit.window = data.uiwindow;
+
+ /* These struct members were added in SDL 2.0.4. */
+ if (versionnum >= SDL_VERSIONNUM(2,0,4)) {
+ if ([data.viewcontroller.view isKindOfClass:[SDL_uikitopenglview class]]) {
+ SDL_uikitopenglview *glview = (SDL_uikitopenglview *)data.viewcontroller.view;
+ info->info.uikit.framebuffer = glview.drawableFramebuffer;
+ info->info.uikit.colorbuffer = glview.drawableRenderbuffer;
+ info->info.uikit.resolveFramebuffer = glview.msaaResolveFramebuffer;
+ } else {
+ info->info.uikit.framebuffer = 0;
+ info->info.uikit.colorbuffer = 0;
+ info->info.uikit.resolveFramebuffer = 0;
+ }
+ }
+
+ return SDL_TRUE;
+ } else {
+ SDL_SetError("Application not compiled with SDL %d.%d",
+ SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
+ return SDL_FALSE;
+ }
+ }
+}
+
+#if !TARGET_OS_TV
+NSUInteger
+UIKit_GetSupportedOrientations(SDL_Window * window)
+{
+ const char *hint = SDL_GetHint(SDL_HINT_ORIENTATIONS);
+ NSUInteger validOrientations = UIInterfaceOrientationMaskAll;
+ NSUInteger orientationMask = 0;
+
+ @autoreleasepool {
+ SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata;
+ UIApplication *app = [UIApplication sharedApplication];
+
+ /* Get all possible valid orientations. If the app delegate doesn't tell
+ * us, we get the orientations from Info.plist via UIApplication. */
+ if ([app.delegate respondsToSelector:@selector(application:supportedInterfaceOrientationsForWindow:)]) {
+ validOrientations = [app.delegate application:app supportedInterfaceOrientationsForWindow:data.uiwindow];
+ } else if ([app respondsToSelector:@selector(supportedInterfaceOrientationsForWindow:)]) {
+ validOrientations = [app supportedInterfaceOrientationsForWindow:data.uiwindow];
+ }
+
+ if (hint != NULL) {
+ NSArray *orientations = [@(hint) componentsSeparatedByString:@" "];
+
+ if ([orientations containsObject:@"LandscapeLeft"]) {
+ orientationMask |= UIInterfaceOrientationMaskLandscapeLeft;
+ }
+ if ([orientations containsObject:@"LandscapeRight"]) {
+ orientationMask |= UIInterfaceOrientationMaskLandscapeRight;
+ }
+ if ([orientations containsObject:@"Portrait"]) {
+ orientationMask |= UIInterfaceOrientationMaskPortrait;
+ }
+ if ([orientations containsObject:@"PortraitUpsideDown"]) {
+ orientationMask |= UIInterfaceOrientationMaskPortraitUpsideDown;
+ }
+ }
+
+ if (orientationMask == 0 && (window->flags & SDL_WINDOW_RESIZABLE)) {
+ /* any orientation is okay. */
+ orientationMask = UIInterfaceOrientationMaskAll;
+ }
+
+ if (orientationMask == 0) {
+ if (window->w >= window->h) {
+ orientationMask |= UIInterfaceOrientationMaskLandscape;
+ }
+ if (window->h >= window->w) {
+ orientationMask |= (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown);
+ }
+ }
+
+ /* Don't allow upside-down orientation on phones, so answering calls is in the natural orientation */
+ if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone) {
+ orientationMask &= ~UIInterfaceOrientationMaskPortraitUpsideDown;
+ }
+
+ /* If none of the specified orientations are actually supported by the
+ * app, we'll revert to what the app supports. An exception would be
+ * thrown by the system otherwise. */
+ if ((validOrientations & orientationMask) == 0) {
+ orientationMask = validOrientations;
+ }
+ }
+
+ return orientationMask;
+}
+#endif /* !TARGET_OS_TV */
+
+int
+SDL_iPhoneSetAnimationCallback(SDL_Window * window, int interval, void (*callback)(void*), void *callbackParam)
+{
+ if (!window || !window->driverdata) {
+ return SDL_SetError("Invalid window");
+ }
+
+ @autoreleasepool {
+ SDL_WindowData *data = (__bridge SDL_WindowData *)window->driverdata;
+ [data.viewcontroller setAnimationCallback:interval
+ callback:callback
+ callbackParam:callbackParam];
+ }
+
+ return 0;
+}
+
+#endif /* SDL_VIDEO_DRIVER_UIKIT */
+
+/* vi: set ts=4 sw=4 expandtab: */
diff --git a/source/3rd-party/SDL2/src/video/uikit/keyinfotable.h b/source/3rd-party/SDL2/src/video/uikit/keyinfotable.h
new file mode 100644
index 0000000..3b23837
--- /dev/null
+++ b/source/3rd-party/SDL2/src/video/uikit/keyinfotable.h
@@ -0,0 +1,174 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 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
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef _UIKIT_KeyInfo
+#define _UIKIT_KeyInfo
+
+#include "SDL_scancode.h"
+
+/*
+ This file is used by the keyboard code in SDL_uikitview.m to convert between characters
+ passed in from the iPhone's virtual keyboard, and tuples of SDL_Scancode and SDL_keymods.
+ For example unicharToUIKeyInfoTable['a'] would give you the scan code and keymod for lower
+ case a.
+*/
+
+typedef struct
+{
+ SDL_Scancode code;
+ Uint16 mod;
+} UIKitKeyInfo;
+
+/* So far only ASCII characters here */
+static UIKitKeyInfo unicharToUIKeyInfoTable[] = {
+/* 0 */ { SDL_SCANCODE_UNKNOWN, 0 },
+/* 1 */ { SDL_SCANCODE_UNKNOWN, 0 },
+/* 2 */ { SDL_SCANCODE_UNKNOWN, 0 },
+/* 3 */ { SDL_SCANCODE_UNKNOWN, 0 },
+/* 4 */ { SDL_SCANCODE_UNKNOWN, 0 },
+/* 5 */ { SDL_SCANCODE_UNKNOWN, 0 },
+/* 6 */ { SDL_SCANCODE_UNKNOWN, 0 },
+/* 7 */ { SDL_SCANCODE_UNKNOWN, 0 },
+/* 8 */ { SDL_SCANCODE_UNKNOWN, 0 },
+/* 9 */ { SDL_SCANCODE_UNKNOWN, 0 },
+/* 10 */ { SDL_SCANCODE_UNKNOWN, 0 },
+/* 11 */ { SDL_SCANCODE_UNKNOWN, 0 },
+/* 12 */ { SDL_SCANCODE_UNKNOWN, 0 },
+/* 13 */ { SDL_SCANCODE_RETURN, 0 },
+/* 14 */ { SDL_SCANCODE_UNKNOWN, 0 },
+/* 15 */ { SDL_SCANCODE_UNKNOWN, 0 },
+/* 16 */ { SDL_SCANCODE_UNKNOWN, 0 },
+/* 17 */ { SDL_SCANCODE_UNKNOWN, 0 },
+/* 18 */ { SDL_SCANCODE_UNKNOWN, 0 },
+/* 19 */ { SDL_SCANCODE_UNKNOWN, 0 },
+/* 20 */ { SDL_SCANCODE_UNKNOWN, 0 },
+/* 21 */ { SDL_SCANCODE_UNKNOWN, 0 },
+/* 22 */ { SDL_SCANCODE_UNKNOWN, 0 },
+/* 23 */ { SDL_SCANCODE_UNKNOWN, 0 },
+/* 24 */ { SDL_SCANCODE_UNKNOWN, 0 },
+/* 25 */ { SDL_SCANCODE_UNKNOWN, 0 },
+/* 26 */ { SDL_SCANCODE_UNKNOWN, 0 },
+/* 27 */ { SDL_SCANCODE_UNKNOWN, 0 },
+/* 28 */ { SDL_SCANCODE_UNKNOWN, 0 },
+/* 29 */ { SDL_SCANCODE_UNKNOWN, 0 },
+/* 30 */ { SDL_SCANCODE_UNKNOWN, 0 },
+/* 31 */ { SDL_SCANCODE_UNKNOWN, 0 },
+/* 32 */ { SDL_SCANCODE_SPACE, 0 },
+/* 33 */ { SDL_SCANCODE_1, KMOD_SHIFT }, /* plus shift modifier '!' */
+/* 34 */ { SDL_SCANCODE_APOSTROPHE, KMOD_SHIFT }, /* plus shift modifier '"' */
+/* 35 */ { SDL_SCANCODE_3, KMOD_SHIFT }, /* plus shift modifier '#' */
+/* 36 */ { SDL_SCANCODE_4, KMOD_SHIFT }, /* plus shift modifier '$' */
+/* 37 */ { SDL_SCANCODE_5, KMOD_SHIFT }, /* plus shift modifier '%' */
+/* 38 */ { SDL_SCANCODE_7, KMOD_SHIFT }, /* plus shift modifier '&' */
+/* 39 */ { SDL_SCANCODE_APOSTROPHE, 0 }, /* ''' */
+/* 40 */ { SDL_SCANCODE_9, KMOD_SHIFT }, /* plus shift modifier '(' */
+/* 41 */ { SDL_SCANCODE_0, KMOD_SHIFT }, /* plus shift modifier ')' */
+/* 42 */ { SDL_SCANCODE_8, KMOD_SHIFT }, /* '*' */
+/* 43 */ { SDL_SCANCODE_EQUALS, KMOD_SHIFT }, /* plus shift modifier '+' */
+/* 44 */ { SDL_SCANCODE_COMMA, 0 }, /* ',' */
+/* 45 */ { SDL_SCANCODE_MINUS, 0 }, /* '-' */
+/* 46 */ { SDL_SCANCODE_PERIOD, 0 }, /* '.' */
+/* 47 */ { SDL_SCANCODE_SLASH, 0 }, /* '/' */
+/* 48 */ { SDL_SCANCODE_0, 0 },
+/* 49 */ { SDL_SCANCODE_1, 0 },
+/* 50 */ { SDL_SCANCODE_2, 0 },
+/* 51 */ { SDL_SCANCODE_3, 0 },
+/* 52 */ { SDL_SCANCODE_4, 0 },
+/* 53 */ { SDL_SCANCODE_5, 0 },
+/* 54 */ { SDL_SCANCODE_6, 0 },
+/* 55 */ { SDL_SCANCODE_7, 0 },
+/* 56 */ { SDL_SCANCODE_8, 0 },
+/* 57 */ { SDL_SCANCODE_9, 0 },
+/* 58 */ { SDL_SCANCODE_SEMICOLON, KMOD_SHIFT }, /* plus shift modifier ';' */
+/* 59 */ { SDL_SCANCODE_SEMICOLON, 0 },
+/* 60 */ { SDL_SCANCODE_COMMA, KMOD_SHIFT }, /* plus shift modifier '<' */
+/* 61 */ { SDL_SCANCODE_EQUALS, 0 },
+/* 62 */ { SDL_SCANCODE_PERIOD, KMOD_SHIFT }, /* plus shift modifier '>' */
+/* 63 */ { SDL_SCANCODE_SLASH, KMOD_SHIFT }, /* plus shift modifier '?' */
+/* 64 */ { SDL_SCANCODE_2, KMOD_SHIFT }, /* plus shift modifier '@' */
+/* 65 */ { SDL_SCANCODE_A, KMOD_SHIFT }, /* all the following need shift modifiers */
+/* 66 */ { SDL_SCANCODE_B, KMOD_SHIFT },
+/* 67 */ { SDL_SCANCODE_C, KMOD_SHIFT },
+/* 68 */ { SDL_SCANCODE_D, KMOD_SHIFT },
+/* 69 */ { SDL_SCANCODE_E, KMOD_SHIFT },
+/* 70 */ { SDL_SCANCODE_F, KMOD_SHIFT },
+/* 71 */ { SDL_SCANCODE_G, KMOD_SHIFT },
+/* 72 */ { SDL_SCANCODE_H, KMOD_SHIFT },
+/* 73 */ { SDL_SCANCODE_I, KMOD_SHIFT },
+/* 74 */ { SDL_SCANCODE_J, KMOD_SHIFT },
+/* 75 */ { SDL_SCANCODE_K, KMOD_SHIFT },
+/* 76 */ { SDL_SCANCODE_L, KMOD_SHIFT },
+/* 77 */ { SDL_SCANCODE_M, KMOD_SHIFT },
+/* 78 */ { SDL_SCANCODE_N, KMOD_SHIFT },
+/* 79 */ { SDL_SCANCODE_O, KMOD_SHIFT },
+/* 80 */ { SDL_SCANCODE_P, KMOD_SHIFT },
+/* 81 */ { SDL_SCANCODE_Q, KMOD_SHIFT },
+/* 82 */ { SDL_SCANCODE_R, KMOD_SHIFT },
+/* 83 */ { SDL_SCANCODE_S, KMOD_SHIFT },
+/* 84 */ { SDL_SCANCODE_T, KMOD_SHIFT },
+/* 85 */ { SDL_SCANCODE_U, KMOD_SHIFT },
+/* 86 */ { SDL_SCANCODE_V, KMOD_SHIFT },
+/* 87 */ { SDL_SCANCODE_W, KMOD_SHIFT },
+/* 88 */ { SDL_SCANCODE_X, KMOD_SHIFT },
+/* 89 */ { SDL_SCANCODE_Y, KMOD_SHIFT },
+/* 90 */ { SDL_SCANCODE_Z, KMOD_SHIFT },
+/* 91 */ { SDL_SCANCODE_LEFTBRACKET, 0 },
+/* 92 */ { SDL_SCANCODE_BACKSLASH, 0 },
+/* 93 */ { SDL_SCANCODE_RIGHTBRACKET, 0 },
+/* 94 */ { SDL_SCANCODE_6, KMOD_SHIFT }, /* plus shift modifier '^' */
+/* 95 */ { SDL_SCANCODE_MINUS, KMOD_SHIFT }, /* plus shift modifier '_' */
+/* 96 */ { SDL_SCANCODE_GRAVE, KMOD_SHIFT }, /* '`' */
+/* 97 */ { SDL_SCANCODE_A, 0 },
+/* 98 */ { SDL_SCANCODE_B, 0 },
+/* 99 */ { SDL_SCANCODE_C, 0 },
+/* 100 */{ SDL_SCANCODE_D, 0 },
+/* 101 */{ SDL_SCANCODE_E, 0 },
+/* 102 */{ SDL_SCANCODE_F, 0 },
+/* 103 */{ SDL_SCANCODE_G, 0 },
+/* 104 */{ SDL_SCANCODE_H, 0 },
+/* 105 */{ SDL_SCANCODE_I, 0 },
+/* 106 */{ SDL_SCANCODE_J, 0 },
+/* 107 */{ SDL_SCANCODE_K, 0 },
+/* 108 */{ SDL_SCANCODE_L, 0 },
+/* 109 */{ SDL_SCANCODE_M, 0 },
+/* 110 */{ SDL_SCANCODE_N, 0 },
+/* 111 */{ SDL_SCANCODE_O, 0 },
+/* 112 */{ SDL_SCANCODE_P, 0 },
+/* 113 */{ SDL_SCANCODE_Q, 0 },
+/* 114 */{ SDL_SCANCODE_R, 0 },
+/* 115 */{ SDL_SCANCODE_S, 0 },
+/* 116 */{ SDL_SCANCODE_T, 0 },
+/* 117 */{ SDL_SCANCODE_U, 0 },
+/* 118 */{ SDL_SCANCODE_V, 0 },
+/* 119 */{ SDL_SCANCODE_W, 0 },
+/* 120 */{ SDL_SCANCODE_X, 0 },
+/* 121 */{ SDL_SCANCODE_Y, 0 },
+/* 122 */{ SDL_SCANCODE_Z, 0 },
+/* 123 */{ SDL_SCANCODE_LEFTBRACKET, KMOD_SHIFT }, /* plus shift modifier '{' */
+/* 124 */{ SDL_SCANCODE_BACKSLASH, KMOD_SHIFT }, /* plus shift modifier '|' */
+/* 125 */{ SDL_SCANCODE_RIGHTBRACKET, KMOD_SHIFT }, /* plus shift modifier '}' */
+/* 126 */{ SDL_SCANCODE_GRAVE, KMOD_SHIFT }, /* plus shift modifier '~' */
+/* 127 */{ SDL_SCANCODE_BACKSPACE, KMOD_SHIFT }
+};
+
+#endif /* _UIKIT_KeyInfo */
+
+/* vi: set ts=4 sw=4 expandtab: */