Merge commit 'dec0d4ec4153bf9fc2b78ae6c2df45b6ea8dde7a' as 'external/sdl/SDL'

This commit is contained in:
2023-07-25 22:27:55 +02:00
1663 changed files with 627495 additions and 0 deletions

View File

@ -0,0 +1,44 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#ifdef SDL_VIDEO_DRIVER_ANDROID
#include "SDL_androidvideo.h"
#include "SDL_androidclipboard.h"
#include "../../core/android/SDL_android.h"
int Android_SetClipboardText(SDL_VideoDevice *_this, const char *text)
{
return Android_JNI_SetClipboardText(text);
}
char *Android_GetClipboardText(SDL_VideoDevice *_this)
{
return Android_JNI_GetClipboardText();
}
SDL_bool Android_HasClipboardText(SDL_VideoDevice *_this)
{
return Android_JNI_HasClipboardText();
}
#endif /* SDL_VIDEO_DRIVER_ANDROID */

View File

@ -0,0 +1,30 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#ifndef SDL_androidclipboard_h_
#define SDL_androidclipboard_h_
extern int Android_SetClipboardText(SDL_VideoDevice *_this, const char *text);
extern char *Android_GetClipboardText(SDL_VideoDevice *_this);
extern SDL_bool Android_HasClipboardText(SDL_VideoDevice *_this);
#endif /* SDL_androidclipboard_h_ */

View File

@ -0,0 +1,255 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#ifdef SDL_VIDEO_DRIVER_ANDROID
#include "SDL_androidevents.h"
#include "SDL_androidkeyboard.h"
#include "SDL_androidwindow.h"
#include "../SDL_sysvideo.h"
#include "../../events/SDL_events_c.h"
#include "../../audio/android/SDL_androidaudio.h"
#include "../../audio/aaudio/SDL_aaudio.h"
#include "../../audio/openslES/SDL_openslES.h"
/* Number of 'type' events in the event queue */
static int SDL_NumberOfEvents(Uint32 type)
{
return SDL_PeepEvents(NULL, 0, SDL_PEEKEVENT, type, type);
}
#ifdef SDL_VIDEO_OPENGL_EGL
static void android_egl_context_restore(SDL_Window *window)
{
if (window) {
SDL_Event event;
SDL_WindowData *data = window->driverdata;
if (SDL_GL_MakeCurrent(window, (SDL_GLContext)data->egl_context) < 0) {
/* The context is no longer valid, create a new one */
data->egl_context = (EGLContext)SDL_GL_CreateContext(window);
SDL_GL_MakeCurrent(window, (SDL_GLContext)data->egl_context);
event.type = SDL_EVENT_RENDER_DEVICE_RESET;
event.common.timestamp = 0;
SDL_PushEvent(&event);
}
data->backup_done = 0;
if (data->has_swap_interval) {
SDL_GL_SetSwapInterval(data->swap_interval);
}
}
}
static void android_egl_context_backup(SDL_Window *window)
{
if (window) {
int interval = 0;
/* Keep a copy of the EGL Context so we can try to restore it when we resume */
SDL_WindowData *data = window->driverdata;
data->egl_context = SDL_GL_GetCurrentContext();
/* Save/Restore the swap interval / vsync */
if (SDL_GL_GetSwapInterval(&interval) == 0) {
data->has_swap_interval = 1;
data->swap_interval = interval;
}
/* We need to do this so the EGLSurface can be freed */
SDL_GL_MakeCurrent(window, NULL);
data->backup_done = 1;
}
}
#endif
/*
* Android_ResumeSem and Android_PauseSem are signaled from Java_org_libsdl_app_SDLActivity_nativePause and Java_org_libsdl_app_SDLActivity_nativeResume
* When the pause semaphore is signaled, if Android_PumpEvents_Blocking is used, the event loop will block until the resume signal is emitted.
*
* No polling necessary
*/
void Android_PumpEvents_Blocking(SDL_VideoDevice *_this)
{
SDL_VideoData *videodata = _this->driverdata;
if (videodata->isPaused) {
SDL_bool isContextExternal = SDL_IsVideoContextExternal();
#ifdef SDL_VIDEO_OPENGL_EGL
/* Make sure this is the last thing we do before pausing */
if (!isContextExternal) {
SDL_LockMutex(Android_ActivityMutex);
android_egl_context_backup(Android_Window);
SDL_UnlockMutex(Android_ActivityMutex);
}
#endif
ANDROIDAUDIO_PauseDevices();
openslES_PauseDevices();
aaudio_PauseDevices();
if (SDL_WaitSemaphore(Android_ResumeSem) == 0) {
videodata->isPaused = 0;
/* Android_ResumeSem was signaled */
SDL_SendAppEvent(SDL_EVENT_WILL_ENTER_FOREGROUND);
ANDROIDAUDIO_ResumeDevices();
openslES_ResumeDevices();
aaudio_ResumeDevices();
/* Restore the GL Context from here, as this operation is thread dependent */
#ifdef SDL_VIDEO_OPENGL_EGL
if (!isContextExternal && !SDL_HasEvent(SDL_EVENT_QUIT)) {
SDL_LockMutex(Android_ActivityMutex);
android_egl_context_restore(Android_Window);
SDL_UnlockMutex(Android_ActivityMutex);
}
#endif
/* Make sure SW Keyboard is restored when an app becomes foreground */
if (SDL_TextInputActive()) {
Android_StartTextInput(_this); /* Only showTextInput */
}
SDL_SendAppEvent(SDL_EVENT_DID_ENTER_FOREGROUND);
SDL_SendWindowEvent(Android_Window, SDL_EVENT_WINDOW_RESTORED, 0, 0);
}
} else {
if (videodata->isPausing || SDL_TryWaitSemaphore(Android_PauseSem) == 0) {
/* Android_PauseSem was signaled */
if (videodata->isPausing == 0) {
SDL_SendWindowEvent(Android_Window, SDL_EVENT_WINDOW_MINIMIZED, 0, 0);
SDL_SendAppEvent(SDL_EVENT_WILL_ENTER_BACKGROUND);
SDL_SendAppEvent(SDL_EVENT_DID_ENTER_BACKGROUND);
}
/* We've been signaled to pause (potentially several times), but before we block ourselves,
* we need to make sure that the very last event (of the first pause sequence, if several)
* has reached the app */
if (SDL_NumberOfEvents(SDL_EVENT_DID_ENTER_BACKGROUND) > SDL_GetSemaphoreValue(Android_PauseSem)) {
videodata->isPausing = 1;
} else {
videodata->isPausing = 0;
videodata->isPaused = 1;
}
}
}
if (aaudio_DetectBrokenPlayState()) {
aaudio_PauseDevices();
aaudio_ResumeDevices();
}
}
void Android_PumpEvents_NonBlocking(SDL_VideoDevice *_this)
{
SDL_VideoData *videodata = _this->driverdata;
static int backup_context = 0;
if (videodata->isPaused) {
SDL_bool isContextExternal = SDL_IsVideoContextExternal();
if (backup_context) {
#ifdef SDL_VIDEO_OPENGL_EGL
if (!isContextExternal) {
SDL_LockMutex(Android_ActivityMutex);
android_egl_context_backup(Android_Window);
SDL_UnlockMutex(Android_ActivityMutex);
}
#endif
if (videodata->pauseAudio) {
ANDROIDAUDIO_PauseDevices();
openslES_PauseDevices();
aaudio_PauseDevices();
}
backup_context = 0;
}
if (SDL_TryWaitSemaphore(Android_ResumeSem) == 0) {
videodata->isPaused = 0;
/* Android_ResumeSem was signaled */
SDL_SendAppEvent(SDL_EVENT_WILL_ENTER_FOREGROUND);
if (videodata->pauseAudio) {
ANDROIDAUDIO_ResumeDevices();
openslES_ResumeDevices();
aaudio_ResumeDevices();
}
#ifdef SDL_VIDEO_OPENGL_EGL
/* Restore the GL Context from here, as this operation is thread dependent */
if (!isContextExternal && !SDL_HasEvent(SDL_EVENT_QUIT)) {
SDL_LockMutex(Android_ActivityMutex);
android_egl_context_restore(Android_Window);
SDL_UnlockMutex(Android_ActivityMutex);
}
#endif
/* Make sure SW Keyboard is restored when an app becomes foreground */
if (SDL_TextInputActive()) {
Android_StartTextInput(_this); /* Only showTextInput */
}
SDL_SendAppEvent(SDL_EVENT_DID_ENTER_FOREGROUND);
SDL_SendWindowEvent(Android_Window, SDL_EVENT_WINDOW_RESTORED, 0, 0);
}
} else {
if (videodata->isPausing || SDL_TryWaitSemaphore(Android_PauseSem) == 0) {
/* Android_PauseSem was signaled */
if (videodata->isPausing == 0) {
SDL_SendWindowEvent(Android_Window, SDL_EVENT_WINDOW_MINIMIZED, 0, 0);
SDL_SendAppEvent(SDL_EVENT_WILL_ENTER_BACKGROUND);
SDL_SendAppEvent(SDL_EVENT_DID_ENTER_BACKGROUND);
}
/* We've been signaled to pause (potentially several times), but before we block ourselves,
* we need to make sure that the very last event (of the first pause sequence, if several)
* has reached the app */
if (SDL_NumberOfEvents(SDL_EVENT_DID_ENTER_BACKGROUND) > SDL_GetSemaphoreValue(Android_PauseSem)) {
videodata->isPausing = 1;
} else {
videodata->isPausing = 0;
videodata->isPaused = 1;
backup_context = 1;
}
}
}
if (aaudio_DetectBrokenPlayState()) {
aaudio_PauseDevices();
aaudio_ResumeDevices();
}
}
#endif /* SDL_VIDEO_DRIVER_ANDROID */

View File

@ -0,0 +1,26 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#include "SDL_androidvideo.h"
extern void Android_PumpEvents_Blocking(SDL_VideoDevice *_this);
extern void Android_PumpEvents_NonBlocking(SDL_VideoDevice *_this);

View File

@ -0,0 +1,85 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#if defined(SDL_VIDEO_DRIVER_ANDROID) && defined(SDL_VIDEO_OPENGL_EGL)
/* Android SDL video driver implementation */
#include "../SDL_egl_c.h"
#include "SDL_androidwindow.h"
#include "SDL_androidvideo.h"
#include "SDL_androidgl.h"
#include "../../core/android/SDL_android.h"
#include <android/log.h>
#include <dlfcn.h>
int Android_GLES_MakeCurrent(SDL_VideoDevice *_this, SDL_Window *window, SDL_GLContext context)
{
if (window && context) {
return SDL_EGL_MakeCurrent(_this, window->driverdata->egl_surface, context);
} else {
return SDL_EGL_MakeCurrent(_this, NULL, NULL);
}
}
SDL_GLContext Android_GLES_CreateContext(SDL_VideoDevice *_this, SDL_Window *window)
{
SDL_GLContext ret;
Android_ActivityMutex_Lock_Running();
ret = SDL_EGL_CreateContext(_this, window->driverdata->egl_surface);
SDL_UnlockMutex(Android_ActivityMutex);
return ret;
}
int Android_GLES_SwapWindow(SDL_VideoDevice *_this, SDL_Window *window)
{
int retval;
SDL_LockMutex(Android_ActivityMutex);
/* The following two calls existed in the original Java code
* If you happen to have a device that's affected by their removal,
* please report to our bug tracker. -- Gabriel
*/
/*_this->egl_data->eglWaitNative(EGL_CORE_NATIVE_ENGINE);
_this->egl_data->eglWaitGL();*/
retval = SDL_EGL_SwapBuffers(_this, window->driverdata->egl_surface);
SDL_UnlockMutex(Android_ActivityMutex);
return retval;
}
int Android_GLES_LoadLibrary(SDL_VideoDevice *_this, const char *path)
{
return SDL_EGL_LoadLibrary(_this, path, (NativeDisplayType)0, 0);
}
#endif /* SDL_VIDEO_DRIVER_ANDROID */

View File

@ -0,0 +1,31 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#ifndef SDL_androidgl_h_
#define SDL_androidgl_h_
SDL_GLContext Android_GLES_CreateContext(SDL_VideoDevice *_this, SDL_Window *window);
int Android_GLES_MakeCurrent(SDL_VideoDevice *_this, SDL_Window *window, SDL_GLContext context);
int Android_GLES_SwapWindow(SDL_VideoDevice *_this, SDL_Window *window);
int Android_GLES_LoadLibrary(SDL_VideoDevice *_this, const char *path);
#endif /* SDL_androidgl_h_ */

View File

@ -0,0 +1,367 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#ifdef SDL_VIDEO_DRIVER_ANDROID
#include <android/log.h>
#include "../../events/SDL_events_c.h"
#include "SDL_androidkeyboard.h"
#include "../../core/android/SDL_android.h"
static SDL_Scancode Android_Keycodes[] = {
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_UNKNOWN */
SDL_SCANCODE_SOFTLEFT, /* AKEYCODE_SOFT_LEFT */
SDL_SCANCODE_SOFTRIGHT, /* AKEYCODE_SOFT_RIGHT */
SDL_SCANCODE_AC_HOME, /* AKEYCODE_HOME */
SDL_SCANCODE_AC_BACK, /* AKEYCODE_BACK */
SDL_SCANCODE_CALL, /* AKEYCODE_CALL */
SDL_SCANCODE_ENDCALL, /* AKEYCODE_ENDCALL */
SDL_SCANCODE_0, /* AKEYCODE_0 */
SDL_SCANCODE_1, /* AKEYCODE_1 */
SDL_SCANCODE_2, /* AKEYCODE_2 */
SDL_SCANCODE_3, /* AKEYCODE_3 */
SDL_SCANCODE_4, /* AKEYCODE_4 */
SDL_SCANCODE_5, /* AKEYCODE_5 */
SDL_SCANCODE_6, /* AKEYCODE_6 */
SDL_SCANCODE_7, /* AKEYCODE_7 */
SDL_SCANCODE_8, /* AKEYCODE_8 */
SDL_SCANCODE_9, /* AKEYCODE_9 */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_STAR */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_POUND */
SDL_SCANCODE_UP, /* AKEYCODE_DPAD_UP */
SDL_SCANCODE_DOWN, /* AKEYCODE_DPAD_DOWN */
SDL_SCANCODE_LEFT, /* AKEYCODE_DPAD_LEFT */
SDL_SCANCODE_RIGHT, /* AKEYCODE_DPAD_RIGHT */
SDL_SCANCODE_SELECT, /* AKEYCODE_DPAD_CENTER */
SDL_SCANCODE_VOLUMEUP, /* AKEYCODE_VOLUME_UP */
SDL_SCANCODE_VOLUMEDOWN, /* AKEYCODE_VOLUME_DOWN */
SDL_SCANCODE_POWER, /* AKEYCODE_POWER */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_CAMERA */
SDL_SCANCODE_CLEAR, /* AKEYCODE_CLEAR */
SDL_SCANCODE_A, /* AKEYCODE_A */
SDL_SCANCODE_B, /* AKEYCODE_B */
SDL_SCANCODE_C, /* AKEYCODE_C */
SDL_SCANCODE_D, /* AKEYCODE_D */
SDL_SCANCODE_E, /* AKEYCODE_E */
SDL_SCANCODE_F, /* AKEYCODE_F */
SDL_SCANCODE_G, /* AKEYCODE_G */
SDL_SCANCODE_H, /* AKEYCODE_H */
SDL_SCANCODE_I, /* AKEYCODE_I */
SDL_SCANCODE_J, /* AKEYCODE_J */
SDL_SCANCODE_K, /* AKEYCODE_K */
SDL_SCANCODE_L, /* AKEYCODE_L */
SDL_SCANCODE_M, /* AKEYCODE_M */
SDL_SCANCODE_N, /* AKEYCODE_N */
SDL_SCANCODE_O, /* AKEYCODE_O */
SDL_SCANCODE_P, /* AKEYCODE_P */
SDL_SCANCODE_Q, /* AKEYCODE_Q */
SDL_SCANCODE_R, /* AKEYCODE_R */
SDL_SCANCODE_S, /* AKEYCODE_S */
SDL_SCANCODE_T, /* AKEYCODE_T */
SDL_SCANCODE_U, /* AKEYCODE_U */
SDL_SCANCODE_V, /* AKEYCODE_V */
SDL_SCANCODE_W, /* AKEYCODE_W */
SDL_SCANCODE_X, /* AKEYCODE_X */
SDL_SCANCODE_Y, /* AKEYCODE_Y */
SDL_SCANCODE_Z, /* AKEYCODE_Z */
SDL_SCANCODE_COMMA, /* AKEYCODE_COMMA */
SDL_SCANCODE_PERIOD, /* AKEYCODE_PERIOD */
SDL_SCANCODE_LALT, /* AKEYCODE_ALT_LEFT */
SDL_SCANCODE_RALT, /* AKEYCODE_ALT_RIGHT */
SDL_SCANCODE_LSHIFT, /* AKEYCODE_SHIFT_LEFT */
SDL_SCANCODE_RSHIFT, /* AKEYCODE_SHIFT_RIGHT */
SDL_SCANCODE_TAB, /* AKEYCODE_TAB */
SDL_SCANCODE_SPACE, /* AKEYCODE_SPACE */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_SYM */
SDL_SCANCODE_WWW, /* AKEYCODE_EXPLORER */
SDL_SCANCODE_MAIL, /* AKEYCODE_ENVELOPE */
SDL_SCANCODE_RETURN, /* AKEYCODE_ENTER */
SDL_SCANCODE_BACKSPACE, /* AKEYCODE_DEL */
SDL_SCANCODE_GRAVE, /* AKEYCODE_GRAVE */
SDL_SCANCODE_MINUS, /* AKEYCODE_MINUS */
SDL_SCANCODE_EQUALS, /* AKEYCODE_EQUALS */
SDL_SCANCODE_LEFTBRACKET, /* AKEYCODE_LEFT_BRACKET */
SDL_SCANCODE_RIGHTBRACKET, /* AKEYCODE_RIGHT_BRACKET */
SDL_SCANCODE_BACKSLASH, /* AKEYCODE_BACKSLASH */
SDL_SCANCODE_SEMICOLON, /* AKEYCODE_SEMICOLON */
SDL_SCANCODE_APOSTROPHE, /* AKEYCODE_APOSTROPHE */
SDL_SCANCODE_SLASH, /* AKEYCODE_SLASH */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_AT */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_NUM */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_HEADSETHOOK */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_FOCUS */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_PLUS */
SDL_SCANCODE_MENU, /* AKEYCODE_MENU */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_NOTIFICATION */
SDL_SCANCODE_AC_SEARCH, /* AKEYCODE_SEARCH */
SDL_SCANCODE_AUDIOPLAY, /* AKEYCODE_MEDIA_PLAY_PAUSE */
SDL_SCANCODE_AUDIOSTOP, /* AKEYCODE_MEDIA_STOP */
SDL_SCANCODE_AUDIONEXT, /* AKEYCODE_MEDIA_NEXT */
SDL_SCANCODE_AUDIOPREV, /* AKEYCODE_MEDIA_PREVIOUS */
SDL_SCANCODE_AUDIOREWIND, /* AKEYCODE_MEDIA_REWIND */
SDL_SCANCODE_AUDIOFASTFORWARD, /* AKEYCODE_MEDIA_FAST_FORWARD */
SDL_SCANCODE_MUTE, /* AKEYCODE_MUTE */
SDL_SCANCODE_PAGEUP, /* AKEYCODE_PAGE_UP */
SDL_SCANCODE_PAGEDOWN, /* AKEYCODE_PAGE_DOWN */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_PICTSYMBOLS */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_SWITCH_CHARSET */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_A */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_B */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_C */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_X */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_Y */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_Z */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_L1 */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_R1 */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_L2 */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_R2 */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_THUMBL */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_THUMBR */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_START */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_SELECT */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_MODE */
SDL_SCANCODE_ESCAPE, /* AKEYCODE_ESCAPE */
SDL_SCANCODE_DELETE, /* AKEYCODE_FORWARD_DEL */
SDL_SCANCODE_LCTRL, /* AKEYCODE_CTRL_LEFT */
SDL_SCANCODE_RCTRL, /* AKEYCODE_CTRL_RIGHT */
SDL_SCANCODE_CAPSLOCK, /* AKEYCODE_CAPS_LOCK */
SDL_SCANCODE_SCROLLLOCK, /* AKEYCODE_SCROLL_LOCK */
SDL_SCANCODE_LGUI, /* AKEYCODE_META_LEFT */
SDL_SCANCODE_RGUI, /* AKEYCODE_META_RIGHT */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_FUNCTION */
SDL_SCANCODE_PRINTSCREEN, /* AKEYCODE_SYSRQ */
SDL_SCANCODE_PAUSE, /* AKEYCODE_BREAK */
SDL_SCANCODE_HOME, /* AKEYCODE_MOVE_HOME */
SDL_SCANCODE_END, /* AKEYCODE_MOVE_END */
SDL_SCANCODE_INSERT, /* AKEYCODE_INSERT */
SDL_SCANCODE_AC_FORWARD, /* AKEYCODE_FORWARD */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_MEDIA_PLAY */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_MEDIA_PAUSE */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_MEDIA_CLOSE */
SDL_SCANCODE_EJECT, /* AKEYCODE_MEDIA_EJECT */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_MEDIA_RECORD */
SDL_SCANCODE_F1, /* AKEYCODE_F1 */
SDL_SCANCODE_F2, /* AKEYCODE_F2 */
SDL_SCANCODE_F3, /* AKEYCODE_F3 */
SDL_SCANCODE_F4, /* AKEYCODE_F4 */
SDL_SCANCODE_F5, /* AKEYCODE_F5 */
SDL_SCANCODE_F6, /* AKEYCODE_F6 */
SDL_SCANCODE_F7, /* AKEYCODE_F7 */
SDL_SCANCODE_F8, /* AKEYCODE_F8 */
SDL_SCANCODE_F9, /* AKEYCODE_F9 */
SDL_SCANCODE_F10, /* AKEYCODE_F10 */
SDL_SCANCODE_F11, /* AKEYCODE_F11 */
SDL_SCANCODE_F12, /* AKEYCODE_F12 */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_NUM_LOCK */
SDL_SCANCODE_KP_0, /* AKEYCODE_NUMPAD_0 */
SDL_SCANCODE_KP_1, /* AKEYCODE_NUMPAD_1 */
SDL_SCANCODE_KP_2, /* AKEYCODE_NUMPAD_2 */
SDL_SCANCODE_KP_3, /* AKEYCODE_NUMPAD_3 */
SDL_SCANCODE_KP_4, /* AKEYCODE_NUMPAD_4 */
SDL_SCANCODE_KP_5, /* AKEYCODE_NUMPAD_5 */
SDL_SCANCODE_KP_6, /* AKEYCODE_NUMPAD_6 */
SDL_SCANCODE_KP_7, /* AKEYCODE_NUMPAD_7 */
SDL_SCANCODE_KP_8, /* AKEYCODE_NUMPAD_8 */
SDL_SCANCODE_KP_9, /* AKEYCODE_NUMPAD_9 */
SDL_SCANCODE_KP_DIVIDE, /* AKEYCODE_NUMPAD_DIVIDE */
SDL_SCANCODE_KP_MULTIPLY, /* AKEYCODE_NUMPAD_MULTIPLY */
SDL_SCANCODE_KP_MINUS, /* AKEYCODE_NUMPAD_SUBTRACT */
SDL_SCANCODE_KP_PLUS, /* AKEYCODE_NUMPAD_ADD */
SDL_SCANCODE_KP_PERIOD, /* AKEYCODE_NUMPAD_DOT */
SDL_SCANCODE_KP_COMMA, /* AKEYCODE_NUMPAD_COMMA */
SDL_SCANCODE_KP_ENTER, /* AKEYCODE_NUMPAD_ENTER */
SDL_SCANCODE_KP_EQUALS, /* AKEYCODE_NUMPAD_EQUALS */
SDL_SCANCODE_KP_LEFTPAREN, /* AKEYCODE_NUMPAD_LEFT_PAREN */
SDL_SCANCODE_KP_RIGHTPAREN, /* AKEYCODE_NUMPAD_RIGHT_PAREN */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_VOLUME_MUTE */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_INFO */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_CHANNEL_UP */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_CHANNEL_DOWN */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_ZOOM_IN */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_ZOOM_OUT */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_WINDOW */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_GUIDE */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_DVR */
SDL_SCANCODE_AC_BOOKMARKS, /* AKEYCODE_BOOKMARK */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_CAPTIONS */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_SETTINGS */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_POWER */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_INPUT */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_STB_POWER */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_STB_INPUT */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_AVR_POWER */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_AVR_INPUT */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_PROG_RED */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_PROG_GREEN */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_PROG_YELLOW */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_PROG_BLUE */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_APP_SWITCH */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_1 */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_2 */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_3 */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_4 */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_5 */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_6 */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_7 */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_8 */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_9 */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_10 */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_11 */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_12 */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_13 */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_14 */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_15 */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_BUTTON_16 */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_LANGUAGE_SWITCH */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_MANNER_MODE */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_3D_MODE */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_CONTACTS */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_CALENDAR */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_MUSIC */
SDL_SCANCODE_CALCULATOR, /* AKEYCODE_CALCULATOR */
SDL_SCANCODE_LANG5, /* AKEYCODE_ZENKAKU_HANKAKU */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_EISU */
SDL_SCANCODE_INTERNATIONAL5, /* AKEYCODE_MUHENKAN */
SDL_SCANCODE_INTERNATIONAL4, /* AKEYCODE_HENKAN */
SDL_SCANCODE_LANG3, /* AKEYCODE_KATAKANA_HIRAGANA */
SDL_SCANCODE_INTERNATIONAL3, /* AKEYCODE_YEN */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_RO */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_KANA */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_ASSIST */
SDL_SCANCODE_BRIGHTNESSDOWN, /* AKEYCODE_BRIGHTNESS_DOWN */
SDL_SCANCODE_BRIGHTNESSUP, /* AKEYCODE_BRIGHTNESS_UP */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_MEDIA_AUDIO_TRACK */
SDL_SCANCODE_SLEEP, /* AKEYCODE_SLEEP */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_WAKEUP */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_PAIRING */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_MEDIA_TOP_MENU */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_11 */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_12 */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_LAST_CHANNEL */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_DATA_SERVICE */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_VOICE_ASSIST */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_RADIO_SERVICE */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_TELETEXT */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_NUMBER_ENTRY */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_TERRESTRIAL_ANALOG */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_TERRESTRIAL_DIGITAL */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_SATELLITE */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_SATELLITE_BS */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_SATELLITE_CS */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_SATELLITE_SERVICE */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_NETWORK */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_ANTENNA_CABLE */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_INPUT_HDMI_1 */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_INPUT_HDMI_2 */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_INPUT_HDMI_3 */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_INPUT_HDMI_4 */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_INPUT_COMPOSITE_1 */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_INPUT_COMPOSITE_2 */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_INPUT_COMPONENT_1 */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_INPUT_COMPONENT_2 */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_INPUT_VGA_1 */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_AUDIO_DESCRIPTION */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_AUDIO_DESCRIPTION_MIX_UP */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_AUDIO_DESCRIPTION_MIX_DOWN */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_ZOOM_MODE */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_CONTENTS_MENU */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_MEDIA_CONTEXT_MENU */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_TV_TIMER_PROGRAMMING */
SDL_SCANCODE_HELP, /* AKEYCODE_HELP */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_NAVIGATE_PREVIOUS */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_NAVIGATE_NEXT */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_NAVIGATE_IN */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_NAVIGATE_OUT */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_STEM_PRIMARY */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_STEM_1 */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_STEM_2 */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_STEM_3 */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_DPAD_UP_LEFT */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_DPAD_DOWN_LEFT */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_DPAD_UP_RIGHT */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_DPAD_DOWN_RIGHT */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_MEDIA_SKIP_FORWARD */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_MEDIA_SKIP_BACKWARD */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_MEDIA_STEP_FORWARD */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_MEDIA_STEP_BACKWARD */
SDL_SCANCODE_UNKNOWN, /* AKEYCODE_SOFT_SLEEP */
SDL_SCANCODE_CUT, /* AKEYCODE_CUT */
SDL_SCANCODE_COPY, /* AKEYCODE_COPY */
SDL_SCANCODE_PASTE, /* AKEYCODE_PASTE */
};
static SDL_Scancode TranslateKeycode(int keycode)
{
SDL_Scancode scancode = SDL_SCANCODE_UNKNOWN;
if (keycode < SDL_arraysize(Android_Keycodes)) {
scancode = Android_Keycodes[keycode];
}
if (scancode == SDL_SCANCODE_UNKNOWN) {
__android_log_print(ANDROID_LOG_INFO, "SDL", "Unknown keycode %d", keycode);
}
return scancode;
}
int Android_OnKeyDown(int keycode)
{
return SDL_SendKeyboardKey(0, SDL_PRESSED, TranslateKeycode(keycode));
}
int Android_OnKeyUp(int keycode)
{
return SDL_SendKeyboardKey(0, SDL_RELEASED, TranslateKeycode(keycode));
}
SDL_bool Android_HasScreenKeyboardSupport(SDL_VideoDevice *_this)
{
return SDL_TRUE;
}
SDL_bool Android_IsScreenKeyboardShown(SDL_VideoDevice *_this, SDL_Window *window)
{
return Android_JNI_IsScreenKeyboardShown();
}
void Android_StartTextInput(SDL_VideoDevice *_this)
{
SDL_VideoData *videodata = _this->driverdata;
Android_JNI_ShowTextInput(&videodata->textRect);
}
void Android_StopTextInput(SDL_VideoDevice *_this)
{
Android_JNI_HideTextInput();
}
int Android_SetTextInputRect(SDL_VideoDevice *_this, const SDL_Rect *rect)
{
SDL_VideoData *videodata = _this->driverdata;
videodata->textRect = *rect;
return 0;
}
#endif /* SDL_VIDEO_DRIVER_ANDROID */

View File

@ -0,0 +1,33 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#include "SDL_androidvideo.h"
extern int Android_OnKeyDown(int keycode);
extern int Android_OnKeyUp(int keycode);
extern SDL_bool Android_HasScreenKeyboardSupport(SDL_VideoDevice *_this);
extern SDL_bool Android_IsScreenKeyboardShown(SDL_VideoDevice *_this, SDL_Window *window);
extern void Android_StartTextInput(SDL_VideoDevice *_this);
extern void Android_StopTextInput(SDL_VideoDevice *_this);
extern int Android_SetTextInputRect(SDL_VideoDevice *_this, const SDL_Rect *rect);

View File

@ -0,0 +1,33 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#ifdef SDL_VIDEO_DRIVER_ANDROID
#include "SDL_androidmessagebox.h"
#include "../../core/android/SDL_android.h"
int Android_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
{
return Android_JNI_ShowMessageBox(messageboxdata, buttonid);
}
#endif /* SDL_VIDEO_DRIVER_ANDROID */

View File

@ -0,0 +1,27 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#ifdef SDL_VIDEO_DRIVER_ANDROID
extern int Android_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid);
#endif /* SDL_VIDEO_DRIVER_ANDROID */

View File

@ -0,0 +1,253 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#ifdef SDL_VIDEO_DRIVER_ANDROID
#include "SDL_androidmouse.h"
#include "../../events/SDL_mouse_c.h"
#include "../../core/android/SDL_android.h"
/* See Android's MotionEvent class for constants */
#define ACTION_DOWN 0
#define ACTION_UP 1
#define ACTION_MOVE 2
#define ACTION_HOVER_MOVE 7
#define ACTION_SCROLL 8
#define BUTTON_PRIMARY 1
#define BUTTON_SECONDARY 2
#define BUTTON_TERTIARY 4
#define BUTTON_BACK 8
#define BUTTON_FORWARD 16
typedef struct
{
int custom_cursor;
int system_cursor;
} SDL_AndroidCursorData;
/* Last known Android mouse button state (includes all buttons) */
static int last_state;
/* Blank cursor */
static SDL_Cursor *empty_cursor;
static SDL_Cursor *Android_WrapCursor(int custom_cursor, int system_cursor)
{
SDL_Cursor *cursor;
cursor = SDL_calloc(1, sizeof(*cursor));
if (cursor) {
SDL_AndroidCursorData *data = (SDL_AndroidCursorData *)SDL_calloc(1, sizeof(*data));
if (data) {
data->custom_cursor = custom_cursor;
data->system_cursor = system_cursor;
cursor->driverdata = data;
} else {
SDL_free(cursor);
cursor = NULL;
SDL_OutOfMemory();
}
} else {
SDL_OutOfMemory();
}
return cursor;
}
static SDL_Cursor *Android_CreateDefaultCursor()
{
return Android_WrapCursor(0, SDL_SYSTEM_CURSOR_ARROW);
}
static SDL_Cursor *Android_CreateCursor(SDL_Surface *surface, int hot_x, int hot_y)
{
int custom_cursor;
SDL_Surface *converted;
converted = SDL_ConvertSurfaceFormat(surface, SDL_PIXELFORMAT_ARGB8888);
if (converted == NULL) {
return NULL;
}
custom_cursor = Android_JNI_CreateCustomCursor(converted, hot_x, hot_y);
SDL_DestroySurface(converted);
if (!custom_cursor) {
SDL_Unsupported();
return NULL;
}
return Android_WrapCursor(custom_cursor, 0);
}
static SDL_Cursor *Android_CreateSystemCursor(SDL_SystemCursor id)
{
return Android_WrapCursor(0, id);
}
static void Android_FreeCursor(SDL_Cursor *cursor)
{
SDL_AndroidCursorData *data = (SDL_AndroidCursorData *)cursor->driverdata;
if (data->custom_cursor != 0) {
Android_JNI_DestroyCustomCursor(data->custom_cursor);
}
SDL_free(cursor->driverdata);
SDL_free(cursor);
}
static SDL_Cursor *Android_CreateEmptyCursor()
{
if (empty_cursor == NULL) {
SDL_Surface *empty_surface = SDL_CreateSurface(1, 1, SDL_PIXELFORMAT_ARGB8888);
if (empty_surface) {
SDL_memset(empty_surface->pixels, 0, (size_t)empty_surface->h * empty_surface->pitch);
empty_cursor = Android_CreateCursor(empty_surface, 0, 0);
SDL_DestroySurface(empty_surface);
}
}
return empty_cursor;
}
static void Android_DestroyEmptyCursor()
{
if (empty_cursor) {
Android_FreeCursor(empty_cursor);
empty_cursor = NULL;
}
}
static int Android_ShowCursor(SDL_Cursor *cursor)
{
if (cursor == NULL) {
cursor = Android_CreateEmptyCursor();
}
if (cursor) {
SDL_AndroidCursorData *data = (SDL_AndroidCursorData *)cursor->driverdata;
if (data->custom_cursor) {
if (!Android_JNI_SetCustomCursor(data->custom_cursor)) {
return SDL_Unsupported();
}
} else {
if (!Android_JNI_SetSystemCursor(data->system_cursor)) {
return SDL_Unsupported();
}
}
return 0;
} else {
/* SDL error set inside Android_CreateEmptyCursor() */
return -1;
}
}
static int Android_SetRelativeMouseMode(SDL_bool enabled)
{
if (!Android_JNI_SupportsRelativeMouse()) {
return SDL_Unsupported();
}
if (!Android_JNI_SetRelativeMouseEnabled(enabled)) {
return SDL_Unsupported();
}
return 0;
}
void Android_InitMouse(void)
{
SDL_Mouse *mouse = SDL_GetMouse();
mouse->CreateCursor = Android_CreateCursor;
mouse->CreateSystemCursor = Android_CreateSystemCursor;
mouse->ShowCursor = Android_ShowCursor;
mouse->FreeCursor = Android_FreeCursor;
mouse->SetRelativeMouseMode = Android_SetRelativeMouseMode;
SDL_SetDefaultCursor(Android_CreateDefaultCursor());
last_state = 0;
}
void Android_QuitMouse(void)
{
Android_DestroyEmptyCursor();
}
/* Translate Android mouse button state to SDL mouse button */
static Uint8 TranslateButton(int state)
{
if (state & BUTTON_PRIMARY) {
return SDL_BUTTON_LEFT;
} else if (state & BUTTON_SECONDARY) {
return SDL_BUTTON_RIGHT;
} else if (state & BUTTON_TERTIARY) {
return SDL_BUTTON_MIDDLE;
} else if (state & BUTTON_FORWARD) {
return SDL_BUTTON_X1;
} else if (state & BUTTON_BACK) {
return SDL_BUTTON_X2;
} else {
return 0;
}
}
void Android_OnMouse(SDL_Window *window, int state, int action, float x, float y, SDL_bool relative)
{
int changes;
Uint8 button;
if (window == NULL) {
return;
}
switch (action) {
case ACTION_DOWN:
changes = state & ~last_state;
button = TranslateButton(changes);
last_state = state;
SDL_SendMouseMotion(0, window, 0, relative, x, y);
SDL_SendMouseButton(0, window, 0, SDL_PRESSED, button);
break;
case ACTION_UP:
changes = last_state & ~state;
button = TranslateButton(changes);
last_state = state;
SDL_SendMouseMotion(0, window, 0, relative, x, y);
SDL_SendMouseButton(0, window, 0, SDL_RELEASED, button);
break;
case ACTION_MOVE:
case ACTION_HOVER_MOVE:
SDL_SendMouseMotion(0, window, 0, relative, x, y);
break;
case ACTION_SCROLL:
SDL_SendMouseWheel(0, window, 0, x, y, SDL_MOUSEWHEEL_NORMAL);
break;
default:
break;
}
}
#endif /* SDL_VIDEO_DRIVER_ANDROID */

View File

@ -0,0 +1,31 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef SDL_androidmouse_h_
#define SDL_androidmouse_h_
#include "SDL_androidvideo.h"
extern void Android_InitMouse(void);
extern void Android_OnMouse(SDL_Window *window, int button, int action, float x, float y, SDL_bool relative);
extern void Android_QuitMouse(void);
#endif /* SDL_androidmouse_h_ */

View File

@ -0,0 +1,85 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#ifdef SDL_VIDEO_DRIVER_ANDROID
#include <android/log.h>
#include "SDL_androidtouch.h"
#include "../../events/SDL_mouse_c.h"
#include "../../events/SDL_touch_c.h"
#include "../../core/android/SDL_android.h"
#define ACTION_DOWN 0
#define ACTION_UP 1
#define ACTION_MOVE 2
/* #define ACTION_CANCEL 3 */
/* #define ACTION_OUTSIDE 4 */
#define ACTION_POINTER_DOWN 5
#define ACTION_POINTER_UP 6
void Android_InitTouch(void)
{
/* Add all touch devices */
Android_JNI_InitTouch();
}
void Android_QuitTouch(void)
{
}
void Android_OnTouch(SDL_Window *window, int touch_device_id_in, int pointer_finger_id_in, int action, float x, float y, float p)
{
SDL_TouchID touchDeviceId = 0;
SDL_FingerID fingerId = 0;
if (window == NULL) {
return;
}
touchDeviceId = (SDL_TouchID)touch_device_id_in;
if (SDL_AddTouch(touchDeviceId, SDL_TOUCH_DEVICE_DIRECT, "") < 0) {
SDL_Log("error: can't add touch %s, %d", __FILE__, __LINE__);
}
fingerId = (SDL_FingerID)pointer_finger_id_in;
switch (action) {
case ACTION_DOWN:
case ACTION_POINTER_DOWN:
SDL_SendTouch(0, touchDeviceId, fingerId, window, SDL_TRUE, x, y, p);
break;
case ACTION_MOVE:
SDL_SendTouchMotion(0, touchDeviceId, fingerId, window, x, y, p);
break;
case ACTION_UP:
case ACTION_POINTER_UP:
SDL_SendTouch(0, touchDeviceId, fingerId, window, SDL_FALSE, x, y, p);
break;
default:
break;
}
}
#endif /* SDL_VIDEO_DRIVER_ANDROID */

View File

@ -0,0 +1,27 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#include "SDL_androidvideo.h"
extern void Android_InitTouch(void);
extern void Android_QuitTouch(void);
extern void Android_OnTouch(SDL_Window *window, int touch_device_id_in, int pointer_finger_id_in, int action, float x, float y, float p);

View File

@ -0,0 +1,302 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#ifdef SDL_VIDEO_DRIVER_ANDROID
/* Android SDL video driver implementation */
#include "../SDL_sysvideo.h"
#include "../SDL_pixels_c.h"
#include "../../events/SDL_events_c.h"
#include "../../events/SDL_windowevents_c.h"
#include "SDL_androidvideo.h"
#include "SDL_androidgl.h"
#include "SDL_androidclipboard.h"
#include "SDL_androidevents.h"
#include "SDL_androidkeyboard.h"
#include "SDL_androidmouse.h"
#include "SDL_androidtouch.h"
#include "SDL_androidwindow.h"
#include "SDL_androidvulkan.h"
#define ANDROID_VID_DRIVER_NAME "Android"
/* Initialization/Query functions */
static int Android_VideoInit(SDL_VideoDevice *_this);
static void Android_VideoQuit(SDL_VideoDevice *_this);
#include "../SDL_egl_c.h"
#define Android_GLES_GetProcAddress SDL_EGL_GetProcAddressInternal
#define Android_GLES_UnloadLibrary SDL_EGL_UnloadLibrary
#define Android_GLES_SetSwapInterval SDL_EGL_SetSwapInterval
#define Android_GLES_GetSwapInterval SDL_EGL_GetSwapInterval
#define Android_GLES_DeleteContext SDL_EGL_DeleteContext
/* Android driver bootstrap functions */
/* These are filled in with real values in Android_SetScreenResolution on init (before SDL_main()) */
int Android_SurfaceWidth = 0;
int Android_SurfaceHeight = 0;
static int Android_DeviceWidth = 0;
static int Android_DeviceHeight = 0;
static Uint32 Android_ScreenFormat = SDL_PIXELFORMAT_RGB565; /* Default SurfaceView format, in case this is queried before being filled */
float Android_ScreenDensity = 1.0f;
static float Android_ScreenRate = 0.0f;
SDL_Semaphore *Android_PauseSem = NULL;
SDL_Semaphore *Android_ResumeSem = NULL;
SDL_Mutex *Android_ActivityMutex = NULL;
static SDL_SystemTheme Android_SystemTheme;
static int Android_SuspendScreenSaver(SDL_VideoDevice *_this)
{
return Android_JNI_SuspendScreenSaver(_this->suspend_screensaver);
}
static void Android_DeleteDevice(SDL_VideoDevice *device)
{
SDL_free(device->driverdata);
SDL_free(device);
}
static SDL_VideoDevice *Android_CreateDevice(void)
{
SDL_VideoDevice *device;
SDL_VideoData *data;
SDL_bool block_on_pause;
/* Initialize all variables that we clean on shutdown */
device = (SDL_VideoDevice *)SDL_calloc(1, sizeof(SDL_VideoDevice));
if (device == NULL) {
SDL_OutOfMemory();
return NULL;
}
data = (SDL_VideoData *)SDL_calloc(1, sizeof(SDL_VideoData));
if (data == NULL) {
SDL_OutOfMemory();
SDL_free(device);
return NULL;
}
device->driverdata = data;
device->system_theme = Android_SystemTheme;
/* Set the function pointers */
device->VideoInit = Android_VideoInit;
device->VideoQuit = Android_VideoQuit;
block_on_pause = SDL_GetHintBoolean(SDL_HINT_ANDROID_BLOCK_ON_PAUSE, SDL_TRUE);
if (block_on_pause) {
device->PumpEvents = Android_PumpEvents_Blocking;
} else {
device->PumpEvents = Android_PumpEvents_NonBlocking;
}
device->CreateSDLWindow = Android_CreateWindow;
device->SetWindowTitle = Android_SetWindowTitle;
device->SetWindowFullscreen = Android_SetWindowFullscreen;
device->MinimizeWindow = Android_MinimizeWindow;
device->SetWindowResizable = Android_SetWindowResizable;
device->DestroyWindow = Android_DestroyWindow;
device->GetWindowWMInfo = Android_GetWindowWMInfo;
device->free = Android_DeleteDevice;
/* GL pointers */
#ifdef SDL_VIDEO_OPENGL_EGL
device->GL_LoadLibrary = Android_GLES_LoadLibrary;
device->GL_GetProcAddress = Android_GLES_GetProcAddress;
device->GL_UnloadLibrary = Android_GLES_UnloadLibrary;
device->GL_CreateContext = Android_GLES_CreateContext;
device->GL_MakeCurrent = Android_GLES_MakeCurrent;
device->GL_SetSwapInterval = Android_GLES_SetSwapInterval;
device->GL_GetSwapInterval = Android_GLES_GetSwapInterval;
device->GL_SwapWindow = Android_GLES_SwapWindow;
device->GL_DeleteContext = Android_GLES_DeleteContext;
#endif
#ifdef SDL_VIDEO_VULKAN
device->Vulkan_LoadLibrary = Android_Vulkan_LoadLibrary;
device->Vulkan_UnloadLibrary = Android_Vulkan_UnloadLibrary;
device->Vulkan_GetInstanceExtensions = Android_Vulkan_GetInstanceExtensions;
device->Vulkan_CreateSurface = Android_Vulkan_CreateSurface;
#endif
/* Screensaver */
device->SuspendScreenSaver = Android_SuspendScreenSaver;
/* Text input */
device->StartTextInput = Android_StartTextInput;
device->StopTextInput = Android_StopTextInput;
device->SetTextInputRect = Android_SetTextInputRect;
/* Screen keyboard */
device->HasScreenKeyboardSupport = Android_HasScreenKeyboardSupport;
device->IsScreenKeyboardShown = Android_IsScreenKeyboardShown;
/* Clipboard */
device->SetClipboardText = Android_SetClipboardText;
device->GetClipboardText = Android_GetClipboardText;
device->HasClipboardText = Android_HasClipboardText;
return device;
}
VideoBootStrap Android_bootstrap = {
ANDROID_VID_DRIVER_NAME, "SDL Android video driver",
Android_CreateDevice
};
int Android_VideoInit(SDL_VideoDevice *_this)
{
SDL_VideoData *videodata = _this->driverdata;
SDL_DisplayID displayID;
SDL_VideoDisplay *display;
SDL_DisplayMode mode;
videodata->isPaused = SDL_FALSE;
videodata->isPausing = SDL_FALSE;
videodata->pauseAudio = SDL_GetHintBoolean(SDL_HINT_ANDROID_BLOCK_ON_PAUSE_PAUSEAUDIO, SDL_TRUE);
SDL_zero(mode);
mode.format = Android_ScreenFormat;
mode.w = Android_DeviceWidth;
mode.h = Android_DeviceHeight;
mode.refresh_rate = Android_ScreenRate;
mode.driverdata = NULL;
displayID = SDL_AddBasicVideoDisplay(&mode);
if (displayID == 0) {
return -1;
}
display = SDL_GetVideoDisplay(displayID);
display->natural_orientation = Android_JNI_GetDisplayNaturalOrientation();
display->current_orientation = Android_JNI_GetDisplayCurrentOrientation();
display->content_scale = Android_ScreenDensity;
Android_InitTouch();
Android_InitMouse();
/* We're done! */
return 0;
}
void Android_VideoQuit(SDL_VideoDevice *_this)
{
Android_QuitMouse();
Android_QuitTouch();
}
void Android_SetScreenResolution(int surfaceWidth, int surfaceHeight, int deviceWidth, int deviceHeight, float density, float rate)
{
Android_SurfaceWidth = surfaceWidth;
Android_SurfaceHeight = surfaceHeight;
Android_DeviceWidth = deviceWidth;
Android_DeviceHeight = deviceHeight;
Android_ScreenDensity = (density > 0.0f) ? density : 1.0f;
Android_ScreenRate = rate;
}
static Uint32 format_to_pixelFormat(int format)
{
Uint32 pf;
if (format == AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM) { /* 1 */
pf = SDL_PIXELFORMAT_RGBA8888;
} else if (format == AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM) { /* 2 */
pf = SDL_PIXELFORMAT_RGBX8888;
} else if (format == AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM) { /* 3 */
pf = SDL_PIXELFORMAT_RGB24;
} else if (format == AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM) { /* 4*/
pf = SDL_PIXELFORMAT_RGB565;
} else if (format == 5) {
pf = SDL_PIXELFORMAT_BGRA8888;
} else if (format == 6) {
pf = SDL_PIXELFORMAT_RGBA5551;
} else if (format == 7) {
pf = SDL_PIXELFORMAT_RGBA4444;
} else if (format == 0x115) {
/* HAL_PIXEL_FORMAT_BGR_565 */
pf = SDL_PIXELFORMAT_RGB565;
} else {
pf = SDL_PIXELFORMAT_UNKNOWN;
}
return pf;
}
void Android_SetFormat(int format_wanted, int format_got)
{
Uint32 pf_wanted;
Uint32 pf_got;
pf_wanted = format_to_pixelFormat(format_wanted);
pf_got = format_to_pixelFormat(format_got);
Android_ScreenFormat = pf_got;
SDL_Log("pixel format wanted %s (%d), got %s (%d)",
SDL_GetPixelFormatName(pf_wanted), format_wanted,
SDL_GetPixelFormatName(pf_got), format_got);
}
void Android_SendResize(SDL_Window *window)
{
/*
Update the resolution of the desktop mode, so that the window
can be properly resized. The screen resolution change can for
example happen when the Activity enters or exits immersive mode,
which can happen after VideoInit().
*/
SDL_VideoDevice *device = SDL_GetVideoDevice();
if (device && device->num_displays > 0) {
SDL_VideoDisplay *display = &device->displays[0];
SDL_DisplayMode desktop_mode;
SDL_zero(desktop_mode);
desktop_mode.format = Android_ScreenFormat;
desktop_mode.w = Android_DeviceWidth;
desktop_mode.h = Android_DeviceHeight;
desktop_mode.refresh_rate = Android_ScreenRate;
SDL_SetDesktopDisplayMode(display, &desktop_mode);
}
if (window) {
SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_RESIZED, Android_SurfaceWidth, Android_SurfaceHeight);
}
}
void Android_SetDarkMode(SDL_bool enabled)
{
SDL_VideoDevice *device = SDL_GetVideoDevice();
if (enabled) {
Android_SystemTheme = SDL_SYSTEM_THEME_DARK;
} else {
Android_SystemTheme = SDL_SYSTEM_THEME_LIGHT;
}
if (device) {
SDL_SetSystemTheme(Android_SystemTheme);
}
}
#endif /* SDL_VIDEO_DRIVER_ANDROID */

View File

@ -0,0 +1,50 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#ifndef SDL_androidvideo_h_
#define SDL_androidvideo_h_
#include "../SDL_sysvideo.h"
/* Called by the JNI layer when the screen changes size or format */
extern void Android_SetScreenResolution(int surfaceWidth, int surfaceHeight, int deviceWidth, int deviceHeight, float density, float rate);
extern void Android_SetFormat(int format_wanted, int format_got);
extern void Android_SendResize(SDL_Window *window);
extern void Android_SetDarkMode(SDL_bool enabled);
/* Private display data */
struct SDL_VideoData
{
SDL_Rect textRect;
int isPaused;
int isPausing;
int pauseAudio;
};
extern int Android_SurfaceWidth;
extern int Android_SurfaceHeight;
extern float Android_ScreenDensity;
extern SDL_Semaphore *Android_PauseSem, *Android_ResumeSem;
extern SDL_Mutex *Android_ActivityMutex;
#endif /* SDL_androidvideo_h_ */

View File

@ -0,0 +1,168 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
/*
* @author Mark Callow, www.edgewise-consulting.com. Based on Jacob Lifshay's
* SDL_x11vulkan.c.
*/
#include "SDL_internal.h"
#if defined(SDL_VIDEO_VULKAN) && defined(SDL_VIDEO_DRIVER_ANDROID)
#include "SDL_androidvideo.h"
#include "SDL_androidwindow.h"
#include "SDL_androidvulkan.h"
#include <SDL3/SDL_syswm.h>
int Android_Vulkan_LoadLibrary(SDL_VideoDevice *_this, const char *path)
{
VkExtensionProperties *extensions = NULL;
Uint32 i, extensionCount = 0;
SDL_bool hasSurfaceExtension = SDL_FALSE;
SDL_bool hasAndroidSurfaceExtension = SDL_FALSE;
PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = NULL;
if (_this->vulkan_config.loader_handle) {
return SDL_SetError("Vulkan already loaded");
}
/* Load the Vulkan loader library */
if (path == NULL) {
path = SDL_getenv("SDL_VULKAN_LIBRARY");
}
if (path == NULL) {
path = "libvulkan.so";
}
_this->vulkan_config.loader_handle = SDL_LoadObject(path);
if (!_this->vulkan_config.loader_handle) {
return -1;
}
SDL_strlcpy(_this->vulkan_config.loader_path, path,
SDL_arraysize(_this->vulkan_config.loader_path));
vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)SDL_LoadFunction(
_this->vulkan_config.loader_handle, "vkGetInstanceProcAddr");
if (!vkGetInstanceProcAddr) {
goto fail;
}
_this->vulkan_config.vkGetInstanceProcAddr = (void *)vkGetInstanceProcAddr;
_this->vulkan_config.vkEnumerateInstanceExtensionProperties =
(void *)((PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr)(
VK_NULL_HANDLE, "vkEnumerateInstanceExtensionProperties");
if (!_this->vulkan_config.vkEnumerateInstanceExtensionProperties) {
goto fail;
}
extensions = SDL_Vulkan_CreateInstanceExtensionsList(
(PFN_vkEnumerateInstanceExtensionProperties)
_this->vulkan_config.vkEnumerateInstanceExtensionProperties,
&extensionCount);
if (extensions == NULL) {
goto fail;
}
for (i = 0; i < extensionCount; i++) {
if (SDL_strcmp(VK_KHR_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0) {
hasSurfaceExtension = SDL_TRUE;
} else if (SDL_strcmp(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME, extensions[i].extensionName) == 0) {
hasAndroidSurfaceExtension = SDL_TRUE;
}
}
SDL_free(extensions);
if (!hasSurfaceExtension) {
SDL_SetError("Installed Vulkan doesn't implement the " VK_KHR_SURFACE_EXTENSION_NAME " extension");
goto fail;
} else if (!hasAndroidSurfaceExtension) {
SDL_SetError("Installed Vulkan doesn't implement the " VK_KHR_ANDROID_SURFACE_EXTENSION_NAME "extension");
goto fail;
}
return 0;
fail:
SDL_UnloadObject(_this->vulkan_config.loader_handle);
_this->vulkan_config.loader_handle = NULL;
return -1;
}
void Android_Vulkan_UnloadLibrary(SDL_VideoDevice *_this)
{
if (_this->vulkan_config.loader_handle) {
SDL_UnloadObject(_this->vulkan_config.loader_handle);
_this->vulkan_config.loader_handle = NULL;
}
}
SDL_bool Android_Vulkan_GetInstanceExtensions(SDL_VideoDevice *_this,
unsigned *count,
const char **names)
{
static const char *const extensionsForAndroid[] = {
VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_ANDROID_SURFACE_EXTENSION_NAME
};
if (!_this->vulkan_config.loader_handle) {
SDL_SetError("Vulkan is not loaded");
return SDL_FALSE;
}
return SDL_Vulkan_GetInstanceExtensions_Helper(
count, names, SDL_arraysize(extensionsForAndroid),
extensionsForAndroid);
}
SDL_bool Android_Vulkan_CreateSurface(SDL_VideoDevice *_this,
SDL_Window *window,
VkInstance instance,
VkSurfaceKHR *surface)
{
SDL_WindowData *windowData = window->driverdata;
PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr =
(PFN_vkGetInstanceProcAddr)_this->vulkan_config.vkGetInstanceProcAddr;
PFN_vkCreateAndroidSurfaceKHR vkCreateAndroidSurfaceKHR =
(PFN_vkCreateAndroidSurfaceKHR)vkGetInstanceProcAddr(
instance,
"vkCreateAndroidSurfaceKHR");
VkAndroidSurfaceCreateInfoKHR createInfo;
VkResult result;
if (!_this->vulkan_config.loader_handle) {
SDL_SetError("Vulkan is not loaded");
return SDL_FALSE;
}
if (!vkCreateAndroidSurfaceKHR) {
SDL_SetError(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME
" extension is not enabled in the Vulkan instance.");
return SDL_FALSE;
}
SDL_zero(createInfo);
createInfo.sType = VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR;
createInfo.pNext = NULL;
createInfo.flags = 0;
createInfo.window = windowData->native_window;
result = vkCreateAndroidSurfaceKHR(instance, &createInfo,
NULL, surface);
if (result != VK_SUCCESS) {
SDL_SetError("vkCreateAndroidSurfaceKHR failed: %s",
SDL_Vulkan_GetResultString(result));
return SDL_FALSE;
}
return SDL_TRUE;
}
#endif

View File

@ -0,0 +1,49 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
/*
* @author Mark Callow, www.edgewise-consulting.com. Based on Jacob Lifshay's
* SDL_x11vulkan.h.
*/
#include "SDL_internal.h"
#ifndef SDL_androidvulkan_h_
#define SDL_androidvulkan_h_
#include "../SDL_vulkan_internal.h"
#include "../SDL_sysvideo.h"
#if defined(SDL_VIDEO_VULKAN) && defined(SDL_VIDEO_DRIVER_ANDROID)
int Android_Vulkan_LoadLibrary(SDL_VideoDevice *_this, const char *path);
void Android_Vulkan_UnloadLibrary(SDL_VideoDevice *_this);
SDL_bool Android_Vulkan_GetInstanceExtensions(SDL_VideoDevice *_this,
unsigned *count,
const char **names);
SDL_bool Android_Vulkan_CreateSurface(SDL_VideoDevice *_this,
SDL_Window *window,
VkInstance instance,
VkSurfaceKHR *surface);
#endif
#endif /* SDL_androidvulkan_h_ */

View File

@ -0,0 +1,211 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#ifdef SDL_VIDEO_DRIVER_ANDROID
#include "../SDL_sysvideo.h"
#include "../../events/SDL_keyboard_c.h"
#include "../../events/SDL_mouse_c.h"
#include "../../events/SDL_windowevents_c.h"
#include "../../core/android/SDL_android.h"
#include "SDL_androidvideo.h"
#include "SDL_androidwindow.h"
#include <SDL3/SDL_syswm.h>
/* Currently only one window */
SDL_Window *Android_Window = NULL;
int Android_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window)
{
SDL_WindowData *data;
int retval = 0;
Android_ActivityMutex_Lock_Running();
if (Android_Window) {
retval = SDL_SetError("Android only supports one window");
goto endfunction;
}
/* Set orientation */
Android_JNI_SetOrientation(window->w, window->h, window->flags & SDL_WINDOW_RESIZABLE, SDL_GetHint(SDL_HINT_ORIENTATIONS));
/* Adjust the window data to match the screen */
window->x = 0;
window->y = 0;
window->w = Android_SurfaceWidth;
window->h = Android_SurfaceHeight;
/* One window, it always has focus */
SDL_SetMouseFocus(window);
SDL_SetKeyboardFocus(window);
data = (SDL_WindowData *)SDL_calloc(1, sizeof(*data));
if (data == NULL) {
retval = SDL_OutOfMemory();
goto endfunction;
}
data->native_window = Android_JNI_GetNativeWindow();
if (!data->native_window) {
SDL_free(data);
retval = SDL_SetError("Could not fetch native window");
goto endfunction;
}
/* Do not create EGLSurface for Vulkan window since it will then make the window
incompatible with vkCreateAndroidSurfaceKHR */
#ifdef SDL_VIDEO_OPENGL_EGL
if (window->flags & SDL_WINDOW_OPENGL) {
data->egl_surface = SDL_EGL_CreateSurface(_this, window, (NativeWindowType)data->native_window);
if (data->egl_surface == EGL_NO_SURFACE) {
ANativeWindow_release(data->native_window);
SDL_free(data);
retval = -1;
goto endfunction;
}
}
#endif
window->driverdata = data;
Android_Window = window;
endfunction:
SDL_UnlockMutex(Android_ActivityMutex);
return retval;
}
void Android_SetWindowTitle(SDL_VideoDevice *_this, SDL_Window *window)
{
Android_JNI_SetActivityTitle(window->title);
}
void Android_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window *window, SDL_VideoDisplay *display, SDL_bool fullscreen)
{
SDL_LockMutex(Android_ActivityMutex);
if (window == Android_Window) {
SDL_WindowData *data;
int old_w, old_h, new_w, new_h;
/* If the window is being destroyed don't change visible state */
if (!window->is_destroying) {
Android_JNI_SetWindowStyle(fullscreen);
}
/* Ensure our size matches reality after we've executed the window style change.
*
* It is possible that we've set width and height to the full-size display, but on
* Samsung DeX or Chromebooks or other windowed Android environemtns, our window may
* still not be the full display size.
*/
if (!SDL_IsDeXMode() && !SDL_IsChromebook()) {
goto endfunction;
}
data = window->driverdata;
if (data == NULL || !data->native_window) {
if (data && !data->native_window) {
SDL_SetError("Missing native window");
}
goto endfunction;
}
old_w = window->w;
old_h = window->h;
new_w = ANativeWindow_getWidth(data->native_window);
new_h = ANativeWindow_getHeight(data->native_window);
if (new_w < 0 || new_h < 0) {
SDL_SetError("ANativeWindow_getWidth/Height() fails");
}
if (old_w != new_w || old_h != new_h) {
SDL_SendWindowEvent(window, SDL_EVENT_WINDOW_RESIZED, new_w, new_h);
}
}
endfunction:
SDL_UnlockMutex(Android_ActivityMutex);
}
void Android_MinimizeWindow(SDL_VideoDevice *_this, SDL_Window *window)
{
Android_JNI_MinizeWindow();
}
void Android_SetWindowResizable(SDL_VideoDevice *_this, SDL_Window *window, SDL_bool resizable)
{
/* Set orientation */
Android_JNI_SetOrientation(window->w, window->h, window->flags & SDL_WINDOW_RESIZABLE, SDL_GetHint(SDL_HINT_ORIENTATIONS));
}
void Android_DestroyWindow(SDL_VideoDevice *_this, SDL_Window *window)
{
SDL_LockMutex(Android_ActivityMutex);
if (window == Android_Window) {
Android_Window = NULL;
if (window->driverdata) {
SDL_WindowData *data = window->driverdata;
#ifdef SDL_VIDEO_OPENGL_EGL
if (data->egl_surface != EGL_NO_SURFACE) {
SDL_EGL_DestroySurface(_this, data->egl_surface);
}
#endif
if (data->native_window) {
ANativeWindow_release(data->native_window);
}
SDL_free(window->driverdata);
window->driverdata = NULL;
}
}
SDL_UnlockMutex(Android_ActivityMutex);
}
int Android_GetWindowWMInfo(SDL_VideoDevice *_this, SDL_Window *window, SDL_SysWMinfo *info)
{
SDL_WindowData *data = window->driverdata;
info->subsystem = SDL_SYSWM_ANDROID;
info->info.android.window = data->native_window;
#ifdef SDL_VIDEO_OPENGL_EGL
info->info.android.surface = data->egl_surface;
#endif
return 0;
}
#endif /* SDL_VIDEO_DRIVER_ANDROID */

View File

@ -0,0 +1,52 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#ifndef SDL_androidwindow_h_
#define SDL_androidwindow_h_
#include "../../core/android/SDL_android.h"
#include "../SDL_egl_c.h"
extern int Android_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window);
extern void Android_SetWindowTitle(SDL_VideoDevice *_this, SDL_Window *window);
extern void Android_SetWindowFullscreen(SDL_VideoDevice *_this, SDL_Window *window, SDL_VideoDisplay *display, SDL_bool fullscreen);
extern void Android_MinimizeWindow(SDL_VideoDevice *_this, SDL_Window *window);
extern void Android_SetWindowResizable(SDL_VideoDevice *_this, SDL_Window *window, SDL_bool resizable);
extern void Android_DestroyWindow(SDL_VideoDevice *_this, SDL_Window *window);
extern int Android_GetWindowWMInfo(SDL_VideoDevice *_this, SDL_Window *window, struct SDL_SysWMinfo *info);
extern SDL_Window *Android_Window;
struct SDL_WindowData
{
#ifdef SDL_VIDEO_OPENGL_EGL
EGLSurface egl_surface;
EGLContext egl_context; /* We use this to preserve the context when losing focus */
int has_swap_interval; /* Save/Restore the swap interval / vsync */
int swap_interval;
#endif
SDL_bool backup_done;
ANativeWindow *native_window;
};
#endif /* SDL_androidwindow_h_ */