SDL_androidvideo.c (9001B)
1 /* 2 Simple DirectMedia Layer 3 Copyright (C) 1997-2020 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 #if SDL_VIDEO_DRIVER_ANDROID 24 25 /* Android SDL video driver implementation */ 26 27 #include "SDL_video.h" 28 #include "SDL_mouse.h" 29 #include "SDL_hints.h" 30 #include "../SDL_sysvideo.h" 31 #include "../SDL_pixels_c.h" 32 #include "../../events/SDL_events_c.h" 33 #include "../../events/SDL_windowevents_c.h" 34 35 #include "SDL_androidvideo.h" 36 #include "SDL_androidgl.h" 37 #include "SDL_androidclipboard.h" 38 #include "SDL_androidevents.h" 39 #include "SDL_androidkeyboard.h" 40 #include "SDL_androidmouse.h" 41 #include "SDL_androidtouch.h" 42 #include "SDL_androidwindow.h" 43 #include "SDL_androidvulkan.h" 44 45 #define ANDROID_VID_DRIVER_NAME "Android" 46 47 /* Initialization/Query functions */ 48 static int Android_VideoInit(_THIS); 49 static void Android_VideoQuit(_THIS); 50 int Android_GetDisplayDPI(_THIS, SDL_VideoDisplay *display, float *ddpi, float *hdpi, float *vdpi); 51 52 #include "../SDL_egl_c.h" 53 #define Android_GLES_GetProcAddress SDL_EGL_GetProcAddress 54 #define Android_GLES_UnloadLibrary SDL_EGL_UnloadLibrary 55 #define Android_GLES_SetSwapInterval SDL_EGL_SetSwapInterval 56 #define Android_GLES_GetSwapInterval SDL_EGL_GetSwapInterval 57 #define Android_GLES_DeleteContext SDL_EGL_DeleteContext 58 59 /* Android driver bootstrap functions */ 60 61 62 /* These are filled in with real values in Android_SetScreenResolution on init (before SDL_main()) */ 63 int Android_SurfaceWidth = 0; 64 int Android_SurfaceHeight = 0; 65 static int Android_DeviceWidth = 0; 66 static int Android_DeviceHeight = 0; 67 static Uint32 Android_ScreenFormat = SDL_PIXELFORMAT_UNKNOWN; 68 static int Android_ScreenRate = 0; 69 SDL_sem *Android_PauseSem = NULL; 70 SDL_sem *Android_ResumeSem = NULL; 71 SDL_mutex *Android_ActivityMutex = NULL; 72 73 static void 74 Android_SuspendScreenSaver(_THIS) 75 { 76 Android_JNI_SuspendScreenSaver(_this->suspend_screensaver); 77 } 78 79 static void 80 Android_DeleteDevice(SDL_VideoDevice *device) 81 { 82 SDL_free(device->driverdata); 83 SDL_free(device); 84 } 85 86 static SDL_VideoDevice * 87 Android_CreateDevice(int devindex) 88 { 89 SDL_VideoDevice *device; 90 SDL_VideoData *data; 91 SDL_bool block_on_pause; 92 93 /* Initialize all variables that we clean on shutdown */ 94 device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice)); 95 if (!device) { 96 SDL_OutOfMemory(); 97 return NULL; 98 } 99 100 data = (SDL_VideoData *) SDL_calloc(1, sizeof(SDL_VideoData)); 101 if (!data) { 102 SDL_OutOfMemory(); 103 SDL_free(device); 104 return NULL; 105 } 106 107 device->driverdata = data; 108 109 /* Set the function pointers */ 110 device->VideoInit = Android_VideoInit; 111 device->VideoQuit = Android_VideoQuit; 112 block_on_pause = SDL_GetHintBoolean(SDL_HINT_ANDROID_BLOCK_ON_PAUSE, SDL_TRUE); 113 if (block_on_pause) { 114 device->PumpEvents = Android_PumpEvents_Blocking; 115 } else { 116 device->PumpEvents = Android_PumpEvents_NonBlocking; 117 } 118 119 device->GetDisplayDPI = Android_GetDisplayDPI; 120 121 device->CreateSDLWindow = Android_CreateWindow; 122 device->SetWindowTitle = Android_SetWindowTitle; 123 device->SetWindowFullscreen = Android_SetWindowFullscreen; 124 device->MinimizeWindow = Android_MinimizeWindow; 125 device->DestroyWindow = Android_DestroyWindow; 126 device->GetWindowWMInfo = Android_GetWindowWMInfo; 127 128 device->free = Android_DeleteDevice; 129 130 /* GL pointers */ 131 device->GL_LoadLibrary = Android_GLES_LoadLibrary; 132 device->GL_GetProcAddress = Android_GLES_GetProcAddress; 133 device->GL_UnloadLibrary = Android_GLES_UnloadLibrary; 134 device->GL_CreateContext = Android_GLES_CreateContext; 135 device->GL_MakeCurrent = Android_GLES_MakeCurrent; 136 device->GL_SetSwapInterval = Android_GLES_SetSwapInterval; 137 device->GL_GetSwapInterval = Android_GLES_GetSwapInterval; 138 device->GL_SwapWindow = Android_GLES_SwapWindow; 139 device->GL_DeleteContext = Android_GLES_DeleteContext; 140 141 #if SDL_VIDEO_VULKAN 142 device->Vulkan_LoadLibrary = Android_Vulkan_LoadLibrary; 143 device->Vulkan_UnloadLibrary = Android_Vulkan_UnloadLibrary; 144 device->Vulkan_GetInstanceExtensions = Android_Vulkan_GetInstanceExtensions; 145 device->Vulkan_CreateSurface = Android_Vulkan_CreateSurface; 146 #endif 147 148 /* Screensaver */ 149 device->SuspendScreenSaver = Android_SuspendScreenSaver; 150 151 /* Text input */ 152 device->StartTextInput = Android_StartTextInput; 153 device->StopTextInput = Android_StopTextInput; 154 device->SetTextInputRect = Android_SetTextInputRect; 155 156 /* Screen keyboard */ 157 device->HasScreenKeyboardSupport = Android_HasScreenKeyboardSupport; 158 device->IsScreenKeyboardShown = Android_IsScreenKeyboardShown; 159 160 /* Clipboard */ 161 device->SetClipboardText = Android_SetClipboardText; 162 device->GetClipboardText = Android_GetClipboardText; 163 device->HasClipboardText = Android_HasClipboardText; 164 165 return device; 166 } 167 168 VideoBootStrap Android_bootstrap = { 169 ANDROID_VID_DRIVER_NAME, "SDL Android video driver", 170 Android_CreateDevice 171 }; 172 173 174 int 175 Android_VideoInit(_THIS) 176 { 177 SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata; 178 int display_index; 179 SDL_VideoDisplay *display; 180 SDL_DisplayMode mode; 181 182 videodata->isPaused = SDL_FALSE; 183 videodata->isPausing = SDL_FALSE; 184 videodata->pauseAudio = SDL_GetHintBoolean(SDL_HINT_ANDROID_BLOCK_ON_PAUSE_PAUSEAUDIO, SDL_TRUE); 185 186 mode.format = Android_ScreenFormat; 187 mode.w = Android_DeviceWidth; 188 mode.h = Android_DeviceHeight; 189 mode.refresh_rate = Android_ScreenRate; 190 mode.driverdata = NULL; 191 192 display_index = SDL_AddBasicVideoDisplay(&mode); 193 if (display_index < 0) { 194 return -1; 195 } 196 display = SDL_GetDisplay(display_index); 197 display->orientation = Android_JNI_GetDisplayOrientation(); 198 199 SDL_AddDisplayMode(&_this->displays[0], &mode); 200 201 Android_InitKeyboard(); 202 203 Android_InitTouch(); 204 205 Android_InitMouse(); 206 207 /* We're done! */ 208 return 0; 209 } 210 211 void 212 Android_VideoQuit(_THIS) 213 { 214 Android_QuitMouse(); 215 Android_QuitTouch(); 216 } 217 218 int 219 Android_GetDisplayDPI(_THIS, SDL_VideoDisplay *display, float *ddpi, float *hdpi, float *vdpi) 220 { 221 return Android_JNI_GetDisplayDPI(ddpi, hdpi, vdpi); 222 } 223 224 void 225 Android_SetScreenResolution(int surfaceWidth, int surfaceHeight, int deviceWidth, int deviceHeight, Uint32 format, float rate) 226 { 227 Android_SurfaceWidth = surfaceWidth; 228 Android_SurfaceHeight = surfaceHeight; 229 Android_DeviceWidth = deviceWidth; 230 Android_DeviceHeight = deviceHeight; 231 Android_ScreenFormat = format; 232 Android_ScreenRate = (int)rate; 233 } 234 235 void Android_SendResize(SDL_Window *window) 236 { 237 /* 238 Update the resolution of the desktop mode, so that the window 239 can be properly resized. The screen resolution change can for 240 example happen when the Activity enters or exits immersive mode, 241 which can happen after VideoInit(). 242 */ 243 SDL_VideoDevice *device = SDL_GetVideoDevice(); 244 if (device && device->num_displays > 0) 245 { 246 SDL_VideoDisplay *display = &device->displays[0]; 247 display->desktop_mode.format = Android_ScreenFormat; 248 display->desktop_mode.w = Android_DeviceWidth; 249 display->desktop_mode.h = Android_DeviceHeight; 250 display->desktop_mode.refresh_rate = Android_ScreenRate; 251 } 252 253 if (window) { 254 /* Force the current mode to match the resize otherwise the SDL_WINDOWEVENT_RESTORED event 255 * will fall back to the old mode */ 256 SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window); 257 display->display_modes[0].format = Android_ScreenFormat; 258 display->display_modes[0].w = Android_DeviceWidth; 259 display->display_modes[0].h = Android_DeviceHeight; 260 display->display_modes[0].refresh_rate = Android_ScreenRate; 261 display->current_mode = display->display_modes[0]; 262 263 SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, Android_SurfaceWidth, Android_SurfaceHeight); 264 } 265 } 266 267 #endif /* SDL_VIDEO_DRIVER_ANDROID */ 268 269 /* vi: set ts=4 sw=4 expandtab: */