From 30f41c02aec763d32e62351452da9ef582bc3472 Mon Sep 17 00:00:00 2001 From: 3gg <3gg@shellblade.net> Date: Fri, 6 Mar 2026 13:30:59 -0800 Subject: Move contrib libraries to contrib repo --- .../src/video/uikit/SDL_uikitappdelegate.h | 45 -- .../src/video/uikit/SDL_uikitappdelegate.m | 519 --------------- .../SDL-3.2.8/src/video/uikit/SDL_uikitclipboard.h | 33 - .../SDL-3.2.8/src/video/uikit/SDL_uikitclipboard.m | 105 --- .../SDL-3.2.8/src/video/uikit/SDL_uikitevents.h | 40 -- .../SDL-3.2.8/src/video/uikit/SDL_uikitevents.m | 461 ------------- .../src/video/uikit/SDL_uikitmessagebox.h | 28 - .../src/video/uikit/SDL_uikitmessagebox.m | 154 ----- .../SDL-3.2.8/src/video/uikit/SDL_uikitmetalview.h | 54 -- .../SDL-3.2.8/src/video/uikit/SDL_uikitmetalview.m | 140 ---- contrib/SDL-3.2.8/src/video/uikit/SDL_uikitmodes.h | 67 -- contrib/SDL-3.2.8/src/video/uikit/SDL_uikitmodes.m | 543 --------------- .../SDL-3.2.8/src/video/uikit/SDL_uikitopengles.h | 40 -- .../SDL-3.2.8/src/video/uikit/SDL_uikitopengles.m | 221 ------- .../src/video/uikit/SDL_uikitopenglview.h | 62 -- .../src/video/uikit/SDL_uikitopenglview.m | 377 ----------- contrib/SDL-3.2.8/src/video/uikit/SDL_uikitpen.h | 39 -- contrib/SDL-3.2.8/src/video/uikit/SDL_uikitpen.m | 214 ------ contrib/SDL-3.2.8/src/video/uikit/SDL_uikitvideo.h | 52 -- contrib/SDL-3.2.8/src/video/uikit/SDL_uikitvideo.m | 312 --------- contrib/SDL-3.2.8/src/video/uikit/SDL_uikitview.h | 52 -- contrib/SDL-3.2.8/src/video/uikit/SDL_uikitview.m | 587 ---------------- .../src/video/uikit/SDL_uikitviewcontroller.h | 96 --- .../src/video/uikit/SDL_uikitviewcontroller.m | 736 --------------------- .../SDL-3.2.8/src/video/uikit/SDL_uikitvulkan.h | 52 -- .../SDL-3.2.8/src/video/uikit/SDL_uikitvulkan.m | 265 -------- .../SDL-3.2.8/src/video/uikit/SDL_uikitwindow.h | 56 -- .../SDL-3.2.8/src/video/uikit/SDL_uikitwindow.m | 471 ------------- 28 files changed, 5821 deletions(-) delete mode 100644 contrib/SDL-3.2.8/src/video/uikit/SDL_uikitappdelegate.h delete mode 100644 contrib/SDL-3.2.8/src/video/uikit/SDL_uikitappdelegate.m delete mode 100644 contrib/SDL-3.2.8/src/video/uikit/SDL_uikitclipboard.h delete mode 100644 contrib/SDL-3.2.8/src/video/uikit/SDL_uikitclipboard.m delete mode 100644 contrib/SDL-3.2.8/src/video/uikit/SDL_uikitevents.h delete mode 100644 contrib/SDL-3.2.8/src/video/uikit/SDL_uikitevents.m delete mode 100644 contrib/SDL-3.2.8/src/video/uikit/SDL_uikitmessagebox.h delete mode 100644 contrib/SDL-3.2.8/src/video/uikit/SDL_uikitmessagebox.m delete mode 100644 contrib/SDL-3.2.8/src/video/uikit/SDL_uikitmetalview.h delete mode 100644 contrib/SDL-3.2.8/src/video/uikit/SDL_uikitmetalview.m delete mode 100644 contrib/SDL-3.2.8/src/video/uikit/SDL_uikitmodes.h delete mode 100644 contrib/SDL-3.2.8/src/video/uikit/SDL_uikitmodes.m delete mode 100644 contrib/SDL-3.2.8/src/video/uikit/SDL_uikitopengles.h delete mode 100644 contrib/SDL-3.2.8/src/video/uikit/SDL_uikitopengles.m delete mode 100644 contrib/SDL-3.2.8/src/video/uikit/SDL_uikitopenglview.h delete mode 100644 contrib/SDL-3.2.8/src/video/uikit/SDL_uikitopenglview.m delete mode 100644 contrib/SDL-3.2.8/src/video/uikit/SDL_uikitpen.h delete mode 100644 contrib/SDL-3.2.8/src/video/uikit/SDL_uikitpen.m delete mode 100644 contrib/SDL-3.2.8/src/video/uikit/SDL_uikitvideo.h delete mode 100644 contrib/SDL-3.2.8/src/video/uikit/SDL_uikitvideo.m delete mode 100644 contrib/SDL-3.2.8/src/video/uikit/SDL_uikitview.h delete mode 100644 contrib/SDL-3.2.8/src/video/uikit/SDL_uikitview.m delete mode 100644 contrib/SDL-3.2.8/src/video/uikit/SDL_uikitviewcontroller.h delete mode 100644 contrib/SDL-3.2.8/src/video/uikit/SDL_uikitviewcontroller.m delete mode 100644 contrib/SDL-3.2.8/src/video/uikit/SDL_uikitvulkan.h delete mode 100644 contrib/SDL-3.2.8/src/video/uikit/SDL_uikitvulkan.m delete mode 100644 contrib/SDL-3.2.8/src/video/uikit/SDL_uikitwindow.h delete mode 100644 contrib/SDL-3.2.8/src/video/uikit/SDL_uikitwindow.m (limited to 'contrib/SDL-3.2.8/src/video/uikit') diff --git a/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitappdelegate.h b/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitappdelegate.h deleted file mode 100644 index 77ccbfd..0000000 --- a/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitappdelegate.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2025 Sam Lantinga - - 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 - -@interface SDLLaunchScreenController : UIViewController - -- (instancetype)init; -- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil; -- (void)loadView; - -@end - -@interface SDLUIKitDelegate : NSObject - -+ (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 diff --git a/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitappdelegate.m b/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitappdelegate.m deleted file mode 100644 index 6a37e51..0000000 --- a/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitappdelegate.m +++ /dev/null @@ -1,519 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2025 Sam Lantinga - - 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" - -#ifdef SDL_VIDEO_DRIVER_UIKIT - -#include "../SDL_sysvideo.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 SDL_main_func forward_main; -static int forward_argc; -static char **forward_argv; -static int exit_status; - -int SDL_RunApp(int argc, char* argv[], SDL_main_func mainFunction, void * reserved) -{ - int i; - - // store arguments - /* Note that we need to be careful about how we allocate/free memory here. - * If the application calls SDL_SetMemoryFunctions(), we can't rely on - * SDL_free() to use the same allocator after SDL_main() returns. - */ - forward_main = mainFunction; - forward_argc = argc; - forward_argv = (char **)malloc((argc + 1) * sizeof(char *)); // This should NOT be SDL_malloc() - for (i = 0; i < argc; i++) { - forward_argv[i] = malloc((strlen(argv[i]) + 1) * sizeof(char)); // This should NOT be SDL_malloc() - 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]); // This should NOT be SDL_free() - } - free(forward_argv); // This should NOT be SDL_free() - - return exit_status; -} - -#if !defined(SDL_PLATFORM_TVOS) && !defined(SDL_PLATFORM_VISIONOS) -// 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; -} - -@interface SDLLaunchStoryboardViewController : UIViewController -@property(nonatomic, strong) UIViewController *storyboardViewController; -- (instancetype)initWithStoryboardViewController:(UIViewController *)storyboardViewController; -@end - -@implementation SDLLaunchStoryboardViewController - -- (instancetype)initWithStoryboardViewController:(UIViewController *)storyboardViewController -{ - self = [super init]; - self.storyboardViewController = storyboardViewController; - return self; -} - -- (void)viewDidLoad -{ - [super viewDidLoad]; - - [self addChildViewController:self.storyboardViewController]; - [self.view addSubview:self.storyboardViewController.view]; - self.storyboardViewController.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; - self.storyboardViewController.view.frame = self.view.bounds; - [self.storyboardViewController didMoveToParentViewController:self]; - -#ifndef SDL_PLATFORM_VISIONOS - UIApplication.sharedApplication.statusBarHidden = self.prefersStatusBarHidden; - UIApplication.sharedApplication.statusBarStyle = self.preferredStatusBarStyle; -#endif -} - -- (BOOL)prefersStatusBarHidden -{ - return [[NSBundle.mainBundle objectForInfoDictionaryKey:@"UIStatusBarHidden"] boolValue]; -} - -- (UIStatusBarStyle)preferredStatusBarStyle -{ - NSString *statusBarStyle = [NSBundle.mainBundle objectForInfoDictionaryKey:@"UIStatusBarStyle"]; - if ([statusBarStyle isEqualToString:@"UIStatusBarStyleLightContent"]) { - return UIStatusBarStyleLightContent; - } - if (@available(iOS 13.0, *)) { - if ([statusBarStyle isEqualToString:@"UIStatusBarStyleDarkContent"]) { - return UIStatusBarStyleDarkContent; - } - } - return UIStatusBarStyleDefault; -} - -@end -#endif // !SDL_PLATFORM_TVOS - -@interface SDLLaunchScreenController () - -#ifndef SDL_PLATFORM_TVOS -- (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; - - // A launch screen may not exist. Fall back to launch images in that case. - if (screenname) { - @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; - -#ifdef SDL_PLATFORM_VISIONOS - int screenw = SDL_XR_SCREENWIDTH; - int screenh = SDL_XR_SCREENHEIGHT; -#else - int screenw = (int)([UIScreen mainScreen].bounds.size.width + 0.5); - int screenh = (int)([UIScreen mainScreen].bounds.size.height + 0.5); -#endif - - - -#if !defined(SDL_PLATFORM_TVOS) && !defined(SDL_PLATFORM_VISIONOS) - 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 !defined(SDL_PLATFORM_TVOS) && !defined(SDL_PLATFORM_VISIONOS) - 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 !defined(SDL_PLATFORM_TVOS) && !defined(SDL_PLATFORM_VISIONOS) - else { - imagename = [bundle objectForInfoDictionaryKey:@"UILaunchImageFile"]; - - if (imagename) { - image = SDL_LoadLaunchImageNamed(imagename, screenh); - } - - if (!image) { - image = SDL_LoadLaunchImageNamed(@"Default", screenh); - } - } -#endif - - if (image) { -#ifdef SDL_PLATFORM_VISIONOS - CGRect viewFrame = CGRectMake(0, 0, screenw, screenh); -#else - CGRect viewFrame = [UIScreen mainScreen].bounds; -#endif - UIImageView *view = [[UIImageView alloc] initWithFrame:viewFrame]; - UIImageOrientation imageorient = UIImageOrientationUp; - -#if !defined(SDL_PLATFORM_TVOS) && !defined(SDL_PLATFORM_VISIONOS) - // Bugs observed / workaround tested in iOS 8.3. - if (UIInterfaceOrientationIsLandscape(curorient)) { - if (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; - } - } - } -#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. -} - -#ifndef SDL_PLATFORM_TVOS -- (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 // !SDL_PLATFORM_TVOS - -@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; - UIKit_ForceUpdateHomeIndicator(); // Wait for launch screen to hide so settings are applied to the actual view controller. - }]; -} - -- (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_SetiOSEventPump(true); - exit_status = forward_main(forward_argc, forward_argv); - SDL_SetiOSEventPump(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]; - -#ifdef 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 !defined(SDL_PLATFORM_TVOS) && !defined(SDL_PLATFORM_VISIONOS) - screenname = [bundle objectForInfoDictionaryKey:@"UILaunchStoryboardName"]; - - if (screenname) { - @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]; - __auto_type storyboardVc = [storyboard instantiateInitialViewController]; - vc = [[SDLLaunchStoryboardViewController alloc] initWithStoryboardViewController:storyboardVc]; - } - @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) { -#ifdef SDL_PLATFORM_VISIONOS - CGRect viewFrame = CGRectMake(0, 0, SDL_XR_SCREENWIDTH, SDL_XR_SCREENHEIGHT); -#else - CGRect viewFrame = [UIScreen mainScreen].bounds; -#endif - launchWindow = [[UIWindow alloc] initWithFrame:viewFrame]; - - /* 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]]; - - 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_UIKitWindowData *data = (__bridge SDL_UIKitWindowData *)window->internal; - if (data != nil) { - return data.uiwindow; - } - } - } - return nil; -} - -- (void)setWindow:(UIWindow *)window -{ - // Do nothing. -} - -- (void)sendDropFileForURL:(NSURL *)url fromSourceApplication:(NSString *)sourceApplication -{ - NSURL *fileURL = url.filePathURL; - const char *sourceApplicationCString = sourceApplication ? [sourceApplication UTF8String] : NULL; - if (fileURL != nil) { - SDL_SendDropFile(NULL, sourceApplicationCString, fileURL.path.UTF8String); - } else { - SDL_SendDropFile(NULL, sourceApplicationCString, url.absoluteString.UTF8String); - } - SDL_SendDropComplete(NULL); -} - -- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary *)options -{ - // TODO: Handle options - [self sendDropFileForURL:url fromSourceApplication:NULL]; - return YES; -} - -@end - -#endif // SDL_VIDEO_DRIVER_UIKIT diff --git a/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitclipboard.h b/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitclipboard.h deleted file mode 100644 index 1c538c2..0000000 --- a/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitclipboard.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2025 Sam Lantinga - - 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 bool UIKit_SetClipboardText(SDL_VideoDevice *_this, const char *text); -extern char *UIKit_GetClipboardText(SDL_VideoDevice *_this); -extern bool UIKit_HasClipboardText(SDL_VideoDevice *_this); - -extern void UIKit_InitClipboard(SDL_VideoDevice *_this); -extern void UIKit_QuitClipboard(SDL_VideoDevice *_this); - -#endif // SDL_uikitclipboard_h_ diff --git a/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitclipboard.m b/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitclipboard.m deleted file mode 100644 index 8ed4eb0..0000000 --- a/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitclipboard.m +++ /dev/null @@ -1,105 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2025 Sam Lantinga - - 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" - -#ifdef SDL_VIDEO_DRIVER_UIKIT - -#include "SDL_uikitvideo.h" -#include "../../events/SDL_clipboardevents_c.h" - -#import - -bool UIKit_SetClipboardText(SDL_VideoDevice *_this, const char *text) -{ -#ifdef SDL_PLATFORM_TVOS - return SDL_SetError("The clipboard is not available on tvOS"); -#else - @autoreleasepool { - [UIPasteboard generalPasteboard].string = @(text); - return true; - } -#endif -} - -char *UIKit_GetClipboardText(SDL_VideoDevice *_this) -{ -#ifdef SDL_PLATFORM_TVOS - 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 -} - -bool UIKit_HasClipboardText(SDL_VideoDevice *_this) -{ - @autoreleasepool { -#ifndef SDL_PLATFORM_TVOS - if ([UIPasteboard generalPasteboard].string != nil) { - return true; - } -#endif - return false; - } -} - -void UIKit_InitClipboard(SDL_VideoDevice *_this) -{ -#ifndef SDL_PLATFORM_TVOS - @autoreleasepool { - SDL_UIKitVideoData *data = (__bridge SDL_UIKitVideoData *)_this->internal; - NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; - - id observer = [center addObserverForName:UIPasteboardChangedNotification - object:nil - queue:nil - usingBlock:^(NSNotification *note) { - // TODO: compute mime types - SDL_SendClipboardUpdate(false, NULL, 0); - }]; - - data.pasteboardObserver = observer; - } -#endif -} - -void UIKit_QuitClipboard(SDL_VideoDevice *_this) -{ - @autoreleasepool { - SDL_UIKitVideoData *data = (__bridge SDL_UIKitVideoData *)_this->internal; - - if (data.pasteboardObserver != nil) { - [[NSNotificationCenter defaultCenter] removeObserver:data.pasteboardObserver]; - } - - data.pasteboardObserver = nil; - } -} - -#endif // SDL_VIDEO_DRIVER_UIKIT diff --git a/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitevents.h b/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitevents.h deleted file mode 100644 index c767fb1..0000000 --- a/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitevents.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2025 Sam Lantinga - - 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_ - -#import - -#include "../SDL_sysvideo.h" - -extern void SDL_UpdateLifecycleObserver(void); - -extern Uint64 UIKit_GetEventTimestamp(NSTimeInterval nsTimestamp); -extern void UIKit_PumpEvents(SDL_VideoDevice *_this); - -extern void SDL_InitGCKeyboard(void); -extern void SDL_QuitGCKeyboard(void); - -extern void SDL_InitGCMouse(void); -extern bool SDL_GCMouseRelativeMode(void); -extern void SDL_QuitGCMouse(void); - -#endif // SDL_uikitevents_h_ diff --git a/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitevents.m b/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitevents.m deleted file mode 100644 index 86224f7..0000000 --- a/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitevents.m +++ /dev/null @@ -1,461 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2025 Sam Lantinga - - 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" - -#ifdef SDL_VIDEO_DRIVER_UIKIT - -#include "../../events/SDL_events_c.h" -#include "../../main/SDL_main_callbacks.h" - -#include "SDL_uikitevents.h" -#include "SDL_uikitopengles.h" -#include "SDL_uikitvideo.h" -#include "SDL_uikitwindow.h" - -#import -#import - -static BOOL UIKit_EventPumpEnabled = YES; - -@interface SDL_LifecycleObserver : NSObject -@property(nonatomic, assign) BOOL isObservingNotifications; -@end - -@implementation SDL_LifecycleObserver - -- (void)update -{ - NSNotificationCenter *notificationCenter = NSNotificationCenter.defaultCenter; - bool wants_observation = (UIKit_EventPumpEnabled || SDL_HasMainCallbacks()); - if (!wants_observation) { - // Make sure no windows have active animation callbacks - int num_windows = 0; - SDL_free(SDL_GetWindows(&num_windows)); - if (num_windows > 0) { - wants_observation = true; - } - } - if (wants_observation && !self.isObservingNotifications) { - self.isObservingNotifications = YES; - [notificationCenter addObserver:self selector:@selector(applicationDidBecomeActive) name:UIApplicationDidBecomeActiveNotification object:nil]; - [notificationCenter addObserver:self selector:@selector(applicationWillResignActive) name:UIApplicationWillResignActiveNotification object:nil]; - [notificationCenter addObserver:self selector:@selector(applicationDidEnterBackground) name:UIApplicationDidEnterBackgroundNotification object:nil]; - [notificationCenter addObserver:self selector:@selector(applicationWillEnterForeground) name:UIApplicationWillEnterForegroundNotification object:nil]; - [notificationCenter addObserver:self selector:@selector(applicationWillTerminate) name:UIApplicationWillTerminateNotification object:nil]; - [notificationCenter addObserver:self selector:@selector(applicationDidReceiveMemoryWarning) name:UIApplicationDidReceiveMemoryWarningNotification object:nil]; -#if !defined(SDL_PLATFORM_TVOS) && !defined(SDL_PLATFORM_VISIONOS) - [notificationCenter addObserver:self - selector:@selector(applicationDidChangeStatusBarOrientation) - name:UIApplicationDidChangeStatusBarOrientationNotification - object:nil]; -#endif - } else if (!wants_observation && self.isObservingNotifications) { - self.isObservingNotifications = NO; - [notificationCenter removeObserver:self]; - } -} - -- (void)applicationDidBecomeActive -{ - SDL_OnApplicationDidEnterForeground(); -} - -- (void)applicationWillResignActive -{ - SDL_OnApplicationWillEnterBackground(); -} - -- (void)applicationDidEnterBackground -{ - SDL_OnApplicationDidEnterBackground(); -} - -- (void)applicationWillEnterForeground -{ - SDL_OnApplicationWillEnterForeground(); -} - -- (void)applicationWillTerminate -{ - SDL_OnApplicationWillTerminate(); -} - -- (void)applicationDidReceiveMemoryWarning -{ - SDL_OnApplicationDidReceiveMemoryWarning(); -} - -#if !defined(SDL_PLATFORM_TVOS) && !defined(SDL_PLATFORM_VISIONOS) -- (void)applicationDidChangeStatusBarOrientation -{ - SDL_OnApplicationDidChangeStatusBarOrientation(); -} -#endif - -@end - -void SDL_UpdateLifecycleObserver(void) -{ - static SDL_LifecycleObserver *lifecycleObserver; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - lifecycleObserver = [SDL_LifecycleObserver new]; - }); - [lifecycleObserver update]; -} - -void SDL_SetiOSEventPump(bool enabled) -{ - UIKit_EventPumpEnabled = enabled; - - SDL_UpdateLifecycleObserver(); -} - -Uint64 UIKit_GetEventTimestamp(NSTimeInterval nsTimestamp) -{ - static Uint64 timestamp_offset; - Uint64 timestamp = (Uint64)(nsTimestamp * SDL_NS_PER_SECOND); - Uint64 now = SDL_GetTicksNS(); - - if (!timestamp_offset) { - timestamp_offset = (now - timestamp); - } - timestamp += timestamp_offset; - - if (timestamp > now) { - timestamp_offset -= (timestamp - now); - timestamp = now; - } - return timestamp; -} - -void UIKit_PumpEvents(SDL_VideoDevice *_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. -#if defined(SDL_VIDEO_OPENGL_ES) || defined(SDL_VIDEO_OPENGL_ES2) - UIKit_GL_RestoreCurrentContext(); -#endif -} - -static id keyboard_connect_observer = nil; -static id keyboard_disconnect_observer = nil; - -static void OnGCKeyboardConnected(GCKeyboard *keyboard) API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0)) -{ - SDL_KeyboardID keyboardID = (SDL_KeyboardID)(uintptr_t)keyboard; - - SDL_AddKeyboard(keyboardID, NULL, true); - - keyboard.keyboardInput.keyChangedHandler = ^(GCKeyboardInput *kbrd, GCControllerButtonInput *key, GCKeyCode keyCode, BOOL pressed) { - Uint64 timestamp = SDL_GetTicksNS(); - SDL_SendKeyboardKey(timestamp, keyboardID, 0, (SDL_Scancode)keyCode, pressed); - }; - - dispatch_queue_t queue = dispatch_queue_create("org.libsdl.input.keyboard", DISPATCH_QUEUE_SERIAL); - dispatch_set_target_queue(queue, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)); - keyboard.handlerQueue = queue; -} - -static void OnGCKeyboardDisconnected(GCKeyboard *keyboard) API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0)) -{ - SDL_KeyboardID keyboardID = (SDL_KeyboardID)(uintptr_t)keyboard; - - SDL_RemoveKeyboard(keyboardID, true); - - keyboard.keyboardInput.keyChangedHandler = nil; -} - -void SDL_InitGCKeyboard(void) -{ - @autoreleasepool { - if (@available(iOS 14.0, tvOS 14.0, *)) { - NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; - - keyboard_connect_observer = [center addObserverForName:GCKeyboardDidConnectNotification - object:nil - queue:nil - usingBlock:^(NSNotification *note) { - GCKeyboard *keyboard = note.object; - OnGCKeyboardConnected(keyboard); - }]; - - keyboard_disconnect_observer = [center addObserverForName:GCKeyboardDidDisconnectNotification - object:nil - queue:nil - usingBlock:^(NSNotification *note) { - GCKeyboard *keyboard = note.object; - OnGCKeyboardDisconnected(keyboard); - }]; - - if (GCKeyboard.coalescedKeyboard != nil) { - OnGCKeyboardConnected(GCKeyboard.coalescedKeyboard); - } - } - } -} - -void SDL_QuitGCKeyboard(void) -{ - @autoreleasepool { - if (@available(iOS 14.0, tvOS 14.0, *)) { - NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; - - if (keyboard_connect_observer) { - [center removeObserver:keyboard_connect_observer name:GCKeyboardDidConnectNotification object:nil]; - keyboard_connect_observer = nil; - } - - if (keyboard_disconnect_observer) { - [center removeObserver:keyboard_disconnect_observer name:GCKeyboardDidDisconnectNotification object:nil]; - keyboard_disconnect_observer = nil; - } - - if (GCKeyboard.coalescedKeyboard != nil) { - OnGCKeyboardDisconnected(GCKeyboard.coalescedKeyboard); - } - } - } -} - -static id mouse_connect_observer = nil; -static id mouse_disconnect_observer = nil; -static bool mouse_relative_mode = false; -static SDL_MouseWheelDirection mouse_scroll_direction = SDL_MOUSEWHEEL_NORMAL; - -static void UpdateScrollDirection(void) -{ -#if 0 // This code doesn't work for some reason - NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; - if ([userDefaults boolForKey:@"com.apple.swipescrolldirection"]) { - mouse_scroll_direction = SDL_MOUSEWHEEL_FLIPPED; - } else { - mouse_scroll_direction = SDL_MOUSEWHEEL_NORMAL; - } -#else - Boolean keyExistsAndHasValidFormat = NO; - Boolean naturalScrollDirection = CFPreferencesGetAppBooleanValue(CFSTR("com.apple.swipescrolldirection"), kCFPreferencesAnyApplication, &keyExistsAndHasValidFormat); - if (!keyExistsAndHasValidFormat) { - // Couldn't read the preference, assume natural scrolling direction - naturalScrollDirection = YES; - } - if (naturalScrollDirection) { - mouse_scroll_direction = SDL_MOUSEWHEEL_FLIPPED; - } else { - mouse_scroll_direction = SDL_MOUSEWHEEL_NORMAL; - } -#endif -} - -static void UpdatePointerLock(void) -{ - SDL_VideoDevice *_this = SDL_GetVideoDevice(); - SDL_Window *window; - - for (window = _this->windows; window != NULL; window = window->next) { - UIKit_UpdatePointerLock(_this, window); - } -} - -static bool SetGCMouseRelativeMode(bool enabled) -{ - mouse_relative_mode = enabled; - UpdatePointerLock(); - return true; -} - -static void OnGCMouseButtonChanged(SDL_MouseID mouseID, Uint8 button, BOOL pressed) -{ - Uint64 timestamp = SDL_GetTicksNS(); - SDL_SendMouseButton(timestamp, SDL_GetMouseFocus(), mouseID, button, pressed); -} - -static void OnGCMouseConnected(GCMouse *mouse) API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0)) -{ - SDL_MouseID mouseID = (SDL_MouseID)(uintptr_t)mouse; - - SDL_AddMouse(mouseID, NULL, true); - - mouse.mouseInput.leftButton.pressedChangedHandler = ^(GCControllerButtonInput *button, float value, BOOL pressed) { - OnGCMouseButtonChanged(mouseID, SDL_BUTTON_LEFT, pressed); - }; - mouse.mouseInput.middleButton.pressedChangedHandler = ^(GCControllerButtonInput *button, float value, BOOL pressed) { - OnGCMouseButtonChanged(mouseID, SDL_BUTTON_MIDDLE, pressed); - }; - mouse.mouseInput.rightButton.pressedChangedHandler = ^(GCControllerButtonInput *button, float value, BOOL pressed) { - OnGCMouseButtonChanged(mouseID, SDL_BUTTON_RIGHT, pressed); - }; - - int auxiliary_button = SDL_BUTTON_X1; - for (GCControllerButtonInput *btn in mouse.mouseInput.auxiliaryButtons) { - btn.pressedChangedHandler = ^(GCControllerButtonInput *button, float value, BOOL pressed) { - OnGCMouseButtonChanged(mouseID, auxiliary_button, pressed); - }; - ++auxiliary_button; - } - - mouse.mouseInput.mouseMovedHandler = ^(GCMouseInput *mouseInput, float deltaX, float deltaY) { - Uint64 timestamp = SDL_GetTicksNS(); - - if (SDL_GCMouseRelativeMode()) { - SDL_SendMouseMotion(timestamp, SDL_GetMouseFocus(), mouseID, true, deltaX, -deltaY); - } - }; - - mouse.mouseInput.scroll.valueChangedHandler = ^(GCControllerDirectionPad *dpad, float xValue, float yValue) { - Uint64 timestamp = SDL_GetTicksNS(); - - /* Raw scroll values come in here, vertical values in the first axis, horizontal values in the second axis. - * The vertical values are negative moving the mouse wheel up and positive moving it down. - * The horizontal values are negative moving the mouse wheel left and positive moving it right. - * The vertical values are inverted compared to SDL, and the horizontal values are as expected. - */ - float vertical = -xValue; - float horizontal = yValue; - - if (mouse_scroll_direction == SDL_MOUSEWHEEL_FLIPPED) { - // Since these are raw values, we need to flip them ourselves - vertical = -vertical; - horizontal = -horizontal; - } - SDL_SendMouseWheel(timestamp, SDL_GetMouseFocus(), mouseID, horizontal, vertical, mouse_scroll_direction); - }; - UpdateScrollDirection(); - - dispatch_queue_t queue = dispatch_queue_create("org.libsdl.input.mouse", DISPATCH_QUEUE_SERIAL); - dispatch_set_target_queue(queue, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)); - mouse.handlerQueue = queue; - - UpdatePointerLock(); -} - -static void OnGCMouseDisconnected(GCMouse *mouse) API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0)) -{ - SDL_MouseID mouseID = (SDL_MouseID)(uintptr_t)mouse; - - mouse.mouseInput.mouseMovedHandler = nil; - - mouse.mouseInput.leftButton.pressedChangedHandler = nil; - mouse.mouseInput.middleButton.pressedChangedHandler = nil; - mouse.mouseInput.rightButton.pressedChangedHandler = nil; - - for (GCControllerButtonInput *button in mouse.mouseInput.auxiliaryButtons) { - button.pressedChangedHandler = nil; - } - - UpdatePointerLock(); - - SDL_RemoveMouse(mouseID, true); -} - -void SDL_InitGCMouse(void) -{ - @autoreleasepool { - // There is a bug where mouse accumulates duplicate deltas over time in iOS 14.0 - if (@available(iOS 14.1, tvOS 14.1, *)) { - /* iOS will not send the new pointer touch events if you don't have this key, - * and we need them to differentiate between mouse events and real touch events. - */ - BOOL indirect_input_available = [[[[NSBundle mainBundle] infoDictionary] objectForKey:@"UIApplicationSupportsIndirectInputEvents"] boolValue]; - if (indirect_input_available) { - NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; - - mouse_connect_observer = [center addObserverForName:GCMouseDidConnectNotification - object:nil - queue:nil - usingBlock:^(NSNotification *note) { - GCMouse *mouse = note.object; - OnGCMouseConnected(mouse); - }]; - - mouse_disconnect_observer = [center addObserverForName:GCMouseDidDisconnectNotification - object:nil - queue:nil - usingBlock:^(NSNotification *note) { - GCMouse *mouse = note.object; - OnGCMouseDisconnected(mouse); - }]; - - for (GCMouse *mouse in [GCMouse mice]) { - OnGCMouseConnected(mouse); - } - - SDL_GetMouse()->SetRelativeMouseMode = SetGCMouseRelativeMode; - } else { - NSLog(@"You need UIApplicationSupportsIndirectInputEvents in your Info.plist for mouse support"); - } - } - } -} - -bool SDL_GCMouseRelativeMode(void) -{ - return mouse_relative_mode; -} - -void SDL_QuitGCMouse(void) -{ - @autoreleasepool { - if (@available(iOS 14.1, tvOS 14.1, *)) { - NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; - - if (mouse_connect_observer) { - [center removeObserver:mouse_connect_observer name:GCMouseDidConnectNotification object:nil]; - mouse_connect_observer = nil; - } - - if (mouse_disconnect_observer) { - [center removeObserver:mouse_disconnect_observer name:GCMouseDidDisconnectNotification object:nil]; - mouse_disconnect_observer = nil; - } - - for (GCMouse *mouse in [GCMouse mice]) { - OnGCMouseDisconnected(mouse); - } - - SDL_GetMouse()->SetRelativeMouseMode = NULL; - } - } -} - -#endif // SDL_VIDEO_DRIVER_UIKIT diff --git a/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitmessagebox.h b/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitmessagebox.h deleted file mode 100644 index 5c21f7c..0000000 --- a/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitmessagebox.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2025 Sam Lantinga - - 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" - -#ifdef SDL_VIDEO_DRIVER_UIKIT - -extern bool UIKit_ShowingMessageBox(void); -extern bool UIKit_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonID); - -#endif // SDL_VIDEO_DRIVER_UIKIT diff --git a/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitmessagebox.m b/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitmessagebox.m deleted file mode 100644 index a57b3f7..0000000 --- a/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitmessagebox.m +++ /dev/null @@ -1,154 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2025 Sam Lantinga - - 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" - -#ifdef SDL_VIDEO_DRIVER_UIKIT - -#include "SDL_uikitvideo.h" -#include "SDL_uikitwindow.h" - -// Display a UIKit message box - -static bool s_showingMessageBox = false; - -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 = true; - while ((*clickedindex) == messageboxdata->numbuttons) { - [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]; - } - s_showingMessageBox = false; - } -} - -static BOOL UIKit_ShowMessageBoxAlertController(const SDL_MessageBoxData *messageboxdata, int *buttonID) -{ - int i; - int __block clickedindex = messageboxdata->numbuttons; - 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; - const SDL_MessageBoxButtonData *sdlButton; - - if (messageboxdata->flags & SDL_MESSAGEBOX_BUTTONS_RIGHT_TO_LEFT) { - sdlButton = &messageboxdata->buttons[messageboxdata->numbuttons - 1 - i]; - } else { - sdlButton = &messageboxdata->buttons[i]; - } - - if (sdlButton->flags & SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT) { - style = UIAlertActionStyleCancel; - } - - action = [UIAlertAction actionWithTitle:@(sdlButton->text) - style:style - handler:^(UIAlertAction *alertAction) { - clickedindex = (int)(sdlButton - messageboxdata->buttons); - }]; - [alert addAction:action]; - - if (sdlButton->flags & SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT) { - alert.preferredAction = action; - } - } - - if (messageboxdata->window) { - SDL_UIKitWindowData *data = (__bridge SDL_UIKitWindowData *)messageboxdata->window->internal; - window = data.uiwindow; - } - - if (window == nil || window.rootViewController == nil) { -#ifdef SDL_PLATFORM_VISIONOS - alertwindow = [[UIWindow alloc] init]; -#else - alertwindow = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; -#endif - 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; - } - - UIKit_ForceUpdateHomeIndicator(); - - *buttonID = messageboxdata->buttons[clickedindex].buttonID; - return YES; -} - -static void UIKit_ShowMessageBoxImpl(const SDL_MessageBoxData *messageboxdata, int *buttonID, int *result) -{ - @autoreleasepool { - if (UIKit_ShowMessageBoxAlertController(messageboxdata, buttonID)) { - *result = true; - } else { - *result = SDL_SetError("Could not show message box."); - } - } -} - -bool UIKit_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonID) -{ - @autoreleasepool { - __block int result = true; - - if ([NSThread isMainThread]) { - UIKit_ShowMessageBoxImpl(messageboxdata, buttonID, &result); - } else { - dispatch_sync(dispatch_get_main_queue(), ^{ - UIKit_ShowMessageBoxImpl(messageboxdata, buttonID, &result); - }); - } - return result; - } -} - -#endif // SDL_VIDEO_DRIVER_UIKIT diff --git a/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitmetalview.h b/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitmetalview.h deleted file mode 100644 index 20bcf7c..0000000 --- a/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitmetalview.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2025 Sam Lantinga - - 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 @slime73 on GitHub for their gist showing how to add a CAMetalLayer - * backed view. - */ - -#ifndef SDL_uikitmetalview_h_ -#define SDL_uikitmetalview_h_ - -#include "../SDL_sysvideo.h" -#include "SDL_uikitwindow.h" - -#if defined(SDL_VIDEO_DRIVER_UIKIT) && (defined(SDL_VIDEO_VULKAN) || defined(SDL_VIDEO_METAL)) - -#import -#import -#import - -@interface SDL_uikitmetalview : SDL_uikitview - -- (instancetype)initWithFrame:(CGRect)frame - scale:(CGFloat)scale; - -@end - -SDL_MetalView UIKit_Metal_CreateView(SDL_VideoDevice *_this, SDL_Window *window); -void UIKit_Metal_DestroyView(SDL_VideoDevice *_this, SDL_MetalView view); -void *UIKit_Metal_GetLayer(SDL_VideoDevice *_this, SDL_MetalView view); - -#endif // SDL_VIDEO_DRIVER_UIKIT && (SDL_VIDEO_VULKAN || SDL_VIDEO_METAL) - -#endif // SDL_uikitmetalview_h_ diff --git a/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitmetalview.m b/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitmetalview.m deleted file mode 100644 index 010dae4..0000000 --- a/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitmetalview.m +++ /dev/null @@ -1,140 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2025 Sam Lantinga - - 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 @slime73 on GitHub for their gist showing how to add a CAMetalLayer - * backed view. - */ - -#include "SDL_internal.h" - -#if defined(SDL_VIDEO_DRIVER_UIKIT) && (defined(SDL_VIDEO_VULKAN) || defined(SDL_VIDEO_METAL)) - -#include "../SDL_sysvideo.h" -#include "../../events/SDL_windowevents_c.h" - -#import "SDL_uikitwindow.h" -#import "SDL_uikitmetalview.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 = SDL_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 *metallayer = ((CAMetalLayer *)self.layer); - if (metallayer.drawableSize.width != size.width || - metallayer.drawableSize.height != size.height) { - metallayer.drawableSize = size; - SDL_SendWindowEvent([self getSDLWindow], SDL_EVENT_WINDOW_METAL_VIEW_RESIZED, 0, 0); - } -} - -@end - -SDL_MetalView UIKit_Metal_CreateView(SDL_VideoDevice *_this, SDL_Window *window) -{ - @autoreleasepool { - SDL_UIKitWindowData *data = (__bridge SDL_UIKitWindowData *)window->internal; - CGFloat scale = 1.0; - SDL_uikitmetalview *metalview; - - if (window->flags & SDL_WINDOW_HIGH_PIXEL_DENSITY) { - /* 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. - */ -#ifndef SDL_PLATFORM_VISIONOS - scale = data.uiwindow.screen.nativeScale; -#else - // VisionOS doesn't use the concept of "nativeScale" like other iOS devices. - // We use a fixed scale factor of 2.0 to achieve better pixel density. - // This is because VisionOS presents a virtual 1280x720 "screen", but we need - // to render at a higher resolution for optimal visual quality. - // TODO: Consider making this configurable or determining it dynamically - // based on the specific visionOS device capabilities. - scale = 2.0; -#endif - } - - metalview = [[SDL_uikitmetalview alloc] initWithFrame:data.uiwindow.bounds - scale:scale]; - if (metalview == nil) { - SDL_OutOfMemory(); - return NULL; - } - - [metalview setSDLWindow:window]; - - return (void *)CFBridgingRetain(metalview); - } -} - -void UIKit_Metal_DestroyView(SDL_VideoDevice *_this, SDL_MetalView view) -{ - @autoreleasepool { - SDL_uikitmetalview *metalview = CFBridgingRelease(view); - - if ([metalview isKindOfClass:[SDL_uikitmetalview class]]) { - [metalview setSDLWindow:NULL]; - } - } -} - -void *UIKit_Metal_GetLayer(SDL_VideoDevice *_this, SDL_MetalView view) -{ - @autoreleasepool { - SDL_uikitview *uiview = (__bridge SDL_uikitview *)view; - return (__bridge void *)uiview.layer; - } -} - -#endif // SDL_VIDEO_DRIVER_UIKIT && (SDL_VIDEO_VULKAN || SDL_VIDEO_METAL) diff --git a/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitmodes.h b/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitmodes.h deleted file mode 100644 index 1b25cfd..0000000 --- a/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitmodes.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2025 Sam Lantinga - - 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_UIKitDisplayData : NSObject - -#ifndef SDL_PLATFORM_VISIONOS -- (instancetype)initWithScreen:(UIScreen *)screen; -@property(nonatomic, strong) UIScreen *uiscreen; -#endif - -@end - -@interface SDL_UIKitDisplayModeData : NSObject -#ifndef SDL_PLATFORM_VISIONOS -@property(nonatomic, strong) UIScreenMode *uiscreenmode; -#endif - -@end - -#ifndef SDL_PLATFORM_VISIONOS -extern bool UIKit_IsDisplayLandscape(UIScreen *uiscreen); -#endif - -extern bool UIKit_InitModes(SDL_VideoDevice *_this); -#ifndef SDL_PLATFORM_VISIONOS -extern bool UIKit_AddDisplay(UIScreen *uiscreen, bool send_event); -extern void UIKit_DelDisplay(UIScreen *uiscreen, bool send_event); -#endif -extern bool UIKit_GetDisplayModes(SDL_VideoDevice *_this, SDL_VideoDisplay *display); -extern bool UIKit_SetDisplayMode(SDL_VideoDevice *_this, SDL_VideoDisplay *display, SDL_DisplayMode *mode); -extern void UIKit_QuitModes(SDL_VideoDevice *_this); -extern bool UIKit_GetDisplayUsableBounds(SDL_VideoDevice *_this, SDL_VideoDisplay *display, SDL_Rect *rect); - -// because visionOS does not have a screen -// we create a fake display to maintain compatibility. -// By default, a window measures 1280x720 pt. -// https://developer.apple.com/design/human-interface-guidelines/windows#visionOS -#ifdef SDL_PLATFORM_VISIONOS -#define SDL_XR_SCREENWIDTH 1280 -#define SDL_XR_SCREENHEIGHT 720 -#endif - -#endif // SDL_uikitmodes_h_ diff --git a/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitmodes.m b/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitmodes.m deleted file mode 100644 index d3247db..0000000 --- a/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitmodes.m +++ /dev/null @@ -1,543 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2025 Sam Lantinga - - 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" - -#ifdef SDL_VIDEO_DRIVER_UIKIT - -#include "SDL_uikitmodes.h" - -#include "../../events/SDL_events_c.h" - -#import - -@implementation SDL_UIKitDisplayData - -#ifndef SDL_PLATFORM_VISIONOS -- (instancetype)initWithScreen:(UIScreen *)screen -{ - if (self = [super init]) { - self.uiscreen = screen; - } - return self; -} -@synthesize uiscreen; -#endif - -@end - -@implementation SDL_UIKitDisplayModeData - -#ifndef SDL_PLATFORM_VISIONOS -@synthesize uiscreenmode; -#endif - -@end - -@interface SDL_DisplayWatch : NSObject -@end - -#ifndef SDL_PLATFORM_VISIONOS -@implementation SDL_DisplayWatch - -+ (void)start -{ - NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; - - [center addObserver:self - selector:@selector(screenConnected:) - name:UIScreenDidConnectNotification - object:nil]; - [center addObserver:self - selector:@selector(screenDisconnected:) - name:UIScreenDidDisconnectNotification - object:nil]; -} - -+ (void)stop -{ - NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; - - [center removeObserver:self - name:UIScreenDidConnectNotification - object:nil]; - [center removeObserver:self - name:UIScreenDidDisconnectNotification - object:nil]; -} - -+ (void)screenConnected:(NSNotification *)notification -{ - UIScreen *uiscreen = [notification object]; - UIKit_AddDisplay(uiscreen, true); -} - -+ (void)screenDisconnected:(NSNotification *)notification -{ - UIScreen *uiscreen = [notification object]; - UIKit_DelDisplay(uiscreen, true); -} - -@end -#endif - -#ifndef SDL_PLATFORM_VISIONOS -static bool UIKit_AllocateDisplayModeData(SDL_DisplayMode *mode, - UIScreenMode *uiscreenmode) -{ - SDL_UIKitDisplayModeData *data = nil; - - if (uiscreenmode != nil) { - // Allocate the display mode data - data = [[SDL_UIKitDisplayModeData alloc] init]; - if (!data) { - return SDL_OutOfMemory(); - } - - data.uiscreenmode = uiscreenmode; - } - - mode->internal = (void *)CFBridgingRetain(data); - - return true; -} -#endif - -static void UIKit_FreeDisplayModeData(SDL_DisplayMode *mode) -{ - if (mode->internal != NULL) { - CFRelease(mode->internal); - mode->internal = NULL; - } -} - -#ifndef SDL_PLATFORM_VISIONOS -static float UIKit_GetDisplayModeRefreshRate(UIScreen *uiscreen) -{ - return (float)uiscreen.maximumFramesPerSecond; -} - -static bool UIKit_AddSingleDisplayMode(SDL_VideoDisplay *display, int w, int h, - UIScreen *uiscreen, UIScreenMode *uiscreenmode) -{ - SDL_DisplayMode mode; - - SDL_zero(mode); - if (!UIKit_AllocateDisplayModeData(&mode, uiscreenmode)) { - return false; - } - - mode.w = w; - mode.h = h; - mode.pixel_density = uiscreen.nativeScale; - mode.refresh_rate = UIKit_GetDisplayModeRefreshRate(uiscreen); - mode.format = SDL_PIXELFORMAT_ABGR8888; - - if (SDL_AddFullscreenDisplayMode(display, &mode)) { - return true; - } else { - UIKit_FreeDisplayModeData(&mode); - return false; - } -} - -static bool UIKit_AddDisplayMode(SDL_VideoDisplay *display, int w, int h, - UIScreen *uiscreen, UIScreenMode *uiscreenmode, bool addRotation) -{ - if (!UIKit_AddSingleDisplayMode(display, w, h, uiscreen, uiscreenmode)) { - return false; - } - - if (addRotation) { - // Add the rotated version - if (!UIKit_AddSingleDisplayMode(display, h, w, uiscreen, uiscreenmode)) { - return false; - } - } - - return true; -} - -static CGSize GetUIScreenModeSize(UIScreen *uiscreen, UIScreenMode *mode) -{ - /* For devices such as iPhone 6/7/8 Plus, the UIScreenMode reported by iOS - * isn't the physical pixels of the display, but rather the point size times - * the scale. For example, on iOS 12.2 on iPhone 8 Plus the physical pixel - * resolution is 1080x1920, the size reported by mode.size is 1242x2208, - * the size in points is 414x736, the scale property is 3.0, and the - * nativeScale property is ~2.6087 (ie 1920.0 / 736.0). - * - * What we want for the mode size is the point size, and the pixel density - * is the native scale. - * - * Note that the iOS Simulator doesn't have this behavior for those devices. - * https://github.com/libsdl-org/SDL/issues/3220 - */ - CGSize size = mode.size; - - size.width = SDL_round(size.width / uiscreen.scale); - size.height = SDL_round(size.height / uiscreen.scale); - - return size; -} - -bool UIKit_AddDisplay(UIScreen *uiscreen, bool send_event) -{ - UIScreenMode *uiscreenmode = uiscreen.currentMode; - CGSize size = GetUIScreenModeSize(uiscreen, uiscreenmode); - SDL_VideoDisplay display; - SDL_DisplayMode 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; - } - - SDL_zero(mode); - mode.w = (int)size.width; - mode.h = (int)size.height; - mode.pixel_density = uiscreen.nativeScale; - mode.format = SDL_PIXELFORMAT_ABGR8888; - mode.refresh_rate = UIKit_GetDisplayModeRefreshRate(uiscreen); - - if (!UIKit_AllocateDisplayModeData(&mode, uiscreenmode)) { - return false; - } - - SDL_zero(display); -#ifndef SDL_PLATFORM_TVOS - if (uiscreen == [UIScreen mainScreen]) { - // The natural orientation (used by sensors) is portrait - display.natural_orientation = SDL_ORIENTATION_PORTRAIT; - } else -#endif - if (UIKit_IsDisplayLandscape(uiscreen)) { - display.natural_orientation = SDL_ORIENTATION_LANDSCAPE; - } else { - display.natural_orientation = SDL_ORIENTATION_PORTRAIT; - } - display.desktop_mode = mode; - - display.HDR.SDR_white_level = 1.0f; - display.HDR.HDR_headroom = 1.0f; - -#ifndef SDL_PLATFORM_TVOS - if (@available(iOS 16.0, *)) { - if (uiscreen.currentEDRHeadroom > 1.0f) { - display.HDR.HDR_headroom = uiscreen.currentEDRHeadroom; - } else { - display.HDR.HDR_headroom = uiscreen.potentialEDRHeadroom; - } - } -#endif // !SDL_PLATFORM_TVOS - - // Allocate the display data -#ifdef SDL_PLATFORM_VISIONOS - SDL_UIKitDisplayData *data = [[SDL_UIKitDisplayData alloc] init]; -#else - SDL_UIKitDisplayData *data = [[SDL_UIKitDisplayData alloc] initWithScreen:uiscreen]; -#endif - if (!data) { - UIKit_FreeDisplayModeData(&display.desktop_mode); - return SDL_OutOfMemory(); - } - - display.internal = (SDL_DisplayData *)CFBridgingRetain(data); - if (SDL_AddVideoDisplay(&display, send_event) == 0) { - return false; - } - return true; -} -#endif - -#ifdef SDL_PLATFORM_VISIONOS -bool UIKit_AddDisplay(bool send_event){ - CGSize size = CGSizeMake(SDL_XR_SCREENWIDTH, SDL_XR_SCREENHEIGHT); - SDL_VideoDisplay display; - SDL_DisplayMode mode; - - SDL_zero(mode); - mode.w = (int)size.width; - mode.h = (int)size.height; - mode.pixel_density = 1; - mode.format = SDL_PIXELFORMAT_ABGR8888; - mode.refresh_rate = 60.0f; - - display.natural_orientation = SDL_ORIENTATION_LANDSCAPE; - - display.desktop_mode = mode; - - SDL_UIKitDisplayData *data = [[SDL_UIKitDisplayData alloc] init]; - - if (!data) { - UIKit_FreeDisplayModeData(&display.desktop_mode); - return SDL_OutOfMemory(); - } - - display.internal = (SDL_DisplayData *)CFBridgingRetain(data); - if (SDL_AddVideoDisplay(&display, send_event) == 0) { - return false; - } - return true; -} -#endif - -#ifndef SDL_PLATFORM_VISIONOS - -void UIKit_DelDisplay(UIScreen *uiscreen, bool send_event) -{ - SDL_DisplayID *displays; - int i; - - displays = SDL_GetDisplays(NULL); - if (displays) { - for (i = 0; displays[i]; ++i) { - SDL_VideoDisplay *display = SDL_GetVideoDisplay(displays[i]); - SDL_UIKitDisplayData *data = (__bridge SDL_UIKitDisplayData *)display->internal; - - if (data && data.uiscreen == uiscreen) { - CFRelease(display->internal); - display->internal = NULL; - SDL_DelVideoDisplay(displays[i], send_event); - break; - } - } - SDL_free(displays); - } -} - -bool UIKit_IsDisplayLandscape(UIScreen *uiscreen) -{ -#ifndef SDL_PLATFORM_TVOS - if (uiscreen == [UIScreen mainScreen]) { - return UIInterfaceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation); - } else -#endif // !SDL_PLATFORM_TVOS - { - CGSize size = uiscreen.bounds.size; - return (size.width > size.height); - } -} -#endif -bool UIKit_InitModes(SDL_VideoDevice *_this) -{ - @autoreleasepool { -#ifdef SDL_PLATFORM_VISIONOS - UIKit_AddDisplay(false); -#else - for (UIScreen *uiscreen in [UIScreen screens]) { - if (!UIKit_AddDisplay(uiscreen, false)) { - return false; - } - } -#endif - -#if !defined(SDL_PLATFORM_TVOS) && !defined(SDL_PLATFORM_VISIONOS) - SDL_OnApplicationDidChangeStatusBarOrientation(); -#endif - -#ifndef SDL_PLATFORM_VISIONOS - [SDL_DisplayWatch start]; -#endif - } - - return true; -} - -bool UIKit_GetDisplayModes(SDL_VideoDevice *_this, SDL_VideoDisplay *display) -{ -#ifndef SDL_PLATFORM_VISIONOS - @autoreleasepool { - SDL_UIKitDisplayData *data = (__bridge SDL_UIKitDisplayData *)display->internal; - - bool isLandscape = UIKit_IsDisplayLandscape(data.uiscreen); - bool addRotation = (data.uiscreen == [UIScreen mainScreen]); - NSArray *availableModes = nil; - -#ifdef SDL_PLATFORM_TVOS - addRotation = false; - availableModes = @[ data.uiscreen.currentMode ]; -#else - availableModes = data.uiscreen.availableModes; -#endif - - for (UIScreenMode *uimode in availableModes) { - CGSize size = GetUIScreenModeSize(data.uiscreen, uimode); - int w = (int)size.width; - int h = (int)size.height; - - // 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); - } - } -#endif - return true; -} - -bool UIKit_SetDisplayMode(SDL_VideoDevice *_this, SDL_VideoDisplay *display, SDL_DisplayMode *mode) -{ -#ifndef SDL_PLATFORM_VISIONOS - @autoreleasepool { - SDL_UIKitDisplayData *data = (__bridge SDL_UIKitDisplayData *)display->internal; - -#ifndef SDL_PLATFORM_TVOS - SDL_UIKitDisplayModeData *modedata = (__bridge SDL_UIKitDisplayModeData *)mode->internal; - [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"); - } - } - } - } -#endif - return true; -} - -bool UIKit_GetDisplayUsableBounds(SDL_VideoDevice *_this, SDL_VideoDisplay *display, SDL_Rect *rect) -{ - @autoreleasepool { - SDL_UIKitDisplayData *data = (__bridge SDL_UIKitDisplayData *)display->internal; -#ifdef SDL_PLATFORM_VISIONOS - CGRect frame = CGRectMake(0, 0, SDL_XR_SCREENWIDTH, SDL_XR_SCREENHEIGHT); -#else - CGRect frame = data.uiscreen.bounds; -#endif - - /* 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(display->id, rect)) { - return false; - } - - rect->x += (int)frame.origin.x; - rect->y += (int)frame.origin.y; - rect->w = (int)frame.size.width; - rect->h = (int)frame.size.height; - } - - return true; -} - -void UIKit_QuitModes(SDL_VideoDevice *_this) -{ -#ifndef SDL_PLATFORM_VISIONOS - [SDL_DisplayWatch stop]; -#endif - - // 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_fullscreen_modes; j++) { - SDL_DisplayMode *mode = &display->fullscreen_modes[j]; - UIKit_FreeDisplayModeData(mode); - } - - if (display->internal != NULL) { - CFRelease(display->internal); - display->internal = NULL; - } - } - } -} - -#if !defined(SDL_PLATFORM_TVOS) && !defined(SDL_PLATFORM_VISIONOS) -void SDL_OnApplicationDidChangeStatusBarOrientation(void) -{ - BOOL isLandscape = UIInterfaceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation); - SDL_VideoDisplay *display = SDL_GetVideoDisplay(SDL_GetPrimaryDisplay()); - - if (display) { - SDL_DisplayMode *mode = &display->desktop_mode; - SDL_DisplayOrientation orientation = SDL_ORIENTATION_UNKNOWN; - int i; - - /* The desktop display mode should be kept in sync with the screen - * orientation so that updating a window's fullscreen state to - * fullscreen desktop keeps the window dimensions in the - * correct orientation. */ - if (isLandscape != (mode->w > mode->h)) { - SDL_DisplayMode new_mode; - SDL_copyp(&new_mode, mode); - new_mode.w = mode->h; - new_mode.h = mode->w; - - // Make sure we don't free the current display mode data - mode->internal = NULL; - - SDL_SetDesktopDisplayMode(display, &new_mode); - } - - // Same deal with the fullscreen modes - for (i = 0; i < display->num_fullscreen_modes; ++i) { - mode = &display->fullscreen_modes[i]; - if (isLandscape != (mode->w > mode->h)) { - int height = mode->w; - mode->w = mode->h; - mode->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_EVENT_DISPLAY_ORIENTATION, orientation, 0); - } -} -#endif // !SDL_PLATFORM_TVOS - -#endif // SDL_VIDEO_DRIVER_UIKIT diff --git a/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitopengles.h b/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitopengles.h deleted file mode 100644 index cc259f7..0000000 --- a/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitopengles.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2025 Sam Lantinga - - 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_ - -#if defined(SDL_VIDEO_OPENGL_ES) || defined(SDL_VIDEO_OPENGL_ES2) - -#include "../SDL_sysvideo.h" - -extern bool UIKit_GL_MakeCurrent(SDL_VideoDevice *_this, SDL_Window *window, - SDL_GLContext context); -extern bool UIKit_GL_SwapWindow(SDL_VideoDevice *_this, SDL_Window *window); -extern SDL_GLContext UIKit_GL_CreateContext(SDL_VideoDevice *_this, SDL_Window *window); -extern bool UIKit_GL_DestroyContext(SDL_VideoDevice *_this, SDL_GLContext context); -extern SDL_FunctionPointer UIKit_GL_GetProcAddress(SDL_VideoDevice *_this, const char *proc); -extern bool UIKit_GL_LoadLibrary(SDL_VideoDevice *_this, const char *path); - -extern void UIKit_GL_RestoreCurrentContext(void); - -#endif // SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2 - -#endif // SDL_uikitopengles_ diff --git a/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitopengles.m b/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitopengles.m deleted file mode 100644 index a73588b..0000000 --- a/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitopengles.m +++ /dev/null @@ -1,221 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2025 Sam Lantinga - - 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 defined(SDL_VIDEO_DRIVER_UIKIT) && (defined(SDL_VIDEO_OPENGL_ES) || defined(SDL_VIDEO_OPENGL_ES2)) - -#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 - -@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 - -SDL_FunctionPointer UIKit_GL_GetProcAddress(SDL_VideoDevice *_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_DestroyContext makes it current without passing the window -*/ -bool UIKit_GL_MakeCurrent(SDL_VideoDevice *_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 true; -} - -bool UIKit_GL_LoadLibrary(SDL_VideoDevice *_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 true; -} - -bool UIKit_GL_SwapWindow(SDL_VideoDevice *_this, SDL_Window *window) -{ - @autoreleasepool { - SDLEAGLContext *context = (__bridge SDLEAGLContext *)SDL_GL_GetCurrentContext(); - -#ifdef 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 true; -} - -SDL_GLContext UIKit_GL_CreateContext(SDL_VideoDevice *_this, SDL_Window *window) -{ - @autoreleasepool { - SDLEAGLContext *context = nil; - SDL_uikitopenglview *view; - SDL_UIKitWindowData *data = (__bridge SDL_UIKitWindowData *)window->internal; - 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. - if (major > 3 || (major == 3 && minor > 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 *currContext = (__bridge EAGLContext *)SDL_GL_GetCurrentContext(); - sharegroup = currContext.sharegroup; - } - - if (window->flags & SDL_WINDOW_HIGH_PIXEL_DENSITY) { - /* 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. */ - scale = data.uiwindow.screen.nativeScale; - } - - 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; - } - - SDL_PropertiesID props = SDL_GetWindowProperties(window); - SDL_SetNumberProperty(props, SDL_PROP_WINDOW_UIKIT_OPENGL_FRAMEBUFFER_NUMBER, view.drawableFramebuffer); - SDL_SetNumberProperty(props, SDL_PROP_WINDOW_UIKIT_OPENGL_RENDERBUFFER_NUMBER, view.drawableRenderbuffer); - SDL_SetNumberProperty(props, SDL_PROP_WINDOW_UIKIT_OPENGL_RESOLVE_FRAMEBUFFER_NUMBER, view.msaaResolveFramebuffer); - - // The context owns the view / drawable. - context.sdlView = view; - - if (!UIKit_GL_MakeCurrent(_this, window, (__bridge SDL_GLContext)context)) { - UIKit_GL_DestroyContext(_this, (SDL_GLContext)CFBridgingRetain(context)); - return NULL; - } - - /* We return a +1'd context. The window's internal owns the view (via - * MakeCurrent.) */ - return (SDL_GLContext)CFBridgingRetain(context); - } -} - -bool UIKit_GL_DestroyContext(SDL_VideoDevice *_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); - } - return true; -} - -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 diff --git a/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitopenglview.h b/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitopenglview.h deleted file mode 100644 index 3286a16..0000000 --- a/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitopenglview.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2025 Sam Lantinga - - 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. -*/ - -#if defined(SDL_VIDEO_OPENGL_ES) || defined(SDL_VIDEO_OPENGL_ES2) - -#import -#import -#import - -#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 - -#endif // SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2 diff --git a/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitopenglview.m b/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitopenglview.m deleted file mode 100644 index 71d167f..0000000 --- a/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitopenglview.m +++ /dev/null @@ -1,377 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2025 Sam Lantinga - - 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 defined(SDL_VIDEO_DRIVER_UIKIT) && (defined(SDL_VIDEO_OPENGL_ES) || defined(SDL_VIDEO_OPENGL_ES2)) - -#include -#include -#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 = SDL_min(samples, maxsamples); - } - - if (sRGB) { - colorFormat = kEAGLColorFormatSRGBA8; - colorBufferFormat = GL_SRGB8_ALPHA8; - } 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 diff --git a/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitpen.h b/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitpen.h deleted file mode 100644 index 1e75589..0000000 --- a/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitpen.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2025 Sam Lantinga - - 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_uikitpen_h_ -#define SDL_uikitpen_h_ - -#include "SDL_uikitvideo.h" -#include "SDL_uikitwindow.h" - -extern bool UIKit_InitPen(SDL_VideoDevice *_this); -extern void UIKit_HandlePenMotion(SDL_uikitview *view, UITouch *pencil); -extern void UIKit_HandlePenPress(SDL_uikitview *view, UITouch *pencil); -extern void UIKit_HandlePenRelease(SDL_uikitview *view, UITouch *pencil); - -#if !defined(SDL_PLATFORM_TVOS) -extern void UIKit_HandlePenHover(SDL_uikitview *view, UIHoverGestureRecognizer *recognizer) API_AVAILABLE(ios(13.0)); -#endif - -extern void UIKit_QuitPen(SDL_VideoDevice *_this); - -#endif // SDL_uikitpen_h_ diff --git a/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitpen.m b/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitpen.m deleted file mode 100644 index 5209681..0000000 --- a/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitpen.m +++ /dev/null @@ -1,214 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2025 Sam Lantinga - - 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" - -#ifdef SDL_VIDEO_DRIVER_UIKIT - -#include "SDL_uikitevents.h" -#include "SDL_uikitpen.h" -#include "SDL_uikitwindow.h" - -#include "../../events/SDL_pen_c.h" - -// Fix build errors when using an older SDK by defining these selectors -#if !defined(SDL_PLATFORM_TVOS) - -@interface UITouch (SDL) -#if !(__IPHONE_OS_VERSION_MAX_ALLOWED >= 170500) -@property (nonatomic, readonly) CGFloat rollAngle; -#endif -@end - -@interface UIHoverGestureRecognizer (SDL) -#if !(__IPHONE_OS_VERSION_MAX_ALLOWED >= 160100) -@property (nonatomic, readonly) CGFloat zOffset; -#endif -#if !(__IPHONE_OS_VERSION_MAX_ALLOWED >= 160400) -- (CGFloat) azimuthAngleInView:(UIView *) view; - -@property (nonatomic, readonly) CGFloat altitudeAngle; -#endif -#if !(__IPHONE_OS_VERSION_MAX_ALLOWED >= 170500) -@property (nonatomic, readonly) CGFloat rollAngle; -#endif -@end - -#endif // !SDL_PLATFORM_TVOS - -static SDL_PenID apple_pencil_id = 0; - -bool UIKit_InitPen(SDL_VideoDevice *_this) -{ - return true; -} - -// we only have one Apple Pencil at a time, and it must be paired to the iOS device. -// We only know about its existence when it first sends an event, so add an single SDL pen -// device here if we haven't already. -static SDL_PenID UIKit_AddPenIfNecesary() -{ - if (!apple_pencil_id) { - SDL_PenInfo info; - SDL_zero(info); - info.capabilities = SDL_PEN_CAPABILITY_PRESSURE | SDL_PEN_CAPABILITY_XTILT | SDL_PEN_CAPABILITY_YTILT; - info.max_tilt = 90.0f; - info.num_buttons = 0; - info.subtype = SDL_PEN_TYPE_PENCIL; - - if (@available(iOS 17.5, *)) { // need rollAngle method. - info.capabilities |= SDL_PEN_CAPABILITY_ROTATION; - } - - if (@available(ios 16.1, *)) { // need zOffset method. - info.capabilities |= SDL_PEN_CAPABILITY_DISTANCE; - } - - // Apple Pencil and iOS can report when the pencil is being "squeezed" but it's a boolean thing, - // so we can't use it for tangential pressure. - - // There's only ever one Apple Pencil at most, so we just pass a non-zero value for the handle. - apple_pencil_id = SDL_AddPenDevice(0, "Apple Pencil", &info, (void *) (size_t) 0x1); - } - - return apple_pencil_id; -} - -static void UIKit_HandlePenAxes(SDL_Window *window, NSTimeInterval nstimestamp, float zOffset, const CGPoint *point, float force, - float maximumPossibleForce, float azimuthAngleInView, float altitudeAngle, float rollAngle) -{ - const SDL_PenID penId = UIKit_AddPenIfNecesary(); - if (penId) { - const Uint64 timestamp = UIKit_GetEventTimestamp(nstimestamp); - const float radians_to_degrees = 180.0f / SDL_PI_F; - - // Normalize force to 0.0f ... 1.0f range. - const float pressure = force / maximumPossibleForce; - - // azimuthAngleInView is in radians, with 0 being the pen's back end pointing due east on the screen when the - // tip is touching the screen, and negative when heading north from there, positive to the south. - // So convert to degrees, 0 being due east, etc. - const float azimuth_angle = azimuthAngleInView * radians_to_degrees; - - // altitudeAngle is in radians, with 0 being the pen laying flat on (parallel to) the device - // screen and PI/2 being it pointing straight up from (perpendicular to) the device screen. - // So convert to degrees, 0 being flat and 90 being straight up. - const float altitude_angle = altitudeAngle * radians_to_degrees; - - // the azimuth_angle goes from -180 to 180 (with abs(angle) moving from 180 to 0, left to right), but SDL wants - // it from -90 (back facing west) to 90 (back facing east). - const float xtilt = (180.0f - SDL_fabsf(azimuth_angle)) - 90.0f; - - // the altitude_angle goes from 0 to 90 regardless of which direction the pen is lifting off the device, but SDL wants - // it from -90 (flat facing north) to 90 (flat facing south). - const float ytilt = (azimuth_angle < 0.0f) ? -(90.0f - altitude_angle) : (90.0f - altitude_angle); - - // rotation is in radians, and only available on a later iOS. - const float rotation = rollAngle * radians_to_degrees; // !!! FIXME: this might need adjustment, I don't have a pencil that supports it. - - SDL_SendPenMotion(timestamp, penId, window, point->x, point->y); - SDL_SendPenAxis(timestamp, penId, window, SDL_PEN_AXIS_PRESSURE, pressure); - SDL_SendPenAxis(timestamp, penId, window, SDL_PEN_AXIS_XTILT, xtilt); - SDL_SendPenAxis(timestamp, penId, window, SDL_PEN_AXIS_YTILT, ytilt); - SDL_SendPenAxis(timestamp, penId, window, SDL_PEN_AXIS_ROTATION, rotation); - SDL_SendPenAxis(timestamp, penId, window, SDL_PEN_AXIS_DISTANCE, zOffset); - } -} - -#if !defined(SDL_PLATFORM_TVOS) -extern void UIKit_HandlePenHover(SDL_uikitview *view, UIHoverGestureRecognizer *recognizer) -{ - float zOffset = 0.0f; - if (@available(iOS 16.1, *)) { - zOffset = (float) [recognizer zOffset]; - } - - float azimuthAngleInView = 0.0f; - if (@available(iOS 16.4, *)) { - azimuthAngleInView = (float) [recognizer azimuthAngleInView:view]; - } - - float altitudeAngle = 0.0f; - if (@available(iOS 16.4, *)) { - altitudeAngle = (float) [recognizer altitudeAngle]; - } - - float rollAngle = 0.0f; - if (@available(iOS 17.5, *)) { - rollAngle = (float) [recognizer rollAngle]; - } - - SDL_Window *window = [view getSDLWindow]; - const CGPoint point = [recognizer locationInView:view]; - - // force is zero here; if you're here, you're not touching. - // !!! FIXME: no timestamp on these...? - UIKit_HandlePenAxes(window, 0, zOffset, &point, 0.0f, 1.0f, azimuthAngleInView, altitudeAngle, rollAngle); -} -#endif - -static void UIKit_HandlePenAxesFromUITouch(SDL_uikitview *view, UITouch *pencil) -{ - float rollAngle = 0.0f; -#if !defined(SDL_PLATFORM_TVOS) - if (@available(iOS 17.5, *)) { - rollAngle = (float) [pencil rollAngle]; - } -#endif - - SDL_Window *window = [view getSDLWindow]; - const CGPoint point = [pencil locationInView:view]; - - // zOffset is zero here; if you're here, you're touching. - UIKit_HandlePenAxes(window, [pencil timestamp], 0.0f, &point, [pencil force], [pencil maximumPossibleForce], [pencil azimuthAngleInView:view], [pencil altitudeAngle], rollAngle); -} - -void UIKit_HandlePenMotion(SDL_uikitview *view, UITouch *pencil) -{ - UIKit_HandlePenAxesFromUITouch(view, pencil); -} - -void UIKit_HandlePenPress(SDL_uikitview *view, UITouch *pencil) -{ - const SDL_PenID penId = UIKit_AddPenIfNecesary(); - if (penId) { - UIKit_HandlePenAxesFromUITouch(view, pencil); - SDL_SendPenTouch(UIKit_GetEventTimestamp([pencil timestamp]), penId, [view getSDLWindow], false, true); - } -} - -void UIKit_HandlePenRelease(SDL_uikitview *view, UITouch *pencil) -{ - const SDL_PenID penId = UIKit_AddPenIfNecesary(); - if (penId) { - SDL_SendPenTouch(UIKit_GetEventTimestamp([pencil timestamp]), penId, [view getSDLWindow], false, false); - UIKit_HandlePenAxesFromUITouch(view, pencil); - } -} - -void UIKit_QuitPen(SDL_VideoDevice *_this) -{ - if (apple_pencil_id) { - SDL_RemovePenDevice(0, apple_pencil_id); - apple_pencil_id = 0; - } -} - -#endif // SDL_VIDEO_DRIVER_UIKIT diff --git a/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitvideo.h b/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitvideo.h deleted file mode 100644 index 927e646..0000000 --- a/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitvideo.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2025 Sam Lantinga - - 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 - -@interface SDL_UIKitVideoData : NSObject - -@property(nonatomic, assign) id pasteboardObserver; - -@end - -#ifdef SDL_PLATFORM_VISIONOS -CGRect UIKit_ComputeViewFrame(SDL_Window *window); -#else -CGRect UIKit_ComputeViewFrame(SDL_Window *window, UIScreen *screen); -#endif - -#endif // __OBJC__ - -bool UIKit_SuspendScreenSaver(SDL_VideoDevice *_this); - -void UIKit_ForceUpdateHomeIndicator(void); - -bool UIKit_IsSystemVersionAtLeast(double version); - -SDL_SystemTheme UIKit_GetSystemTheme(void); - -#endif // SDL_uikitvideo_h_ diff --git a/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitvideo.m b/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitvideo.m deleted file mode 100644 index 5c3987d..0000000 --- a/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitvideo.m +++ /dev/null @@ -1,312 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2025 Sam Lantinga - - 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" - -#ifdef SDL_VIDEO_DRIVER_UIKIT - -#import - -#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" -#include "SDL_uikitmetalview.h" -#include "SDL_uikitmessagebox.h" - -#define UIKITVID_DRIVER_NAME "uikit" - -@implementation SDL_UIKitVideoData - -@end - -// Initialization/Query functions -static bool UIKit_VideoInit(SDL_VideoDevice *_this); -static void UIKit_VideoQuit(SDL_VideoDevice *_this); - -// DUMMY driver bootstrap functions - -static void UIKit_DeleteDevice(SDL_VideoDevice *device) -{ - @autoreleasepool { - if (device->internal){ - CFRelease(device->internal); - } - SDL_free(device); - } -} - -static SDL_VideoDevice *UIKit_CreateDevice(void) -{ - @autoreleasepool { - SDL_VideoDevice *device; - SDL_UIKitVideoData *data; - - // Initialize all variables that we clean on shutdown - device = (SDL_VideoDevice *)SDL_calloc(1, sizeof(SDL_VideoDevice)); - if (!device) { - return NULL; - } - - data = [SDL_UIKitVideoData new]; - - device->internal = (SDL_VideoData *)CFBridgingRetain(data); - device->system_theme = UIKit_GetSystemTheme(); - - // 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->GetDisplayUsableBounds = UIKit_GetDisplayUsableBounds; - device->GetWindowSizeInPixels = UIKit_GetWindowSizeInPixels; - -#ifdef SDL_IPHONE_KEYBOARD - device->HasScreenKeyboardSupport = UIKit_HasScreenKeyboardSupport; - device->StartTextInput = UIKit_StartTextInput; - device->StopTextInput = UIKit_StopTextInput; - device->SetTextInputProperties = UIKit_SetTextInputProperties; - device->IsScreenKeyboardShown = UIKit_IsScreenKeyboardShown; - device->UpdateTextInputArea = UIKit_UpdateTextInputArea; -#endif - - device->SetClipboardText = UIKit_SetClipboardText; - device->GetClipboardText = UIKit_GetClipboardText; - device->HasClipboardText = UIKit_HasClipboardText; - - // OpenGL (ES) functions -#if defined(SDL_VIDEO_OPENGL_ES) || defined(SDL_VIDEO_OPENGL_ES2) - device->GL_MakeCurrent = UIKit_GL_MakeCurrent; - device->GL_SwapWindow = UIKit_GL_SwapWindow; - device->GL_CreateContext = UIKit_GL_CreateContext; - device->GL_DestroyContext = UIKit_GL_DestroyContext; - device->GL_GetProcAddress = UIKit_GL_GetProcAddress; - device->GL_LoadLibrary = UIKit_GL_LoadLibrary; -#endif - device->free = UIKit_DeleteDevice; - -#ifdef 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_DestroySurface = UIKit_Vulkan_DestroySurface; -#endif - -#ifdef SDL_VIDEO_METAL - device->Metal_CreateView = UIKit_Metal_CreateView; - device->Metal_DestroyView = UIKit_Metal_DestroyView; - device->Metal_GetLayer = UIKit_Metal_GetLayer; -#endif - - device->device_caps = VIDEO_DEVICE_CAPS_SENDS_FULLSCREEN_DIMENSIONS; - - device->gl_config.accelerated = 1; - - return device; - } -} - -VideoBootStrap UIKIT_bootstrap = { - UIKITVID_DRIVER_NAME, "SDL UIKit video driver", - UIKit_CreateDevice, - UIKit_ShowMessageBox, - false -}; - -static bool UIKit_VideoInit(SDL_VideoDevice *_this) -{ - _this->gl_config.driver_loaded = 1; - - if (!UIKit_InitModes(_this)) { - return false; - } - - SDL_InitGCKeyboard(); - SDL_InitGCMouse(); - - UIKit_InitClipboard(_this); - - return true; -} - -static void UIKit_VideoQuit(SDL_VideoDevice *_this) -{ - UIKit_QuitClipboard(_this); - - SDL_QuitGCKeyboard(); - SDL_QuitGCMouse(); - - UIKit_QuitModes(_this); -} - -bool UIKit_SuspendScreenSaver(SDL_VideoDevice *_this) -{ - @autoreleasepool { - UIApplication *app = [UIApplication sharedApplication]; - - // Prevent the display from dimming and going to sleep. - app.idleTimerDisabled = (_this->suspend_screensaver != false); - } - return true; -} - -bool UIKit_IsSystemVersionAtLeast(double version) -{ - return [[UIDevice currentDevice].systemVersion doubleValue] >= version; -} - -SDL_SystemTheme UIKit_GetSystemTheme(void) -{ -#ifndef SDL_PLATFORM_VISIONOS - if (@available(iOS 12.0, tvOS 10.0, *)) { - switch ([UIScreen mainScreen].traitCollection.userInterfaceStyle) { - case UIUserInterfaceStyleDark: - return SDL_SYSTEM_THEME_DARK; - case UIUserInterfaceStyleLight: - return SDL_SYSTEM_THEME_LIGHT; - default: - break; - } - } -#endif - return SDL_SYSTEM_THEME_UNKNOWN; -} - -#ifdef SDL_PLATFORM_VISIONOS -CGRect UIKit_ComputeViewFrame(SDL_Window *window){ - return CGRectMake(window->x, window->y, window->w, window->h); -} -#else -CGRect UIKit_ComputeViewFrame(SDL_Window *window, UIScreen *screen) -{ - SDL_UIKitWindowData *data = (__bridge SDL_UIKitWindowData *)window->internal; - CGRect frame = screen.bounds; - - /* Use the UIWindow bounds instead of the UIScreen bounds, when possible. - * The uiwindow bounds may be smaller than the screen bounds when Split View - * is used on an iPad. */ - if (data != nil && data.uiwindow != nil) { - frame = data.uiwindow.bounds; - } - -#ifndef SDL_PLATFORM_TVOS - /* 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 */ - UIInterfaceOrientation orient = [UIApplication sharedApplication].statusBarOrientation; - BOOL landscape = UIInterfaceOrientationIsLandscape(orient) || - !(UIKit_GetSupportedOrientations(window) & (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown)); - BOOL fullscreen = CGRectEqualToRect(screen.bounds, frame); - - /* The orientation flip doesn't make sense when the window is smaller - * than the screen (iPad Split View, for example). */ - if (fullscreen && (landscape != (frame.size.width > frame.size.height))) { - float height = frame.size.width; - frame.size.width = frame.size.height; - frame.size.height = height; - } -#endif - - return frame; -} - -#endif - -void UIKit_ForceUpdateHomeIndicator(void) -{ -#ifndef SDL_PLATFORM_TVOS - // Force the main SDL window to re-evaluate home indicator state - SDL_Window *focus = SDL_GetKeyboardFocus(); - if (focus) { - SDL_UIKitWindowData *data = (__bridge SDL_UIKitWindowData *)focus->internal; - if (data != nil) { - [data.viewcontroller performSelectorOnMainThread:@selector(setNeedsUpdateOfHomeIndicatorAutoHidden) withObject:nil waitUntilDone:NO]; - [data.viewcontroller performSelectorOnMainThread:@selector(setNeedsUpdateOfScreenEdgesDeferringSystemGestures) withObject:nil waitUntilDone:NO]; - } - } -#endif // !SDL_PLATFORM_TVOS -} - -/* - * iOS log support. - * - * This doesn't really have anything to do with the interfaces of the SDL video - * subsystem, but we need to stuff this into an Objective-C source code file. - * - * NOTE: This is copypasted from src/video/cocoa/SDL_cocoavideo.m! Thus, if - * Cocoa is supported, we use that one instead. Be sure both versions remain - * identical! - */ - -#ifndef SDL_VIDEO_DRIVER_COCOA -void SDL_NSLog(const char *prefix, const char *text) -{ - @autoreleasepool { - NSString *nsText = [NSString stringWithUTF8String:text]; - if (prefix && *prefix) { - NSString *nsPrefix = [NSString stringWithUTF8String:prefix]; - NSLog(@"%@%@", nsPrefix, nsText); - } else { - NSLog(@"%@", nsText); - } - } -} -#endif // SDL_VIDEO_DRIVER_COCOA - -/* - * iOS Tablet, etc, detection - * - * This doesn't really have anything to do with the interfaces of the SDL video - * subsystem, but we need to stuff this into an Objective-C source code file. - */ -bool SDL_IsIPad(void) -{ - return ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad); -} - -bool SDL_IsAppleTV(void) -{ - return ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomTV); -} - -#endif // SDL_VIDEO_DRIVER_UIKIT diff --git a/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitview.h b/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitview.h deleted file mode 100644 index 78c2bed..0000000 --- a/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitview.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2025 Sam Lantinga - - 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 - -#include "../SDL_sysvideo.h" - -#if !defined(SDL_PLATFORM_TVOS) -@interface SDL_uikitview : UIView -#else -@interface SDL_uikitview : UIView -#endif - -- (instancetype)initWithFrame:(CGRect)frame; - -- (void)setSDLWindow:(SDL_Window *)window; -- (SDL_Window *)getSDLWindow; - -#if !defined(SDL_PLATFORM_TVOS) -- (void)pencilHovering:(UIHoverGestureRecognizer *)recognizer API_AVAILABLE(ios(13.0)); - -- (UIPointerRegion *)pointerInteraction:(UIPointerInteraction *)interaction regionForRequest:(UIPointerRegionRequest *)request defaultRegion:(UIPointerRegion *)defaultRegion API_AVAILABLE(ios(13.4)); -- (UIPointerStyle *)pointerInteraction:(UIPointerInteraction *)interaction styleForRegion:(UIPointerRegion *)region API_AVAILABLE(ios(13.4)); -- (void)indirectPointerHovering:(UIHoverGestureRecognizer *)recognizer API_AVAILABLE(ios(13.4)); -#endif - -- (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; - -- (void)safeAreaInsetsDidChange; - -@end diff --git a/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitview.m b/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitview.m deleted file mode 100644 index ba3b09b..0000000 --- a/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitview.m +++ /dev/null @@ -1,587 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2025 Sam Lantinga - - 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" - -#ifdef SDL_VIDEO_DRIVER_UIKIT - -#include "SDL_uikitview.h" - -#include "../../events/SDL_mouse_c.h" -#include "../../events/SDL_touch_c.h" -#include "../../events/SDL_events_c.h" - -#include "SDL_uikitappdelegate.h" -#include "SDL_uikitevents.h" -#include "SDL_uikitmodes.h" -#include "SDL_uikitpen.h" -#include "SDL_uikitwindow.h" - -// The maximum number of mouse buttons we support -#define MAX_MOUSE_BUTTONS 5 - -// This is defined in SDL_sysjoystick.m -#ifndef SDL_JOYSTICK_DISABLED -extern int SDL_AppleTVRemoteOpenedAsJoystick; -#endif - -@implementation SDL_uikitview -{ - SDL_Window *sdlwindow; - - SDL_TouchID directTouchId; - SDL_TouchID indirectTouchId; - -#if !defined(SDL_PLATFORM_TVOS) - UIPointerInteraction *indirectPointerInteraction API_AVAILABLE(ios(13.4)); -#endif -} - -- (instancetype)initWithFrame:(CGRect)frame -{ - if ((self = [super initWithFrame:frame])) { -#ifdef SDL_PLATFORM_TVOS - // 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; - - directTouchId = 1; - indirectTouchId = 2; - -#ifndef SDL_PLATFORM_TVOS - self.multipleTouchEnabled = YES; - SDL_AddTouch(directTouchId, SDL_TOUCH_DEVICE_DIRECT, ""); - - if (@available(iOS 13.0, *)) { - UIHoverGestureRecognizer *pencilRecognizer = [[UIHoverGestureRecognizer alloc] initWithTarget:self action:@selector(pencilHovering:)]; - pencilRecognizer.allowedTouchTypes = @[@(UITouchTypePencil)]; - [self addGestureRecognizer:pencilRecognizer]; - } - - if (@available(iOS 13.4, *)) { - indirectPointerInteraction = [[UIPointerInteraction alloc] initWithDelegate:self]; - [self addInteraction:indirectPointerInteraction]; - - UIHoverGestureRecognizer *indirectPointerRecognizer = [[UIHoverGestureRecognizer alloc] initWithTarget:self action:@selector(indirectPointerHovering:)]; - indirectPointerRecognizer.allowedTouchTypes = @[@(UITouchTypeIndirectPointer)]; - [self addGestureRecognizer:indirectPointerRecognizer]; - } -#endif // !defined(SDL_PLATFORM_TVOS) - } - - return self; -} - -- (void)setSDLWindow:(SDL_Window *)window -{ - SDL_UIKitWindowData *data = nil; - - if (window == sdlwindow) { - return; - } - - // Remove ourself from the old window. - if (sdlwindow) { - SDL_uikitview *view = nil; - data = (__bridge SDL_UIKitWindowData *)sdlwindow->internal; - - [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]; - } - - sdlwindow = window; - - // Add ourself to the new window. - if (window) { - data = (__bridge SDL_UIKitWindowData *)window->internal; - - // 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]; - } -} - -- (SDL_Window *)getSDLWindow -{ - return sdlwindow; -} - -#if !defined(SDL_PLATFORM_TVOS) - -- (UIPointerRegion *)pointerInteraction:(UIPointerInteraction *)interaction regionForRequest:(UIPointerRegionRequest *)request defaultRegion:(UIPointerRegion *)defaultRegion API_AVAILABLE(ios(13.4)) -{ - return [UIPointerRegion regionWithRect:self.bounds identifier:nil]; -} - -- (UIPointerStyle *)pointerInteraction:(UIPointerInteraction *)interaction styleForRegion:(UIPointerRegion *)region API_AVAILABLE(ios(13.4)) -{ - if (SDL_CursorVisible()) { - return nil; - } else { - return [UIPointerStyle hiddenPointerStyle]; - } -} - -- (void)indirectPointerHovering:(UIHoverGestureRecognizer *)recognizer API_AVAILABLE(ios(13.4)) -{ - switch (recognizer.state) { - case UIGestureRecognizerStateBegan: - case UIGestureRecognizerStateChanged: - { - CGPoint point = [recognizer locationInView:self]; - SDL_SendMouseMotion(0, sdlwindow, SDL_GLOBAL_MOUSE_ID, false, point.x, point.y); - break; - } - - default: - break; - } -} - -- (void)indirectPointerMoving:(UITouch *)touch API_AVAILABLE(ios(13.4)) -{ - CGPoint locationInView = [self touchLocation:touch shouldNormalize:NO]; - SDL_SendMouseMotion(0, sdlwindow, SDL_GLOBAL_MOUSE_ID, false, locationInView.x, locationInView.y); -} - -- (void)indirectPointerPressed:(UITouch *)touch fromEvent:(UIEvent *)event API_AVAILABLE(ios(13.4)) -{ - if (!SDL_HasMouse()) { - int i; - - for (i = 1; i <= MAX_MOUSE_BUTTONS; ++i) { - if (event.buttonMask & SDL_BUTTON_MASK(i)) { - Uint8 button; - - switch (i) { - case 1: - button = SDL_BUTTON_LEFT; - break; - case 2: - button = SDL_BUTTON_RIGHT; - break; - case 3: - button = SDL_BUTTON_MIDDLE; - break; - default: - button = (Uint8)i; - break; - } - SDL_SendMouseButton(UIKit_GetEventTimestamp([touch timestamp]), sdlwindow, SDL_GLOBAL_MOUSE_ID, button, true); - } - } - } -} - -- (void)indirectPointerReleased:(UITouch *)touch fromEvent:(UIEvent *)event API_AVAILABLE(ios(13.4)) -{ - if (!SDL_HasMouse()) { - int i; - SDL_MouseButtonFlags buttons = SDL_GetMouseState(NULL, NULL); - - for (i = 0; i < MAX_MOUSE_BUTTONS; ++i) { - if (buttons & SDL_BUTTON_MASK(i)) { - SDL_SendMouseButton(UIKit_GetEventTimestamp([touch timestamp]), sdlwindow, SDL_GLOBAL_MOUSE_ID, (Uint8)i, false); - } - } - } -} - -- (void)pencilHovering:(UIHoverGestureRecognizer *)recognizer API_AVAILABLE(ios(13.0)) -{ - switch (recognizer.state) { - case UIGestureRecognizerStateBegan: - case UIGestureRecognizerStateChanged: - UIKit_HandlePenHover(self, recognizer); - break; - - case UIGestureRecognizerStateEnded: - case UIGestureRecognizerStateCancelled: - // we track touches elsewhere, so if a hover "ends" we'll deal with that there. - break; - - default: - break; - } -} - -- (void)pencilMoving:(UITouch *)touch -{ - UIKit_HandlePenMotion(self, touch); -} - -- (void)pencilPressed:(UITouch *)touch -{ - UIKit_HandlePenPress(self, touch); -} - -- (void)pencilReleased:(UITouch *)touch -{ - UIKit_HandlePenRelease(self, touch); -} - -#endif // !defined(SDL_PLATFORM_TVOS) - -- (SDL_TouchDeviceType)touchTypeForTouch:(UITouch *)touch -{ - if (touch.type == UITouchTypeIndirect) { - return SDL_TOUCH_DEVICE_INDIRECT_RELATIVE; - } - return SDL_TOUCH_DEVICE_DIRECT; -} - -- (SDL_TouchID)touchIdForType:(SDL_TouchDeviceType)type -{ - switch (type) { - case SDL_TOUCH_DEVICE_DIRECT: - default: - return directTouchId; - case SDL_TOUCH_DEVICE_INDIRECT_RELATIVE: - return indirectTouchId; - } -} - -- (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 -{ - return (float)touch.force; -} - -- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event -{ - for (UITouch *touch in touches) { -#if !defined(SDL_PLATFORM_TVOS) - if (@available(iOS 13.0, *)) { - if (touch.type == UITouchTypePencil) { - [self pencilPressed:touch]; - continue; - } - } - - if (@available(iOS 13.4, *)) { - if (touch.type == UITouchTypeIndirectPointer) { - [self indirectPointerPressed:touch fromEvent:event]; - continue; - } - } -#endif // !defined(SDL_PLATFORM_TVOS) - - SDL_TouchDeviceType touchType = [self touchTypeForTouch:touch]; - SDL_TouchID touchId = [self touchIdForType:touchType]; - float pressure = [self pressureForTouch:touch]; - - if (SDL_AddTouch(touchId, touchType, "") < 0) { - continue; - } - - // FIXME, need to send: int clicks = (int) touch.tapCount; ? - - CGPoint locationInView = [self touchLocation:touch shouldNormalize:YES]; - SDL_SendTouch(UIKit_GetEventTimestamp([event timestamp]), - touchId, (SDL_FingerID)(uintptr_t)touch, sdlwindow, - SDL_EVENT_FINGER_DOWN, locationInView.x, locationInView.y, pressure); - } -} - -- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event -{ - for (UITouch *touch in touches) { -#if !defined(SDL_PLATFORM_TVOS) - if (@available(iOS 13.0, *)) { - if (touch.type == UITouchTypePencil) { - [self pencilReleased:touch]; - continue; - } - } - - if (@available(iOS 13.4, *)) { - if (touch.type == UITouchTypeIndirectPointer) { - [self indirectPointerReleased:touch fromEvent:event]; - continue; - } - } -#endif // !defined(SDL_PLATFORM_TVOS) - - SDL_TouchDeviceType touchType = [self touchTypeForTouch:touch]; - SDL_TouchID touchId = [self touchIdForType:touchType]; - float pressure = [self pressureForTouch:touch]; - - if (SDL_AddTouch(touchId, touchType, "") < 0) { - continue; - } - - // FIXME, need to send: int clicks = (int) touch.tapCount; ? - - CGPoint locationInView = [self touchLocation:touch shouldNormalize:YES]; - SDL_SendTouch(UIKit_GetEventTimestamp([event timestamp]), - touchId, (SDL_FingerID)(uintptr_t)touch, sdlwindow, - SDL_EVENT_FINGER_UP, locationInView.x, locationInView.y, pressure); - } -} - -- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event -{ - for (UITouch *touch in touches) { -#if !defined(SDL_PLATFORM_TVOS) - if (@available(iOS 13.0, *)) { - if (touch.type == UITouchTypePencil) { - [self pencilReleased:touch]; - continue; - } - } - - if (@available(iOS 13.4, *)) { - if (touch.type == UITouchTypeIndirectPointer) { - [self indirectPointerReleased:touch fromEvent:event]; - continue; - } - } -#endif // !defined(SDL_PLATFORM_TVOS) - - SDL_TouchDeviceType touchType = [self touchTypeForTouch:touch]; - SDL_TouchID touchId = [self touchIdForType:touchType]; - float pressure = [self pressureForTouch:touch]; - - if (SDL_AddTouch(touchId, touchType, "") < 0) { - continue; - } - - CGPoint locationInView = [self touchLocation:touch shouldNormalize:YES]; - SDL_SendTouch(UIKit_GetEventTimestamp([event timestamp]), - touchId, (SDL_FingerID)(uintptr_t)touch, sdlwindow, - SDL_EVENT_FINGER_CANCELED, locationInView.x, locationInView.y, pressure); - } -} - -- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event -{ - for (UITouch *touch in touches) { -#if !defined(SDL_PLATFORM_TVOS) - if (@available(iOS 13.0, *)) { - if (touch.type == UITouchTypePencil) { - [self pencilMoving:touch]; - continue; - } - } - - if (@available(iOS 13.4, *)) { - if (touch.type == UITouchTypeIndirectPointer) { - [self indirectPointerMoving:touch]; - continue; - } - } -#endif // !defined(SDL_PLATFORM_TVOS) - - SDL_TouchDeviceType touchType = [self touchTypeForTouch:touch]; - SDL_TouchID touchId = [self touchIdForType:touchType]; - float pressure = [self pressureForTouch:touch]; - - if (SDL_AddTouch(touchId, touchType, "") < 0) { - continue; - } - - CGPoint locationInView = [self touchLocation:touch shouldNormalize:YES]; - SDL_SendTouchMotion(UIKit_GetEventTimestamp([event timestamp]), - touchId, (SDL_FingerID)(uintptr_t)touch, sdlwindow, - locationInView.x, locationInView.y, pressure); - } -} - -- (void)safeAreaInsetsDidChange -{ - // Update the safe area insets - SDL_SetWindowSafeAreaInsets(sdlwindow, - (int)SDL_ceilf(self.safeAreaInsets.left), - (int)SDL_ceilf(self.safeAreaInsets.right), - (int)SDL_ceilf(self.safeAreaInsets.top), - (int)SDL_ceilf(self.safeAreaInsets.bottom)); -} - -- (SDL_Scancode)scancodeFromPress:(UIPress *)press -{ - if (press.key != nil) { - return (SDL_Scancode)press.key.keyCode; - } - -#ifndef SDL_JOYSTICK_DISABLED - // Presses from Apple TV remote - if (!SDL_AppleTVRemoteOpenedAsJoystick) { - switch (press.type) { - 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: - break; - } - } -#endif // !SDL_JOYSTICK_DISABLED - - return SDL_SCANCODE_UNKNOWN; -} - -- (void)pressesBegan:(NSSet *)presses withEvent:(UIPressesEvent *)event -{ - if (!SDL_HasKeyboard()) { - for (UIPress *press in presses) { - SDL_Scancode scancode = [self scancodeFromPress:press]; - SDL_SendKeyboardKey(UIKit_GetEventTimestamp([event timestamp]), SDL_GLOBAL_KEYBOARD_ID, 0, scancode, true); - } - } - if (SDL_TextInputActive(sdlwindow)) { - [super pressesBegan:presses withEvent:event]; - } -} - -- (void)pressesEnded:(NSSet *)presses withEvent:(UIPressesEvent *)event -{ - if (!SDL_HasKeyboard()) { - for (UIPress *press in presses) { - SDL_Scancode scancode = [self scancodeFromPress:press]; - SDL_SendKeyboardKey(UIKit_GetEventTimestamp([event timestamp]), SDL_GLOBAL_KEYBOARD_ID, 0, scancode, false); - } - } - if (SDL_TextInputActive(sdlwindow)) { - [super pressesEnded:presses withEvent:event]; - } -} - -- (void)pressesCancelled:(NSSet *)presses withEvent:(UIPressesEvent *)event -{ - if (!SDL_HasKeyboard()) { - for (UIPress *press in presses) { - SDL_Scancode scancode = [self scancodeFromPress:press]; - SDL_SendKeyboardKey(UIKit_GetEventTimestamp([event timestamp]), SDL_GLOBAL_KEYBOARD_ID, 0, scancode, false); - } - } - if (SDL_TextInputActive(sdlwindow)) { - [super pressesCancelled:presses withEvent:event]; - } -} - -- (void)pressesChanged:(NSSet *)presses withEvent:(UIPressesEvent *)event -{ - // This is only called when the force of a press changes. - if (SDL_TextInputActive(sdlwindow)) { - [super pressesChanged:presses withEvent:event]; - } -} - -#ifdef SDL_PLATFORM_TVOS -- (void)swipeGesture:(UISwipeGestureRecognizer *)gesture -{ - // Swipe gestures don't trigger begin states. - if (gesture.state == UIGestureRecognizerStateEnded) { -#ifndef SDL_JOYSTICK_DISABLED - 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_SendKeyboardKeyAutoRelease(0, SDL_SCANCODE_UP); - break; - case UISwipeGestureRecognizerDirectionDown: - SDL_SendKeyboardKeyAutoRelease(0, SDL_SCANCODE_DOWN); - break; - case UISwipeGestureRecognizerDirectionLeft: - SDL_SendKeyboardKeyAutoRelease(0, SDL_SCANCODE_LEFT); - break; - case UISwipeGestureRecognizerDirectionRight: - SDL_SendKeyboardKeyAutoRelease(0, SDL_SCANCODE_RIGHT); - break; - } - } -#endif // !SDL_JOYSTICK_DISABLED - } -} -#endif // SDL_PLATFORM_TVOS - -@end - -#endif // SDL_VIDEO_DRIVER_UIKIT diff --git a/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitviewcontroller.h b/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitviewcontroller.h deleted file mode 100644 index d52e478..0000000 --- a/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitviewcontroller.h +++ /dev/null @@ -1,96 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2025 Sam Lantinga - - 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 - -#include "../SDL_sysvideo.h" - -#ifdef SDL_PLATFORM_TVOS -#import -#define SDLRootViewController GCEventViewController -#else -#define SDLRootViewController UIViewController -#endif - -@interface SDLUITextField : UITextField -- (BOOL)canPerformAction:(SEL)action withSender:(id)sender; -@end - -#ifdef SDL_IPHONE_KEYBOARD -@interface SDL_uikitviewcontroller : SDLRootViewController -#else -@interface SDL_uikitviewcontroller : SDLRootViewController -#endif - -@property(nonatomic, assign) SDL_Window *window; - -- (instancetype)initWithSDLWindow:(SDL_Window *)_window; - -- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection; - -- (void)setAnimationCallback:(int)interval - callback:(void (*)(void *))callback - callbackParam:(void *)callbackParam; - -- (void)startAnimation; -- (void)stopAnimation; - -- (void)doLoop:(CADisplayLink *)sender; - -- (void)loadView; -- (void)viewDidLayoutSubviews; - -#ifndef SDL_PLATFORM_TVOS -- (NSUInteger)supportedInterfaceOrientations; -- (BOOL)prefersStatusBarHidden; -- (BOOL)prefersHomeIndicatorAutoHidden; -- (UIRectEdge)preferredScreenEdgesDeferringSystemGestures; - -@property(nonatomic, assign) int homeIndicatorHidden; -#endif - -#ifdef SDL_IPHONE_KEYBOARD -- (bool)startTextInput; -- (bool)stopTextInput; -- (void)initKeyboard; -- (void)deinitKeyboard; - -- (void)keyboardWillShow:(NSNotification *)notification; -- (void)keyboardWillHide:(NSNotification *)notification; - -- (void)updateKeyboard; - -@property(nonatomic, assign, getter=isTextFieldFocused) BOOL textFieldFocused; -@property(nonatomic, assign) SDL_Rect textInputRect; -@property(nonatomic, assign) int keyboardHeight; -#endif - -@end - -#ifdef SDL_IPHONE_KEYBOARD -bool UIKit_HasScreenKeyboardSupport(SDL_VideoDevice *_this); -bool UIKit_StartTextInput(SDL_VideoDevice *_this, SDL_Window *window, SDL_PropertiesID props); -bool UIKit_StopTextInput(SDL_VideoDevice *_this, SDL_Window *window); -void UIKit_SetTextInputProperties(SDL_VideoDevice *_this, SDL_Window *window, SDL_PropertiesID props); -bool UIKit_IsScreenKeyboardShown(SDL_VideoDevice *_this, SDL_Window *window); -bool UIKit_UpdateTextInputArea(SDL_VideoDevice *_this, SDL_Window *window); -#endif diff --git a/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitviewcontroller.m b/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitviewcontroller.m deleted file mode 100644 index 45f2d64..0000000 --- a/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitviewcontroller.m +++ /dev/null @@ -1,736 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2025 Sam Lantinga - - 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" - -#ifdef SDL_VIDEO_DRIVER_UIKIT - -#include "../SDL_sysvideo.h" -#include "../../events/SDL_events_c.h" - -#include "SDL_uikitviewcontroller.h" -#include "SDL_uikitmessagebox.h" -#include "SDL_uikitevents.h" -#include "SDL_uikitvideo.h" -#include "SDL_uikitmodes.h" -#include "SDL_uikitwindow.h" -#include "SDL_uikitopengles.h" - -#ifdef SDL_PLATFORM_TVOS -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 - -#ifndef SDL_PLATFORM_TVOS -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; - [viewcontroller setNeedsUpdateOfHomeIndicatorAutoHidden]; - [viewcontroller setNeedsUpdateOfScreenEdgesDeferringSystemGestures]; - } -} -#endif - -@implementation SDLUITextField : UITextField -- (BOOL)canPerformAction:(SEL)action withSender:(id)sender -{ - if (action == @selector(paste:)) { - return NO; - } - - return [super canPerformAction:action withSender:sender]; -} -@end - -@implementation SDL_uikitviewcontroller -{ - CADisplayLink *displayLink; - int animationInterval; - void (*animationCallback)(void *); - void *animationCallbackParam; - -#ifdef SDL_IPHONE_KEYBOARD - SDLUITextField *textField; - BOOL hidingKeyboard; - BOOL rotatingOrientation; - NSString *committedText; - NSString *obligateForBackspace; -#endif -} - -@synthesize window; - -- (instancetype)initWithSDLWindow:(SDL_Window *)_window -{ - if (self = [super initWithNibName:nil bundle:nil]) { - self.window = _window; - -#ifdef SDL_IPHONE_KEYBOARD - [self initKeyboard]; - hidingKeyboard = NO; - rotatingOrientation = NO; -#endif - -#ifdef SDL_PLATFORM_TVOS - SDL_AddHintCallback(SDL_HINT_APPLE_TV_CONTROLLER_UI_EVENTS, - SDL_AppleTVControllerUIHintChanged, - (__bridge void *)self); -#endif - -#ifndef SDL_PLATFORM_TVOS - SDL_AddHintCallback(SDL_HINT_IOS_HIDE_HOME_INDICATOR, - SDL_HideHomeIndicatorHintChanged, - (__bridge void *)self); -#endif - - // Enable high refresh rates on iOS - // To enable this on phones, you should add the following line to Info.plist: - // CADisableMinimumFrameDurationOnPhone - if (@available(iOS 15.0, tvOS 15.0, *)) { - const SDL_DisplayMode *mode = SDL_GetDesktopDisplayMode(SDL_GetPrimaryDisplay()); - if (mode && mode->refresh_rate > 60.0f) { - int frame_rate = (int)mode->refresh_rate; - displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(doLoop:)]; - displayLink.preferredFrameRateRange = CAFrameRateRangeMake((frame_rate * 2) / 3, frame_rate, frame_rate); - [displayLink addToRunLoop:NSRunLoop.currentRunLoop forMode:NSDefaultRunLoopMode]; - } - } - } - return self; -} - -- (void)dealloc -{ -#ifdef SDL_IPHONE_KEYBOARD - [self deinitKeyboard]; -#endif - -#ifdef SDL_PLATFORM_TVOS - SDL_RemoveHintCallback(SDL_HINT_APPLE_TV_CONTROLLER_UI_EVENTS, - SDL_AppleTVControllerUIHintChanged, - (__bridge void *)self); -#endif - -#ifndef SDL_PLATFORM_TVOS - SDL_RemoveHintCallback(SDL_HINT_IOS_HIDE_HOME_INDICATOR, - SDL_HideHomeIndicatorHintChanged, - (__bridge void *)self); -#endif -} - -- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection -{ - SDL_SetSystemTheme(UIKit_GetSystemTheme()); -} - -- (void)setAnimationCallback:(int)interval - callback:(void (*)(void *))callback - callbackParam:(void *)callbackParam -{ - [self stopAnimation]; - - if (interval <= 0) { - interval = 1; - } - animationInterval = interval; - animationCallback = callback; - animationCallbackParam = callbackParam; - - if (animationCallback) { - [self startAnimation]; - } -} - -- (void)startAnimation -{ - displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(doLoop:)]; - -#ifdef SDL_PLATFORM_VISIONOS - displayLink.preferredFramesPerSecond = 90 / animationInterval; //TODO: Get frame max frame rate on visionOS -#else - SDL_UIKitWindowData *data = (__bridge SDL_UIKitWindowData *)window->internal; - - displayLink.preferredFramesPerSecond = data.uiwindow.screen.maximumFramesPerSecond / 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 (animationCallback && !UIKit_ShowingMessageBox()) { - // See the comment in the function definition. -#if defined(SDL_VIDEO_OPENGL_ES) || defined(SDL_VIDEO_OPENGL_ES2) - UIKit_GL_RestoreCurrentContext(); -#endif - - 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_EVENT_WINDOW_RESIZED, w, h); -} - -#ifndef SDL_PLATFORM_TVOS -- (NSUInteger)supportedInterfaceOrientations -{ - return UIKit_GetSupportedOrientations(window); -} - -- (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; - } -} - -- (BOOL)prefersPointerLocked -{ - return SDL_GCMouseRelativeMode() ? YES : NO; -} - -#endif // !SDL_PLATFORM_TVOS - -/* - ---- Keyboard related functionality below this line ---- - */ -#ifdef SDL_IPHONE_KEYBOARD - -@synthesize textInputRect; -@synthesize keyboardHeight; -@synthesize textFieldFocused; - -// Set ourselves up as a UITextFieldDelegate -- (void)initKeyboard -{ - obligateForBackspace = @" "; // 64 space - textField = [[SDLUITextField alloc] initWithFrame:CGRectZero]; - textField.delegate = self; - // placeholder so there is something to delete! - textField.text = obligateForBackspace; - committedText = textField.text; - - textField.hidden = YES; - textFieldFocused = NO; - - NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; -#ifndef SDL_PLATFORM_TVOS - [center addObserver:self - selector:@selector(keyboardWillShow:) - name:UIKeyboardWillShowNotification - object:nil]; - [center addObserver:self - selector:@selector(keyboardWillHide:) - name:UIKeyboardWillHideNotification - object:nil]; - [center addObserver:self - selector:@selector(keyboardDidHide:) - name:UIKeyboardDidHideNotification - object:nil]; -#endif - [center addObserver:self - selector:@selector(textFieldTextDidChange:) - name:UITextFieldTextDidChangeNotification - object:nil]; -} - -- (NSArray *)keyCommands -{ - NSMutableArray *commands = [[NSMutableArray alloc] init]; - [commands addObject:[UIKeyCommand keyCommandWithInput:UIKeyInputUpArrow modifierFlags:kNilOptions action:@selector(handleCommand:)]]; - [commands addObject:[UIKeyCommand keyCommandWithInput:UIKeyInputDownArrow modifierFlags:kNilOptions action:@selector(handleCommand:)]]; - [commands addObject:[UIKeyCommand keyCommandWithInput:UIKeyInputLeftArrow modifierFlags:kNilOptions action:@selector(handleCommand:)]]; - [commands addObject:[UIKeyCommand keyCommandWithInput:UIKeyInputRightArrow modifierFlags:kNilOptions action:@selector(handleCommand:)]]; - [commands addObject:[UIKeyCommand keyCommandWithInput:UIKeyInputEscape modifierFlags:kNilOptions action:@selector(handleCommand:)]]; - return [NSArray arrayWithArray:commands]; -} - -- (void)handleCommand:(UIKeyCommand *)keyCommand -{ - SDL_Scancode scancode = SDL_SCANCODE_UNKNOWN; - NSString *input = keyCommand.input; - - if (input == UIKeyInputUpArrow) { - scancode = SDL_SCANCODE_UP; - } else if (input == UIKeyInputDownArrow) { - scancode = SDL_SCANCODE_DOWN; - } else if (input == UIKeyInputLeftArrow) { - scancode = SDL_SCANCODE_LEFT; - } else if (input == UIKeyInputRightArrow) { - scancode = SDL_SCANCODE_RIGHT; - } else if (input == UIKeyInputEscape) { - scancode = SDL_SCANCODE_ESCAPE; - } - - if (scancode != SDL_SCANCODE_UNKNOWN) { - SDL_SendKeyboardKeyAutoRelease(0, scancode); - } -} - -- (void)setView:(UIView *)view -{ - [super setView:view]; - - [view addSubview:textField]; - - if (textFieldFocused) { - /* startTextInput has been called before the text field was added to the view, - * call it again for the text field to actually become first responder. */ - [self startTextInput]; - } -} - -- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id)coordinator -{ - [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator]; - rotatingOrientation = YES; - [coordinator - animateAlongsideTransition:^(id context) { - } - completion:^(id context) { - self->rotatingOrientation = NO; - }]; -} - -- (void)deinitKeyboard -{ - NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; -#ifndef SDL_PLATFORM_TVOS - [center removeObserver:self - name:UIKeyboardWillShowNotification - object:nil]; - [center removeObserver:self - name:UIKeyboardWillHideNotification - object:nil]; - [center removeObserver:self - name:UIKeyboardDidHideNotification - object:nil]; -#endif - [center removeObserver:self - name:UITextFieldTextDidChangeNotification - object:nil]; -} - -- (void)setTextFieldProperties:(SDL_PropertiesID) props -{ - textField.secureTextEntry = NO; - - switch (SDL_GetTextInputType(props)) { - default: - case SDL_TEXTINPUT_TYPE_TEXT: - textField.keyboardType = UIKeyboardTypeDefault; - textField.textContentType = nil; - break; - case SDL_TEXTINPUT_TYPE_TEXT_NAME: - textField.keyboardType = UIKeyboardTypeDefault; - textField.textContentType = UITextContentTypeName; - break; - case SDL_TEXTINPUT_TYPE_TEXT_EMAIL: - textField.keyboardType = UIKeyboardTypeEmailAddress; - textField.textContentType = UITextContentTypeEmailAddress; - break; - case SDL_TEXTINPUT_TYPE_TEXT_USERNAME: - textField.keyboardType = UIKeyboardTypeDefault; - textField.textContentType = UITextContentTypeUsername; - break; - case SDL_TEXTINPUT_TYPE_TEXT_PASSWORD_HIDDEN: - textField.keyboardType = UIKeyboardTypeDefault; - textField.textContentType = UITextContentTypePassword; - textField.secureTextEntry = YES; - break; - case SDL_TEXTINPUT_TYPE_TEXT_PASSWORD_VISIBLE: - textField.keyboardType = UIKeyboardTypeDefault; - textField.textContentType = UITextContentTypePassword; - break; - case SDL_TEXTINPUT_TYPE_NUMBER: - textField.keyboardType = UIKeyboardTypeDecimalPad; - textField.textContentType = nil; - break; - case SDL_TEXTINPUT_TYPE_NUMBER_PASSWORD_HIDDEN: - textField.keyboardType = UIKeyboardTypeNumberPad; - if (@available(iOS 12.0, tvOS 12.0, *)) { - textField.textContentType = UITextContentTypeOneTimeCode; - } else { - textField.textContentType = nil; - } - textField.secureTextEntry = YES; - break; - case SDL_TEXTINPUT_TYPE_NUMBER_PASSWORD_VISIBLE: - textField.keyboardType = UIKeyboardTypeNumberPad; - if (@available(iOS 12.0, tvOS 12.0, *)) { - textField.textContentType = UITextContentTypeOneTimeCode; - } else { - textField.textContentType = nil; - } - break; - } - - switch (SDL_GetTextInputCapitalization(props)) { - default: - case SDL_CAPITALIZE_NONE: - textField.autocapitalizationType = UITextAutocapitalizationTypeNone; - break; - case SDL_CAPITALIZE_LETTERS: - textField.autocapitalizationType = UITextAutocapitalizationTypeAllCharacters; - break; - case SDL_CAPITALIZE_WORDS: - textField.autocapitalizationType = UITextAutocapitalizationTypeWords; - break; - case SDL_CAPITALIZE_SENTENCES: - textField.autocapitalizationType = UITextAutocapitalizationTypeSentences; - break; - } - - if (SDL_GetTextInputAutocorrect(props)) { - textField.autocorrectionType = UITextAutocorrectionTypeYes; - textField.spellCheckingType = UITextSpellCheckingTypeYes; - } else { - textField.autocorrectionType = UITextAutocorrectionTypeNo; - textField.spellCheckingType = UITextSpellCheckingTypeNo; - } - - if (SDL_GetTextInputMultiline(props)) { - textField.enablesReturnKeyAutomatically = YES; - } else { - textField.enablesReturnKeyAutomatically = NO; - } - - if (!textField.window) { - /* textField has not been added to the view yet, - we don't have to do anything. */ - return; - } - - // the text field needs to be re-added to the view in order to update correctly. - UIView *superview = textField.superview; - [textField removeFromSuperview]; - [superview addSubview:textField]; - - if (SDL_TextInputActive(window)) { - [textField becomeFirstResponder]; - } -} - -/* requests the SDL text field to become focused and accept text input. - * also shows the onscreen virtual keyboard if no hardware keyboard is attached. */ -- (bool)startTextInput -{ - textFieldFocused = YES; - if (!textField.window) { - /* textField has not been added to the view yet, - * we will try again when that happens. */ - return true; - } - - return [textField becomeFirstResponder]; -} - -/* requests the SDL text field to lose focus and stop accepting text input. - * also hides the onscreen virtual keyboard if no hardware keyboard is attached. */ -- (bool)stopTextInput -{ - textFieldFocused = NO; - if (!textField.window) { - /* textField has not been added to the view yet, - * we will try again when that happens. */ - return true; - } - - [self resetTextState]; - return [textField resignFirstResponder]; -} - -- (void)keyboardWillShow:(NSNotification *)notification -{ -#ifndef SDL_PLATFORM_TVOS - 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 - - /* A keyboard hide transition has been interrupted with a show (keyboardWillHide has been called but keyboardDidHide didn't). - * since text input was stopped by the hide, we have to start it again. */ - if (hidingKeyboard) { - SDL_StartTextInput(window); - hidingKeyboard = NO; - } -} - -- (void)keyboardWillHide:(NSNotification *)notification -{ - hidingKeyboard = YES; - [self setKeyboardHeight:0]; - - /* When the user dismisses the software keyboard by the "hide" button in the bottom right corner, - * we want to reflect that on SDL_TextInputActive by calling SDL_StopTextInput...on certain conditions */ - if (SDL_TextInputActive(window) - /* keyboardWillHide gets called when a hardware keyboard is attached, - * keep text input state active if hiding while there is a hardware keyboard. - * if the hardware keyboard gets detached, the software keyboard will appear anyway. */ - && !SDL_HasKeyboard() - /* When the device changes orientation, a sequence of hide and show transitions are triggered. - * keep text input state active in this case. */ - && !rotatingOrientation) { - SDL_StopTextInput(window); - } -} - -- (void)keyboardDidHide:(NSNotification *)notification -{ - hidingKeyboard = NO; -} - -- (void)textFieldTextDidChange:(NSNotification *)notification -{ - if (textField.markedTextRange == nil) { - NSUInteger compareLength = SDL_min(textField.text.length, committedText.length); - NSUInteger matchLength; - - // Backspace over characters that are no longer in the string - for (matchLength = 0; matchLength < compareLength; ++matchLength) { - if ([committedText characterAtIndex:matchLength] != [textField.text characterAtIndex:matchLength]) { - break; - } - } - if (matchLength < committedText.length) { - size_t deleteLength = SDL_utf8strlen([[committedText substringFromIndex:matchLength] UTF8String]); - while (deleteLength > 0) { - // Send distinct down and up events for each backspace action - SDL_SendKeyboardKey(0, SDL_GLOBAL_KEYBOARD_ID, 0, SDL_SCANCODE_BACKSPACE, true); - SDL_SendKeyboardKey(0, SDL_GLOBAL_KEYBOARD_ID, 0, SDL_SCANCODE_BACKSPACE, false); - --deleteLength; - } - } - - if (matchLength < textField.text.length) { - NSString *pendingText = [textField.text substringFromIndex:matchLength]; - if (!SDL_HardwareKeyboardKeyPressed()) { - /* Go through all the characters in the string we've been sent and - * convert them to key presses */ - NSUInteger i; - for (i = 0; i < pendingText.length; i++) { - SDL_SendKeyboardUnicodeKey(0, [pendingText characterAtIndex:i]); - } - } - SDL_SendKeyboardText([pendingText UTF8String]); - } - committedText = textField.text; - } -} - -- (void)updateKeyboard -{ - SDL_UIKitWindowData *data = (__bridge SDL_UIKitWindowData *) window->internal; - - CGAffineTransform t = self.view.transform; - CGPoint offset = CGPointMake(0.0, 0.0); -#ifdef SDL_PLATFORM_VISIONOS - CGRect frame = UIKit_ComputeViewFrame(window); -#else - CGRect frame = UIKit_ComputeViewFrame(window, data.uiwindow.screen); -#endif - - if (self.keyboardHeight && self.textInputRect.h) { - int rectbottom = (int)(self.textInputRect.y + self.textInputRect.h); - int keybottom = (int)(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 -{ - keyboardHeight = height; - [self updateKeyboard]; -} - -// UITextFieldDelegate method. Invoked when user types something. -- (BOOL)textField:(UITextField *)_textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string -{ - if (textField.markedTextRange == nil) { - if (textField.text.length < 16) { - [self resetTextState]; - } - } - return YES; -} - -// Terminates the editing session -- (BOOL)textFieldShouldReturn:(UITextField *)_textField -{ - SDL_SendKeyboardKeyAutoRelease(0, SDL_SCANCODE_RETURN); - if (textFieldFocused && - SDL_GetHintBoolean(SDL_HINT_RETURN_KEY_HIDES_IME, false)) { - SDL_StopTextInput(window); - } - return YES; -} - -- (void)resetTextState -{ - textField.text = obligateForBackspace; - committedText = textField.text; -} - -#endif - -@end - -// iPhone keyboard addition functions -#ifdef SDL_IPHONE_KEYBOARD - -static SDL_uikitviewcontroller *GetWindowViewController(SDL_Window *window) -{ - if (!window || !window->internal) { - SDL_SetError("Invalid window"); - return nil; - } - - SDL_UIKitWindowData *data = (__bridge SDL_UIKitWindowData *)window->internal; - - return data.viewcontroller; -} - -bool UIKit_HasScreenKeyboardSupport(SDL_VideoDevice *_this) -{ - return true; -} - -bool UIKit_StartTextInput(SDL_VideoDevice *_this, SDL_Window *window, SDL_PropertiesID props) -{ - @autoreleasepool { - SDL_uikitviewcontroller *vc = GetWindowViewController(window); - return [vc startTextInput]; - } -} - -bool UIKit_StopTextInput(SDL_VideoDevice *_this, SDL_Window *window) -{ - @autoreleasepool { - SDL_uikitviewcontroller *vc = GetWindowViewController(window); - return [vc stopTextInput]; - } -} - -void UIKit_SetTextInputProperties(SDL_VideoDevice *_this, SDL_Window *window, SDL_PropertiesID props) -{ - @autoreleasepool { - SDL_uikitviewcontroller *vc = GetWindowViewController(window); - [vc setTextFieldProperties:props]; - } -} - -bool UIKit_IsScreenKeyboardShown(SDL_VideoDevice *_this, SDL_Window *window) -{ - @autoreleasepool { - SDL_uikitviewcontroller *vc = GetWindowViewController(window); - if (vc != nil) { - return vc.textFieldFocused; - } - return false; - } -} - -bool UIKit_UpdateTextInputArea(SDL_VideoDevice *_this, SDL_Window *window) -{ - @autoreleasepool { - SDL_uikitviewcontroller *vc = GetWindowViewController(window); - if (vc != nil) { - vc.textInputRect = window->text_input_rect; - - if (vc.textFieldFocused) { - [vc updateKeyboard]; - } - } - } - return true; -} - -#endif // SDL_IPHONE_KEYBOARD - -#endif // SDL_VIDEO_DRIVER_UIKIT diff --git a/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitvulkan.h b/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitvulkan.h deleted file mode 100644 index 6957670..0000000 --- a/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitvulkan.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2025 Sam Lantinga - - 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 defined(SDL_VIDEO_VULKAN) && defined(SDL_VIDEO_DRIVER_UIKIT) - -extern bool UIKit_Vulkan_LoadLibrary(SDL_VideoDevice *_this, const char *path); -extern void UIKit_Vulkan_UnloadLibrary(SDL_VideoDevice *_this); -extern char const* const* UIKit_Vulkan_GetInstanceExtensions(SDL_VideoDevice *_this, Uint32 *count); -extern bool UIKit_Vulkan_CreateSurface(SDL_VideoDevice *_this, - SDL_Window *window, - VkInstance instance, - const struct VkAllocationCallbacks *allocator, - VkSurfaceKHR *surface); -extern void UIKit_Vulkan_DestroySurface(SDL_VideoDevice *_this, - VkInstance instance, - VkSurfaceKHR surface, - const struct VkAllocationCallbacks *allocator); - -#endif - -#endif // SDL_uikitvulkan_h_ diff --git a/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitvulkan.m b/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitvulkan.m deleted file mode 100644 index 332593b..0000000 --- a/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitvulkan.m +++ /dev/null @@ -1,265 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2025 Sam Lantinga - - 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 defined(SDL_VIDEO_VULKAN) && defined(SDL_VIDEO_DRIVER_UIKIT) - -#include "SDL_uikitvideo.h" -#include "SDL_uikitwindow.h" - -#include "SDL_uikitvulkan.h" -#include "SDL_uikitmetalview.h" - -#include - -const char *defaultPaths[] = { - "libvulkan.dylib", -}; - -/* Since libSDL is static, could use RTLD_SELF. Using RTLD_DEFAULT is future - * proofing. */ -#define DEFAULT_HANDLE RTLD_DEFAULT - -bool UIKit_Vulkan_LoadLibrary(SDL_VideoDevice *_this, const char *path) -{ - VkExtensionProperties *extensions = NULL; - Uint32 extensionCount = 0; - bool hasSurfaceExtension = false; - bool hasMetalSurfaceExtension = false; - bool hasIOSSurfaceExtension = false; - PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = NULL; - - if (_this->vulkan_config.loader_handle) { - return SDL_SetError("Vulkan Portability library is already loaded."); - } - - // Load the Vulkan loader library - if (!path) { - path = SDL_GetHint(SDL_HINT_VULKAN_LIBRARY); - } - - if (!path) { - // Handle the case where Vulkan Portability is linked statically. - vkGetInstanceProcAddr = - (PFN_vkGetInstanceProcAddr)dlsym(DEFAULT_HANDLE, - "vkGetInstanceProcAddr"); - } - - if (vkGetInstanceProcAddr) { - _this->vulkan_config.loader_handle = DEFAULT_HANDLE; - } else { - const char **paths; - const char *foundPath = NULL; - int numPaths; - int i; - - if (path) { - paths = &path; - numPaths = 1; - } else { - // Look for the .dylib packaged with the application instead. - paths = defaultPaths; - numPaths = SDL_arraysize(defaultPaths); - } - - for (i = 0; i < numPaths && _this->vulkan_config.loader_handle == NULL; i++) { - foundPath = paths[i]; - _this->vulkan_config.loader_handle = SDL_LoadObject(foundPath); - } - - if (_this->vulkan_config.loader_handle == NULL) { - return SDL_SetError("Failed to load Vulkan Portability library"); - } - - 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", - "linked Vulkan Portability library", - (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 = true; - } else if (SDL_strcmp(VK_EXT_METAL_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0) { - hasMetalSurfaceExtension = true; - } else if (SDL_strcmp(VK_MVK_IOS_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0) { - hasIOSSurfaceExtension = true; - } - } - - SDL_free(extensions); - - if (!hasSurfaceExtension) { - SDL_SetError("Installed Vulkan Portability doesn't implement the " VK_KHR_SURFACE_EXTENSION_NAME " extension"); - goto fail; - } else if (!hasMetalSurfaceExtension && !hasIOSSurfaceExtension) { - SDL_SetError("Installed Vulkan Portability doesn't implement the " VK_EXT_METAL_SURFACE_EXTENSION_NAME " or " VK_MVK_IOS_SURFACE_EXTENSION_NAME " extensions"); - goto fail; - } - - return true; - -fail: - _this->vulkan_config.loader_handle = NULL; - return false; -} - -void UIKit_Vulkan_UnloadLibrary(SDL_VideoDevice *_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; - } -} - -char const* const* UIKit_Vulkan_GetInstanceExtensions(SDL_VideoDevice *_this, - Uint32 *count) -{ - static const char *const extensionsForUIKit[] = { - VK_KHR_SURFACE_EXTENSION_NAME, VK_EXT_METAL_SURFACE_EXTENSION_NAME - }; - if(count) { - *count = SDL_arraysize(extensionsForUIKit); - } - return extensionsForUIKit; -} - -bool UIKit_Vulkan_CreateSurface(SDL_VideoDevice *_this, - SDL_Window *window, - VkInstance instance, - const struct VkAllocationCallbacks *allocator, - VkSurfaceKHR *surface) -{ - PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = - (PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr; - PFN_vkCreateMetalSurfaceEXT vkCreateMetalSurfaceEXT = - (PFN_vkCreateMetalSurfaceEXT)vkGetInstanceProcAddr( - (VkInstance)instance, - "vkCreateMetalSurfaceEXT"); - PFN_vkCreateIOSSurfaceMVK vkCreateIOSSurfaceMVK = - (PFN_vkCreateIOSSurfaceMVK)vkGetInstanceProcAddr( - (VkInstance)instance, - "vkCreateIOSSurfaceMVK"); - VkResult result; - SDL_MetalView metalview; - - if (!_this->vulkan_config.loader_handle) { - return SDL_SetError("Vulkan is not loaded"); - } - - if (!vkCreateMetalSurfaceEXT && !vkCreateIOSSurfaceMVK) { - return SDL_SetError(VK_EXT_METAL_SURFACE_EXTENSION_NAME " or " VK_MVK_IOS_SURFACE_EXTENSION_NAME - " extensions are not enabled in the Vulkan instance."); - } - - metalview = UIKit_Metal_CreateView(_this, window); - if (metalview == NULL) { - return false; - } - - if (vkCreateMetalSurfaceEXT) { - VkMetalSurfaceCreateInfoEXT createInfo = {}; - createInfo.sType = VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT; - createInfo.pNext = NULL; - createInfo.flags = 0; - createInfo.pLayer = (__bridge const CAMetalLayer *) - UIKit_Metal_GetLayer(_this, metalview); - result = vkCreateMetalSurfaceEXT(instance, &createInfo, allocator, surface); - if (result != VK_SUCCESS) { - UIKit_Metal_DestroyView(_this, metalview); - return SDL_SetError("vkCreateMetalSurfaceEXT failed: %s", SDL_Vulkan_GetResultString(result)); - } - } else { - VkIOSSurfaceCreateInfoMVK createInfo = {}; - createInfo.sType = VK_STRUCTURE_TYPE_IOS_SURFACE_CREATE_INFO_MVK; - createInfo.pNext = NULL; - createInfo.flags = 0; - createInfo.pView = (const void *)metalview; - result = vkCreateIOSSurfaceMVK(instance, &createInfo, - allocator, surface); - if (result != VK_SUCCESS) { - UIKit_Metal_DestroyView(_this, metalview); - return SDL_SetError("vkCreateIOSSurfaceMVK failed: %s", SDL_Vulkan_GetResultString(result)); - } - } - - /* Unfortunately there's no SDL_Vulkan_DestroySurface function we can call - * Metal_DestroyView from. Right now the metal view's ref count is +2 (one - * from returning a new view object in CreateView, and one because it's - * a subview of the window.) If we release the view here to make it +1, it - * will be destroyed when the window is destroyed. - * - * TODO: Now that we have SDL_Vulkan_DestroySurface someone with enough - * knowledge of Metal can proceed. */ - CFBridgingRelease(metalview); - - return true; -} - -void UIKit_Vulkan_DestroySurface(SDL_VideoDevice *_this, - VkInstance instance, - VkSurfaceKHR surface, - const struct VkAllocationCallbacks *allocator) -{ - if (_this->vulkan_config.loader_handle) { - SDL_Vulkan_DestroySurface_Internal(_this->vulkan_config.vkGetInstanceProcAddr, instance, surface, allocator); - // TODO: Add CFBridgingRelease(metalview) here perhaps? - } -} - -#endif diff --git a/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitwindow.h b/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitwindow.h deleted file mode 100644 index da1fb63..0000000 --- a/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitwindow.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2025 Sam Lantinga - - 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 bool UIKit_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_PropertiesID create_props); -extern void UIKit_SetWindowTitle(SDL_VideoDevice *_this, SDL_Window *window); -extern void UIKit_ShowWindow(SDL_VideoDevice *_this, SDL_Window *window); -extern void UIKit_HideWindow(SDL_VideoDevice *_this, SDL_Window *window); -extern void UIKit_RaiseWindow(SDL_VideoDevice *_this, SDL_Window *window); -extern void UIKit_SetWindowBordered(SDL_VideoDevice *_this, SDL_Window *window, bool bordered); -extern SDL_FullscreenResult UIKit_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window *window, SDL_VideoDisplay *display, SDL_FullscreenOp fullscreen); -extern void UIKit_UpdatePointerLock(SDL_VideoDevice *_this, SDL_Window *window); -extern void UIKit_DestroyWindow(SDL_VideoDevice *_this, SDL_Window *window); -extern void UIKit_GetWindowSizeInPixels(SDL_VideoDevice *_this, SDL_Window *window, int *w, int *h); - -extern NSUInteger UIKit_GetSupportedOrientations(SDL_Window *window); - -#define SDL_METALVIEW_TAG 255 - -@class UIWindow; - -@interface SDL_UIKitWindowData : 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_ diff --git a/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitwindow.m b/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitwindow.m deleted file mode 100644 index 2b258b1..0000000 --- a/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitwindow.m +++ /dev/null @@ -1,471 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2025 Sam Lantinga - - 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" - -#ifdef SDL_VIDEO_DRIVER_UIKIT - -#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_uikitappdelegate.h" -#include "SDL_uikitview.h" -#include "SDL_uikitopenglview.h" - -#include - -@implementation SDL_UIKitWindowData - -@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 -{ -#ifndef SDL_PLATFORM_VISIONOS - // Workaround to fix window orientation issues in iOS 8. - /* As of July 1 2019, I haven't been able to reproduce any orientation - * issues with this disabled on iOS 12. The issue this is meant to fix might - * only happen on iOS 8, or it might have been fixed another way with other - * code... This code prevents split view (iOS 9+) from working on iPads, so - * we want to avoid using it if possible. */ - if (!UIKit_IsSystemVersionAtLeast(9.0)) { - self.frame = self.screen.bounds; - } -#endif - [super layoutSubviews]; -} - -@end - -static bool SetupWindowData(SDL_VideoDevice *_this, SDL_Window *window, UIWindow *uiwindow, bool created) -{ - SDL_VideoDisplay *display = SDL_GetVideoDisplayForWindow(window); - SDL_UIKitDisplayData *displaydata = (__bridge SDL_UIKitDisplayData *)display->internal; - SDL_uikitview *view; - -#ifdef SDL_PLATFORM_VISIONOS - CGRect frame = UIKit_ComputeViewFrame(window); -#else - CGRect frame = UIKit_ComputeViewFrame(window, displaydata.uiscreen); -#endif - - int width = (int)frame.size.width; - int height = (int)frame.size.height; - - SDL_UIKitWindowData *data = [[SDL_UIKitWindowData alloc] init]; - if (!data) { - return SDL_OutOfMemory(); - } - - window->internal = (SDL_WindowData *)CFBridgingRetain(data); - - data.uiwindow = uiwindow; - -#ifndef SDL_PLATFORM_VISIONOS - 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. - } -#endif - -#if !defined(SDL_PLATFORM_TVOS) && !defined(SDL_PLATFORM_VISIONOS) - if (displaydata.uiscreen == [UIScreen mainScreen]) { - 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 // !SDL_PLATFORM_TVOS - -#if 0 // Don't set the x/y position, it's already placed on a display - window->x = 0; - window->y = 0; -#endif - 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 - * hierarchy. */ - [view setSDLWindow:window]; - - SDL_PropertiesID props = SDL_GetWindowProperties(window); - SDL_SetPointerProperty(props, SDL_PROP_WINDOW_UIKIT_WINDOW_POINTER, (__bridge void *)data.uiwindow); - SDL_SetNumberProperty(props, SDL_PROP_WINDOW_UIKIT_METAL_VIEW_TAG_NUMBER, SDL_METALVIEW_TAG); - - return true; -} - -bool UIKit_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_PropertiesID create_props) -{ - @autoreleasepool { - SDL_VideoDisplay *display = SDL_GetVideoDisplayForWindow(window); - SDL_UIKitDisplayData *data = (__bridge SDL_UIKitDisplayData *)display->internal; - SDL_Window *other; - - // We currently only handle a single window per display on iOS - for (other = _this->windows; other; other = other->next) { - if (other != window && SDL_GetVideoDisplayForWindow(other) == display) { - return SDL_SetError("Only one window allowed per display."); - } - } - - /* If monitor has a resolution of 0x0 (hasn't been explicitly set by the - * user, so it's in standby), try to force the display to a resolution - * that most closely matches the desired window size. */ -#if !defined(SDL_PLATFORM_TVOS) && !defined(SDL_PLATFORM_VISIONOS) - const CGSize origsize = data.uiscreen.currentMode.size; - if ((origsize.width == 0.0f) && (origsize.height == 0.0f)) { - SDL_DisplayMode bestmode; - bool include_high_density_modes = false; - if (window->flags & SDL_WINDOW_HIGH_PIXEL_DENSITY) { - include_high_density_modes = true; - } - if (SDL_GetClosestFullscreenDisplayMode(display->id, window->w, window->h, 0.0f, include_high_density_modes, &bestmode)) { - SDL_UIKitDisplayModeData *modedata = (__bridge SDL_UIKitDisplayModeData *)bestmode.internal; - [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. */ - SDL_SetCurrentDisplayMode(display, &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 // !SDL_PLATFORM_TVOS - - // ignore the size user requested, and make a fullscreen window - // !!! FIXME: can we have a smaller view? -#ifdef SDL_PLATFORM_VISIONOS - UIWindow *uiwindow = [[SDL_uikitwindow alloc] initWithFrame:CGRectMake(window->x, window->y, window->w, window->h)]; -#else - UIWindow *uiwindow = [[SDL_uikitwindow alloc] initWithFrame:data.uiscreen.bounds]; -#endif - - // put the window on an external display if appropriate. -#ifndef SDL_PLATFORM_VISIONOS - if (data.uiscreen != [UIScreen mainScreen]) { - [uiwindow setScreen:data.uiscreen]; - } -#endif - - if (!SetupWindowData(_this, window, uiwindow, true)) { - return false; - } - } - - return true; -} - -void UIKit_SetWindowTitle(SDL_VideoDevice *_this, SDL_Window *window) -{ - @autoreleasepool { - SDL_UIKitWindowData *data = (__bridge SDL_UIKitWindowData *)window->internal; - data.viewcontroller.title = @(window->title); - } -} - -void UIKit_ShowWindow(SDL_VideoDevice *_this, SDL_Window *window) -{ - @autoreleasepool { - SDL_UIKitWindowData *data = (__bridge SDL_UIKitWindowData *)window->internal; - [data.uiwindow makeKeyAndVisible]; - - // Make this window the current mouse focus for touch input - SDL_VideoDisplay *display = SDL_GetVideoDisplayForWindow(window); - SDL_UIKitDisplayData *displaydata = (__bridge SDL_UIKitDisplayData *)display->internal; -#ifndef SDL_PLATFORM_VISIONOS - if (displaydata.uiscreen == [UIScreen mainScreen]) -#endif - { - SDL_SetMouseFocus(window); - SDL_SetKeyboardFocus(window); - } - } -} - -void UIKit_HideWindow(SDL_VideoDevice *_this, SDL_Window *window) -{ - @autoreleasepool { - SDL_UIKitWindowData *data = (__bridge SDL_UIKitWindowData *)window->internal; - data.uiwindow.hidden = YES; - } -} - -void UIKit_RaiseWindow(SDL_VideoDevice *_this, SDL_Window *window) -{ -#if defined(SDL_VIDEO_OPENGL_ES) || defined(SDL_VIDEO_OPENGL_ES2) - /* 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); -#endif -} - -static void UIKit_UpdateWindowBorder(SDL_VideoDevice *_this, SDL_Window *window) -{ - SDL_UIKitWindowData *data = (__bridge SDL_UIKitWindowData *)window->internal; - SDL_uikitviewcontroller *viewcontroller = data.viewcontroller; - -#if !defined(SDL_PLATFORM_TVOS) && !defined(SDL_PLATFORM_VISIONOS) - if (data.uiwindow.screen == [UIScreen mainScreen]) { - if (window->flags & (SDL_WINDOW_FULLSCREEN | SDL_WINDOW_BORDERLESS)) { - [UIApplication sharedApplication].statusBarHidden = YES; - } else { - [UIApplication sharedApplication].statusBarHidden = NO; - } - - [viewcontroller setNeedsStatusBarAppearanceUpdate]; - } - - // Update the view's frame to account for the status bar change. - viewcontroller.view.frame = UIKit_ComputeViewFrame(window, data.uiwindow.screen); -#endif // !SDL_PLATFORM_TVOS - -#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(SDL_VideoDevice *_this, SDL_Window *window, bool bordered) -{ - @autoreleasepool { - if (bordered) { - window->flags &= ~SDL_WINDOW_BORDERLESS; - } else { - window->flags |= SDL_WINDOW_BORDERLESS; - } - UIKit_UpdateWindowBorder(_this, window); - } -} - -SDL_FullscreenResult UIKit_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window *window, SDL_VideoDisplay *display, SDL_FullscreenOp fullscreen) -{ - @autoreleasepool { - SDL_SendWindowEvent(window, fullscreen ? SDL_EVENT_WINDOW_ENTER_FULLSCREEN : SDL_EVENT_WINDOW_LEAVE_FULLSCREEN, 0, 0); - UIKit_UpdateWindowBorder(_this, window); - } - return SDL_FULLSCREEN_SUCCEEDED; -} - -void UIKit_UpdatePointerLock(SDL_VideoDevice *_this, SDL_Window *window) -{ -#ifndef SDL_PLATFORM_TVOS - @autoreleasepool { - SDL_UIKitWindowData *data = (__bridge SDL_UIKitWindowData *)window->internal; - SDL_uikitviewcontroller *viewcontroller = data.viewcontroller; - if (@available(iOS 14.0, *)) { - [viewcontroller setNeedsUpdateOfPrefersPointerLocked]; - } - } -#endif // !SDL_PLATFORM_TVOS -} - -void UIKit_DestroyWindow(SDL_VideoDevice *_this, SDL_Window *window) -{ - @autoreleasepool { - if (window->internal != NULL) { - SDL_UIKitWindowData *data = (__bridge SDL_UIKitWindowData *)window->internal; - 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; - - CFRelease(window->internal); - window->internal = NULL; - } - } -} - -void UIKit_GetWindowSizeInPixels(SDL_VideoDevice *_this, SDL_Window *window, int *w, int *h) -{ - @autoreleasepool { - SDL_UIKitWindowData *windata = (__bridge SDL_UIKitWindowData *)window->internal; - UIView *view = windata.viewcontroller.view; - CGSize size = view.bounds.size; - CGFloat scale = 1.0; - - - if (window->flags & SDL_WINDOW_HIGH_PIXEL_DENSITY) { -#ifndef SDL_PLATFORM_VISIONOS - scale = windata.uiwindow.screen.nativeScale; -#else - scale = 2.0; -#endif - } - - - /* Integer truncation of fractional values matches SDL_uikitmetalview and - * SDL_uikitopenglview. */ - *w = (int)(size.width * scale); - *h = (int)(size.height * scale); - } -} - -#ifndef SDL_PLATFORM_TVOS -NSUInteger -UIKit_GetSupportedOrientations(SDL_Window *window) -{ - const char *hint = SDL_GetHint(SDL_HINT_ORIENTATIONS); - NSUInteger validOrientations = UIInterfaceOrientationMaskAll; - NSUInteger orientationMask = 0; - - @autoreleasepool { - SDL_UIKitWindowData *data = (__bridge SDL_UIKitWindowData *)window->internal; - 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 { - 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->floating.w >= window->floating.h) { - orientationMask |= UIInterfaceOrientationMaskLandscape; - } - if (window->floating.h >= window->floating.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 // !SDL_PLATFORM_TVOS - -bool SDL_SetiOSAnimationCallback(SDL_Window *window, int interval, SDL_iOSAnimationCallback callback, void *callbackParam) -{ - if (!window || !window->internal) { - return SDL_SetError("Invalid window"); - } - - @autoreleasepool { - SDL_UIKitWindowData *data = (__bridge SDL_UIKitWindowData *)window->internal; - [data.viewcontroller setAnimationCallback:interval - callback:callback - callbackParam:callbackParam]; - } - - return true; -} - -#endif // SDL_VIDEO_DRIVER_UIKIT -- cgit v1.2.3