Atlas - SDL_androidvideo.c
Home / ext / SDL / src / video / android Lines: 1 | Size: 10975 bytes [Download] [Show on GitHub] [Search similar files] [Raw] [Raw (proxy)][FILE BEGIN]1/* 2 Simple DirectMedia Layer 3 Copyright (C) 1997-2025 Sam Lantinga <[email protected]> 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 146 // Clipboard 147 device->SetClipboardText = Android_SetClipboardText; 148 device->GetClipboardText = Android_GetClipboardText; 149 device->HasClipboardText = Android_HasClipboardText; 150 151 device->device_caps = VIDEO_DEVICE_CAPS_SENDS_FULLSCREEN_DIMENSIONS; 152 153 return device; 154} 155 156VideoBootStrap Android_bootstrap = { 157 ANDROID_VID_DRIVER_NAME, "SDL Android video driver", 158 Android_CreateDevice, 159 Android_ShowMessageBox, 160 false 161}; 162 163bool Android_VideoInit(SDL_VideoDevice *_this) 164{ 165 SDL_VideoData *videodata = _this->internal; 166 SDL_DisplayID displayID; 167 SDL_VideoDisplay *display; 168 SDL_DisplayMode mode; 169 170 videodata->isPaused = false; 171 videodata->isPausing = false; 172 173 SDL_zero(mode); 174 mode.format = Android_ScreenFormat; 175 mode.w = Android_DeviceWidth; 176 mode.h = Android_DeviceHeight; 177 mode.refresh_rate = Android_ScreenRate; 178 179 displayID = SDL_AddBasicVideoDisplay(&mode); 180 if (displayID == 0) { 181 return false; 182 } 183 display = SDL_GetVideoDisplay(displayID); 184 display->natural_orientation = Android_JNI_GetDisplayNaturalOrientation(); 185 display->current_orientation = Android_JNI_GetDisplayCurrentOrientation(); 186 display->content_scale = Android_ScreenDensity; 187 188 Android_InitTouch(); 189 190 Android_InitMouse(); 191 192 // We're done! 193 return true; 194} 195 196void Android_VideoQuit(SDL_VideoDevice *_this) 197{ 198 Android_QuitMouse(); 199 Android_QuitTouch(); 200} 201 202void Android_SetScreenResolution(int surfaceWidth, int surfaceHeight, int deviceWidth, int deviceHeight, float density, float rate) 203{ 204 Android_SurfaceWidth = surfaceWidth; 205 Android_SurfaceHeight = surfaceHeight; 206 Android_DeviceWidth = deviceWidth; 207 Android_DeviceHeight = deviceHeight; 208 Android_ScreenDensity = (density > 0.0f) ? density : 1.0f; 209 Android_ScreenRate = rate; 210} 211 212static Uint32 format_to_pixelFormat(int format) 213{ 214 Uint32 pf; 215 if (format == AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM) { // 1 216 pf = SDL_PIXELFORMAT_RGBA8888; 217 } else if (format == AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM) { // 2 218 pf = SDL_PIXELFORMAT_RGBX8888; 219 } else if (format == AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM) { // 3 220 pf = SDL_PIXELFORMAT_RGB24; 221 } else if (format == AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM) { // 4 222 pf = SDL_PIXELFORMAT_RGB565; 223 } else if (format == 5) { 224 pf = SDL_PIXELFORMAT_BGRA8888; 225 } else if (format == 6) { 226 pf = SDL_PIXELFORMAT_RGBA5551; 227 } else if (format == 7) { 228 pf = SDL_PIXELFORMAT_RGBA4444; 229 } else if (format == 0x115) { 230 // HAL_PIXEL_FORMAT_BGR_565 231 pf = SDL_PIXELFORMAT_RGB565; 232 } else { 233 pf = SDL_PIXELFORMAT_UNKNOWN; 234 } 235 return pf; 236} 237 238void Android_SetFormat(int format_wanted, int format_got) 239{ 240 Uint32 pf_wanted; 241 Uint32 pf_got; 242 243 pf_wanted = format_to_pixelFormat(format_wanted); 244 pf_got = format_to_pixelFormat(format_got); 245 246 Android_ScreenFormat = pf_got; 247 248 SDL_Log("pixel format wanted %s (%d), got %s (%d)", 249 SDL_GetPixelFormatName(pf_wanted), format_wanted, 250 SDL_GetPixelFormatName(pf_got), format_got); 251} 252 253static void Android_SendOrientationUpdate(void) 254{ 255 /* If we've received a compatible resize event, update the 256 * orientation immediately, otherwise wait for the display 257 * resize event. 258 */ 259 SDL_VideoDevice *device = SDL_GetVideoDevice(); 260 if (device && device->num_displays > 0) { 261 SDL_VideoDisplay *display = device->displays[0]; 262 bool mode_landscape = (display->desktop_mode.w > display->desktop_mode.h); 263 bool sensor_landscape = (Android_ScreenOrientation == SDL_ORIENTATION_LANDSCAPE || Android_ScreenOrientation == SDL_ORIENTATION_LANDSCAPE_FLIPPED); 264 if (sensor_landscape == mode_landscape) { 265 SDL_SendDisplayEvent(display, SDL_EVENT_DISPLAY_ORIENTATION, Android_ScreenOrientation, 0); 266 } 267 } 268} 269 270void Android_SetOrientation(SDL_DisplayOrientation orientation) 271{ 272 Android_ScreenOrientation = orientation; 273 Android_SendOrientationUpdate(); 274} 275 276void Android_SendResize(SDL_Window *window) 277{ 278 /* 279 Update the resolution of the desktop mode, so that the window 280 can be properly resized. The screen resolution change can for 281 example happen when the Activity enters or exits immersive mode, 282 which can happen after VideoInit(). 283 */ 284 SDL_VideoDevice *device = SDL_GetVideoDevice(); 285 if (device && device->num_displays > 0) { 286 SDL_VideoDisplay *display = device->displays[0]; 287 SDL_DisplayMode desktop_mode; 288 289 SDL_zero(desktop_mode); 290 desktop_mode.format = Android_ScreenFormat; 291 desktop_mode.w = Android_DeviceWidth; 292 desktop_mode.h = Android_DeviceHeight; 293 desktop_mode.refresh_rate = Android_ScreenRate; 294 SDL_SetDesktopDisplayMode(display, &desktop_mode); 295 Android_SendOrientationUpdate(); 296 } 297 298 if (window) { 299 SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_RESIZED, Android_SurfaceWidth, Android_SurfaceHeight); 300 } 301} 302 303void Android_SetWindowSafeAreaInsets(int left, int right, int top, int bottom) 304{ 305 Android_SafeInsetLeft = left; 306 Android_SafeInsetRight = right; 307 Android_SafeInsetTop = top; 308 Android_SafeInsetBottom = bottom; 309 310 if (Android_Window) { 311 SDL_SetWindowSafeAreaInsets(Android_Window, left, right, top, bottom); 312 } 313} 314 315void Android_SetDarkMode(bool enabled) 316{ 317 SDL_VideoDevice *device = SDL_GetVideoDevice(); 318 319 if (enabled) { 320 Android_SystemTheme = SDL_SYSTEM_THEME_DARK; 321 } else { 322 Android_SystemTheme = SDL_SYSTEM_THEME_LIGHT; 323 } 324 325 if (device) { 326 SDL_SetSystemTheme(Android_SystemTheme); 327 } 328} 329 330#endif // SDL_VIDEO_DRIVER_ANDROID 331[FILE END](C) 2025 0x4248 (C) 2025 4248 Media and 4248 Systems, All part of 0x4248 See LICENCE files for more information. Not all files are by 0x4248 always check Licencing.