summaryrefslogtreecommitdiff
path: root/contrib/SDL-3.2.8/src/video/android
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/SDL-3.2.8/src/video/android')
-rw-r--r--contrib/SDL-3.2.8/src/video/android/SDL_androidclipboard.c44
-rw-r--r--contrib/SDL-3.2.8/src/video/android/SDL_androidclipboard.h30
-rw-r--r--contrib/SDL-3.2.8/src/video/android/SDL_androidevents.c269
-rw-r--r--contrib/SDL-3.2.8/src/video/android/SDL_androidevents.h26
-rw-r--r--contrib/SDL-3.2.8/src/video/android/SDL_androidgl.c88
-rw-r--r--contrib/SDL-3.2.8/src/video/android/SDL_androidgl.h31
-rw-r--r--contrib/SDL-3.2.8/src/video/android/SDL_androidkeyboard.c468
-rw-r--r--contrib/SDL-3.2.8/src/video/android/SDL_androidkeyboard.h32
-rw-r--r--contrib/SDL-3.2.8/src/video/android/SDL_androidmessagebox.c33
-rw-r--r--contrib/SDL-3.2.8/src/video/android/SDL_androidmessagebox.h27
-rw-r--r--contrib/SDL-3.2.8/src/video/android/SDL_androidmouse.c250
-rw-r--r--contrib/SDL-3.2.8/src/video/android/SDL_androidmouse.h31
-rw-r--r--contrib/SDL-3.2.8/src/video/android/SDL_androidpen.c98
-rw-r--r--contrib/SDL-3.2.8/src/video/android/SDL_androidpen.h25
-rw-r--r--contrib/SDL-3.2.8/src/video/android/SDL_androidtouch.c96
-rw-r--r--contrib/SDL-3.2.8/src/video/android/SDL_androidtouch.h27
-rw-r--r--contrib/SDL-3.2.8/src/video/android/SDL_androidvideo.c331
-rw-r--r--contrib/SDL-3.2.8/src/video/android/SDL_androidvideo.h52
-rw-r--r--contrib/SDL-3.2.8/src/video/android/SDL_androidvulkan.c171
-rw-r--r--contrib/SDL-3.2.8/src/video/android/SDL_androidvulkan.h52
-rw-r--r--contrib/SDL-3.2.8/src/video/android/SDL_androidwindow.c204
-rw-r--r--contrib/SDL-3.2.8/src/video/android/SDL_androidwindow.h51
22 files changed, 2436 insertions, 0 deletions
diff --git a/contrib/SDL-3.2.8/src/video/android/SDL_androidclipboard.c b/contrib/SDL-3.2.8/src/video/android/SDL_androidclipboard.c
new file mode 100644
index 0000000..ec02350
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/video/android/SDL_androidclipboard.c
@@ -0,0 +1,44 @@
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#include "SDL_androidvideo.h"
26#include "SDL_androidclipboard.h"
27#include "../../core/android/SDL_android.h"
28
29bool Android_SetClipboardText(SDL_VideoDevice *_this, const char *text)
30{
31 return Android_JNI_SetClipboardText(text);
32}
33
34char *Android_GetClipboardText(SDL_VideoDevice *_this)
35{
36 return Android_JNI_GetClipboardText();
37}
38
39bool Android_HasClipboardText(SDL_VideoDevice *_this)
40{
41 return Android_JNI_HasClipboardText();
42}
43
44#endif // SDL_VIDEO_DRIVER_ANDROID
diff --git a/contrib/SDL-3.2.8/src/video/android/SDL_androidclipboard.h b/contrib/SDL-3.2.8/src/video/android/SDL_androidclipboard.h
new file mode 100644
index 0000000..d102112
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/video/android/SDL_androidclipboard.h
@@ -0,0 +1,30 @@
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#ifndef SDL_androidclipboard_h_
24#define SDL_androidclipboard_h_
25
26extern bool Android_SetClipboardText(SDL_VideoDevice *_this, const char *text);
27extern char *Android_GetClipboardText(SDL_VideoDevice *_this);
28extern bool Android_HasClipboardText(SDL_VideoDevice *_this);
29
30#endif // SDL_androidclipboard_h_
diff --git a/contrib/SDL-3.2.8/src/video/android/SDL_androidevents.c b/contrib/SDL-3.2.8/src/video/android/SDL_androidevents.c
new file mode 100644
index 0000000..e32d272
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/video/android/SDL_androidevents.c
@@ -0,0 +1,269 @@
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#include "SDL_androidevents.h"
26#include "SDL_androidkeyboard.h"
27#include "SDL_androidwindow.h"
28#include "../SDL_sysvideo.h"
29#include "../../events/SDL_events_c.h"
30
31#include "../../audio/aaudio/SDL_aaudio.h"
32#include "../../audio/openslES/SDL_openslES.h"
33
34
35#ifdef SDL_VIDEO_OPENGL_EGL
36static void android_egl_context_restore(SDL_Window *window)
37{
38 if (window) {
39 SDL_WindowData *data = window->internal;
40 SDL_GL_MakeCurrent(window, NULL);
41 if (!SDL_GL_MakeCurrent(window, (SDL_GLContext)data->egl_context)) {
42 // The context is no longer valid, create a new one
43 data->egl_context = (EGLContext)SDL_GL_CreateContext(window);
44 SDL_GL_MakeCurrent(window, (SDL_GLContext)data->egl_context);
45 SDL_Event event;
46 SDL_zero(event);
47 event.type = SDL_EVENT_RENDER_DEVICE_RESET;
48 event.render.windowID = SDL_GetWindowID(window);
49 SDL_PushEvent(&event);
50 }
51 data->backup_done = false;
52
53 if (data->has_swap_interval) {
54 SDL_GL_SetSwapInterval(data->swap_interval);
55 }
56
57 }
58}
59
60static void android_egl_context_backup(SDL_Window *window)
61{
62 if (window) {
63 int interval = 0;
64 // Keep a copy of the EGL Context so we can try to restore it when we resume
65 SDL_WindowData *data = window->internal;
66 data->egl_context = SDL_GL_GetCurrentContext();
67
68 // Save/Restore the swap interval / vsync
69 if (SDL_GL_GetSwapInterval(&interval)) {
70 data->has_swap_interval = 1;
71 data->swap_interval = interval;
72 }
73
74 // We need to do this so the EGLSurface can be freed
75 SDL_GL_MakeCurrent(window, NULL);
76 data->backup_done = true;
77 }
78}
79#endif
80
81/*
82 * Android_ResumeSem and Android_PauseSem are signaled from Java_org_libsdl_app_SDLActivity_nativePause and Java_org_libsdl_app_SDLActivity_nativeResume
83 */
84static bool Android_EventsInitialized;
85static bool Android_BlockOnPause = true;
86static bool Android_Paused;
87static bool Android_PausedAudio;
88static bool Android_Destroyed;
89
90void Android_InitEvents(void)
91{
92 if (!Android_EventsInitialized) {
93 Android_BlockOnPause = SDL_GetHintBoolean(SDL_HINT_ANDROID_BLOCK_ON_PAUSE, true);
94 Android_Paused = false;
95 Android_Destroyed = false;
96 Android_EventsInitialized = true;
97 }
98}
99
100static void Android_PauseAudio(void)
101{
102 OPENSLES_PauseDevices();
103 AAUDIO_PauseDevices();
104 Android_PausedAudio = true;
105}
106
107static void Android_ResumeAudio(void)
108{
109 if (Android_PausedAudio) {
110 OPENSLES_ResumeDevices();
111 AAUDIO_ResumeDevices();
112 Android_PausedAudio = false;
113 }
114}
115
116static void Android_OnPause(void)
117{
118 SDL_OnApplicationWillEnterBackground();
119 SDL_OnApplicationDidEnterBackground();
120
121 /* The semantics are that as soon as the enter background event
122 * has been queued, the app will block. The application should
123 * do any life cycle handling in an event filter while the event
124 * was being queued.
125 */
126#ifdef SDL_VIDEO_OPENGL_EGL
127 if (Android_Window && !Android_Window->external_graphics_context) {
128 Android_LockActivityMutex();
129 android_egl_context_backup(Android_Window);
130 Android_UnlockActivityMutex();
131 }
132#endif
133
134 if (Android_BlockOnPause) {
135 // We're blocking, also pause audio
136 Android_PauseAudio();
137 }
138
139 Android_Paused = true;
140}
141
142static void Android_OnResume(void)
143{
144 Android_Paused = false;
145
146 SDL_OnApplicationWillEnterForeground();
147
148 Android_ResumeAudio();
149
150#ifdef SDL_VIDEO_OPENGL_EGL
151 // Restore the GL Context from here, as this operation is thread dependent
152 if (Android_Window && !Android_Window->external_graphics_context && !SDL_HasEvent(SDL_EVENT_QUIT)) {
153 Android_LockActivityMutex();
154 android_egl_context_restore(Android_Window);
155 Android_UnlockActivityMutex();
156 }
157#endif
158
159 // Make sure SW Keyboard is restored when an app becomes foreground
160 if (Android_Window) {
161 Android_RestoreScreenKeyboardOnResume(SDL_GetVideoDevice(), Android_Window);
162 }
163
164 SDL_OnApplicationDidEnterForeground();
165}
166
167static void Android_OnLowMemory(void)
168{
169 SDL_SendAppEvent(SDL_EVENT_LOW_MEMORY);
170}
171
172static void Android_OnDestroy(void)
173{
174 // Make sure we unblock any audio processing before we quit
175 Android_ResumeAudio();
176
177 /* Discard previous events. The user should have handled state storage
178 * in SDL_EVENT_WILL_ENTER_BACKGROUND. After nativeSendQuit() is called, no
179 * events other than SDL_EVENT_QUIT and SDL_EVENT_TERMINATING should fire */
180 SDL_FlushEvents(SDL_EVENT_FIRST, SDL_EVENT_LAST);
181 SDL_SendQuit();
182 SDL_SendAppEvent(SDL_EVENT_TERMINATING);
183
184 Android_Destroyed = true;
185}
186
187static void Android_HandleLifecycleEvent(SDL_AndroidLifecycleEvent event)
188{
189 switch (event) {
190 case SDL_ANDROID_LIFECYCLE_WAKE:
191 // Nothing to do, just return
192 break;
193 case SDL_ANDROID_LIFECYCLE_PAUSE:
194 Android_OnPause();
195 break;
196 case SDL_ANDROID_LIFECYCLE_RESUME:
197 Android_OnResume();
198 break;
199 case SDL_ANDROID_LIFECYCLE_LOWMEMORY:
200 Android_OnLowMemory();
201 break;
202 case SDL_ANDROID_LIFECYCLE_DESTROY:
203 Android_OnDestroy();
204 break;
205 default:
206 break;
207 }
208}
209
210static Sint64 GetLifecycleEventTimeout(bool paused, Sint64 timeoutNS)
211{
212 if (Android_Paused) {
213 if (Android_BlockOnPause) {
214 timeoutNS = -1;
215 } else if (timeoutNS == 0) {
216 timeoutNS = SDL_MS_TO_NS(100);
217 }
218 }
219 return timeoutNS;
220}
221
222void Android_PumpEvents(Sint64 timeoutNS)
223{
224 SDL_AndroidLifecycleEvent event;
225 bool paused = Android_Paused;
226
227 while (!Android_Destroyed &&
228 Android_WaitLifecycleEvent(&event, GetLifecycleEventTimeout(paused, timeoutNS))) {
229 Android_HandleLifecycleEvent(event);
230
231 switch (event) {
232 case SDL_ANDROID_LIFECYCLE_WAKE:
233 // Finish handling events quickly if we're not paused
234 timeoutNS = 0;
235 break;
236 case SDL_ANDROID_LIFECYCLE_PAUSE:
237 // Finish handling events at the current timeout and return to process events one more time before blocking.
238 break;
239 case SDL_ANDROID_LIFECYCLE_RESUME:
240 // Finish handling events at the resume state timeout
241 paused = false;
242 break;
243 default:
244 break;
245 }
246 }
247}
248
249bool Android_WaitActiveAndLockActivity(void)
250{
251 while (Android_Paused && !Android_Destroyed) {
252 Android_PumpEvents(-1);
253 }
254
255 if (Android_Destroyed) {
256 SDL_SetError("Android activity has been destroyed");
257 return false;
258 }
259
260 Android_LockActivityMutex();
261 return true;
262}
263
264void Android_QuitEvents(void)
265{
266 Android_EventsInitialized = false;
267}
268
269#endif // SDL_VIDEO_DRIVER_ANDROID
diff --git a/contrib/SDL-3.2.8/src/video/android/SDL_androidevents.h b/contrib/SDL-3.2.8/src/video/android/SDL_androidevents.h
new file mode 100644
index 0000000..bb57d3b
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/video/android/SDL_androidevents.h
@@ -0,0 +1,26 @@
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
23extern void Android_InitEvents(void);
24extern void Android_PumpEvents(Sint64 timeoutNS);
25extern bool Android_WaitActiveAndLockActivity(void);
26extern void Android_QuitEvents(void);
diff --git a/contrib/SDL-3.2.8/src/video/android/SDL_androidgl.c b/contrib/SDL-3.2.8/src/video/android/SDL_androidgl.c
new file mode 100644
index 0000000..37fb2d5
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/video/android/SDL_androidgl.c
@@ -0,0 +1,88 @@
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#if defined(SDL_VIDEO_DRIVER_ANDROID) && defined(SDL_VIDEO_OPENGL_EGL)
24
25// Android SDL video driver implementation
26
27#include "../SDL_egl_c.h"
28#include "SDL_androidwindow.h"
29
30#include "SDL_androidvideo.h"
31#include "SDL_androidevents.h"
32#include "SDL_androidgl.h"
33#include "../../core/android/SDL_android.h"
34
35#include <android/log.h>
36
37#include <dlfcn.h>
38
39bool Android_GLES_MakeCurrent(SDL_VideoDevice *_this, SDL_Window *window, SDL_GLContext context)
40{
41 if (window && context) {
42 return SDL_EGL_MakeCurrent(_this, window->internal->egl_surface, context);
43 } else {
44 return SDL_EGL_MakeCurrent(_this, NULL, NULL);
45 }
46}
47
48SDL_GLContext Android_GLES_CreateContext(SDL_VideoDevice *_this, SDL_Window *window)
49{
50 SDL_GLContext result;
51
52 if (!Android_WaitActiveAndLockActivity()) {
53 return NULL;
54 }
55
56 result = SDL_EGL_CreateContext(_this, window->internal->egl_surface);
57
58 Android_UnlockActivityMutex();
59
60 return result;
61}
62
63bool Android_GLES_SwapWindow(SDL_VideoDevice *_this, SDL_Window *window)
64{
65 bool result;
66
67 Android_LockActivityMutex();
68
69 /* The following two calls existed in the original Java code
70 * If you happen to have a device that's affected by their removal,
71 * please report to our bug tracker. -- Gabriel
72 */
73
74 /*_this->egl_data->eglWaitNative(EGL_CORE_NATIVE_ENGINE);
75 _this->egl_data->eglWaitGL();*/
76 result = SDL_EGL_SwapBuffers(_this, window->internal->egl_surface);
77
78 Android_UnlockActivityMutex();
79
80 return result;
81}
82
83bool Android_GLES_LoadLibrary(SDL_VideoDevice *_this, const char *path)
84{
85 return SDL_EGL_LoadLibrary(_this, path, (NativeDisplayType)0, 0);
86}
87
88#endif // SDL_VIDEO_DRIVER_ANDROID
diff --git a/contrib/SDL-3.2.8/src/video/android/SDL_androidgl.h b/contrib/SDL-3.2.8/src/video/android/SDL_androidgl.h
new file mode 100644
index 0000000..99c84d0
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/video/android/SDL_androidgl.h
@@ -0,0 +1,31 @@
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#ifndef SDL_androidgl_h_
24#define SDL_androidgl_h_
25
26extern SDL_GLContext Android_GLES_CreateContext(SDL_VideoDevice *_this, SDL_Window *window);
27extern bool Android_GLES_MakeCurrent(SDL_VideoDevice *_this, SDL_Window *window, SDL_GLContext context);
28extern bool Android_GLES_SwapWindow(SDL_VideoDevice *_this, SDL_Window *window);
29extern bool Android_GLES_LoadLibrary(SDL_VideoDevice *_this, const char *path);
30
31#endif // SDL_androidgl_h_
diff --git a/contrib/SDL-3.2.8/src/video/android/SDL_androidkeyboard.c b/contrib/SDL-3.2.8/src/video/android/SDL_androidkeyboard.c
new file mode 100644
index 0000000..03af7c6
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/video/android/SDL_androidkeyboard.c
@@ -0,0 +1,468 @@
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#include <android/log.h>
26
27#include "../../events/SDL_events_c.h"
28
29#include "SDL_androidkeyboard.h"
30
31#include "../../core/android/SDL_android.h"
32
33#define TYPE_CLASS_TEXT 0x00000001
34#define TYPE_CLASS_NUMBER 0x00000002
35#define TYPE_CLASS_PHONE 0x00000003
36#define TYPE_CLASS_DATETIME 0x00000004
37
38#define TYPE_DATETIME_VARIATION_NORMAL 0x00000000
39#define TYPE_DATETIME_VARIATION_DATE 0x00000010
40#define TYPE_DATETIME_VARIATION_TIME 0x00000020
41
42#define TYPE_NUMBER_VARIATION_NORMAL 0x00000000
43#define TYPE_NUMBER_VARIATION_PASSWORD 0x00000010
44#define TYPE_NUMBER_FLAG_SIGNED 0x00001000
45#define TYPE_NUMBER_FLAG_DECIMAL 0x00002000
46
47#define TYPE_TEXT_FLAG_CAP_CHARACTERS 0x00001000
48#define TYPE_TEXT_FLAG_CAP_WORDS 0x00002000
49#define TYPE_TEXT_FLAG_CAP_SENTENCES 0x00004000
50#define TYPE_TEXT_FLAG_AUTO_CORRECT 0x00008000
51#define TYPE_TEXT_FLAG_AUTO_COMPLETE 0x00010000
52#define TYPE_TEXT_FLAG_MULTI_LINE 0x00020000
53#define TYPE_TEXT_FLAG_IME_MULTI_LINE 0x00040000
54#define TYPE_TEXT_FLAG_NO_SUGGESTIONS 0x00080000
55
56#define TYPE_TEXT_VARIATION_NORMAL 0x00000000
57#define TYPE_TEXT_VARIATION_URI 0x00000010
58#define TYPE_TEXT_VARIATION_EMAIL_ADDRESS 0x00000020
59#define TYPE_TEXT_VARIATION_EMAIL_SUBJECT 0x00000030
60#define TYPE_TEXT_VARIATION_SHORT_MESSAGE 0x00000040
61#define TYPE_TEXT_VARIATION_LONG_MESSAGE 0x00000050
62#define TYPE_TEXT_VARIATION_PERSON_NAME 0x00000060
63#define TYPE_TEXT_VARIATION_POSTAL_ADDRESS 0x00000070
64#define TYPE_TEXT_VARIATION_PASSWORD 0x00000080
65#define TYPE_TEXT_VARIATION_VISIBLE_PASSWORD 0x00000090
66#define TYPE_TEXT_VARIATION_WEB_EDIT_TEXT 0x000000a0
67#define TYPE_TEXT_VARIATION_FILTER 0x000000b0
68#define TYPE_TEXT_VARIATION_PHONETIC 0x000000c0
69#define TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS 0x000000d0
70#define TYPE_TEXT_VARIATION_WEB_PASSWORD 0x000000e0
71
72
73static SDL_Scancode Android_Keycodes[] = {
74 SDL_SCANCODE_UNKNOWN, // AKEYCODE_UNKNOWN
75 SDL_SCANCODE_SOFTLEFT, // AKEYCODE_SOFT_LEFT
76 SDL_SCANCODE_SOFTRIGHT, // AKEYCODE_SOFT_RIGHT
77 SDL_SCANCODE_AC_HOME, // AKEYCODE_HOME
78 SDL_SCANCODE_AC_BACK, // AKEYCODE_BACK
79 SDL_SCANCODE_CALL, // AKEYCODE_CALL
80 SDL_SCANCODE_ENDCALL, // AKEYCODE_ENDCALL
81 SDL_SCANCODE_0, // AKEYCODE_0
82 SDL_SCANCODE_1, // AKEYCODE_1
83 SDL_SCANCODE_2, // AKEYCODE_2
84 SDL_SCANCODE_3, // AKEYCODE_3
85 SDL_SCANCODE_4, // AKEYCODE_4
86 SDL_SCANCODE_5, // AKEYCODE_5
87 SDL_SCANCODE_6, // AKEYCODE_6
88 SDL_SCANCODE_7, // AKEYCODE_7
89 SDL_SCANCODE_8, // AKEYCODE_8
90 SDL_SCANCODE_9, // AKEYCODE_9
91 SDL_SCANCODE_UNKNOWN, // AKEYCODE_STAR
92 SDL_SCANCODE_UNKNOWN, // AKEYCODE_POUND
93 SDL_SCANCODE_UP, // AKEYCODE_DPAD_UP
94 SDL_SCANCODE_DOWN, // AKEYCODE_DPAD_DOWN
95 SDL_SCANCODE_LEFT, // AKEYCODE_DPAD_LEFT
96 SDL_SCANCODE_RIGHT, // AKEYCODE_DPAD_RIGHT
97 SDL_SCANCODE_SELECT, // AKEYCODE_DPAD_CENTER
98 SDL_SCANCODE_VOLUMEUP, // AKEYCODE_VOLUME_UP
99 SDL_SCANCODE_VOLUMEDOWN, // AKEYCODE_VOLUME_DOWN
100 SDL_SCANCODE_POWER, // AKEYCODE_POWER
101 SDL_SCANCODE_UNKNOWN, // AKEYCODE_CAMERA
102 SDL_SCANCODE_CLEAR, // AKEYCODE_CLEAR
103 SDL_SCANCODE_A, // AKEYCODE_A
104 SDL_SCANCODE_B, // AKEYCODE_B
105 SDL_SCANCODE_C, // AKEYCODE_C
106 SDL_SCANCODE_D, // AKEYCODE_D
107 SDL_SCANCODE_E, // AKEYCODE_E
108 SDL_SCANCODE_F, // AKEYCODE_F
109 SDL_SCANCODE_G, // AKEYCODE_G
110 SDL_SCANCODE_H, // AKEYCODE_H
111 SDL_SCANCODE_I, // AKEYCODE_I
112 SDL_SCANCODE_J, // AKEYCODE_J
113 SDL_SCANCODE_K, // AKEYCODE_K
114 SDL_SCANCODE_L, // AKEYCODE_L
115 SDL_SCANCODE_M, // AKEYCODE_M
116 SDL_SCANCODE_N, // AKEYCODE_N
117 SDL_SCANCODE_O, // AKEYCODE_O
118 SDL_SCANCODE_P, // AKEYCODE_P
119 SDL_SCANCODE_Q, // AKEYCODE_Q
120 SDL_SCANCODE_R, // AKEYCODE_R
121 SDL_SCANCODE_S, // AKEYCODE_S
122 SDL_SCANCODE_T, // AKEYCODE_T
123 SDL_SCANCODE_U, // AKEYCODE_U
124 SDL_SCANCODE_V, // AKEYCODE_V
125 SDL_SCANCODE_W, // AKEYCODE_W
126 SDL_SCANCODE_X, // AKEYCODE_X
127 SDL_SCANCODE_Y, // AKEYCODE_Y
128 SDL_SCANCODE_Z, // AKEYCODE_Z
129 SDL_SCANCODE_COMMA, // AKEYCODE_COMMA
130 SDL_SCANCODE_PERIOD, // AKEYCODE_PERIOD
131 SDL_SCANCODE_LALT, // AKEYCODE_ALT_LEFT
132 SDL_SCANCODE_RALT, // AKEYCODE_ALT_RIGHT
133 SDL_SCANCODE_LSHIFT, // AKEYCODE_SHIFT_LEFT
134 SDL_SCANCODE_RSHIFT, // AKEYCODE_SHIFT_RIGHT
135 SDL_SCANCODE_TAB, // AKEYCODE_TAB
136 SDL_SCANCODE_SPACE, // AKEYCODE_SPACE
137 SDL_SCANCODE_UNKNOWN, // AKEYCODE_SYM
138 SDL_SCANCODE_UNKNOWN, // AKEYCODE_EXPLORER
139 SDL_SCANCODE_UNKNOWN, // AKEYCODE_ENVELOPE
140 SDL_SCANCODE_RETURN, // AKEYCODE_ENTER
141 SDL_SCANCODE_BACKSPACE, // AKEYCODE_DEL
142 SDL_SCANCODE_GRAVE, // AKEYCODE_GRAVE
143 SDL_SCANCODE_MINUS, // AKEYCODE_MINUS
144 SDL_SCANCODE_EQUALS, // AKEYCODE_EQUALS
145 SDL_SCANCODE_LEFTBRACKET, // AKEYCODE_LEFT_BRACKET
146 SDL_SCANCODE_RIGHTBRACKET, // AKEYCODE_RIGHT_BRACKET
147 SDL_SCANCODE_BACKSLASH, // AKEYCODE_BACKSLASH
148 SDL_SCANCODE_SEMICOLON, // AKEYCODE_SEMICOLON
149 SDL_SCANCODE_APOSTROPHE, // AKEYCODE_APOSTROPHE
150 SDL_SCANCODE_SLASH, // AKEYCODE_SLASH
151 SDL_SCANCODE_UNKNOWN, // AKEYCODE_AT
152 SDL_SCANCODE_UNKNOWN, // AKEYCODE_NUM
153 SDL_SCANCODE_UNKNOWN, // AKEYCODE_HEADSETHOOK
154 SDL_SCANCODE_UNKNOWN, // AKEYCODE_FOCUS
155 SDL_SCANCODE_UNKNOWN, // AKEYCODE_PLUS
156 SDL_SCANCODE_MENU, // AKEYCODE_MENU
157 SDL_SCANCODE_UNKNOWN, // AKEYCODE_NOTIFICATION
158 SDL_SCANCODE_AC_SEARCH, // AKEYCODE_SEARCH
159 SDL_SCANCODE_MEDIA_PLAY_PAUSE, // AKEYCODE_MEDIA_PLAY_PAUSE
160 SDL_SCANCODE_MEDIA_STOP, // AKEYCODE_MEDIA_STOP
161 SDL_SCANCODE_MEDIA_NEXT_TRACK, // AKEYCODE_MEDIA_NEXT
162 SDL_SCANCODE_MEDIA_PREVIOUS_TRACK, // AKEYCODE_MEDIA_PREVIOUS
163 SDL_SCANCODE_MEDIA_REWIND, // AKEYCODE_MEDIA_REWIND
164 SDL_SCANCODE_MEDIA_FAST_FORWARD, // AKEYCODE_MEDIA_FAST_FORWARD
165 SDL_SCANCODE_MUTE, // AKEYCODE_MUTE
166 SDL_SCANCODE_PAGEUP, // AKEYCODE_PAGE_UP
167 SDL_SCANCODE_PAGEDOWN, // AKEYCODE_PAGE_DOWN
168 SDL_SCANCODE_UNKNOWN, // AKEYCODE_PICTSYMBOLS
169 SDL_SCANCODE_UNKNOWN, // AKEYCODE_SWITCH_CHARSET
170 SDL_SCANCODE_UNKNOWN, // AKEYCODE_BUTTON_A
171 SDL_SCANCODE_UNKNOWN, // AKEYCODE_BUTTON_B
172 SDL_SCANCODE_UNKNOWN, // AKEYCODE_BUTTON_C
173 SDL_SCANCODE_UNKNOWN, // AKEYCODE_BUTTON_X
174 SDL_SCANCODE_UNKNOWN, // AKEYCODE_BUTTON_Y
175 SDL_SCANCODE_UNKNOWN, // AKEYCODE_BUTTON_Z
176 SDL_SCANCODE_UNKNOWN, // AKEYCODE_BUTTON_L1
177 SDL_SCANCODE_UNKNOWN, // AKEYCODE_BUTTON_R1
178 SDL_SCANCODE_UNKNOWN, // AKEYCODE_BUTTON_L2
179 SDL_SCANCODE_UNKNOWN, // AKEYCODE_BUTTON_R2
180 SDL_SCANCODE_UNKNOWN, // AKEYCODE_BUTTON_THUMBL
181 SDL_SCANCODE_UNKNOWN, // AKEYCODE_BUTTON_THUMBR
182 SDL_SCANCODE_UNKNOWN, // AKEYCODE_BUTTON_START
183 SDL_SCANCODE_UNKNOWN, // AKEYCODE_BUTTON_SELECT
184 SDL_SCANCODE_UNKNOWN, // AKEYCODE_BUTTON_MODE
185 SDL_SCANCODE_ESCAPE, // AKEYCODE_ESCAPE
186 SDL_SCANCODE_DELETE, // AKEYCODE_FORWARD_DEL
187 SDL_SCANCODE_LCTRL, // AKEYCODE_CTRL_LEFT
188 SDL_SCANCODE_RCTRL, // AKEYCODE_CTRL_RIGHT
189 SDL_SCANCODE_CAPSLOCK, // AKEYCODE_CAPS_LOCK
190 SDL_SCANCODE_SCROLLLOCK, // AKEYCODE_SCROLL_LOCK
191 SDL_SCANCODE_LGUI, // AKEYCODE_META_LEFT
192 SDL_SCANCODE_RGUI, // AKEYCODE_META_RIGHT
193 SDL_SCANCODE_UNKNOWN, // AKEYCODE_FUNCTION
194 SDL_SCANCODE_PRINTSCREEN, // AKEYCODE_SYSRQ
195 SDL_SCANCODE_PAUSE, // AKEYCODE_BREAK
196 SDL_SCANCODE_HOME, // AKEYCODE_MOVE_HOME
197 SDL_SCANCODE_END, // AKEYCODE_MOVE_END
198 SDL_SCANCODE_INSERT, // AKEYCODE_INSERT
199 SDL_SCANCODE_AC_FORWARD, // AKEYCODE_FORWARD
200 SDL_SCANCODE_MEDIA_PLAY, // AKEYCODE_MEDIA_PLAY
201 SDL_SCANCODE_MEDIA_PAUSE, // AKEYCODE_MEDIA_PAUSE
202 SDL_SCANCODE_UNKNOWN, // AKEYCODE_MEDIA_CLOSE
203 SDL_SCANCODE_MEDIA_EJECT, // AKEYCODE_MEDIA_EJECT
204 SDL_SCANCODE_MEDIA_RECORD, // AKEYCODE_MEDIA_RECORD
205 SDL_SCANCODE_F1, // AKEYCODE_F1
206 SDL_SCANCODE_F2, // AKEYCODE_F2
207 SDL_SCANCODE_F3, // AKEYCODE_F3
208 SDL_SCANCODE_F4, // AKEYCODE_F4
209 SDL_SCANCODE_F5, // AKEYCODE_F5
210 SDL_SCANCODE_F6, // AKEYCODE_F6
211 SDL_SCANCODE_F7, // AKEYCODE_F7
212 SDL_SCANCODE_F8, // AKEYCODE_F8
213 SDL_SCANCODE_F9, // AKEYCODE_F9
214 SDL_SCANCODE_F10, // AKEYCODE_F10
215 SDL_SCANCODE_F11, // AKEYCODE_F11
216 SDL_SCANCODE_F12, // AKEYCODE_F12
217 SDL_SCANCODE_NUMLOCKCLEAR, // AKEYCODE_NUM_LOCK
218 SDL_SCANCODE_KP_0, // AKEYCODE_NUMPAD_0
219 SDL_SCANCODE_KP_1, // AKEYCODE_NUMPAD_1
220 SDL_SCANCODE_KP_2, // AKEYCODE_NUMPAD_2
221 SDL_SCANCODE_KP_3, // AKEYCODE_NUMPAD_3
222 SDL_SCANCODE_KP_4, // AKEYCODE_NUMPAD_4
223 SDL_SCANCODE_KP_5, // AKEYCODE_NUMPAD_5
224 SDL_SCANCODE_KP_6, // AKEYCODE_NUMPAD_6
225 SDL_SCANCODE_KP_7, // AKEYCODE_NUMPAD_7
226 SDL_SCANCODE_KP_8, // AKEYCODE_NUMPAD_8
227 SDL_SCANCODE_KP_9, // AKEYCODE_NUMPAD_9
228 SDL_SCANCODE_KP_DIVIDE, // AKEYCODE_NUMPAD_DIVIDE
229 SDL_SCANCODE_KP_MULTIPLY, // AKEYCODE_NUMPAD_MULTIPLY
230 SDL_SCANCODE_KP_MINUS, // AKEYCODE_NUMPAD_SUBTRACT
231 SDL_SCANCODE_KP_PLUS, // AKEYCODE_NUMPAD_ADD
232 SDL_SCANCODE_KP_PERIOD, // AKEYCODE_NUMPAD_DOT
233 SDL_SCANCODE_KP_COMMA, // AKEYCODE_NUMPAD_COMMA
234 SDL_SCANCODE_KP_ENTER, // AKEYCODE_NUMPAD_ENTER
235 SDL_SCANCODE_KP_EQUALS, // AKEYCODE_NUMPAD_EQUALS
236 SDL_SCANCODE_KP_LEFTPAREN, // AKEYCODE_NUMPAD_LEFT_PAREN
237 SDL_SCANCODE_KP_RIGHTPAREN, // AKEYCODE_NUMPAD_RIGHT_PAREN
238 SDL_SCANCODE_UNKNOWN, // AKEYCODE_VOLUME_MUTE
239 SDL_SCANCODE_UNKNOWN, // AKEYCODE_INFO
240 SDL_SCANCODE_CHANNEL_INCREMENT, // AKEYCODE_CHANNEL_UP
241 SDL_SCANCODE_CHANNEL_INCREMENT, // AKEYCODE_CHANNEL_DOWN
242 SDL_SCANCODE_UNKNOWN, // AKEYCODE_ZOOM_IN
243 SDL_SCANCODE_UNKNOWN, // AKEYCODE_ZOOM_OUT
244 SDL_SCANCODE_UNKNOWN, // AKEYCODE_TV
245 SDL_SCANCODE_UNKNOWN, // AKEYCODE_WINDOW
246 SDL_SCANCODE_UNKNOWN, // AKEYCODE_GUIDE
247 SDL_SCANCODE_UNKNOWN, // AKEYCODE_DVR
248 SDL_SCANCODE_AC_BOOKMARKS, // AKEYCODE_BOOKMARK
249 SDL_SCANCODE_UNKNOWN, // AKEYCODE_CAPTIONS
250 SDL_SCANCODE_UNKNOWN, // AKEYCODE_SETTINGS
251 SDL_SCANCODE_UNKNOWN, // AKEYCODE_TV_POWER
252 SDL_SCANCODE_UNKNOWN, // AKEYCODE_TV_INPUT
253 SDL_SCANCODE_UNKNOWN, // AKEYCODE_STB_POWER
254 SDL_SCANCODE_UNKNOWN, // AKEYCODE_STB_INPUT
255 SDL_SCANCODE_UNKNOWN, // AKEYCODE_AVR_POWER
256 SDL_SCANCODE_UNKNOWN, // AKEYCODE_AVR_INPUT
257 SDL_SCANCODE_UNKNOWN, // AKEYCODE_PROG_RED
258 SDL_SCANCODE_UNKNOWN, // AKEYCODE_PROG_GREEN
259 SDL_SCANCODE_UNKNOWN, // AKEYCODE_PROG_YELLOW
260 SDL_SCANCODE_UNKNOWN, // AKEYCODE_PROG_BLUE
261 SDL_SCANCODE_UNKNOWN, // AKEYCODE_APP_SWITCH
262 SDL_SCANCODE_UNKNOWN, // AKEYCODE_BUTTON_1
263 SDL_SCANCODE_UNKNOWN, // AKEYCODE_BUTTON_2
264 SDL_SCANCODE_UNKNOWN, // AKEYCODE_BUTTON_3
265 SDL_SCANCODE_UNKNOWN, // AKEYCODE_BUTTON_4
266 SDL_SCANCODE_UNKNOWN, // AKEYCODE_BUTTON_5
267 SDL_SCANCODE_UNKNOWN, // AKEYCODE_BUTTON_6
268 SDL_SCANCODE_UNKNOWN, // AKEYCODE_BUTTON_7
269 SDL_SCANCODE_UNKNOWN, // AKEYCODE_BUTTON_8
270 SDL_SCANCODE_UNKNOWN, // AKEYCODE_BUTTON_9
271 SDL_SCANCODE_UNKNOWN, // AKEYCODE_BUTTON_10
272 SDL_SCANCODE_UNKNOWN, // AKEYCODE_BUTTON_11
273 SDL_SCANCODE_UNKNOWN, // AKEYCODE_BUTTON_12
274 SDL_SCANCODE_UNKNOWN, // AKEYCODE_BUTTON_13
275 SDL_SCANCODE_UNKNOWN, // AKEYCODE_BUTTON_14
276 SDL_SCANCODE_UNKNOWN, // AKEYCODE_BUTTON_15
277 SDL_SCANCODE_UNKNOWN, // AKEYCODE_BUTTON_16
278 SDL_SCANCODE_UNKNOWN, // AKEYCODE_LANGUAGE_SWITCH
279 SDL_SCANCODE_UNKNOWN, // AKEYCODE_MANNER_MODE
280 SDL_SCANCODE_UNKNOWN, // AKEYCODE_3D_MODE
281 SDL_SCANCODE_UNKNOWN, // AKEYCODE_CONTACTS
282 SDL_SCANCODE_UNKNOWN, // AKEYCODE_CALENDAR
283 SDL_SCANCODE_UNKNOWN, // AKEYCODE_MUSIC
284 SDL_SCANCODE_UNKNOWN, // AKEYCODE_CALCULATOR
285 SDL_SCANCODE_LANG5, // AKEYCODE_ZENKAKU_HANKAKU
286 SDL_SCANCODE_UNKNOWN, // AKEYCODE_EISU
287 SDL_SCANCODE_INTERNATIONAL5, // AKEYCODE_MUHENKAN
288 SDL_SCANCODE_INTERNATIONAL4, // AKEYCODE_HENKAN
289 SDL_SCANCODE_LANG3, // AKEYCODE_KATAKANA_HIRAGANA
290 SDL_SCANCODE_INTERNATIONAL3, // AKEYCODE_YEN
291 SDL_SCANCODE_UNKNOWN, // AKEYCODE_RO
292 SDL_SCANCODE_UNKNOWN, // AKEYCODE_KANA
293 SDL_SCANCODE_UNKNOWN, // AKEYCODE_ASSIST
294 SDL_SCANCODE_UNKNOWN, // AKEYCODE_BRIGHTNESS_DOWN
295 SDL_SCANCODE_UNKNOWN, // AKEYCODE_BRIGHTNESS_UP
296 SDL_SCANCODE_UNKNOWN, // AKEYCODE_MEDIA_AUDIO_TRACK
297 SDL_SCANCODE_SLEEP, // AKEYCODE_SLEEP
298 SDL_SCANCODE_UNKNOWN, // AKEYCODE_WAKEUP
299 SDL_SCANCODE_UNKNOWN, // AKEYCODE_PAIRING
300 SDL_SCANCODE_UNKNOWN, // AKEYCODE_MEDIA_TOP_MENU
301 SDL_SCANCODE_UNKNOWN, // AKEYCODE_11
302 SDL_SCANCODE_UNKNOWN, // AKEYCODE_12
303 SDL_SCANCODE_UNKNOWN, // AKEYCODE_LAST_CHANNEL
304 SDL_SCANCODE_UNKNOWN, // AKEYCODE_TV_DATA_SERVICE
305 SDL_SCANCODE_UNKNOWN, // AKEYCODE_VOICE_ASSIST
306 SDL_SCANCODE_UNKNOWN, // AKEYCODE_TV_RADIO_SERVICE
307 SDL_SCANCODE_UNKNOWN, // AKEYCODE_TV_TELETEXT
308 SDL_SCANCODE_UNKNOWN, // AKEYCODE_TV_NUMBER_ENTRY
309 SDL_SCANCODE_UNKNOWN, // AKEYCODE_TV_TERRESTRIAL_ANALOG
310 SDL_SCANCODE_UNKNOWN, // AKEYCODE_TV_TERRESTRIAL_DIGITAL
311 SDL_SCANCODE_UNKNOWN, // AKEYCODE_TV_SATELLITE
312 SDL_SCANCODE_UNKNOWN, // AKEYCODE_TV_SATELLITE_BS
313 SDL_SCANCODE_UNKNOWN, // AKEYCODE_TV_SATELLITE_CS
314 SDL_SCANCODE_UNKNOWN, // AKEYCODE_TV_SATELLITE_SERVICE
315 SDL_SCANCODE_UNKNOWN, // AKEYCODE_TV_NETWORK
316 SDL_SCANCODE_UNKNOWN, // AKEYCODE_TV_ANTENNA_CABLE
317 SDL_SCANCODE_UNKNOWN, // AKEYCODE_TV_INPUT_HDMI_1
318 SDL_SCANCODE_UNKNOWN, // AKEYCODE_TV_INPUT_HDMI_2
319 SDL_SCANCODE_UNKNOWN, // AKEYCODE_TV_INPUT_HDMI_3
320 SDL_SCANCODE_UNKNOWN, // AKEYCODE_TV_INPUT_HDMI_4
321 SDL_SCANCODE_UNKNOWN, // AKEYCODE_TV_INPUT_COMPOSITE_1
322 SDL_SCANCODE_UNKNOWN, // AKEYCODE_TV_INPUT_COMPOSITE_2
323 SDL_SCANCODE_UNKNOWN, // AKEYCODE_TV_INPUT_COMPONENT_1
324 SDL_SCANCODE_UNKNOWN, // AKEYCODE_TV_INPUT_COMPONENT_2
325 SDL_SCANCODE_UNKNOWN, // AKEYCODE_TV_INPUT_VGA_1
326 SDL_SCANCODE_UNKNOWN, // AKEYCODE_TV_AUDIO_DESCRIPTION
327 SDL_SCANCODE_UNKNOWN, // AKEYCODE_TV_AUDIO_DESCRIPTION_MIX_UP
328 SDL_SCANCODE_UNKNOWN, // AKEYCODE_TV_AUDIO_DESCRIPTION_MIX_DOWN
329 SDL_SCANCODE_UNKNOWN, // AKEYCODE_TV_ZOOM_MODE
330 SDL_SCANCODE_UNKNOWN, // AKEYCODE_TV_CONTENTS_MENU
331 SDL_SCANCODE_UNKNOWN, // AKEYCODE_TV_MEDIA_CONTEXT_MENU
332 SDL_SCANCODE_UNKNOWN, // AKEYCODE_TV_TIMER_PROGRAMMING
333 SDL_SCANCODE_HELP, // AKEYCODE_HELP
334 SDL_SCANCODE_UNKNOWN, // AKEYCODE_NAVIGATE_PREVIOUS
335 SDL_SCANCODE_UNKNOWN, // AKEYCODE_NAVIGATE_NEXT
336 SDL_SCANCODE_UNKNOWN, // AKEYCODE_NAVIGATE_IN
337 SDL_SCANCODE_UNKNOWN, // AKEYCODE_NAVIGATE_OUT
338 SDL_SCANCODE_UNKNOWN, // AKEYCODE_STEM_PRIMARY
339 SDL_SCANCODE_UNKNOWN, // AKEYCODE_STEM_1
340 SDL_SCANCODE_UNKNOWN, // AKEYCODE_STEM_2
341 SDL_SCANCODE_UNKNOWN, // AKEYCODE_STEM_3
342 SDL_SCANCODE_UNKNOWN, // AKEYCODE_DPAD_UP_LEFT
343 SDL_SCANCODE_UNKNOWN, // AKEYCODE_DPAD_DOWN_LEFT
344 SDL_SCANCODE_UNKNOWN, // AKEYCODE_DPAD_UP_RIGHT
345 SDL_SCANCODE_UNKNOWN, // AKEYCODE_DPAD_DOWN_RIGHT
346 SDL_SCANCODE_UNKNOWN, // AKEYCODE_MEDIA_SKIP_FORWARD
347 SDL_SCANCODE_UNKNOWN, // AKEYCODE_MEDIA_SKIP_BACKWARD
348 SDL_SCANCODE_UNKNOWN, // AKEYCODE_MEDIA_STEP_FORWARD
349 SDL_SCANCODE_UNKNOWN, // AKEYCODE_MEDIA_STEP_BACKWARD
350 SDL_SCANCODE_UNKNOWN, // AKEYCODE_SOFT_SLEEP
351 SDL_SCANCODE_CUT, // AKEYCODE_CUT
352 SDL_SCANCODE_COPY, // AKEYCODE_COPY
353 SDL_SCANCODE_PASTE, // AKEYCODE_PASTE
354};
355
356static bool SDL_screen_keyboard_shown;
357
358static SDL_Scancode TranslateKeycode(int keycode)
359{
360 SDL_Scancode scancode = SDL_SCANCODE_UNKNOWN;
361
362 if (keycode < SDL_arraysize(Android_Keycodes)) {
363 scancode = Android_Keycodes[keycode];
364 }
365 if (scancode == SDL_SCANCODE_UNKNOWN) {
366 __android_log_print(ANDROID_LOG_INFO, "SDL", "Unknown keycode %d", keycode);
367 }
368 return scancode;
369}
370
371void Android_OnKeyDown(int keycode)
372{
373 SDL_SendKeyboardKey(0, SDL_DEFAULT_KEYBOARD_ID, keycode, TranslateKeycode(keycode), true);
374}
375
376void Android_OnKeyUp(int keycode)
377{
378 SDL_SendKeyboardKey(0, SDL_DEFAULT_KEYBOARD_ID, keycode, TranslateKeycode(keycode), false);
379}
380
381bool Android_HasScreenKeyboardSupport(SDL_VideoDevice *_this)
382{
383 return true;
384}
385
386void Android_ShowScreenKeyboard(SDL_VideoDevice *_this, SDL_Window *window, SDL_PropertiesID props)
387{
388 int input_type = 0;
389 if (SDL_HasProperty(props, SDL_PROP_TEXTINPUT_ANDROID_INPUTTYPE_NUMBER)) {
390 input_type = (int)SDL_GetNumberProperty(props, SDL_PROP_TEXTINPUT_ANDROID_INPUTTYPE_NUMBER, 0);
391 } else {
392 switch (SDL_GetTextInputType(props)) {
393 default:
394 case SDL_TEXTINPUT_TYPE_TEXT:
395 input_type = (TYPE_CLASS_TEXT | TYPE_TEXT_VARIATION_NORMAL);
396 break;
397 case SDL_TEXTINPUT_TYPE_TEXT_NAME:
398 input_type = (TYPE_CLASS_TEXT | TYPE_TEXT_VARIATION_PERSON_NAME);
399 break;
400 case SDL_TEXTINPUT_TYPE_TEXT_EMAIL:
401 input_type = (TYPE_CLASS_TEXT | TYPE_TEXT_VARIATION_EMAIL_ADDRESS);
402 break;
403 case SDL_TEXTINPUT_TYPE_TEXT_USERNAME:
404 input_type = (TYPE_CLASS_TEXT | TYPE_TEXT_VARIATION_NORMAL);
405 break;
406 case SDL_TEXTINPUT_TYPE_TEXT_PASSWORD_HIDDEN:
407 input_type = (TYPE_CLASS_TEXT | TYPE_TEXT_VARIATION_PASSWORD);
408 break;
409 case SDL_TEXTINPUT_TYPE_TEXT_PASSWORD_VISIBLE:
410 input_type = (TYPE_CLASS_TEXT | TYPE_TEXT_VARIATION_VISIBLE_PASSWORD);
411 break;
412 case SDL_TEXTINPUT_TYPE_NUMBER:
413 input_type = (TYPE_CLASS_NUMBER | TYPE_NUMBER_VARIATION_NORMAL);
414 break;
415 case SDL_TEXTINPUT_TYPE_NUMBER_PASSWORD_HIDDEN:
416 input_type = (TYPE_CLASS_NUMBER | TYPE_NUMBER_VARIATION_PASSWORD);
417 break;
418 case SDL_TEXTINPUT_TYPE_NUMBER_PASSWORD_VISIBLE:
419 input_type = (TYPE_CLASS_NUMBER | TYPE_NUMBER_VARIATION_NORMAL);
420 break;
421 }
422
423 switch (SDL_GetTextInputCapitalization(props)) {
424 default:
425 case SDL_CAPITALIZE_NONE:
426 break;
427 case SDL_CAPITALIZE_LETTERS:
428 input_type |= TYPE_TEXT_FLAG_CAP_CHARACTERS;
429 break;
430 case SDL_CAPITALIZE_WORDS:
431 input_type |= TYPE_TEXT_FLAG_CAP_WORDS;
432 break;
433 case SDL_CAPITALIZE_SENTENCES:
434 input_type |= TYPE_TEXT_FLAG_CAP_SENTENCES;
435 break;
436 }
437
438 if (SDL_GetTextInputAutocorrect(props)) {
439 input_type |= (TYPE_TEXT_FLAG_AUTO_CORRECT | TYPE_TEXT_FLAG_AUTO_COMPLETE);
440 }
441
442 if (SDL_GetTextInputMultiline(props)) {
443 input_type |= TYPE_TEXT_FLAG_MULTI_LINE;
444 }
445 }
446 Android_JNI_ShowScreenKeyboard(input_type, &window->text_input_rect);
447 SDL_screen_keyboard_shown = true;
448}
449
450void Android_HideScreenKeyboard(SDL_VideoDevice *_this, SDL_Window *window)
451{
452 Android_JNI_HideScreenKeyboard();
453 SDL_screen_keyboard_shown = false;
454}
455
456void Android_RestoreScreenKeyboardOnResume(SDL_VideoDevice *_this, SDL_Window *window)
457{
458 if (SDL_screen_keyboard_shown) {
459 Android_ShowScreenKeyboard(_this, window, window->text_input_props);
460 }
461}
462
463bool Android_IsScreenKeyboardShown(SDL_VideoDevice *_this, SDL_Window *window)
464{
465 return Android_JNI_IsScreenKeyboardShown();
466}
467
468#endif // SDL_VIDEO_DRIVER_ANDROID
diff --git a/contrib/SDL-3.2.8/src/video/android/SDL_androidkeyboard.h b/contrib/SDL-3.2.8/src/video/android/SDL_androidkeyboard.h
new file mode 100644
index 0000000..c192991
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/video/android/SDL_androidkeyboard.h
@@ -0,0 +1,32 @@
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#include "SDL_androidvideo.h"
24
25extern void Android_OnKeyDown(int keycode);
26extern void Android_OnKeyUp(int keycode);
27
28extern bool Android_HasScreenKeyboardSupport(SDL_VideoDevice *_this);
29extern void Android_ShowScreenKeyboard(SDL_VideoDevice *_this, SDL_Window *window, SDL_PropertiesID props);
30extern void Android_HideScreenKeyboard(SDL_VideoDevice *_this, SDL_Window *window);
31extern void Android_RestoreScreenKeyboardOnResume(SDL_VideoDevice *_this, SDL_Window *window);
32extern bool Android_IsScreenKeyboardShown(SDL_VideoDevice *_this, SDL_Window *window);
diff --git a/contrib/SDL-3.2.8/src/video/android/SDL_androidmessagebox.c b/contrib/SDL-3.2.8/src/video/android/SDL_androidmessagebox.c
new file mode 100644
index 0000000..9387082
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/video/android/SDL_androidmessagebox.c
@@ -0,0 +1,33 @@
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#include "SDL_androidmessagebox.h"
26#include "../../core/android/SDL_android.h"
27
28bool Android_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonID)
29{
30 return Android_JNI_ShowMessageBox(messageboxdata, buttonID);
31}
32
33#endif // SDL_VIDEO_DRIVER_ANDROID
diff --git a/contrib/SDL-3.2.8/src/video/android/SDL_androidmessagebox.h b/contrib/SDL-3.2.8/src/video/android/SDL_androidmessagebox.h
new file mode 100644
index 0000000..6cd5d7c
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/video/android/SDL_androidmessagebox.h
@@ -0,0 +1,27 @@
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
25extern bool Android_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonID);
26
27#endif // SDL_VIDEO_DRIVER_ANDROID
diff --git a/contrib/SDL-3.2.8/src/video/android/SDL_androidmouse.c b/contrib/SDL-3.2.8/src/video/android/SDL_androidmouse.c
new file mode 100644
index 0000000..2facf0d
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/video/android/SDL_androidmouse.c
@@ -0,0 +1,250 @@
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
22#include "SDL_internal.h"
23
24#ifdef SDL_VIDEO_DRIVER_ANDROID
25
26#include "SDL_androidmouse.h"
27
28#include "../../events/SDL_mouse_c.h"
29
30#include "../../core/android/SDL_android.h"
31
32// See Android's MotionEvent class for constants
33#define ACTION_DOWN 0
34#define ACTION_UP 1
35#define ACTION_MOVE 2
36#define ACTION_HOVER_MOVE 7
37#define ACTION_SCROLL 8
38#define BUTTON_PRIMARY 1
39#define BUTTON_SECONDARY 2
40#define BUTTON_TERTIARY 4
41#define BUTTON_BACK 8
42#define BUTTON_FORWARD 16
43
44struct SDL_CursorData
45{
46 int custom_cursor;
47 int system_cursor;
48};
49
50// Last known Android mouse button state (includes all buttons)
51static int last_state;
52
53// Blank cursor
54static SDL_Cursor *empty_cursor;
55
56static SDL_Cursor *Android_WrapCursor(int custom_cursor, int system_cursor)
57{
58 SDL_Cursor *cursor;
59
60 cursor = SDL_calloc(1, sizeof(*cursor));
61 if (cursor) {
62 SDL_CursorData *data = (SDL_CursorData *)SDL_calloc(1, sizeof(*data));
63 if (data) {
64 data->custom_cursor = custom_cursor;
65 data->system_cursor = system_cursor;
66 cursor->internal = data;
67 } else {
68 SDL_free(cursor);
69 cursor = NULL;
70 }
71 }
72
73 return cursor;
74}
75
76static SDL_Cursor *Android_CreateDefaultCursor(void)
77{
78 SDL_SystemCursor id = SDL_GetDefaultSystemCursor();
79 return Android_WrapCursor(0, id);
80}
81
82static SDL_Cursor *Android_CreateCursor(SDL_Surface *surface, int hot_x, int hot_y)
83{
84 int custom_cursor;
85 SDL_Surface *converted;
86
87 converted = SDL_ConvertSurface(surface, SDL_PIXELFORMAT_ARGB8888);
88 if (!converted) {
89 return NULL;
90 }
91 custom_cursor = Android_JNI_CreateCustomCursor(converted, hot_x, hot_y);
92 SDL_DestroySurface(converted);
93 if (!custom_cursor) {
94 SDL_Unsupported();
95 return NULL;
96 }
97 return Android_WrapCursor(custom_cursor, 0);
98}
99
100static SDL_Cursor *Android_CreateSystemCursor(SDL_SystemCursor id)
101{
102 return Android_WrapCursor(0, id);
103}
104
105static void Android_FreeCursor(SDL_Cursor *cursor)
106{
107 SDL_CursorData *data = cursor->internal;
108 if (data->custom_cursor != 0) {
109 Android_JNI_DestroyCustomCursor(data->custom_cursor);
110 }
111 SDL_free(cursor->internal);
112 SDL_free(cursor);
113}
114
115static SDL_Cursor *Android_CreateEmptyCursor(void)
116{
117 if (!empty_cursor) {
118 SDL_Surface *empty_surface = SDL_CreateSurface(1, 1, SDL_PIXELFORMAT_ARGB8888);
119 if (empty_surface) {
120 SDL_memset(empty_surface->pixels, 0, (size_t)empty_surface->h * empty_surface->pitch);
121 empty_cursor = Android_CreateCursor(empty_surface, 0, 0);
122 SDL_DestroySurface(empty_surface);
123 }
124 }
125 return empty_cursor;
126}
127
128static void Android_DestroyEmptyCursor(void)
129{
130 if (empty_cursor) {
131 Android_FreeCursor(empty_cursor);
132 empty_cursor = NULL;
133 }
134}
135
136static bool Android_ShowCursor(SDL_Cursor *cursor)
137{
138 if (!cursor) {
139 cursor = Android_CreateEmptyCursor();
140 }
141 if (cursor) {
142 SDL_CursorData *data = cursor->internal;
143 if (data->custom_cursor) {
144 if (!Android_JNI_SetCustomCursor(data->custom_cursor)) {
145 return SDL_Unsupported();
146 }
147 } else {
148 if (!Android_JNI_SetSystemCursor(data->system_cursor)) {
149 return SDL_Unsupported();
150 }
151 }
152 return true;
153 } else {
154 // SDL error set inside Android_CreateEmptyCursor()
155 return false;
156 }
157}
158
159static bool Android_SetRelativeMouseMode(bool enabled)
160{
161 if (!Android_JNI_SupportsRelativeMouse()) {
162 return SDL_Unsupported();
163 }
164
165 if (!Android_JNI_SetRelativeMouseEnabled(enabled)) {
166 return SDL_Unsupported();
167 }
168
169 return true;
170}
171
172void Android_InitMouse(void)
173{
174 SDL_Mouse *mouse = SDL_GetMouse();
175
176 mouse->CreateCursor = Android_CreateCursor;
177 mouse->CreateSystemCursor = Android_CreateSystemCursor;
178 mouse->ShowCursor = Android_ShowCursor;
179 mouse->FreeCursor = Android_FreeCursor;
180 mouse->SetRelativeMouseMode = Android_SetRelativeMouseMode;
181
182 SDL_SetDefaultCursor(Android_CreateDefaultCursor());
183
184 last_state = 0;
185}
186
187void Android_QuitMouse(void)
188{
189 Android_DestroyEmptyCursor();
190}
191
192// Translate Android mouse button state to SDL mouse button
193static Uint8 TranslateButton(int state)
194{
195 if (state & BUTTON_PRIMARY) {
196 return SDL_BUTTON_LEFT;
197 } else if (state & BUTTON_SECONDARY) {
198 return SDL_BUTTON_RIGHT;
199 } else if (state & BUTTON_TERTIARY) {
200 return SDL_BUTTON_MIDDLE;
201 } else if (state & BUTTON_FORWARD) {
202 return SDL_BUTTON_X1;
203 } else if (state & BUTTON_BACK) {
204 return SDL_BUTTON_X2;
205 } else {
206 return 0;
207 }
208}
209
210void Android_OnMouse(SDL_Window *window, int state, int action, float x, float y, bool relative)
211{
212 int changes;
213 Uint8 button;
214
215 if (!window) {
216 return;
217 }
218
219 switch (action) {
220 case ACTION_DOWN:
221 changes = state & ~last_state;
222 button = TranslateButton(changes);
223 last_state = state;
224 SDL_SendMouseMotion(0, window, SDL_DEFAULT_MOUSE_ID, relative, x, y);
225 SDL_SendMouseButton(0, window, SDL_DEFAULT_MOUSE_ID, button, true);
226 break;
227
228 case ACTION_UP:
229 changes = last_state & ~state;
230 button = TranslateButton(changes);
231 last_state = state;
232 SDL_SendMouseMotion(0, window, SDL_DEFAULT_MOUSE_ID, relative, x, y);
233 SDL_SendMouseButton(0, window, SDL_DEFAULT_MOUSE_ID, button, false);
234 break;
235
236 case ACTION_MOVE:
237 case ACTION_HOVER_MOVE:
238 SDL_SendMouseMotion(0, window, SDL_DEFAULT_MOUSE_ID, relative, x, y);
239 break;
240
241 case ACTION_SCROLL:
242 SDL_SendMouseWheel(0, window, SDL_DEFAULT_MOUSE_ID, x, y, SDL_MOUSEWHEEL_NORMAL);
243 break;
244
245 default:
246 break;
247 }
248}
249
250#endif // SDL_VIDEO_DRIVER_ANDROID
diff --git a/contrib/SDL-3.2.8/src/video/android/SDL_androidmouse.h b/contrib/SDL-3.2.8/src/video/android/SDL_androidmouse.h
new file mode 100644
index 0000000..3a5d01a
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/video/android/SDL_androidmouse.h
@@ -0,0 +1,31 @@
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
22#ifndef SDL_androidmouse_h_
23#define SDL_androidmouse_h_
24
25#include "SDL_androidvideo.h"
26
27extern void Android_InitMouse(void);
28extern void Android_OnMouse(SDL_Window *window, int button, int action, float x, float y, bool relative);
29extern void Android_QuitMouse(void);
30
31#endif // SDL_androidmouse_h_
diff --git a/contrib/SDL-3.2.8/src/video/android/SDL_androidpen.c b/contrib/SDL-3.2.8/src/video/android/SDL_androidpen.c
new file mode 100644
index 0000000..e287cab
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/video/android/SDL_androidpen.c
@@ -0,0 +1,98 @@
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#include "SDL_androidpen.h"
26#include "../../events/SDL_pen_c.h"
27#include "../../core/android/SDL_android.h"
28
29#define ACTION_DOWN 0
30#define ACTION_UP 1
31#define ACTION_CANCEL 3
32#define ACTION_POINTER_DOWN 5
33#define ACTION_POINTER_UP 6
34#define ACTION_HOVER_EXIT 10
35
36void Android_OnPen(SDL_Window *window, int pen_id_in, int button, int action, float x, float y, float p)
37{
38 if (!window) {
39 return;
40 }
41
42 // pointer index starts from zero.
43 pen_id_in++;
44
45 SDL_PenID pen = SDL_FindPenByHandle((void *) (size_t) pen_id_in);
46 if (!pen) {
47 // TODO: Query JNI for pen device info
48 SDL_PenInfo peninfo;
49 SDL_zero(peninfo);
50 peninfo.capabilities = SDL_PEN_CAPABILITY_PRESSURE | SDL_PEN_CAPABILITY_ERASER;
51 peninfo.num_buttons = 2;
52 peninfo.subtype = SDL_PEN_TYPE_PEN;
53 pen = SDL_AddPenDevice(0, NULL, &peninfo, (void *) (size_t) pen_id_in);
54 if (!pen) {
55 SDL_Log("error: can't add a pen device %d", pen_id_in);
56 return;
57 }
58 }
59
60 SDL_SendPenMotion(0, pen, window, x, y);
61 SDL_SendPenAxis(0, pen, window, SDL_PEN_AXIS_PRESSURE, p);
62 // TODO: add more axis
63
64 SDL_PenInputFlags current = SDL_GetPenStatus(pen, NULL, 0);
65 int diff = current ^ button;
66 if (diff != 0) {
67 // Android only exposes BUTTON_STYLUS_PRIMARY and BUTTON_STYLUS_SECONDARY
68 if (diff & SDL_PEN_INPUT_BUTTON_1)
69 SDL_SendPenButton(0, pen, window, 1, (button & SDL_PEN_INPUT_BUTTON_1) != 0);
70
71 if (diff & SDL_PEN_INPUT_BUTTON_2)
72 SDL_SendPenButton(0, pen, window, 2, (button & SDL_PEN_INPUT_BUTTON_2) != 0);
73 }
74
75 // button contains DOWN/ERASER_TIP on DOWN/UP regardless of pressed state, use action to distinguish
76 // we don't compare tip flags above because MotionEvent.getButtonState doesn't return stylus tip/eraser state.
77 switch (action) {
78 case ACTION_CANCEL:
79 case ACTION_HOVER_EXIT:
80 SDL_RemovePenDevice(0, pen);
81 break;
82
83 case ACTION_DOWN:
84 case ACTION_POINTER_DOWN:
85 SDL_SendPenTouch(0, pen, window, (button & SDL_PEN_INPUT_ERASER_TIP) != 0, true);
86 break;
87
88 case ACTION_UP:
89 case ACTION_POINTER_UP:
90 SDL_SendPenTouch(0, pen, window, (button & SDL_PEN_INPUT_ERASER_TIP) != 0, false);
91 break;
92
93 default:
94 break;
95 }
96}
97
98#endif // SDL_VIDEO_DRIVER_ANDROID
diff --git a/contrib/SDL-3.2.8/src/video/android/SDL_androidpen.h b/contrib/SDL-3.2.8/src/video/android/SDL_androidpen.h
new file mode 100644
index 0000000..99a5aee
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/video/android/SDL_androidpen.h
@@ -0,0 +1,25 @@
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#include "SDL_androidvideo.h"
24
25extern void Android_OnPen(SDL_Window *window, int pen_id_in, int button, int action, float x, float y, float p);
diff --git a/contrib/SDL-3.2.8/src/video/android/SDL_androidtouch.c b/contrib/SDL-3.2.8/src/video/android/SDL_androidtouch.c
new file mode 100644
index 0000000..661c9a1
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/video/android/SDL_androidtouch.c
@@ -0,0 +1,96 @@
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#include <android/log.h>
26
27#include "SDL_androidtouch.h"
28#include "../../events/SDL_mouse_c.h"
29#include "../../events/SDL_touch_c.h"
30#include "../../core/android/SDL_android.h"
31
32#define ACTION_DOWN 0
33#define ACTION_UP 1
34#define ACTION_MOVE 2
35#define ACTION_CANCEL 3
36// #define ACTION_OUTSIDE 4
37#define ACTION_POINTER_DOWN 5
38#define ACTION_POINTER_UP 6
39
40void Android_InitTouch(void)
41{
42 // Add all touch devices
43 Android_JNI_InitTouch();
44}
45
46void Android_QuitTouch(void)
47{
48}
49
50void Android_OnTouch(SDL_Window *window, int touch_device_id_in, int pointer_finger_id_in, int action, float x, float y, float p)
51{
52 SDL_TouchID touchDeviceId = 0;
53 SDL_FingerID fingerId = 0;
54
55 if (!window) {
56 return;
57 }
58
59 /* Touch device -1 appears when using Android emulator, eg:
60 * adb shell input mouse tap 100 100
61 * adb shell input touchscreen tap 100 100
62 */
63 touchDeviceId = (SDL_TouchID)(touch_device_id_in + 2);
64
65 // Finger ID should be greater than 0
66 fingerId = (SDL_FingerID)(pointer_finger_id_in + 1);
67
68 if (SDL_AddTouch(touchDeviceId, SDL_TOUCH_DEVICE_DIRECT, "") < 0) {
69 SDL_Log("error: can't add touch %s, %d", __FILE__, __LINE__);
70 }
71
72 switch (action) {
73 case ACTION_DOWN:
74 case ACTION_POINTER_DOWN:
75 SDL_SendTouch(0, touchDeviceId, fingerId, window, SDL_EVENT_FINGER_DOWN, x, y, p);
76 break;
77
78 case ACTION_MOVE:
79 SDL_SendTouchMotion(0, touchDeviceId, fingerId, window, x, y, p);
80 break;
81
82 case ACTION_UP:
83 case ACTION_POINTER_UP:
84 SDL_SendTouch(0, touchDeviceId, fingerId, window, SDL_EVENT_FINGER_UP, x, y, p);
85 break;
86
87 case ACTION_CANCEL:
88 SDL_SendTouch(0, touchDeviceId, fingerId, window, SDL_EVENT_FINGER_CANCELED, x, y, p);
89 break;
90
91 default:
92 break;
93 }
94}
95
96#endif // SDL_VIDEO_DRIVER_ANDROID
diff --git a/contrib/SDL-3.2.8/src/video/android/SDL_androidtouch.h b/contrib/SDL-3.2.8/src/video/android/SDL_androidtouch.h
new file mode 100644
index 0000000..2aef822
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/video/android/SDL_androidtouch.h
@@ -0,0 +1,27 @@
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#include "SDL_androidvideo.h"
24
25extern void Android_InitTouch(void);
26extern void Android_QuitTouch(void);
27extern void Android_OnTouch(SDL_Window *window, int touch_device_id_in, int pointer_finger_id_in, int action, float x, float y, float p);
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
diff --git a/contrib/SDL-3.2.8/src/video/android/SDL_androidvideo.h b/contrib/SDL-3.2.8/src/video/android/SDL_androidvideo.h
new file mode 100644
index 0000000..c561637
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/video/android/SDL_androidvideo.h
@@ -0,0 +1,52 @@
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#ifndef SDL_androidvideo_h_
24#define SDL_androidvideo_h_
25
26#include "../SDL_sysvideo.h"
27
28// Called by the JNI layer when the screen changes size or format
29extern void Android_SetScreenResolution(int surfaceWidth, int surfaceHeight, int deviceWidth, int deviceHeight, float density, float rate);
30extern void Android_SetFormat(int format_wanted, int format_got);
31extern void Android_SetOrientation(SDL_DisplayOrientation orientation);
32extern void Android_SendResize(SDL_Window *window);
33extern void Android_SetWindowSafeAreaInsets(int left, int right, int top, int bottom);
34extern void Android_SetDarkMode(bool enabled);
35
36// Private display data
37
38struct SDL_VideoData
39{
40 int isPaused;
41 int isPausing;
42};
43
44extern int Android_SurfaceWidth;
45extern int Android_SurfaceHeight;
46extern float Android_ScreenDensity;
47extern int Android_SafeInsetLeft;
48extern int Android_SafeInsetRight;
49extern int Android_SafeInsetTop;
50extern int Android_SafeInsetBottom;
51
52#endif // SDL_androidvideo_h_
diff --git a/contrib/SDL-3.2.8/src/video/android/SDL_androidvulkan.c b/contrib/SDL-3.2.8/src/video/android/SDL_androidvulkan.c
new file mode 100644
index 0000000..4d38388
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/video/android/SDL_androidvulkan.c
@@ -0,0 +1,171 @@
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
22/*
23 * @author Mark Callow, www.edgewise-consulting.com. Based on Jacob Lifshay's
24 * SDL_x11vulkan.c.
25 */
26
27#include "SDL_internal.h"
28
29#if defined(SDL_VIDEO_VULKAN) && defined(SDL_VIDEO_DRIVER_ANDROID)
30
31#include "../SDL_vulkan_internal.h"
32
33#include "SDL_androidvideo.h"
34#include "SDL_androidwindow.h"
35
36#include "SDL_androidvulkan.h"
37
38
39bool Android_Vulkan_LoadLibrary(SDL_VideoDevice *_this, const char *path)
40{
41 VkExtensionProperties *extensions = NULL;
42 Uint32 i, extensionCount = 0;
43 bool hasSurfaceExtension = false;
44 bool hasAndroidSurfaceExtension = false;
45 PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = NULL;
46 if (_this->vulkan_config.loader_handle) {
47 return SDL_SetError("Vulkan already loaded");
48 }
49
50 // Load the Vulkan loader library
51 if (!path) {
52 path = SDL_GetHint(SDL_HINT_VULKAN_LIBRARY);
53 }
54 if (!path) {
55 path = "libvulkan.so";
56 }
57 _this->vulkan_config.loader_handle = SDL_LoadObject(path);
58 if (!_this->vulkan_config.loader_handle) {
59 return false;
60 }
61 SDL_strlcpy(_this->vulkan_config.loader_path, path,
62 SDL_arraysize(_this->vulkan_config.loader_path));
63 vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)SDL_LoadFunction(
64 _this->vulkan_config.loader_handle, "vkGetInstanceProcAddr");
65 if (!vkGetInstanceProcAddr) {
66 goto fail;
67 }
68 _this->vulkan_config.vkGetInstanceProcAddr = (void *)vkGetInstanceProcAddr;
69 _this->vulkan_config.vkEnumerateInstanceExtensionProperties =
70 (void *)((PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr)(
71 VK_NULL_HANDLE, "vkEnumerateInstanceExtensionProperties");
72 if (!_this->vulkan_config.vkEnumerateInstanceExtensionProperties) {
73 goto fail;
74 }
75 extensions = SDL_Vulkan_CreateInstanceExtensionsList(
76 (PFN_vkEnumerateInstanceExtensionProperties)
77 _this->vulkan_config.vkEnumerateInstanceExtensionProperties,
78 &extensionCount);
79 if (!extensions) {
80 goto fail;
81 }
82 for (i = 0; i < extensionCount; i++) {
83 if (SDL_strcmp(VK_KHR_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0) {
84 hasSurfaceExtension = true;
85 } else if (SDL_strcmp(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0) {
86 hasAndroidSurfaceExtension = true;
87 }
88 }
89 SDL_free(extensions);
90 if (!hasSurfaceExtension) {
91 SDL_SetError("Installed Vulkan doesn't implement the " VK_KHR_SURFACE_EXTENSION_NAME " extension");
92 goto fail;
93 } else if (!hasAndroidSurfaceExtension) {
94 SDL_SetError("Installed Vulkan doesn't implement the " VK_KHR_ANDROID_SURFACE_EXTENSION_NAME "extension");
95 goto fail;
96 }
97 return true;
98
99fail:
100 SDL_UnloadObject(_this->vulkan_config.loader_handle);
101 _this->vulkan_config.loader_handle = NULL;
102 return false;
103}
104
105void Android_Vulkan_UnloadLibrary(SDL_VideoDevice *_this)
106{
107 if (_this->vulkan_config.loader_handle) {
108 SDL_UnloadObject(_this->vulkan_config.loader_handle);
109 _this->vulkan_config.loader_handle = NULL;
110 }
111}
112
113char const* const* Android_Vulkan_GetInstanceExtensions(SDL_VideoDevice *_this,
114 Uint32 *count)
115{
116 static const char *const extensionsForAndroid[] = {
117 VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_ANDROID_SURFACE_EXTENSION_NAME
118 };
119 if (count) {
120 *count = SDL_arraysize(extensionsForAndroid);
121 }
122 return extensionsForAndroid;
123}
124
125bool Android_Vulkan_CreateSurface(SDL_VideoDevice *_this,
126 SDL_Window *window,
127 VkInstance instance,
128 const struct VkAllocationCallbacks *allocator,
129 VkSurfaceKHR *surface)
130{
131 SDL_WindowData *windowData = window->internal;
132 PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr =
133 (PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr;
134 PFN_vkCreateAndroidSurfaceKHR vkCreateAndroidSurfaceKHR =
135 (PFN_vkCreateAndroidSurfaceKHR)vkGetInstanceProcAddr(
136 instance,
137 "vkCreateAndroidSurfaceKHR");
138 VkAndroidSurfaceCreateInfoKHR createInfo;
139 VkResult result;
140
141 if (!_this->vulkan_config.loader_handle) {
142 return SDL_SetError("Vulkan is not loaded");
143 }
144
145 if (!vkCreateAndroidSurfaceKHR) {
146 return SDL_SetError(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME
147 " extension is not enabled in the Vulkan instance.");
148 }
149 SDL_zero(createInfo);
150 createInfo.sType = VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR;
151 createInfo.pNext = NULL;
152 createInfo.flags = 0;
153 createInfo.window = windowData->native_window;
154 result = vkCreateAndroidSurfaceKHR(instance, &createInfo, allocator, surface);
155 if (result != VK_SUCCESS) {
156 return SDL_SetError("vkCreateAndroidSurfaceKHR failed: %s", SDL_Vulkan_GetResultString(result));
157 }
158 return true;
159}
160
161void Android_Vulkan_DestroySurface(SDL_VideoDevice *_this,
162 VkInstance instance,
163 VkSurfaceKHR surface,
164 const struct VkAllocationCallbacks *allocator)
165{
166 if (_this->vulkan_config.loader_handle) {
167 SDL_Vulkan_DestroySurface_Internal(_this->vulkan_config.vkGetInstanceProcAddr, instance, surface, allocator);
168 }
169}
170
171#endif
diff --git a/contrib/SDL-3.2.8/src/video/android/SDL_androidvulkan.h b/contrib/SDL-3.2.8/src/video/android/SDL_androidvulkan.h
new file mode 100644
index 0000000..4f7cd51
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/video/android/SDL_androidvulkan.h
@@ -0,0 +1,52 @@
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
22/*
23 * @author Mark Callow, www.edgewise-consulting.com. Based on Jacob Lifshay's
24 * SDL_x11vulkan.h.
25 */
26
27#include "SDL_internal.h"
28
29#ifndef SDL_androidvulkan_h_
30#define SDL_androidvulkan_h_
31
32#include "../SDL_vulkan_internal.h"
33#include "../SDL_sysvideo.h"
34
35#if defined(SDL_VIDEO_VULKAN) && defined(SDL_VIDEO_DRIVER_ANDROID)
36
37extern bool Android_Vulkan_LoadLibrary(SDL_VideoDevice *_this, const char *path);
38extern void Android_Vulkan_UnloadLibrary(SDL_VideoDevice *_this);
39extern char const* const* Android_Vulkan_GetInstanceExtensions(SDL_VideoDevice *_this, Uint32 *count);
40extern bool Android_Vulkan_CreateSurface(SDL_VideoDevice *_this,
41 SDL_Window *window,
42 VkInstance instance,
43 const struct VkAllocationCallbacks *allocator,
44 VkSurfaceKHR *surface);
45extern void Android_Vulkan_DestroySurface(SDL_VideoDevice *_this,
46 VkInstance instance,
47 VkSurfaceKHR surface,
48 const struct VkAllocationCallbacks *allocator);
49
50#endif
51
52#endif // SDL_androidvulkan_h_
diff --git a/contrib/SDL-3.2.8/src/video/android/SDL_androidwindow.c b/contrib/SDL-3.2.8/src/video/android/SDL_androidwindow.c
new file mode 100644
index 0000000..af840b2
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/video/android/SDL_androidwindow.c
@@ -0,0 +1,204 @@
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#include "../SDL_sysvideo.h"
26#include "../../events/SDL_keyboard_c.h"
27#include "../../events/SDL_mouse_c.h"
28#include "../../events/SDL_windowevents_c.h"
29#include "../../core/android/SDL_android.h"
30
31#include "SDL_androidvideo.h"
32#include "SDL_androidevents.h"
33#include "SDL_androidwindow.h"
34
35
36// Currently only one window
37SDL_Window *Android_Window = NULL;
38
39bool Android_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_PropertiesID create_props)
40{
41 SDL_WindowData *data;
42 bool result = true;
43
44 if (!Android_WaitActiveAndLockActivity()) {
45 return false;
46 }
47
48 if (Android_Window) {
49 result = SDL_SetError("Android only supports one window");
50 goto endfunction;
51 }
52
53 // Set orientation
54 Android_JNI_SetOrientation(window->w, window->h, window->flags & SDL_WINDOW_RESIZABLE, SDL_GetHint(SDL_HINT_ORIENTATIONS));
55
56 // Adjust the window data to match the screen
57 window->x = 0;
58 window->y = 0;
59 window->w = Android_SurfaceWidth;
60 window->h = Android_SurfaceHeight;
61
62 // One window, it always has focus
63 SDL_SetMouseFocus(window);
64 SDL_SetKeyboardFocus(window);
65
66 data = (SDL_WindowData *)SDL_calloc(1, sizeof(*data));
67 if (!data) {
68 result = false;
69 goto endfunction;
70 }
71
72 data->native_window = Android_JNI_GetNativeWindow();
73 if (!data->native_window) {
74 SDL_free(data);
75 result = SDL_SetError("Could not fetch native window");
76 goto endfunction;
77 }
78 SDL_SetPointerProperty(SDL_GetWindowProperties(window), SDL_PROP_WINDOW_ANDROID_WINDOW_POINTER, data->native_window);
79
80 /* Do not create EGLSurface for Vulkan window since it will then make the window
81 incompatible with vkCreateAndroidSurfaceKHR */
82#ifdef SDL_VIDEO_OPENGL_EGL
83 if (window->flags & SDL_WINDOW_OPENGL) {
84 data->egl_surface = SDL_EGL_CreateSurface(_this, window, (NativeWindowType)data->native_window);
85
86 if (data->egl_surface == EGL_NO_SURFACE) {
87 ANativeWindow_release(data->native_window);
88 SDL_free(data);
89 result = false;
90 goto endfunction;
91 }
92 }
93 SDL_SetPointerProperty(SDL_GetWindowProperties(window), SDL_PROP_WINDOW_ANDROID_SURFACE_POINTER, data->egl_surface);
94#endif
95
96 SDL_SetWindowSafeAreaInsets(window, Android_SafeInsetLeft, Android_SafeInsetRight, Android_SafeInsetTop, Android_SafeInsetBottom);
97
98 window->internal = data;
99 Android_Window = window;
100
101endfunction:
102
103 Android_UnlockActivityMutex();
104
105 return result;
106}
107
108void Android_SetWindowTitle(SDL_VideoDevice *_this, SDL_Window *window)
109{
110 Android_JNI_SetActivityTitle(window->title);
111}
112
113SDL_FullscreenResult Android_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window *window, SDL_VideoDisplay *display, SDL_FullscreenOp fullscreen)
114{
115 Android_LockActivityMutex();
116
117 if (window == Android_Window) {
118 SDL_WindowData *data;
119 int old_w, old_h, new_w, new_h;
120
121 // If the window is being destroyed don't change visible state
122 if (!window->is_destroying) {
123 Android_JNI_SetWindowStyle(fullscreen);
124 }
125
126 /* Ensure our size matches reality after we've executed the window style change.
127 *
128 * It is possible that we've set width and height to the full-size display, but on
129 * Samsung DeX or Chromebooks or other windowed Android environemtns, our window may
130 * still not be the full display size.
131 */
132 if (!SDL_IsDeXMode() && !SDL_IsChromebook()) {
133 goto endfunction;
134 }
135
136 data = window->internal;
137 if (!data || !data->native_window) {
138 if (data && !data->native_window) {
139 SDL_SetError("Missing native window");
140 }
141 goto endfunction;
142 }
143
144 old_w = window->w;
145 old_h = window->h;
146
147 new_w = ANativeWindow_getWidth(data->native_window);
148 new_h = ANativeWindow_getHeight(data->native_window);
149
150 if (new_w < 0 || new_h < 0) {
151 SDL_SetError("ANativeWindow_getWidth/Height() fails");
152 }
153
154 if (old_w != new_w || old_h != new_h) {
155 SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_RESIZED, new_w, new_h);
156 }
157 }
158
159endfunction:
160
161 Android_UnlockActivityMutex();
162
163 return SDL_FULLSCREEN_SUCCEEDED;
164}
165
166void Android_MinimizeWindow(SDL_VideoDevice *_this, SDL_Window *window)
167{
168 Android_JNI_MinizeWindow();
169}
170
171void Android_SetWindowResizable(SDL_VideoDevice *_this, SDL_Window *window, bool resizable)
172{
173 // Set orientation
174 Android_JNI_SetOrientation(window->w, window->h, window->flags & SDL_WINDOW_RESIZABLE, SDL_GetHint(SDL_HINT_ORIENTATIONS));
175}
176
177void Android_DestroyWindow(SDL_VideoDevice *_this, SDL_Window *window)
178{
179 Android_LockActivityMutex();
180
181 if (window == Android_Window) {
182 Android_Window = NULL;
183
184 if (window->internal) {
185 SDL_WindowData *data = window->internal;
186
187#ifdef SDL_VIDEO_OPENGL_EGL
188 if (data->egl_surface != EGL_NO_SURFACE) {
189 SDL_EGL_DestroySurface(_this, data->egl_surface);
190 }
191#endif
192
193 if (data->native_window) {
194 ANativeWindow_release(data->native_window);
195 }
196 SDL_free(window->internal);
197 window->internal = NULL;
198 }
199 }
200
201 Android_UnlockActivityMutex();
202}
203
204#endif // SDL_VIDEO_DRIVER_ANDROID
diff --git a/contrib/SDL-3.2.8/src/video/android/SDL_androidwindow.h b/contrib/SDL-3.2.8/src/video/android/SDL_androidwindow.h
new file mode 100644
index 0000000..5590b59
--- /dev/null
+++ b/contrib/SDL-3.2.8/src/video/android/SDL_androidwindow.h
@@ -0,0 +1,51 @@
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#ifndef SDL_androidwindow_h_
24#define SDL_androidwindow_h_
25
26#include "../../core/android/SDL_android.h"
27#include "../SDL_egl_c.h"
28
29extern bool Android_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_PropertiesID create_props);
30extern void Android_SetWindowTitle(SDL_VideoDevice *_this, SDL_Window *window);
31extern SDL_FullscreenResult Android_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window *window, SDL_VideoDisplay *display, SDL_FullscreenOp fullscreen);
32extern void Android_MinimizeWindow(SDL_VideoDevice *_this, SDL_Window *window);
33extern void Android_SetWindowResizable(SDL_VideoDevice *_this, SDL_Window *window, bool resizable);
34
35extern void Android_DestroyWindow(SDL_VideoDevice *_this, SDL_Window *window);
36extern SDL_Window *Android_Window;
37
38struct SDL_WindowData
39{
40#ifdef SDL_VIDEO_OPENGL_EGL
41 EGLSurface egl_surface;
42 EGLContext egl_context; // We use this to preserve the context when losing focus
43 int has_swap_interval; // Save/Restore the swap interval / vsync
44 int swap_interval;
45#endif
46 bool backup_done;
47 ANativeWindow *native_window;
48
49};
50
51#endif // SDL_androidwindow_h_