summaryrefslogtreecommitdiff
path: root/contrib/SDL-3.2.8/src/video/android/SDL_androidvideo.c
diff options
context:
space:
mode:
author3gg <3gg@shellblade.net>2025-12-27 12:03:39 -0800
committer3gg <3gg@shellblade.net>2025-12-27 12:03:39 -0800
commit5a079a2d114f96d4847d1ee305d5b7c16eeec50e (patch)
tree8926ab44f168acf787d8e19608857b3af0f82758 /contrib/SDL-3.2.8/src/video/android/SDL_androidvideo.c
Initial commit
Diffstat (limited to 'contrib/SDL-3.2.8/src/video/android/SDL_androidvideo.c')
-rw-r--r--contrib/SDL-3.2.8/src/video/android/SDL_androidvideo.c331
1 files changed, 331 insertions, 0 deletions
diff --git a/contrib/SDL-3.2.8/src/video/android/SDL_androidvideo.c b/contrib/SDL-3.2.8/src/video/android/SDL_androidvideo.c
new file mode 100644
index 0000000..b154ff7
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/video/android/SDL_androidvideo.c
@@ -0,0 +1,331 @@
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_ANDROID
24
25// Android SDL video driver implementation
26
27#include "../SDL_sysvideo.h"
28#include "../SDL_pixels_c.h"
29#include "../../events/SDL_events_c.h"
30#include "../../events/SDL_windowevents_c.h"
31
32#include "SDL_androidvideo.h"
33#include "SDL_androidgl.h"
34#include "SDL_androidclipboard.h"
35#include "SDL_androidevents.h"
36#include "SDL_androidkeyboard.h"
37#include "SDL_androidmouse.h"
38#include "SDL_androidtouch.h"
39#include "SDL_androidwindow.h"
40#include "SDL_androidvulkan.h"
41#include "SDL_androidmessagebox.h"
42
43#define ANDROID_VID_DRIVER_NAME "android"
44
45// Initialization/Query functions
46static bool Android_VideoInit(SDL_VideoDevice *_this);
47static void Android_VideoQuit(SDL_VideoDevice *_this);
48
49#include "../SDL_egl_c.h"
50#define Android_GLES_GetProcAddress SDL_EGL_GetProcAddressInternal
51#define Android_GLES_UnloadLibrary SDL_EGL_UnloadLibrary
52#define Android_GLES_SetSwapInterval SDL_EGL_SetSwapInterval
53#define Android_GLES_GetSwapInterval SDL_EGL_GetSwapInterval
54#define Android_GLES_DestroyContext SDL_EGL_DestroyContext
55
56// Android driver bootstrap functions
57
58// These are filled in with real values in Android_SetScreenResolution on init (before SDL_main())
59int Android_SurfaceWidth = 0;
60int Android_SurfaceHeight = 0;
61static int Android_DeviceWidth = 0;
62static int Android_DeviceHeight = 0;
63static Uint32 Android_ScreenFormat = SDL_PIXELFORMAT_RGB565; // Default SurfaceView format, in case this is queried before being filled
64float Android_ScreenDensity = 1.0f;
65static float Android_ScreenRate = 0.0f;
66static SDL_DisplayOrientation Android_ScreenOrientation = SDL_ORIENTATION_UNKNOWN;
67int Android_SafeInsetLeft = 0;
68int Android_SafeInsetRight = 0;
69int Android_SafeInsetTop = 0;
70int Android_SafeInsetBottom = 0;
71static SDL_SystemTheme Android_SystemTheme;
72
73static bool Android_SuspendScreenSaver(SDL_VideoDevice *_this)
74{
75 return Android_JNI_SuspendScreenSaver(_this->suspend_screensaver);
76}
77
78static void Android_DeleteDevice(SDL_VideoDevice *device)
79{
80 SDL_free(device->internal);
81 SDL_free(device);
82}
83
84static SDL_VideoDevice *Android_CreateDevice(void)
85{
86 SDL_VideoDevice *device;
87 SDL_VideoData *data;
88
89 // Initialize all variables that we clean on shutdown
90 device = (SDL_VideoDevice *)SDL_calloc(1, sizeof(SDL_VideoDevice));
91 if (!device) {
92 return NULL;
93 }
94
95 data = (SDL_VideoData *)SDL_calloc(1, sizeof(SDL_VideoData));
96 if (!data) {
97 SDL_free(device);
98 return NULL;
99 }
100
101 device->internal = data;
102 device->system_theme = Android_SystemTheme;
103
104 // Set the function pointers
105 device->VideoInit = Android_VideoInit;
106 device->VideoQuit = Android_VideoQuit;
107
108 device->CreateSDLWindow = Android_CreateWindow;
109 device->SetWindowTitle = Android_SetWindowTitle;
110 device->SetWindowFullscreen = Android_SetWindowFullscreen;
111 device->MinimizeWindow = Android_MinimizeWindow;
112 device->SetWindowResizable = Android_SetWindowResizable;
113 device->DestroyWindow = Android_DestroyWindow;
114
115 device->free = Android_DeleteDevice;
116
117 // GL pointers
118#ifdef SDL_VIDEO_OPENGL_EGL
119 device->GL_LoadLibrary = Android_GLES_LoadLibrary;
120 device->GL_GetProcAddress = Android_GLES_GetProcAddress;
121 device->GL_UnloadLibrary = Android_GLES_UnloadLibrary;
122 device->GL_CreateContext = Android_GLES_CreateContext;
123 device->GL_MakeCurrent = Android_GLES_MakeCurrent;
124 device->GL_SetSwapInterval = Android_GLES_SetSwapInterval;
125 device->GL_GetSwapInterval = Android_GLES_GetSwapInterval;
126 device->GL_SwapWindow = Android_GLES_SwapWindow;
127 device->GL_DestroyContext = Android_GLES_DestroyContext;
128#endif
129
130#ifdef SDL_VIDEO_VULKAN
131 device->Vulkan_LoadLibrary = Android_Vulkan_LoadLibrary;
132 device->Vulkan_UnloadLibrary = Android_Vulkan_UnloadLibrary;
133 device->Vulkan_GetInstanceExtensions = Android_Vulkan_GetInstanceExtensions;
134 device->Vulkan_CreateSurface = Android_Vulkan_CreateSurface;
135 device->Vulkan_DestroySurface = Android_Vulkan_DestroySurface;
136#endif
137
138 // Screensaver
139 device->SuspendScreenSaver = Android_SuspendScreenSaver;
140
141 // Screen keyboard
142 device->HasScreenKeyboardSupport = Android_HasScreenKeyboardSupport;
143 device->ShowScreenKeyboard = Android_ShowScreenKeyboard;
144 device->HideScreenKeyboard = Android_HideScreenKeyboard;
145 device->IsScreenKeyboardShown = Android_IsScreenKeyboardShown;
146
147 // Clipboard
148 device->SetClipboardText = Android_SetClipboardText;
149 device->GetClipboardText = Android_GetClipboardText;
150 device->HasClipboardText = Android_HasClipboardText;
151
152 device->device_caps = VIDEO_DEVICE_CAPS_SENDS_FULLSCREEN_DIMENSIONS;
153
154 return device;
155}
156
157VideoBootStrap Android_bootstrap = {
158 ANDROID_VID_DRIVER_NAME, "SDL Android video driver",
159 Android_CreateDevice,
160 Android_ShowMessageBox,
161 false
162};
163
164bool Android_VideoInit(SDL_VideoDevice *_this)
165{
166 SDL_VideoData *videodata = _this->internal;
167 SDL_DisplayID displayID;
168 SDL_VideoDisplay *display;
169 SDL_DisplayMode mode;
170
171 videodata->isPaused = false;
172 videodata->isPausing = false;
173
174 SDL_zero(mode);
175 mode.format = Android_ScreenFormat;
176 mode.w = Android_DeviceWidth;
177 mode.h = Android_DeviceHeight;
178 mode.refresh_rate = Android_ScreenRate;
179
180 displayID = SDL_AddBasicVideoDisplay(&mode);
181 if (displayID == 0) {
182 return false;
183 }
184 display = SDL_GetVideoDisplay(displayID);
185 display->natural_orientation = Android_JNI_GetDisplayNaturalOrientation();
186 display->current_orientation = Android_JNI_GetDisplayCurrentOrientation();
187 display->content_scale = Android_ScreenDensity;
188
189 Android_InitTouch();
190
191 Android_InitMouse();
192
193 // We're done!
194 return true;
195}
196
197void Android_VideoQuit(SDL_VideoDevice *_this)
198{
199 Android_QuitMouse();
200 Android_QuitTouch();
201}
202
203void Android_SetScreenResolution(int surfaceWidth, int surfaceHeight, int deviceWidth, int deviceHeight, float density, float rate)
204{
205 Android_SurfaceWidth = surfaceWidth;
206 Android_SurfaceHeight = surfaceHeight;
207 Android_DeviceWidth = deviceWidth;
208 Android_DeviceHeight = deviceHeight;
209 Android_ScreenDensity = (density > 0.0f) ? density : 1.0f;
210 Android_ScreenRate = rate;
211}
212
213static Uint32 format_to_pixelFormat(int format)
214{
215 Uint32 pf;
216 if (format == AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM) { // 1
217 pf = SDL_PIXELFORMAT_RGBA8888;
218 } else if (format == AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM) { // 2
219 pf = SDL_PIXELFORMAT_RGBX8888;
220 } else if (format == AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM) { // 3
221 pf = SDL_PIXELFORMAT_RGB24;
222 } else if (format == AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM) { // 4
223 pf = SDL_PIXELFORMAT_RGB565;
224 } else if (format == 5) {
225 pf = SDL_PIXELFORMAT_BGRA8888;
226 } else if (format == 6) {
227 pf = SDL_PIXELFORMAT_RGBA5551;
228 } else if (format == 7) {
229 pf = SDL_PIXELFORMAT_RGBA4444;
230 } else if (format == 0x115) {
231 // HAL_PIXEL_FORMAT_BGR_565
232 pf = SDL_PIXELFORMAT_RGB565;
233 } else {
234 pf = SDL_PIXELFORMAT_UNKNOWN;
235 }
236 return pf;
237}
238
239void Android_SetFormat(int format_wanted, int format_got)
240{
241 Uint32 pf_wanted;
242 Uint32 pf_got;
243
244 pf_wanted = format_to_pixelFormat(format_wanted);
245 pf_got = format_to_pixelFormat(format_got);
246
247 Android_ScreenFormat = pf_got;
248
249 SDL_Log("pixel format wanted %s (%d), got %s (%d)",
250 SDL_GetPixelFormatName(pf_wanted), format_wanted,
251 SDL_GetPixelFormatName(pf_got), format_got);
252}
253
254static void Android_SendOrientationUpdate(void)
255{
256 /* If we've received a compatible resize event, update the
257 * orientation immediately, otherwise wait for the display
258 * resize event.
259 */
260 SDL_VideoDevice *device = SDL_GetVideoDevice();
261 if (device && device->num_displays > 0) {
262 SDL_VideoDisplay *display = device->displays[0];
263 bool mode_landscape = (display->desktop_mode.w > display->desktop_mode.h);
264 bool sensor_landscape = (Android_ScreenOrientation == SDL_ORIENTATION_LANDSCAPE || Android_ScreenOrientation == SDL_ORIENTATION_LANDSCAPE_FLIPPED);
265 if (sensor_landscape == mode_landscape) {
266 SDL_SendDisplayEvent(display, SDL_EVENT_DISPLAY_ORIENTATION, Android_ScreenOrientation, 0);
267 }
268 }
269}
270
271void Android_SetOrientation(SDL_DisplayOrientation orientation)
272{
273 Android_ScreenOrientation = orientation;
274 Android_SendOrientationUpdate();
275}
276
277void Android_SendResize(SDL_Window *window)
278{
279 /*
280 Update the resolution of the desktop mode, so that the window
281 can be properly resized. The screen resolution change can for
282 example happen when the Activity enters or exits immersive mode,
283 which can happen after VideoInit().
284 */
285 SDL_VideoDevice *device = SDL_GetVideoDevice();
286 if (device && device->num_displays > 0) {
287 SDL_VideoDisplay *display = device->displays[0];
288 SDL_DisplayMode desktop_mode;
289
290 SDL_zero(desktop_mode);
291 desktop_mode.format = Android_ScreenFormat;
292 desktop_mode.w = Android_DeviceWidth;
293 desktop_mode.h = Android_DeviceHeight;
294 desktop_mode.refresh_rate = Android_ScreenRate;
295 SDL_SetDesktopDisplayMode(display, &desktop_mode);
296 Android_SendOrientationUpdate();
297 }
298
299 if (window) {
300 SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_RESIZED, Android_SurfaceWidth, Android_SurfaceHeight);
301 }
302}
303
304void Android_SetWindowSafeAreaInsets(int left, int right, int top, int bottom)
305{
306 Android_SafeInsetLeft = left;
307 Android_SafeInsetRight = right;
308 Android_SafeInsetTop = top;
309 Android_SafeInsetBottom = bottom;
310
311 if (Android_Window) {
312 SDL_SetWindowSafeAreaInsets(Android_Window, left, right, top, bottom);
313 }
314}
315
316void Android_SetDarkMode(bool enabled)
317{
318 SDL_VideoDevice *device = SDL_GetVideoDevice();
319
320 if (enabled) {
321 Android_SystemTheme = SDL_SYSTEM_THEME_DARK;
322 } else {
323 Android_SystemTheme = SDL_SYSTEM_THEME_LIGHT;
324 }
325
326 if (device) {
327 SDL_SetSystemTheme(Android_SystemTheme);
328 }
329}
330
331#endif // SDL_VIDEO_DRIVER_ANDROID