1 /*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2016 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
28 #include "SDL_video.h"
29 #include "SDL_mouse.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_androidclipboard.h"
37 #include "SDL_androidevents.h"
38 #include "SDL_androidkeyboard.h"
39 #include "SDL_androidmouse.h"
40 #include "SDL_androidtouch.h"
41 #include "SDL_androidwindow.h"
42
43 #define ANDROID_VID_DRIVER_NAME "Android"
44
45 /* Initialization/Query functions */
46 static int Android_VideoInit(_THIS);
47 static void Android_VideoQuit(_THIS);
48
49 #include "../SDL_egl_c.h"
50 /* GL functions (SDL_androidgl.c) */
51 extern SDL_GLContext Android_GLES_CreateContext(_THIS, SDL_Window * window);
52 extern int Android_GLES_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context);
53 extern void Android_GLES_SwapWindow(_THIS, SDL_Window * window);
54 extern int Android_GLES_LoadLibrary(_THIS, const char *path);
55 #define Android_GLES_GetProcAddress SDL_EGL_GetProcAddress
56 #define Android_GLES_UnloadLibrary SDL_EGL_UnloadLibrary
57 #define Android_GLES_SetSwapInterval SDL_EGL_SetSwapInterval
58 #define Android_GLES_GetSwapInterval SDL_EGL_GetSwapInterval
59 #define Android_GLES_DeleteContext SDL_EGL_DeleteContext
60
61 /* Android driver bootstrap functions */
62
63
64 /* These are filled in with real values in Android_SetScreenResolution on init (before SDL_main()) */
65 int Android_ScreenWidth = 0;
66 int Android_ScreenHeight = 0;
67 Uint32 Android_ScreenFormat = SDL_PIXELFORMAT_UNKNOWN;
68 int Android_ScreenRate = 0;
69
70 SDL_sem *Android_PauseSem = NULL, *Android_ResumeSem = NULL;
71
72 /* Currently only one window */
73 SDL_Window *Android_Window = NULL;
74
75 static int
Android_Available(void)76 Android_Available(void)
77 {
78 return 1;
79 }
80
81 static void
Android_SuspendScreenSaver(_THIS)82 Android_SuspendScreenSaver(_THIS)
83 {
84 Android_JNI_SuspendScreenSaver(_this->suspend_screensaver);
85 }
86
87 static void
Android_DeleteDevice(SDL_VideoDevice * device)88 Android_DeleteDevice(SDL_VideoDevice * device)
89 {
90 SDL_free(device->driverdata);
91 SDL_free(device);
92 }
93
94 static SDL_VideoDevice *
Android_CreateDevice(int devindex)95 Android_CreateDevice(int devindex)
96 {
97 SDL_VideoDevice *device;
98 SDL_VideoData *data;
99
100 /* Initialize all variables that we clean on shutdown */
101 device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice));
102 if (!device) {
103 SDL_OutOfMemory();
104 return NULL;
105 }
106
107 data = (SDL_VideoData*) SDL_calloc(1, sizeof(SDL_VideoData));
108 if (!data) {
109 SDL_OutOfMemory();
110 SDL_free(device);
111 return NULL;
112 }
113
114 device->driverdata = data;
115
116 /* Set the function pointers */
117 device->VideoInit = Android_VideoInit;
118 device->VideoQuit = Android_VideoQuit;
119 device->PumpEvents = Android_PumpEvents;
120
121 device->CreateWindow = Android_CreateWindow;
122 device->SetWindowTitle = Android_SetWindowTitle;
123 device->DestroyWindow = Android_DestroyWindow;
124 device->GetWindowWMInfo = Android_GetWindowWMInfo;
125
126 device->free = Android_DeleteDevice;
127
128 /* GL pointers */
129 device->GL_LoadLibrary = Android_GLES_LoadLibrary;
130 device->GL_GetProcAddress = Android_GLES_GetProcAddress;
131 device->GL_UnloadLibrary = Android_GLES_UnloadLibrary;
132 device->GL_CreateContext = Android_GLES_CreateContext;
133 device->GL_MakeCurrent = Android_GLES_MakeCurrent;
134 device->GL_SetSwapInterval = Android_GLES_SetSwapInterval;
135 device->GL_GetSwapInterval = Android_GLES_GetSwapInterval;
136 device->GL_SwapWindow = Android_GLES_SwapWindow;
137 device->GL_DeleteContext = Android_GLES_DeleteContext;
138
139 /* Screensaver */
140 device->SuspendScreenSaver = Android_SuspendScreenSaver;
141
142 /* Text input */
143 device->StartTextInput = Android_StartTextInput;
144 device->StopTextInput = Android_StopTextInput;
145 device->SetTextInputRect = Android_SetTextInputRect;
146
147 /* Screen keyboard */
148 device->HasScreenKeyboardSupport = Android_HasScreenKeyboardSupport;
149 device->IsScreenKeyboardShown = Android_IsScreenKeyboardShown;
150
151 /* Clipboard */
152 device->SetClipboardText = Android_SetClipboardText;
153 device->GetClipboardText = Android_GetClipboardText;
154 device->HasClipboardText = Android_HasClipboardText;
155
156 return device;
157 }
158
159 VideoBootStrap Android_bootstrap = {
160 ANDROID_VID_DRIVER_NAME, "SDL Android video driver",
161 Android_Available, Android_CreateDevice
162 };
163
164
165 int
Android_VideoInit(_THIS)166 Android_VideoInit(_THIS)
167 {
168 SDL_DisplayMode mode;
169
170 mode.format = Android_ScreenFormat;
171 mode.w = Android_ScreenWidth;
172 mode.h = Android_ScreenHeight;
173 mode.refresh_rate = Android_ScreenRate;
174 mode.driverdata = NULL;
175 if (SDL_AddBasicVideoDisplay(&mode) < 0) {
176 return -1;
177 }
178
179 SDL_AddDisplayMode(&_this->displays[0], &mode);
180
181 Android_InitKeyboard();
182
183 Android_InitTouch();
184
185 Android_InitMouse();
186
187 /* We're done! */
188 return 0;
189 }
190
191 void
Android_VideoQuit(_THIS)192 Android_VideoQuit(_THIS)
193 {
194 Android_QuitTouch();
195 }
196
197 void
Android_SetScreenResolution(int width,int height,Uint32 format,float rate)198 Android_SetScreenResolution(int width, int height, Uint32 format, float rate)
199 {
200 Android_ScreenWidth = width;
201 Android_ScreenHeight = height;
202 Android_ScreenFormat = format;
203 Android_ScreenRate = rate;
204
205 /*
206 Update the resolution of the desktop mode, so that the window
207 can be properly resized. The screen resolution change can for
208 example happen when the Activity enters or exists immersive mode,
209 which can happen after VideoInit().
210 */
211 SDL_VideoDevice* device = SDL_GetVideoDevice();
212 if (device && device->num_displays > 0)
213 {
214 SDL_VideoDisplay* display = &device->displays[0];
215 display->desktop_mode.format = Android_ScreenFormat;
216 display->desktop_mode.w = Android_ScreenWidth;
217 display->desktop_mode.h = Android_ScreenHeight;
218 display->desktop_mode.refresh_rate = Android_ScreenRate;
219 }
220
221 if (Android_Window) {
222 SDL_SendWindowEvent(Android_Window, SDL_WINDOWEVENT_RESIZED, width, height);
223
224 /* Force the current mode to match the resize otherwise the SDL_WINDOWEVENT_RESTORED event
225 * will fall back to the old mode */
226 SDL_VideoDisplay *display = SDL_GetDisplayForWindow(Android_Window);
227
228 display->current_mode.format = format;
229 display->current_mode.w = width;
230 display->current_mode.h = height;
231 display->current_mode.refresh_rate = rate;
232 }
233 }
234
235 #endif /* SDL_VIDEO_DRIVER_ANDROID */
236
237 /* vi: set ts=4 sw=4 expandtab: */
238