2 Simple DirectMedia Layer
3 Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
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.
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:
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.
21 #include "../../SDL_internal.h"
23 #if SDL_VIDEO_DRIVER_ANDROID
25 /* Android SDL video driver implementation */
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"
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"
45 #define ANDROID_VID_DRIVER_NAME "Android"
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);
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
59 /* Android driver bootstrap functions */
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;
74 Android_SuspendScreenSaver(_THIS)
76 Android_JNI_SuspendScreenSaver(_this->suspend_screensaver);
80 Android_DeleteDevice(SDL_VideoDevice *device)
82 SDL_free(device->driverdata);
86 static SDL_VideoDevice *
87 Android_CreateDevice(int devindex)
89 SDL_VideoDevice *device;
91 SDL_bool block_on_pause;
93 /* Initialize all variables that we clean on shutdown */
94 device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice));
100 data = (SDL_VideoData *) SDL_calloc(1, sizeof(SDL_VideoData));
107 device->driverdata = data;
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;
116 device->PumpEvents = Android_PumpEvents_NonBlocking;
119 device->GetDisplayDPI = Android_GetDisplayDPI;
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;
128 device->free = Android_DeleteDevice;
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;
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;
149 device->SuspendScreenSaver = Android_SuspendScreenSaver;
152 device->StartTextInput = Android_StartTextInput;
153 device->StopTextInput = Android_StopTextInput;
154 device->SetTextInputRect = Android_SetTextInputRect;
156 /* Screen keyboard */
157 device->HasScreenKeyboardSupport = Android_HasScreenKeyboardSupport;
158 device->IsScreenKeyboardShown = Android_IsScreenKeyboardShown;
161 device->SetClipboardText = Android_SetClipboardText;
162 device->GetClipboardText = Android_GetClipboardText;
163 device->HasClipboardText = Android_HasClipboardText;
168 VideoBootStrap Android_bootstrap = {
169 ANDROID_VID_DRIVER_NAME, "SDL Android video driver",
175 Android_VideoInit(_THIS)
177 SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata;
179 SDL_VideoDisplay *display;
180 SDL_DisplayMode mode;
182 videodata->isPaused = SDL_FALSE;
183 videodata->isPausing = SDL_FALSE;
184 videodata->pauseAudio = SDL_GetHintBoolean(SDL_HINT_ANDROID_BLOCK_ON_PAUSE_PAUSEAUDIO, SDL_TRUE);
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;
192 display_index = SDL_AddBasicVideoDisplay(&mode);
193 if (display_index < 0) {
196 display = SDL_GetDisplay(display_index);
197 display->orientation = Android_JNI_GetDisplayOrientation();
199 SDL_AddDisplayMode(&_this->displays[0], &mode);
201 Android_InitKeyboard();
212 Android_VideoQuit(_THIS)
219 Android_GetDisplayDPI(_THIS, SDL_VideoDisplay *display, float *ddpi, float *hdpi, float *vdpi)
221 return Android_JNI_GetDisplayDPI(ddpi, hdpi, vdpi);
225 Android_SetScreenResolution(int surfaceWidth, int surfaceHeight, int deviceWidth, int deviceHeight, Uint32 format, float rate)
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;
235 void Android_SendResize(SDL_Window *window)
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().
243 SDL_VideoDevice *device = SDL_GetVideoDevice();
244 if (device && device->num_displays > 0)
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;
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];
263 SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, Android_SurfaceWidth, Android_SurfaceHeight);
267 #endif /* SDL_VIDEO_DRIVER_ANDROID */
269 /* vi: set ts=4 sw=4 expandtab: */