summaryrefslogtreecommitdiff
path: root/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitvideo.m
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/SDL-3.2.8/src/video/uikit/SDL_uikitvideo.m')
-rw-r--r--contrib/SDL-3.2.8/src/video/uikit/SDL_uikitvideo.m312
1 files changed, 312 insertions, 0 deletions
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
new file mode 100644
index 0000000..5c3987d
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/video/uikit/SDL_uikitvideo.m
@@ -0,0 +1,312 @@
1/*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
4
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
20*/
21#include "SDL_internal.h"
22
23#ifdef SDL_VIDEO_DRIVER_UIKIT
24
25#import <UIKit/UIKit.h>
26
27#include "../SDL_sysvideo.h"
28#include "../SDL_pixels_c.h"
29#include "../../events/SDL_events_c.h"
30
31#include "SDL_uikitvideo.h"
32#include "SDL_uikitevents.h"
33#include "SDL_uikitmodes.h"
34#include "SDL_uikitwindow.h"
35#include "SDL_uikitopengles.h"
36#include "SDL_uikitclipboard.h"
37#include "SDL_uikitvulkan.h"
38#include "SDL_uikitmetalview.h"
39#include "SDL_uikitmessagebox.h"
40
41#define UIKITVID_DRIVER_NAME "uikit"
42
43@implementation SDL_UIKitVideoData
44
45@end
46
47// Initialization/Query functions
48static bool UIKit_VideoInit(SDL_VideoDevice *_this);
49static void UIKit_VideoQuit(SDL_VideoDevice *_this);
50
51// DUMMY driver bootstrap functions
52
53static void UIKit_DeleteDevice(SDL_VideoDevice *device)
54{
55 @autoreleasepool {
56 if (device->internal){
57 CFRelease(device->internal);
58 }
59 SDL_free(device);
60 }
61}
62
63static SDL_VideoDevice *UIKit_CreateDevice(void)
64{
65 @autoreleasepool {
66 SDL_VideoDevice *device;
67 SDL_UIKitVideoData *data;
68
69 // Initialize all variables that we clean on shutdown
70 device = (SDL_VideoDevice *)SDL_calloc(1, sizeof(SDL_VideoDevice));
71 if (!device) {
72 return NULL;
73 }
74
75 data = [SDL_UIKitVideoData new];
76
77 device->internal = (SDL_VideoData *)CFBridgingRetain(data);
78 device->system_theme = UIKit_GetSystemTheme();
79
80 // Set the function pointers
81 device->VideoInit = UIKit_VideoInit;
82 device->VideoQuit = UIKit_VideoQuit;
83 device->GetDisplayModes = UIKit_GetDisplayModes;
84 device->SetDisplayMode = UIKit_SetDisplayMode;
85 device->PumpEvents = UIKit_PumpEvents;
86 device->SuspendScreenSaver = UIKit_SuspendScreenSaver;
87 device->CreateSDLWindow = UIKit_CreateWindow;
88 device->SetWindowTitle = UIKit_SetWindowTitle;
89 device->ShowWindow = UIKit_ShowWindow;
90 device->HideWindow = UIKit_HideWindow;
91 device->RaiseWindow = UIKit_RaiseWindow;
92 device->SetWindowBordered = UIKit_SetWindowBordered;
93 device->SetWindowFullscreen = UIKit_SetWindowFullscreen;
94 device->DestroyWindow = UIKit_DestroyWindow;
95 device->GetDisplayUsableBounds = UIKit_GetDisplayUsableBounds;
96 device->GetWindowSizeInPixels = UIKit_GetWindowSizeInPixels;
97
98#ifdef SDL_IPHONE_KEYBOARD
99 device->HasScreenKeyboardSupport = UIKit_HasScreenKeyboardSupport;
100 device->StartTextInput = UIKit_StartTextInput;
101 device->StopTextInput = UIKit_StopTextInput;
102 device->SetTextInputProperties = UIKit_SetTextInputProperties;
103 device->IsScreenKeyboardShown = UIKit_IsScreenKeyboardShown;
104 device->UpdateTextInputArea = UIKit_UpdateTextInputArea;
105#endif
106
107 device->SetClipboardText = UIKit_SetClipboardText;
108 device->GetClipboardText = UIKit_GetClipboardText;
109 device->HasClipboardText = UIKit_HasClipboardText;
110
111 // OpenGL (ES) functions
112#if defined(SDL_VIDEO_OPENGL_ES) || defined(SDL_VIDEO_OPENGL_ES2)
113 device->GL_MakeCurrent = UIKit_GL_MakeCurrent;
114 device->GL_SwapWindow = UIKit_GL_SwapWindow;
115 device->GL_CreateContext = UIKit_GL_CreateContext;
116 device->GL_DestroyContext = UIKit_GL_DestroyContext;
117 device->GL_GetProcAddress = UIKit_GL_GetProcAddress;
118 device->GL_LoadLibrary = UIKit_GL_LoadLibrary;
119#endif
120 device->free = UIKit_DeleteDevice;
121
122#ifdef SDL_VIDEO_VULKAN
123 device->Vulkan_LoadLibrary = UIKit_Vulkan_LoadLibrary;
124 device->Vulkan_UnloadLibrary = UIKit_Vulkan_UnloadLibrary;
125 device->Vulkan_GetInstanceExtensions = UIKit_Vulkan_GetInstanceExtensions;
126 device->Vulkan_CreateSurface = UIKit_Vulkan_CreateSurface;
127 device->Vulkan_DestroySurface = UIKit_Vulkan_DestroySurface;
128#endif
129
130#ifdef SDL_VIDEO_METAL
131 device->Metal_CreateView = UIKit_Metal_CreateView;
132 device->Metal_DestroyView = UIKit_Metal_DestroyView;
133 device->Metal_GetLayer = UIKit_Metal_GetLayer;
134#endif
135
136 device->device_caps = VIDEO_DEVICE_CAPS_SENDS_FULLSCREEN_DIMENSIONS;
137
138 device->gl_config.accelerated = 1;
139
140 return device;
141 }
142}
143
144VideoBootStrap UIKIT_bootstrap = {
145 UIKITVID_DRIVER_NAME, "SDL UIKit video driver",
146 UIKit_CreateDevice,
147 UIKit_ShowMessageBox,
148 false
149};
150
151static bool UIKit_VideoInit(SDL_VideoDevice *_this)
152{
153 _this->gl_config.driver_loaded = 1;
154
155 if (!UIKit_InitModes(_this)) {
156 return false;
157 }
158
159 SDL_InitGCKeyboard();
160 SDL_InitGCMouse();
161
162 UIKit_InitClipboard(_this);
163
164 return true;
165}
166
167static void UIKit_VideoQuit(SDL_VideoDevice *_this)
168{
169 UIKit_QuitClipboard(_this);
170
171 SDL_QuitGCKeyboard();
172 SDL_QuitGCMouse();
173
174 UIKit_QuitModes(_this);
175}
176
177bool UIKit_SuspendScreenSaver(SDL_VideoDevice *_this)
178{
179 @autoreleasepool {
180 UIApplication *app = [UIApplication sharedApplication];
181
182 // Prevent the display from dimming and going to sleep.
183 app.idleTimerDisabled = (_this->suspend_screensaver != false);
184 }
185 return true;
186}
187
188bool UIKit_IsSystemVersionAtLeast(double version)
189{
190 return [[UIDevice currentDevice].systemVersion doubleValue] >= version;
191}
192
193SDL_SystemTheme UIKit_GetSystemTheme(void)
194{
195#ifndef SDL_PLATFORM_VISIONOS
196 if (@available(iOS 12.0, tvOS 10.0, *)) {
197 switch ([UIScreen mainScreen].traitCollection.userInterfaceStyle) {
198 case UIUserInterfaceStyleDark:
199 return SDL_SYSTEM_THEME_DARK;
200 case UIUserInterfaceStyleLight:
201 return SDL_SYSTEM_THEME_LIGHT;
202 default:
203 break;
204 }
205 }
206#endif
207 return SDL_SYSTEM_THEME_UNKNOWN;
208}
209
210#ifdef SDL_PLATFORM_VISIONOS
211CGRect UIKit_ComputeViewFrame(SDL_Window *window){
212 return CGRectMake(window->x, window->y, window->w, window->h);
213}
214#else
215CGRect UIKit_ComputeViewFrame(SDL_Window *window, UIScreen *screen)
216{
217 SDL_UIKitWindowData *data = (__bridge SDL_UIKitWindowData *)window->internal;
218 CGRect frame = screen.bounds;
219
220 /* Use the UIWindow bounds instead of the UIScreen bounds, when possible.
221 * The uiwindow bounds may be smaller than the screen bounds when Split View
222 * is used on an iPad. */
223 if (data != nil && data.uiwindow != nil) {
224 frame = data.uiwindow.bounds;
225 }
226
227#ifndef SDL_PLATFORM_TVOS
228 /* iOS 10 seems to have a bug where, in certain conditions, putting the
229 * device to sleep with the a landscape-only app open, re-orienting the
230 * device to portrait, and turning it back on will result in the screen
231 * bounds returning portrait orientation despite the app being in landscape.
232 * This is a workaround until a better solution can be found.
233 * https://bugzilla.libsdl.org/show_bug.cgi?id=3505
234 * https://bugzilla.libsdl.org/show_bug.cgi?id=3465
235 * https://forums.developer.apple.com/thread/65337 */
236 UIInterfaceOrientation orient = [UIApplication sharedApplication].statusBarOrientation;
237 BOOL landscape = UIInterfaceOrientationIsLandscape(orient) ||
238 !(UIKit_GetSupportedOrientations(window) & (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown));
239 BOOL fullscreen = CGRectEqualToRect(screen.bounds, frame);
240
241 /* The orientation flip doesn't make sense when the window is smaller
242 * than the screen (iPad Split View, for example). */
243 if (fullscreen && (landscape != (frame.size.width > frame.size.height))) {
244 float height = frame.size.width;
245 frame.size.width = frame.size.height;
246 frame.size.height = height;
247 }
248#endif
249
250 return frame;
251}
252
253#endif
254
255void UIKit_ForceUpdateHomeIndicator(void)
256{
257#ifndef SDL_PLATFORM_TVOS
258 // Force the main SDL window to re-evaluate home indicator state
259 SDL_Window *focus = SDL_GetKeyboardFocus();
260 if (focus) {
261 SDL_UIKitWindowData *data = (__bridge SDL_UIKitWindowData *)focus->internal;
262 if (data != nil) {
263 [data.viewcontroller performSelectorOnMainThread:@selector(setNeedsUpdateOfHomeIndicatorAutoHidden) withObject:nil waitUntilDone:NO];
264 [data.viewcontroller performSelectorOnMainThread:@selector(setNeedsUpdateOfScreenEdgesDeferringSystemGestures) withObject:nil waitUntilDone:NO];
265 }
266 }
267#endif // !SDL_PLATFORM_TVOS
268}
269
270/*
271 * iOS log support.
272 *
273 * This doesn't really have anything to do with the interfaces of the SDL video
274 * subsystem, but we need to stuff this into an Objective-C source code file.
275 *
276 * NOTE: This is copypasted from src/video/cocoa/SDL_cocoavideo.m! Thus, if
277 * Cocoa is supported, we use that one instead. Be sure both versions remain
278 * identical!
279 */
280
281#ifndef SDL_VIDEO_DRIVER_COCOA
282void SDL_NSLog(const char *prefix, const char *text)
283{
284 @autoreleasepool {
285 NSString *nsText = [NSString stringWithUTF8String:text];
286 if (prefix && *prefix) {
287 NSString *nsPrefix = [NSString stringWithUTF8String:prefix];
288 NSLog(@"%@%@", nsPrefix, nsText);
289 } else {
290 NSLog(@"%@", nsText);
291 }
292 }
293}
294#endif // SDL_VIDEO_DRIVER_COCOA
295
296/*
297 * iOS Tablet, etc, detection
298 *
299 * This doesn't really have anything to do with the interfaces of the SDL video
300 * subsystem, but we need to stuff this into an Objective-C source code file.
301 */
302bool SDL_IsIPad(void)
303{
304 return ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad);
305}
306
307bool SDL_IsAppleTV(void)
308{
309 return ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomTV);
310}
311
312#endif // SDL_VIDEO_DRIVER_UIKIT