diff options
Diffstat (limited to 'Source/3rdParty/SDL2/src/core/android')
-rw-r--r-- | Source/3rdParty/SDL2/src/core/android/SDL_android.c | 2401 | ||||
-rw-r--r-- | Source/3rdParty/SDL2/src/core/android/SDL_android.h | 135 | ||||
-rw-r--r-- | Source/3rdParty/SDL2/src/core/android/keyinfotable.h | 175 |
3 files changed, 0 insertions, 2711 deletions
diff --git a/Source/3rdParty/SDL2/src/core/android/SDL_android.c b/Source/3rdParty/SDL2/src/core/android/SDL_android.c deleted file mode 100644 index a56575e..0000000 --- a/Source/3rdParty/SDL2/src/core/android/SDL_android.c +++ /dev/null @@ -1,2401 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2018 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_stdinc.h" -#include "SDL_assert.h" -#include "SDL_hints.h" -#include "SDL_log.h" -#include "SDL_main.h" - -#ifdef __ANDROID__ - -#include "SDL_system.h" -#include "SDL_android.h" - -#include "keyinfotable.h" - -#include "../../events/SDL_events_c.h" -#include "../../video/android/SDL_androidkeyboard.h" -#include "../../video/android/SDL_androidmouse.h" -#include "../../video/android/SDL_androidtouch.h" -#include "../../video/android/SDL_androidvideo.h" -#include "../../video/android/SDL_androidwindow.h" -#include "../../joystick/android/SDL_sysjoystick_c.h" -#include "../../haptic/android/SDL_syshaptic_c.h" - -#include <android/log.h> -#include <pthread.h> -#include <sys/types.h> -#include <unistd.h> -#include <dlfcn.h> -/* #define LOG_TAG "SDL_android" */ -/* #define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__) */ -/* #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__) */ -#define LOGI(...) do {} while (0) -#define LOGE(...) do {} while (0) - - -#define SDL_JAVA_PREFIX org_libsdl_app -#define CONCAT1(prefix, class, function) CONCAT2(prefix, class, function) -#define CONCAT2(prefix, class, function) Java_ ## prefix ## _ ## class ## _ ## function -#define SDL_JAVA_INTERFACE(function) CONCAT1(SDL_JAVA_PREFIX, SDLActivity, function) -#define SDL_JAVA_AUDIO_INTERFACE(function) CONCAT1(SDL_JAVA_PREFIX, SDLAudioManager, function) -#define SDL_JAVA_CONTROLLER_INTERFACE(function) CONCAT1(SDL_JAVA_PREFIX, SDLControllerManager, function) -#define SDL_JAVA_INTERFACE_INPUT_CONNECTION(function) CONCAT1(SDL_JAVA_PREFIX, SDLInputConnection, function) - -/* Audio encoding definitions */ -#define ENCODING_PCM_8BIT 3 -#define ENCODING_PCM_16BIT 2 -#define ENCODING_PCM_FLOAT 4 - -/* Java class SDLActivity */ -JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetupJNI)( - JNIEnv* mEnv, jclass cls); - -JNIEXPORT int JNICALL SDL_JAVA_INTERFACE(nativeRunMain)( - JNIEnv* env, jclass cls, - jstring library, jstring function, jobject array); - -JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeDropFile)( - JNIEnv* env, jclass jcls, - jstring filename); - -JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeResize)( - JNIEnv* env, jclass jcls, - jint surfaceWidth, jint surfaceHeight, - jint deviceWidth, jint deviceHeight, jint format, jfloat rate); - -JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeSurfaceChanged)( - JNIEnv* env, jclass jcls); - -JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeSurfaceDestroyed)( - JNIEnv* env, jclass jcls); - -JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeKeyDown)( - JNIEnv* env, jclass jcls, - jint keycode); - -JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeKeyUp)( - JNIEnv* env, jclass jcls, - jint keycode); - -JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeKeyboardFocusLost)( - JNIEnv* env, jclass jcls); - -JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeTouch)( - JNIEnv* env, jclass jcls, - jint touch_device_id_in, jint pointer_finger_id_in, - jint action, jfloat x, jfloat y, jfloat p); - -JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeMouse)( - JNIEnv* env, jclass jcls, - jint button, jint action, jfloat x, jfloat y, jboolean relative); - -JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeAccel)( - JNIEnv* env, jclass jcls, - jfloat x, jfloat y, jfloat z); - -JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeClipboardChanged)( - JNIEnv* env, jclass jcls); - -JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeLowMemory)( - JNIEnv* env, jclass cls); - -JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeQuit)( - JNIEnv* env, jclass cls); - -JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativePause)( - JNIEnv* env, jclass cls); - -JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeResume)( - JNIEnv* env, jclass cls); - -JNIEXPORT jstring JNICALL SDL_JAVA_INTERFACE(nativeGetHint)( - JNIEnv* env, jclass cls, - jstring name); - -JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetenv)( - JNIEnv* env, jclass cls, - jstring name, jstring value); - -JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeEnvironmentVariablesSet)( - JNIEnv* env, jclass cls); - -JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeOrientationChanged)( - JNIEnv* env, jclass cls, - jint orientation); - -/* Java class SDLInputConnection */ -JNIEXPORT void JNICALL SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeCommitText)( - JNIEnv* env, jclass cls, - jstring text, jint newCursorPosition); - -JNIEXPORT void JNICALL SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeGenerateScancodeForUnichar)( - JNIEnv* env, jclass cls, - jchar chUnicode); - -JNIEXPORT void JNICALL SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeSetComposingText)( - JNIEnv* env, jclass cls, - jstring text, jint newCursorPosition); - -/* Java class SDLAudioManager */ -JNIEXPORT void JNICALL SDL_JAVA_AUDIO_INTERFACE(nativeSetupJNI)( - JNIEnv *env, jclass jcls); - -/* Java class SDLControllerManager */ -JNIEXPORT void JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeSetupJNI)( - JNIEnv *env, jclass jcls); - -JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(onNativePadDown)( - JNIEnv* env, jclass jcls, - jint device_id, jint keycode); - -JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(onNativePadUp)( - JNIEnv* env, jclass jcls, - jint device_id, jint keycode); - -JNIEXPORT void JNICALL SDL_JAVA_CONTROLLER_INTERFACE(onNativeJoy)( - JNIEnv* env, jclass jcls, - jint device_id, jint axis, jfloat value); - -JNIEXPORT void JNICALL SDL_JAVA_CONTROLLER_INTERFACE(onNativeHat)( - JNIEnv* env, jclass jcls, - jint device_id, jint hat_id, jint x, jint y); - -JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeAddJoystick)( - JNIEnv* env, jclass jcls, - jint device_id, jstring device_name, jstring device_desc, jint vendor_id, jint product_id, - jboolean is_accelerometer, jint button_mask, jint naxes, jint nhats, jint nballs); - -JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeRemoveJoystick)( - JNIEnv* env, jclass jcls, - jint device_id); - -JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeAddHaptic)( - JNIEnv* env, jclass jcls, - jint device_id, jstring device_name); - -JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeRemoveHaptic)( - JNIEnv* env, jclass jcls, - jint device_id); - - - -/* Uncomment this to log messages entering and exiting methods in this file */ -/* #define DEBUG_JNI */ - -static void Android_JNI_ThreadDestroyed(void*); -static void checkJNIReady(void); - -/******************************************************************************* - This file links the Java side of Android with libsdl -*******************************************************************************/ -#include <jni.h> - - -/******************************************************************************* - Globals -*******************************************************************************/ -static pthread_key_t mThreadKey; -static JavaVM* mJavaVM; - -/* Main activity */ -static jclass mActivityClass; - -/* method signatures */ -static jmethodID midGetNativeSurface; -static jmethodID midSetActivityTitle; -static jmethodID midSetWindowStyle; -static jmethodID midSetOrientation; -static jmethodID midGetContext; -static jmethodID midIsTablet; -static jmethodID midIsAndroidTV; -static jmethodID midIsChromebook; -static jmethodID midIsDeXMode; -static jmethodID midManualBackButton; -static jmethodID midInputGetInputDeviceIds; -static jmethodID midSendMessage; -static jmethodID midShowTextInput; -static jmethodID midIsScreenKeyboardShown; -static jmethodID midClipboardSetText; -static jmethodID midClipboardGetText; -static jmethodID midClipboardHasText; -static jmethodID midOpenAPKExpansionInputStream; -static jmethodID midGetManifestEnvironmentVariables; -static jmethodID midGetDisplayDPI; -static jmethodID midCreateCustomCursor; -static jmethodID midSetCustomCursor; -static jmethodID midSetSystemCursor; -static jmethodID midSupportsRelativeMouse; -static jmethodID midSetRelativeMouseEnabled; - -/* audio manager */ -static jclass mAudioManagerClass; - -/* method signatures */ -static jmethodID midAudioOpen; -static jmethodID midAudioWriteByteBuffer; -static jmethodID midAudioWriteShortBuffer; -static jmethodID midAudioWriteFloatBuffer; -static jmethodID midAudioClose; -static jmethodID midCaptureOpen; -static jmethodID midCaptureReadByteBuffer; -static jmethodID midCaptureReadShortBuffer; -static jmethodID midCaptureReadFloatBuffer; -static jmethodID midCaptureClose; - -/* controller manager */ -static jclass mControllerManagerClass; - -/* method signatures */ -static jmethodID midPollInputDevices; -static jmethodID midPollHapticDevices; -static jmethodID midHapticRun; -static jmethodID midHapticStop; - -/* static fields */ -static jfieldID fidSeparateMouseAndTouch; - -/* Accelerometer data storage */ -static float fLastAccelerometer[3]; -static SDL_bool bHasNewData; - -static SDL_bool bHasEnvironmentVariables = SDL_FALSE; - -/******************************************************************************* - Functions called by JNI -*******************************************************************************/ - -/* Library init */ -JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved) -{ - JNIEnv *env; - mJavaVM = vm; - LOGI("JNI_OnLoad called"); - if ((*mJavaVM)->GetEnv(mJavaVM, (void**) &env, JNI_VERSION_1_4) != JNI_OK) { - LOGE("Failed to get the environment using GetEnv()"); - return -1; - } - /* - * Create mThreadKey so we can keep track of the JNIEnv assigned to each thread - * Refer to http://developer.android.com/guide/practices/design/jni.html for the rationale behind this - */ - if (pthread_key_create(&mThreadKey, Android_JNI_ThreadDestroyed) != 0) { - __android_log_print(ANDROID_LOG_ERROR, "SDL", "Error initializing pthread key"); - } - Android_JNI_SetupThread(); - - return JNI_VERSION_1_4; -} - -void checkJNIReady() -{ - if (!mActivityClass || !mAudioManagerClass || !mControllerManagerClass) { - // We aren't fully initialized, let's just return. - return; - } - - SDL_SetMainReady(); -} - -/* Activity initialization -- called before SDL_main() to initialize JNI bindings */ -JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetupJNI)(JNIEnv* mEnv, jclass cls) -{ - __android_log_print(ANDROID_LOG_VERBOSE, "SDL", "nativeSetupJNI()"); - - Android_JNI_SetupThread(); - - mActivityClass = (jclass)((*mEnv)->NewGlobalRef(mEnv, cls)); - - midGetNativeSurface = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, - "getNativeSurface","()Landroid/view/Surface;"); - midSetActivityTitle = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, - "setActivityTitle","(Ljava/lang/String;)Z"); - midSetWindowStyle = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, - "setWindowStyle","(Z)V"); - midSetOrientation = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, - "setOrientation","(IIZLjava/lang/String;)V"); - midGetContext = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, - "getContext","()Landroid/content/Context;"); - midIsTablet = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, - "isTablet", "()Z"); - midIsAndroidTV = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, - "isAndroidTV","()Z"); - midIsChromebook = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, - "isChromebook", "()Z"); - midIsDeXMode = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, - "isDeXMode", "()Z"); - midManualBackButton = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, - "manualBackButton", "()V"); - midInputGetInputDeviceIds = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, - "inputGetInputDeviceIds", "(I)[I"); - midSendMessage = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, - "sendMessage", "(II)Z"); - midShowTextInput = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, - "showTextInput", "(IIII)Z"); - midIsScreenKeyboardShown = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, - "isScreenKeyboardShown","()Z"); - midClipboardSetText = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, - "clipboardSetText", "(Ljava/lang/String;)V"); - midClipboardGetText = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, - "clipboardGetText", "()Ljava/lang/String;"); - midClipboardHasText = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, - "clipboardHasText", "()Z"); - midOpenAPKExpansionInputStream = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, - "openAPKExpansionInputStream", "(Ljava/lang/String;)Ljava/io/InputStream;"); - - midGetManifestEnvironmentVariables = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, - "getManifestEnvironmentVariables", "()Z"); - - midGetDisplayDPI = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, "getDisplayDPI", "()Landroid/util/DisplayMetrics;"); - midCreateCustomCursor = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, "createCustomCursor", "([IIIII)I"); - midSetCustomCursor = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, "setCustomCursor", "(I)Z"); - midSetSystemCursor = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, "setSystemCursor", "(I)Z"); - - midSupportsRelativeMouse = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, "supportsRelativeMouse", "()Z"); - midSetRelativeMouseEnabled = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, "setRelativeMouseEnabled", "(Z)Z"); - - - if (!midGetNativeSurface || - !midSetActivityTitle || !midSetWindowStyle || !midSetOrientation || !midGetContext || !midIsTablet || !midIsAndroidTV || !midInputGetInputDeviceIds || - !midSendMessage || !midShowTextInput || !midIsScreenKeyboardShown || - !midClipboardSetText || !midClipboardGetText || !midClipboardHasText || - !midOpenAPKExpansionInputStream || !midGetManifestEnvironmentVariables || !midGetDisplayDPI || - !midCreateCustomCursor || !midSetCustomCursor || !midSetSystemCursor || !midSupportsRelativeMouse || !midSetRelativeMouseEnabled || - !midIsChromebook || !midIsDeXMode || !midManualBackButton) { - __android_log_print(ANDROID_LOG_WARN, "SDL", "Missing some Java callbacks, do you have the latest version of SDLActivity.java?"); - } - - fidSeparateMouseAndTouch = (*mEnv)->GetStaticFieldID(mEnv, mActivityClass, "mSeparateMouseAndTouch", "Z"); - - if (!fidSeparateMouseAndTouch) { - __android_log_print(ANDROID_LOG_WARN, "SDL", "Missing some Java static fields, do you have the latest version of SDLActivity.java?"); - } - - checkJNIReady(); -} - -/* Audio initialization -- called before SDL_main() to initialize JNI bindings */ -JNIEXPORT void JNICALL SDL_JAVA_AUDIO_INTERFACE(nativeSetupJNI)(JNIEnv* mEnv, jclass cls) -{ - __android_log_print(ANDROID_LOG_VERBOSE, "SDL", "AUDIO nativeSetupJNI()"); - - Android_JNI_SetupThread(); - - mAudioManagerClass = (jclass)((*mEnv)->NewGlobalRef(mEnv, cls)); - - midAudioOpen = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass, - "audioOpen", "(IIII)[I"); - midAudioWriteByteBuffer = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass, - "audioWriteByteBuffer", "([B)V"); - midAudioWriteShortBuffer = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass, - "audioWriteShortBuffer", "([S)V"); - midAudioWriteFloatBuffer = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass, - "audioWriteFloatBuffer", "([F)V"); - midAudioClose = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass, - "audioClose", "()V"); - midCaptureOpen = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass, - "captureOpen", "(IIII)[I"); - midCaptureReadByteBuffer = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass, - "captureReadByteBuffer", "([BZ)I"); - midCaptureReadShortBuffer = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass, - "captureReadShortBuffer", "([SZ)I"); - midCaptureReadFloatBuffer = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass, - "captureReadFloatBuffer", "([FZ)I"); - midCaptureClose = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass, - "captureClose", "()V"); - - if (!midAudioOpen || !midAudioWriteByteBuffer || !midAudioWriteShortBuffer || !midAudioWriteFloatBuffer || !midAudioClose || - !midCaptureOpen || !midCaptureReadByteBuffer || !midCaptureReadShortBuffer || !midCaptureReadFloatBuffer || !midCaptureClose) { - __android_log_print(ANDROID_LOG_WARN, "SDL", "Missing some Java callbacks, do you have the latest version of SDLAudioManager.java?"); - } - - checkJNIReady(); -} - -/* Controller initialization -- called before SDL_main() to initialize JNI bindings */ -JNIEXPORT void JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeSetupJNI)(JNIEnv* mEnv, jclass cls) -{ - __android_log_print(ANDROID_LOG_VERBOSE, "SDL", "CONTROLLER nativeSetupJNI()"); - - Android_JNI_SetupThread(); - - mControllerManagerClass = (jclass)((*mEnv)->NewGlobalRef(mEnv, cls)); - - midPollInputDevices = (*mEnv)->GetStaticMethodID(mEnv, mControllerManagerClass, - "pollInputDevices", "()V"); - midPollHapticDevices = (*mEnv)->GetStaticMethodID(mEnv, mControllerManagerClass, - "pollHapticDevices", "()V"); - midHapticRun = (*mEnv)->GetStaticMethodID(mEnv, mControllerManagerClass, - "hapticRun", "(IFI)V"); - midHapticStop = (*mEnv)->GetStaticMethodID(mEnv, mControllerManagerClass, - "hapticStop", "(I)V"); - - if (!midPollInputDevices || !midPollHapticDevices || !midHapticRun || !midHapticStop) { - __android_log_print(ANDROID_LOG_WARN, "SDL", "Missing some Java callbacks, do you have the latest version of SDLControllerManager.java?"); - } - - checkJNIReady(); -} - -/* SDL main function prototype */ -typedef int (*SDL_main_func)(int argc, char *argv[]); - -/* Start up the SDL app */ -JNIEXPORT int JNICALL SDL_JAVA_INTERFACE(nativeRunMain)(JNIEnv* env, jclass cls, jstring library, jstring function, jobject array) -{ - int status = -1; - const char *library_file; - void *library_handle; - - __android_log_print(ANDROID_LOG_VERBOSE, "SDL", "nativeRunMain()"); - - library_file = (*env)->GetStringUTFChars(env, library, NULL); - library_handle = dlopen(library_file, RTLD_GLOBAL); - if (library_handle) { - const char *function_name; - SDL_main_func SDL_main; - - function_name = (*env)->GetStringUTFChars(env, function, NULL); - SDL_main = (SDL_main_func)dlsym(library_handle, function_name); - if (SDL_main) { - int i; - int argc; - int len; - char **argv; - - /* Prepare the arguments. */ - len = (*env)->GetArrayLength(env, array); - argv = SDL_stack_alloc(char*, 1 + len + 1); - argc = 0; - /* Use the name "app_process" so PHYSFS_platformCalcBaseDir() works. - https://bitbucket.org/MartinFelis/love-android-sdl2/issue/23/release-build-crash-on-start - */ - argv[argc++] = SDL_strdup("app_process"); - for (i = 0; i < len; ++i) { - const char* utf; - char* arg = NULL; - jstring string = (*env)->GetObjectArrayElement(env, array, i); - if (string) { - utf = (*env)->GetStringUTFChars(env, string, 0); - if (utf) { - arg = SDL_strdup(utf); - (*env)->ReleaseStringUTFChars(env, string, utf); - } - (*env)->DeleteLocalRef(env, string); - } - if (!arg) { - arg = SDL_strdup(""); - } - argv[argc++] = arg; - } - argv[argc] = NULL; - - - /* Run the application. */ - status = SDL_main(argc, argv); - - /* Release the arguments. */ - for (i = 0; i < argc; ++i) { - SDL_free(argv[i]); - } - SDL_stack_free(argv); - - } else { - __android_log_print(ANDROID_LOG_ERROR, "SDL", "nativeRunMain(): Couldn't find function %s in library %s", function_name, library_file); - } - (*env)->ReleaseStringUTFChars(env, function, function_name); - - dlclose(library_handle); - - } else { - __android_log_print(ANDROID_LOG_ERROR, "SDL", "nativeRunMain(): Couldn't load library %s", library_file); - } - (*env)->ReleaseStringUTFChars(env, library, library_file); - - /* Do not issue an exit or the whole application will terminate instead of just the SDL thread */ - /* exit(status); */ - - return status; -} - -/* Drop file */ -JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeDropFile)( - JNIEnv* env, jclass jcls, - jstring filename) -{ - const char *path = (*env)->GetStringUTFChars(env, filename, NULL); - SDL_SendDropFile(NULL, path); - (*env)->ReleaseStringUTFChars(env, filename, path); - SDL_SendDropComplete(NULL); -} - -/* Resize */ -JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeResize)( - JNIEnv* env, jclass jcls, - jint surfaceWidth, jint surfaceHeight, - jint deviceWidth, jint deviceHeight, jint format, jfloat rate) -{ - Android_SetScreenResolution(surfaceWidth, surfaceHeight, deviceWidth, deviceHeight, format, rate); -} - -JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeOrientationChanged)( - JNIEnv *env, jclass jcls, - jint orientation) -{ - SDL_VideoDisplay *display = SDL_GetDisplay(0); - SDL_SendDisplayEvent(display, SDL_DISPLAYEVENT_ORIENTATION, orientation); -} - -/* Paddown */ -JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(onNativePadDown)( - JNIEnv* env, jclass jcls, - jint device_id, jint keycode) -{ - return Android_OnPadDown(device_id, keycode); -} - -/* Padup */ -JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(onNativePadUp)( - JNIEnv* env, jclass jcls, - jint device_id, jint keycode) -{ - return Android_OnPadUp(device_id, keycode); -} - -/* Joy */ -JNIEXPORT void JNICALL SDL_JAVA_CONTROLLER_INTERFACE(onNativeJoy)( - JNIEnv* env, jclass jcls, - jint device_id, jint axis, jfloat value) -{ - Android_OnJoy(device_id, axis, value); -} - -/* POV Hat */ -JNIEXPORT void JNICALL SDL_JAVA_CONTROLLER_INTERFACE(onNativeHat)( - JNIEnv* env, jclass jcls, - jint device_id, jint hat_id, jint x, jint y) -{ - Android_OnHat(device_id, hat_id, x, y); -} - - -JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeAddJoystick)( - JNIEnv* env, jclass jcls, - jint device_id, jstring device_name, jstring device_desc, - jint vendor_id, jint product_id, jboolean is_accelerometer, - jint button_mask, jint naxes, jint nhats, jint nballs) -{ - int retval; - const char *name = (*env)->GetStringUTFChars(env, device_name, NULL); - const char *desc = (*env)->GetStringUTFChars(env, device_desc, NULL); - - retval = Android_AddJoystick(device_id, name, desc, vendor_id, product_id, is_accelerometer ? SDL_TRUE : SDL_FALSE, button_mask, naxes, nhats, nballs); - - (*env)->ReleaseStringUTFChars(env, device_name, name); - (*env)->ReleaseStringUTFChars(env, device_desc, desc); - - return retval; -} - -JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeRemoveJoystick)( - JNIEnv* env, jclass jcls, - jint device_id) -{ - return Android_RemoveJoystick(device_id); -} - -JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeAddHaptic)( - JNIEnv* env, jclass jcls, jint device_id, jstring device_name) -{ - int retval; - const char *name = (*env)->GetStringUTFChars(env, device_name, NULL); - - retval = Android_AddHaptic(device_id, name); - - (*env)->ReleaseStringUTFChars(env, device_name, name); - - return retval; -} - -JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeRemoveHaptic)( - JNIEnv* env, jclass jcls, jint device_id) -{ - return Android_RemoveHaptic(device_id); -} - - -/* Surface Created */ -JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeSurfaceChanged)(JNIEnv* env, jclass jcls) -{ - SDL_WindowData *data; - SDL_VideoDevice *_this; - - if (Android_Window == NULL || Android_Window->driverdata == NULL ) { - return; - } - - _this = SDL_GetVideoDevice(); - data = (SDL_WindowData *) Android_Window->driverdata; - - /* If the surface has been previously destroyed by onNativeSurfaceDestroyed, recreate it here */ - if (data->egl_surface == EGL_NO_SURFACE) { - if(data->native_window) { - ANativeWindow_release(data->native_window); - } - data->native_window = Android_JNI_GetNativeWindow(); - data->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType) data->native_window); - } - - /* GL Context handling is done in the event loop because this function is run from the Java thread */ - -} - -/* Surface Destroyed */ -JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeSurfaceDestroyed)(JNIEnv* env, jclass jcls) -{ - /* We have to clear the current context and destroy the egl surface here - * Otherwise there's BAD_NATIVE_WINDOW errors coming from eglCreateWindowSurface on resume - * Ref: http://stackoverflow.com/questions/8762589/eglcreatewindowsurface-on-ics-and-switching-from-2d-to-3d - */ - SDL_WindowData *data; - SDL_VideoDevice *_this; - - if (Android_Window == NULL || Android_Window->driverdata == NULL ) { - return; - } - - _this = SDL_GetVideoDevice(); - data = (SDL_WindowData *) Android_Window->driverdata; - - if (data->egl_surface != EGL_NO_SURFACE) { - SDL_EGL_MakeCurrent(_this, NULL, NULL); - SDL_EGL_DestroySurface(_this, data->egl_surface); - data->egl_surface = EGL_NO_SURFACE; - } - - /* GL Context handling is done in the event loop because this function is run from the Java thread */ - -} - -/* Keydown */ -JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeKeyDown)( - JNIEnv* env, jclass jcls, - jint keycode) -{ - Android_OnKeyDown(keycode); -} - -/* Keyup */ -JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeKeyUp)( - JNIEnv* env, jclass jcls, - jint keycode) -{ - Android_OnKeyUp(keycode); -} - -/* Keyboard Focus Lost */ -JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeKeyboardFocusLost)( - JNIEnv* env, jclass jcls) -{ - /* Calling SDL_StopTextInput will take care of hiding the keyboard and cleaning up the DummyText widget */ - SDL_StopTextInput(); -} - - -/* Touch */ -JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeTouch)( - JNIEnv* env, jclass jcls, - jint touch_device_id_in, jint pointer_finger_id_in, - jint action, jfloat x, jfloat y, jfloat p) -{ - Android_OnTouch(touch_device_id_in, pointer_finger_id_in, action, x, y, p); -} - -/* Mouse */ -JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeMouse)( - JNIEnv* env, jclass jcls, - jint button, jint action, jfloat x, jfloat y, jboolean relative) -{ - Android_OnMouse(button, action, x, y, relative); -} - -/* Accelerometer */ -JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeAccel)( - JNIEnv* env, jclass jcls, - jfloat x, jfloat y, jfloat z) -{ - fLastAccelerometer[0] = x; - fLastAccelerometer[1] = y; - fLastAccelerometer[2] = z; - bHasNewData = SDL_TRUE; -} - -/* Clipboard */ -JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeClipboardChanged)( - JNIEnv* env, jclass jcls) -{ - SDL_SendClipboardUpdate(); -} - -/* Low memory */ -JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeLowMemory)( - JNIEnv* env, jclass cls) -{ - SDL_SendAppEvent(SDL_APP_LOWMEMORY); -} - -/* Quit */ -JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeQuit)( - JNIEnv* env, jclass cls) -{ - /* Discard previous events. The user should have handled state storage - * in SDL_APP_WILLENTERBACKGROUND. After nativeQuit() is called, no - * events other than SDL_QUIT and SDL_APP_TERMINATING should fire */ - SDL_FlushEvents(SDL_FIRSTEVENT, SDL_LASTEVENT); - /* Inject a SDL_QUIT event */ - SDL_SendQuit(); - SDL_SendAppEvent(SDL_APP_TERMINATING); - /* Resume the event loop so that the app can catch SDL_QUIT which - * should now be the top event in the event queue. */ - if (!SDL_SemValue(Android_ResumeSem)) SDL_SemPost(Android_ResumeSem); -} - -/* Pause */ -JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativePause)( - JNIEnv* env, jclass cls) -{ - __android_log_print(ANDROID_LOG_VERBOSE, "SDL", "nativePause()"); - - if (Android_Window) { - SDL_SendWindowEvent(Android_Window, SDL_WINDOWEVENT_FOCUS_LOST, 0, 0); - SDL_SendWindowEvent(Android_Window, SDL_WINDOWEVENT_MINIMIZED, 0, 0); - SDL_SendAppEvent(SDL_APP_WILLENTERBACKGROUND); - SDL_SendAppEvent(SDL_APP_DIDENTERBACKGROUND); - - /* *After* sending the relevant events, signal the pause semaphore - * so the event loop knows to pause and (optionally) block itself */ - if (!SDL_SemValue(Android_PauseSem)) SDL_SemPost(Android_PauseSem); - } -} - -/* Resume */ -JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeResume)( - JNIEnv* env, jclass cls) -{ - __android_log_print(ANDROID_LOG_VERBOSE, "SDL", "nativeResume()"); - - if (Android_Window) { - SDL_SendAppEvent(SDL_APP_WILLENTERFOREGROUND); - SDL_SendAppEvent(SDL_APP_DIDENTERFOREGROUND); - SDL_SendWindowEvent(Android_Window, SDL_WINDOWEVENT_FOCUS_GAINED, 0, 0); - SDL_SendWindowEvent(Android_Window, SDL_WINDOWEVENT_RESTORED, 0, 0); - /* Signal the resume semaphore so the event loop knows to resume and restore the GL Context - * We can't restore the GL Context here because it needs to be done on the SDL main thread - * and this function will be called from the Java thread instead. - */ - if (!SDL_SemValue(Android_ResumeSem)) SDL_SemPost(Android_ResumeSem); - } -} - -JNIEXPORT void JNICALL SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeCommitText)( - JNIEnv* env, jclass cls, - jstring text, jint newCursorPosition) -{ - const char *utftext = (*env)->GetStringUTFChars(env, text, NULL); - - SDL_SendKeyboardText(utftext); - - (*env)->ReleaseStringUTFChars(env, text, utftext); -} - -JNIEXPORT void JNICALL SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeGenerateScancodeForUnichar)( - JNIEnv* env, jclass cls, - jchar chUnicode) -{ - SDL_Scancode code = SDL_SCANCODE_UNKNOWN; - uint16_t mod = 0; - - // We do not care about bigger than 127. - if (chUnicode < 127) { - AndroidKeyInfo info = unicharToAndroidKeyInfoTable[chUnicode]; - code = info.code; - mod = info.mod; - } - - if (mod & KMOD_SHIFT) { - /* If character uses shift, press shift down */ - SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_LSHIFT); - } - - /* send a keydown and keyup even for the character */ - SDL_SendKeyboardKey(SDL_PRESSED, code); - SDL_SendKeyboardKey(SDL_RELEASED, code); - - if (mod & KMOD_SHIFT) { - /* If character uses shift, press shift back up */ - SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_LSHIFT); - } -} - - -JNIEXPORT void JNICALL SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeSetComposingText)( - JNIEnv* env, jclass cls, - jstring text, jint newCursorPosition) -{ - const char *utftext = (*env)->GetStringUTFChars(env, text, NULL); - - SDL_SendEditingText(utftext, 0, 0); - - (*env)->ReleaseStringUTFChars(env, text, utftext); -} - -JNIEXPORT jstring JNICALL SDL_JAVA_INTERFACE(nativeGetHint)( - JNIEnv* env, jclass cls, - jstring name) -{ - const char *utfname = (*env)->GetStringUTFChars(env, name, NULL); - const char *hint = SDL_GetHint(utfname); - - jstring result = (*env)->NewStringUTF(env, hint); - (*env)->ReleaseStringUTFChars(env, name, utfname); - - return result; -} - -JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetenv)( - JNIEnv* env, jclass cls, - jstring name, jstring value) -{ - const char *utfname = (*env)->GetStringUTFChars(env, name, NULL); - const char *utfvalue = (*env)->GetStringUTFChars(env, value, NULL); - - SDL_setenv(utfname, utfvalue, 1); - - (*env)->ReleaseStringUTFChars(env, name, utfname); - (*env)->ReleaseStringUTFChars(env, value, utfvalue); - -} - -/******************************************************************************* - Functions called by SDL into Java -*******************************************************************************/ - -static int s_active = 0; -struct LocalReferenceHolder -{ - JNIEnv *m_env; - const char *m_func; -}; - -static struct LocalReferenceHolder LocalReferenceHolder_Setup(const char *func) -{ - struct LocalReferenceHolder refholder; - refholder.m_env = NULL; - refholder.m_func = func; -#ifdef DEBUG_JNI - SDL_Log("Entering function %s", func); -#endif - return refholder; -} - -static SDL_bool LocalReferenceHolder_Init(struct LocalReferenceHolder *refholder, JNIEnv *env) -{ - const int capacity = 16; - if ((*env)->PushLocalFrame(env, capacity) < 0) { - SDL_SetError("Failed to allocate enough JVM local references"); - return SDL_FALSE; - } - ++s_active; - refholder->m_env = env; - return SDL_TRUE; -} - -static void LocalReferenceHolder_Cleanup(struct LocalReferenceHolder *refholder) -{ -#ifdef DEBUG_JNI - SDL_Log("Leaving function %s", refholder->m_func); -#endif - if (refholder->m_env) { - JNIEnv* env = refholder->m_env; - (*env)->PopLocalFrame(env, NULL); - --s_active; - } -} - -static SDL_bool LocalReferenceHolder_IsActive(void) -{ - return s_active > 0; -} - -ANativeWindow* Android_JNI_GetNativeWindow(void) -{ - ANativeWindow* anw; - jobject s; - JNIEnv *env = Android_JNI_GetEnv(); - - s = (*env)->CallStaticObjectMethod(env, mActivityClass, midGetNativeSurface); - anw = ANativeWindow_fromSurface(env, s); - (*env)->DeleteLocalRef(env, s); - - return anw; -} - -void Android_JNI_SetActivityTitle(const char *title) -{ - JNIEnv *mEnv = Android_JNI_GetEnv(); - - jstring jtitle = (jstring)((*mEnv)->NewStringUTF(mEnv, title)); - (*mEnv)->CallStaticBooleanMethod(mEnv, mActivityClass, midSetActivityTitle, jtitle); - (*mEnv)->DeleteLocalRef(mEnv, jtitle); -} - -void Android_JNI_SetWindowStyle(SDL_bool fullscreen) -{ - JNIEnv *mEnv = Android_JNI_GetEnv(); - (*mEnv)->CallStaticVoidMethod(mEnv, mActivityClass, midSetWindowStyle, fullscreen ? 1 : 0); -} - -void Android_JNI_SetOrientation(int w, int h, int resizable, const char *hint) -{ - JNIEnv *mEnv = Android_JNI_GetEnv(); - - jstring jhint = (jstring)((*mEnv)->NewStringUTF(mEnv, (hint ? hint : ""))); - (*mEnv)->CallStaticVoidMethod(mEnv, mActivityClass, midSetOrientation, w, h, (resizable? 1 : 0), jhint); - (*mEnv)->DeleteLocalRef(mEnv, jhint); -} - -SDL_bool Android_JNI_GetAccelerometerValues(float values[3]) -{ - int i; - SDL_bool retval = SDL_FALSE; - - if (bHasNewData) { - for (i = 0; i < 3; ++i) { - values[i] = fLastAccelerometer[i]; - } - bHasNewData = SDL_FALSE; - retval = SDL_TRUE; - } - - return retval; -} - -static void Android_JNI_ThreadDestroyed(void* value) -{ - /* The thread is being destroyed, detach it from the Java VM and set the mThreadKey value to NULL as required */ - JNIEnv *env = (JNIEnv*) value; - if (env != NULL) { - (*mJavaVM)->DetachCurrentThread(mJavaVM); - pthread_setspecific(mThreadKey, NULL); - } -} - -JNIEnv* Android_JNI_GetEnv(void) -{ - /* From http://developer.android.com/guide/practices/jni.html - * All threads are Linux threads, scheduled by the kernel. - * They're usually started from managed code (using Thread.start), but they can also be created elsewhere and then - * attached to the JavaVM. For example, a thread started with pthread_create can be attached with the - * JNI AttachCurrentThread or AttachCurrentThreadAsDaemon functions. Until a thread is attached, it has no JNIEnv, - * and cannot make JNI calls. - * Attaching a natively-created thread causes a java.lang.Thread object to be constructed and added to the "main" - * ThreadGroup, making it visible to the debugger. Calling AttachCurrentThread on an already-attached thread - * is a no-op. - * Note: You can call this function any number of times for the same thread, there's no harm in it - */ - - JNIEnv *env; - int status = (*mJavaVM)->AttachCurrentThread(mJavaVM, &env, NULL); - if(status < 0) { - LOGE("failed to attach current thread"); - return 0; - } - - /* From http://developer.android.com/guide/practices/jni.html - * Threads attached through JNI must call DetachCurrentThread before they exit. If coding this directly is awkward, - * in Android 2.0 (Eclair) and higher you can use pthread_key_create to define a destructor function that will be - * called before the thread exits, and call DetachCurrentThread from there. (Use that key with pthread_setspecific - * to store the JNIEnv in thread-local-storage; that way it'll be passed into your destructor as the argument.) - * Note: The destructor is not called unless the stored value is != NULL - * Note: You can call this function any number of times for the same thread, there's no harm in it - * (except for some lost CPU cycles) - */ - pthread_setspecific(mThreadKey, (void*) env); - - return env; -} - -int Android_JNI_SetupThread(void) -{ - Android_JNI_GetEnv(); - return 1; -} - -/* - * Audio support - */ -static int audioBufferFormat = 0; -static jobject audioBuffer = NULL; -static void* audioBufferPinned = NULL; -static int captureBufferFormat = 0; -static jobject captureBuffer = NULL; - -int Android_JNI_OpenAudioDevice(int iscapture, SDL_AudioSpec *spec) -{ - int audioformat; - int numBufferFrames; - jobject jbufobj = NULL; - jobject result; - int *resultElements; - jboolean isCopy; - - JNIEnv *env = Android_JNI_GetEnv(); - - if (!env) { - LOGE("callback_handler: failed to attach current thread"); - } - Android_JNI_SetupThread(); - - switch (spec->format) { - case AUDIO_U8: - audioformat = ENCODING_PCM_8BIT; - break; - case AUDIO_S16: - audioformat = ENCODING_PCM_16BIT; - break; - case AUDIO_F32: - audioformat = ENCODING_PCM_FLOAT; - break; - default: - return SDL_SetError("Unsupported audio format: 0x%x", spec->format); - } - - if (iscapture) { - __android_log_print(ANDROID_LOG_VERBOSE, "SDL", "SDL audio: opening device for capture"); - result = (*env)->CallStaticObjectMethod(env, mAudioManagerClass, midCaptureOpen, spec->freq, audioformat, spec->channels, spec->samples); - } else { - __android_log_print(ANDROID_LOG_VERBOSE, "SDL", "SDL audio: opening device for output"); - result = (*env)->CallStaticObjectMethod(env, mAudioManagerClass, midAudioOpen, spec->freq, audioformat, spec->channels, spec->samples); - } - if (result == NULL) { - /* Error during audio initialization, error printed from Java */ - return SDL_SetError("Java-side initialization failed"); - } - - if ((*env)->GetArrayLength(env, (jintArray)result) != 4) { - return SDL_SetError("Unexpected results from Java, expected 4, got %d", (*env)->GetArrayLength(env, (jintArray)result)); - } - isCopy = JNI_FALSE; - resultElements = (*env)->GetIntArrayElements(env, (jintArray)result, &isCopy); - spec->freq = resultElements[0]; - audioformat = resultElements[1]; - switch (audioformat) { - case ENCODING_PCM_8BIT: - spec->format = AUDIO_U8; - break; - case ENCODING_PCM_16BIT: - spec->format = AUDIO_S16; - break; - case ENCODING_PCM_FLOAT: - spec->format = AUDIO_F32; - break; - default: - return SDL_SetError("Unexpected audio format from Java: %d\n", audioformat); - } - spec->channels = resultElements[2]; - spec->samples = resultElements[3]; - (*env)->ReleaseIntArrayElements(env, (jintArray)result, resultElements, JNI_ABORT); - (*env)->DeleteLocalRef(env, result); - - /* Allocating the audio buffer from the Java side and passing it as the return value for audioInit no longer works on - * Android >= 4.2 due to a "stale global reference" error. So now we allocate this buffer directly from this side. */ - switch (audioformat) { - case ENCODING_PCM_8BIT: - { - jbyteArray audioBufferLocal = (*env)->NewByteArray(env, spec->samples * spec->channels); - if (audioBufferLocal) { - jbufobj = (*env)->NewGlobalRef(env, audioBufferLocal); - (*env)->DeleteLocalRef(env, audioBufferLocal); - } - } - break; - case ENCODING_PCM_16BIT: - { - jshortArray audioBufferLocal = (*env)->NewShortArray(env, spec->samples * spec->channels); - if (audioBufferLocal) { - jbufobj = (*env)->NewGlobalRef(env, audioBufferLocal); - (*env)->DeleteLocalRef(env, audioBufferLocal); - } - } - break; - case ENCODING_PCM_FLOAT: - { - jfloatArray audioBufferLocal = (*env)->NewFloatArray(env, spec->samples * spec->channels); - if (audioBufferLocal) { - jbufobj = (*env)->NewGlobalRef(env, audioBufferLocal); - (*env)->DeleteLocalRef(env, audioBufferLocal); - } - } - break; - default: - return SDL_SetError("Unexpected audio format from Java: %d\n", audioformat); - } - - if (jbufobj == NULL) { - __android_log_print(ANDROID_LOG_WARN, "SDL", "SDL audio: could not allocate an audio buffer"); - return SDL_OutOfMemory(); - } - - if (iscapture) { - captureBufferFormat = audioformat; - captureBuffer = jbufobj; - } else { - audioBufferFormat = audioformat; - audioBuffer = jbufobj; - } - numBufferFrames = (*env)->GetArrayLength(env, (jarray)jbufobj); - - if (!iscapture) { - isCopy = JNI_FALSE; - - switch (audioformat) { - case ENCODING_PCM_8BIT: - audioBufferPinned = (*env)->GetByteArrayElements(env, (jbyteArray)audioBuffer, &isCopy); - break; - case ENCODING_PCM_16BIT: - audioBufferPinned = (*env)->GetShortArrayElements(env, (jshortArray)audioBuffer, &isCopy); - break; - case ENCODING_PCM_FLOAT: - audioBufferPinned = (*env)->GetFloatArrayElements(env, (jfloatArray)audioBuffer, &isCopy); - break; - default: - return SDL_SetError("Unexpected audio format from Java: %d\n", audioformat); - } - } - return 0; -} - -int Android_JNI_GetDisplayDPI(float *ddpi, float *xdpi, float *ydpi) -{ - JNIEnv *env = Android_JNI_GetEnv(); - - jobject jDisplayObj = (*env)->CallStaticObjectMethod(env, mActivityClass, midGetDisplayDPI); - jclass jDisplayClass = (*env)->GetObjectClass(env, jDisplayObj); - - jfieldID fidXdpi = (*env)->GetFieldID(env, jDisplayClass, "xdpi", "F"); - jfieldID fidYdpi = (*env)->GetFieldID(env, jDisplayClass, "ydpi", "F"); - jfieldID fidDdpi = (*env)->GetFieldID(env, jDisplayClass, "densityDpi", "I"); - - float nativeXdpi = (*env)->GetFloatField(env, jDisplayObj, fidXdpi); - float nativeYdpi = (*env)->GetFloatField(env, jDisplayObj, fidYdpi); - int nativeDdpi = (*env)->GetIntField(env, jDisplayObj, fidDdpi); - - - (*env)->DeleteLocalRef(env, jDisplayObj); - (*env)->DeleteLocalRef(env, jDisplayClass); - - if (ddpi) { - *ddpi = (float)nativeDdpi; - } - if (xdpi) { - *xdpi = nativeXdpi; - } - if (ydpi) { - *ydpi = nativeYdpi; - } - - return 0; -} - -void * Android_JNI_GetAudioBuffer(void) -{ - return audioBufferPinned; -} - -void Android_JNI_WriteAudioBuffer(void) -{ - JNIEnv *mAudioEnv = Android_JNI_GetEnv(); - - switch (audioBufferFormat) { - case ENCODING_PCM_8BIT: - (*mAudioEnv)->ReleaseByteArrayElements(mAudioEnv, (jbyteArray)audioBuffer, (jbyte *)audioBufferPinned, JNI_COMMIT); - (*mAudioEnv)->CallStaticVoidMethod(mAudioEnv, mAudioManagerClass, midAudioWriteByteBuffer, (jbyteArray)audioBuffer); - break; - case ENCODING_PCM_16BIT: - (*mAudioEnv)->ReleaseShortArrayElements(mAudioEnv, (jshortArray)audioBuffer, (jshort *)audioBufferPinned, JNI_COMMIT); - (*mAudioEnv)->CallStaticVoidMethod(mAudioEnv, mAudioManagerClass, midAudioWriteShortBuffer, (jshortArray)audioBuffer); - break; - case ENCODING_PCM_FLOAT: - (*mAudioEnv)->ReleaseFloatArrayElements(mAudioEnv, (jfloatArray)audioBuffer, (jfloat *)audioBufferPinned, JNI_COMMIT); - (*mAudioEnv)->CallStaticVoidMethod(mAudioEnv, mAudioManagerClass, midAudioWriteFloatBuffer, (jfloatArray)audioBuffer); - break; - default: - __android_log_print(ANDROID_LOG_WARN, "SDL", "SDL audio: unhandled audio buffer format"); - break; - } - - /* JNI_COMMIT means the changes are committed to the VM but the buffer remains pinned */ -} - -int Android_JNI_CaptureAudioBuffer(void *buffer, int buflen) -{ - JNIEnv *env = Android_JNI_GetEnv(); - jboolean isCopy = JNI_FALSE; - jint br; - - switch (captureBufferFormat) { - case ENCODING_PCM_8BIT: - SDL_assert((*env)->GetArrayLength(env, (jshortArray)captureBuffer) == buflen); - br = (*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureReadByteBuffer, (jbyteArray)captureBuffer, JNI_TRUE); - if (br > 0) { - jbyte *ptr = (*env)->GetByteArrayElements(env, (jbyteArray)captureBuffer, &isCopy); - SDL_memcpy(buffer, ptr, br); - (*env)->ReleaseByteArrayElements(env, (jbyteArray)captureBuffer, (jbyte *)ptr, JNI_ABORT); - } - break; - case ENCODING_PCM_16BIT: - SDL_assert((*env)->GetArrayLength(env, (jshortArray)captureBuffer) == (buflen / sizeof(Sint16))); - br = (*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureReadShortBuffer, (jshortArray)captureBuffer, JNI_TRUE); - if (br > 0) { - jshort *ptr = (*env)->GetShortArrayElements(env, (jshortArray)captureBuffer, &isCopy); - br *= sizeof(Sint16); - SDL_memcpy(buffer, ptr, br); - (*env)->ReleaseShortArrayElements(env, (jshortArray)captureBuffer, (jshort *)ptr, JNI_ABORT); - } - break; - case ENCODING_PCM_FLOAT: - SDL_assert((*env)->GetArrayLength(env, (jfloatArray)captureBuffer) == (buflen / sizeof(float))); - br = (*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureReadFloatBuffer, (jfloatArray)captureBuffer, JNI_TRUE); - if (br > 0) { - jfloat *ptr = (*env)->GetFloatArrayElements(env, (jfloatArray)captureBuffer, &isCopy); - br *= sizeof(float); - SDL_memcpy(buffer, ptr, br); - (*env)->ReleaseFloatArrayElements(env, (jfloatArray)captureBuffer, (jfloat *)ptr, JNI_ABORT); - } - break; - default: - __android_log_print(ANDROID_LOG_WARN, "SDL", "SDL audio: unhandled capture buffer format"); - break; - } - return br; -} - -void Android_JNI_FlushCapturedAudio(void) -{ - JNIEnv *env = Android_JNI_GetEnv(); -#if 0 /* !!! FIXME: this needs API 23, or it'll do blocking reads and never end. */ - switch (captureBufferFormat) { - case ENCODING_PCM_8BIT: - { - const jint len = (*env)->GetArrayLength(env, (jbyteArray)captureBuffer); - while ((*env)->CallStaticIntMethod(env, mActivityClass, midCaptureReadByteBuffer, (jbyteArray)captureBuffer, JNI_FALSE) == len) { /* spin */ } - } - break; - case ENCODING_PCM_16BIT: - { - const jint len = (*env)->GetArrayLength(env, (jshortArray)captureBuffer); - while ((*env)->CallStaticIntMethod(env, mActivityClass, midCaptureReadShortBuffer, (jshortArray)captureBuffer, JNI_FALSE) == len) { /* spin */ } - } - break; - case ENCODING_PCM_FLOAT: - { - const jint len = (*env)->GetArrayLength(env, (jfloatArray)captureBuffer); - while ((*env)->CallStaticIntMethod(env, mActivityClass, midCaptureReadFloatBuffer, (jfloatArray)captureBuffer, JNI_FALSE) == len) { /* spin */ } - } - break; - default: - __android_log_print(ANDROID_LOG_WARN, "SDL", "SDL audio: flushing unhandled capture buffer format"); - break; - } -#else - switch (captureBufferFormat) { - case ENCODING_PCM_8BIT: - (*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureReadByteBuffer, (jbyteArray)captureBuffer, JNI_FALSE); - break; - case ENCODING_PCM_16BIT: - (*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureReadShortBuffer, (jshortArray)captureBuffer, JNI_FALSE); - break; - case ENCODING_PCM_FLOAT: - (*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureReadFloatBuffer, (jfloatArray)captureBuffer, JNI_FALSE); - break; - default: - __android_log_print(ANDROID_LOG_WARN, "SDL", "SDL audio: flushing unhandled capture buffer format"); - break; - } -#endif -} - -void Android_JNI_CloseAudioDevice(const int iscapture) -{ - JNIEnv *env = Android_JNI_GetEnv(); - - if (iscapture) { - (*env)->CallStaticVoidMethod(env, mAudioManagerClass, midCaptureClose); - if (captureBuffer) { - (*env)->DeleteGlobalRef(env, captureBuffer); - captureBuffer = NULL; - } - } else { - (*env)->CallStaticVoidMethod(env, mAudioManagerClass, midAudioClose); - if (audioBuffer) { - (*env)->DeleteGlobalRef(env, audioBuffer); - audioBuffer = NULL; - audioBufferPinned = NULL; - } - } -} - -/* Test for an exception and call SDL_SetError with its detail if one occurs */ -/* If the parameter silent is truthy then SDL_SetError() will not be called. */ -static SDL_bool Android_JNI_ExceptionOccurred(SDL_bool silent) -{ - JNIEnv *mEnv = Android_JNI_GetEnv(); - jthrowable exception; - - SDL_assert(LocalReferenceHolder_IsActive()); - - exception = (*mEnv)->ExceptionOccurred(mEnv); - if (exception != NULL) { - jmethodID mid; - - /* Until this happens most JNI operations have undefined behaviour */ - (*mEnv)->ExceptionClear(mEnv); - - if (!silent) { - jclass exceptionClass = (*mEnv)->GetObjectClass(mEnv, exception); - jclass classClass = (*mEnv)->FindClass(mEnv, "java/lang/Class"); - jstring exceptionName; - const char* exceptionNameUTF8; - jstring exceptionMessage; - - mid = (*mEnv)->GetMethodID(mEnv, classClass, "getName", "()Ljava/lang/String;"); - exceptionName = (jstring)(*mEnv)->CallObjectMethod(mEnv, exceptionClass, mid); - exceptionNameUTF8 = (*mEnv)->GetStringUTFChars(mEnv, exceptionName, 0); - - mid = (*mEnv)->GetMethodID(mEnv, exceptionClass, "getMessage", "()Ljava/lang/String;"); - exceptionMessage = (jstring)(*mEnv)->CallObjectMethod(mEnv, exception, mid); - - if (exceptionMessage != NULL) { - const char* exceptionMessageUTF8 = (*mEnv)->GetStringUTFChars(mEnv, exceptionMessage, 0); - SDL_SetError("%s: %s", exceptionNameUTF8, exceptionMessageUTF8); - (*mEnv)->ReleaseStringUTFChars(mEnv, exceptionMessage, exceptionMessageUTF8); - } else { - SDL_SetError("%s", exceptionNameUTF8); - } - - (*mEnv)->ReleaseStringUTFChars(mEnv, exceptionName, exceptionNameUTF8); - } - - return SDL_TRUE; - } - - return SDL_FALSE; -} - -static int Internal_Android_JNI_FileOpen(SDL_RWops* ctx) -{ - struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__); - - int result = 0; - - jmethodID mid; - jobject context; - jobject assetManager; - jobject inputStream; - jclass channels; - jobject readableByteChannel; - jstring fileNameJString; - jobject fd; - jclass fdCls; - jfieldID descriptor; - - JNIEnv *mEnv = Android_JNI_GetEnv(); - if (!LocalReferenceHolder_Init(&refs, mEnv)) { - goto failure; - } - - fileNameJString = (jstring)ctx->hidden.androidio.fileNameRef; - ctx->hidden.androidio.position = 0; - - /* context = SDLActivity.getContext(); */ - context = (*mEnv)->CallStaticObjectMethod(mEnv, mActivityClass, midGetContext); - - /* assetManager = context.getAssets(); */ - mid = (*mEnv)->GetMethodID(mEnv, (*mEnv)->GetObjectClass(mEnv, context), - "getAssets", "()Landroid/content/res/AssetManager;"); - assetManager = (*mEnv)->CallObjectMethod(mEnv, context, mid); - - /* First let's try opening the file to obtain an AssetFileDescriptor. - * This method reads the files directly from the APKs using standard *nix calls - */ - mid = (*mEnv)->GetMethodID(mEnv, (*mEnv)->GetObjectClass(mEnv, assetManager), "openFd", "(Ljava/lang/String;)Landroid/content/res/AssetFileDescriptor;"); - inputStream = (*mEnv)->CallObjectMethod(mEnv, assetManager, mid, fileNameJString); - if (Android_JNI_ExceptionOccurred(SDL_TRUE)) { - goto fallback; - } - - mid = (*mEnv)->GetMethodID(mEnv, (*mEnv)->GetObjectClass(mEnv, inputStream), "getStartOffset", "()J"); - ctx->hidden.androidio.offset = (*mEnv)->CallLongMethod(mEnv, inputStream, mid); - if (Android_JNI_ExceptionOccurred(SDL_TRUE)) { - goto fallback; - } - - mid = (*mEnv)->GetMethodID(mEnv, (*mEnv)->GetObjectClass(mEnv, inputStream), "getDeclaredLength", "()J"); - ctx->hidden.androidio.size = (*mEnv)->CallLongMethod(mEnv, inputStream, mid); - if (Android_JNI_ExceptionOccurred(SDL_TRUE)) { - goto fallback; - } - - mid = (*mEnv)->GetMethodID(mEnv, (*mEnv)->GetObjectClass(mEnv, inputStream), "getFileDescriptor", "()Ljava/io/FileDescriptor;"); - fd = (*mEnv)->CallObjectMethod(mEnv, inputStream, mid); - fdCls = (*mEnv)->GetObjectClass(mEnv, fd); - descriptor = (*mEnv)->GetFieldID(mEnv, fdCls, "descriptor", "I"); - ctx->hidden.androidio.fd = (*mEnv)->GetIntField(mEnv, fd, descriptor); - ctx->hidden.androidio.assetFileDescriptorRef = (*mEnv)->NewGlobalRef(mEnv, inputStream); - - /* Seek to the correct offset in the file. */ - lseek(ctx->hidden.androidio.fd, (off_t)ctx->hidden.androidio.offset, SEEK_SET); - - if (0) { -fallback: - /* Disabled log message because of spam on the Nexus 7 */ - /* __android_log_print(ANDROID_LOG_DEBUG, "SDL", "Falling back to legacy InputStream method for opening file"); */ - - /* Try the old method using InputStream */ - ctx->hidden.androidio.assetFileDescriptorRef = NULL; - - /* inputStream = assetManager.open(<filename>); */ - mid = (*mEnv)->GetMethodID(mEnv, (*mEnv)->GetObjectClass(mEnv, assetManager), - "open", "(Ljava/lang/String;I)Ljava/io/InputStream;"); - inputStream = (*mEnv)->CallObjectMethod(mEnv, assetManager, mid, fileNameJString, 1 /* ACCESS_RANDOM */); - if (Android_JNI_ExceptionOccurred(SDL_FALSE)) { - /* Try fallback to APK expansion files */ - inputStream = (*mEnv)->CallStaticObjectMethod(mEnv, mActivityClass, midOpenAPKExpansionInputStream, fileNameJString); - - /* Exception is checked first because it always needs to be cleared. - * If no exception occurred then the last SDL error message is kept. - */ - if (Android_JNI_ExceptionOccurred(SDL_FALSE) || !inputStream) { - goto failure; - } - } - - ctx->hidden.androidio.inputStreamRef = (*mEnv)->NewGlobalRef(mEnv, inputStream); - - /* Despite all the visible documentation on [Asset]InputStream claiming - * that the .available() method is not guaranteed to return the entire file - * size, comments in <sdk>/samples/<ver>/ApiDemos/src/com/example/ ... - * android/apis/content/ReadAsset.java imply that Android's - * AssetInputStream.available() /will/ always return the total file size - */ - - /* size = inputStream.available(); */ - mid = (*mEnv)->GetMethodID(mEnv, (*mEnv)->GetObjectClass(mEnv, inputStream), - "available", "()I"); - ctx->hidden.androidio.size = (long)(*mEnv)->CallIntMethod(mEnv, inputStream, mid); - if (Android_JNI_ExceptionOccurred(SDL_FALSE)) { - goto failure; - } - - /* readableByteChannel = Channels.newChannel(inputStream); */ - channels = (*mEnv)->FindClass(mEnv, "java/nio/channels/Channels"); - mid = (*mEnv)->GetStaticMethodID(mEnv, channels, - "newChannel", - "(Ljava/io/InputStream;)Ljava/nio/channels/ReadableByteChannel;"); - readableByteChannel = (*mEnv)->CallStaticObjectMethod( - mEnv, channels, mid, inputStream); - if (Android_JNI_ExceptionOccurred(SDL_FALSE)) { - goto failure; - } - - ctx->hidden.androidio.readableByteChannelRef = - (*mEnv)->NewGlobalRef(mEnv, readableByteChannel); - - /* Store .read id for reading purposes */ - mid = (*mEnv)->GetMethodID(mEnv, (*mEnv)->GetObjectClass(mEnv, readableByteChannel), - "read", "(Ljava/nio/ByteBuffer;)I"); - ctx->hidden.androidio.readMethod = mid; - } - - if (0) { -failure: - result = -1; - - (*mEnv)->DeleteGlobalRef(mEnv, (jobject)ctx->hidden.androidio.fileNameRef); - - if(ctx->hidden.androidio.inputStreamRef != NULL) { - (*mEnv)->DeleteGlobalRef(mEnv, (jobject)ctx->hidden.androidio.inputStreamRef); - } - - if(ctx->hidden.androidio.readableByteChannelRef != NULL) { - (*mEnv)->DeleteGlobalRef(mEnv, (jobject)ctx->hidden.androidio.readableByteChannelRef); - } - - if(ctx->hidden.androidio.assetFileDescriptorRef != NULL) { - (*mEnv)->DeleteGlobalRef(mEnv, (jobject)ctx->hidden.androidio.assetFileDescriptorRef); - } - - } - - LocalReferenceHolder_Cleanup(&refs); - return result; -} - -int Android_JNI_FileOpen(SDL_RWops* ctx, - const char* fileName, const char* mode) -{ - struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__); - JNIEnv *mEnv = Android_JNI_GetEnv(); - int retval; - jstring fileNameJString; - - if (!LocalReferenceHolder_Init(&refs, mEnv)) { - LocalReferenceHolder_Cleanup(&refs); - return -1; - } - - if (!ctx) { - LocalReferenceHolder_Cleanup(&refs); - return -1; - } - - fileNameJString = (*mEnv)->NewStringUTF(mEnv, fileName); - ctx->hidden.androidio.fileNameRef = (*mEnv)->NewGlobalRef(mEnv, fileNameJString); - ctx->hidden.androidio.inputStreamRef = NULL; - ctx->hidden.androidio.readableByteChannelRef = NULL; - ctx->hidden.androidio.readMethod = NULL; - ctx->hidden.androidio.assetFileDescriptorRef = NULL; - - retval = Internal_Android_JNI_FileOpen(ctx); - LocalReferenceHolder_Cleanup(&refs); - return retval; -} - -size_t Android_JNI_FileRead(SDL_RWops* ctx, void* buffer, - size_t size, size_t maxnum) -{ - struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__); - - if (ctx->hidden.androidio.assetFileDescriptorRef) { - size_t bytesMax = size * maxnum; - size_t result; - if (ctx->hidden.androidio.size != -1 /* UNKNOWN_LENGTH */ && ctx->hidden.androidio.position + bytesMax > ctx->hidden.androidio.size) { - bytesMax = ctx->hidden.androidio.size - ctx->hidden.androidio.position; - } - result = read(ctx->hidden.androidio.fd, buffer, bytesMax ); - if (result > 0) { - ctx->hidden.androidio.position += result; - LocalReferenceHolder_Cleanup(&refs); - return result / size; - } - LocalReferenceHolder_Cleanup(&refs); - return 0; - } else { - jlong bytesRemaining = (jlong) (size * maxnum); - jlong bytesMax = (jlong) (ctx->hidden.androidio.size - ctx->hidden.androidio.position); - int bytesRead = 0; - JNIEnv *mEnv; - jobject readableByteChannel; - jmethodID readMethod; - jobject byteBuffer; - - /* Don't read more bytes than those that remain in the file, otherwise we get an exception */ - if (bytesRemaining > bytesMax) bytesRemaining = bytesMax; - - mEnv = Android_JNI_GetEnv(); - if (!LocalReferenceHolder_Init(&refs, mEnv)) { - LocalReferenceHolder_Cleanup(&refs); - return 0; - } - - readableByteChannel = (jobject)ctx->hidden.androidio.readableByteChannelRef; - readMethod = (jmethodID)ctx->hidden.androidio.readMethod; - byteBuffer = (*mEnv)->NewDirectByteBuffer(mEnv, buffer, bytesRemaining); - - while (bytesRemaining > 0) { - /* result = readableByteChannel.read(...); */ - int result = (*mEnv)->CallIntMethod(mEnv, readableByteChannel, readMethod, byteBuffer); - - if (Android_JNI_ExceptionOccurred(SDL_FALSE)) { - LocalReferenceHolder_Cleanup(&refs); - return 0; - } - - if (result < 0) { - break; - } - - bytesRemaining -= result; - bytesRead += result; - ctx->hidden.androidio.position += result; - } - LocalReferenceHolder_Cleanup(&refs); - return bytesRead / size; - } -} - -size_t Android_JNI_FileWrite(SDL_RWops* ctx, const void* buffer, - size_t size, size_t num) -{ - SDL_SetError("Cannot write to Android package filesystem"); - return 0; -} - -static int Internal_Android_JNI_FileClose(SDL_RWops* ctx, SDL_bool release) -{ - struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__); - - int result = 0; - JNIEnv *mEnv = Android_JNI_GetEnv(); - - if (!LocalReferenceHolder_Init(&refs, mEnv)) { - LocalReferenceHolder_Cleanup(&refs); - return SDL_SetError("Failed to allocate enough JVM local references"); - } - - if (ctx) { - if (release) { - (*mEnv)->DeleteGlobalRef(mEnv, (jobject)ctx->hidden.androidio.fileNameRef); - } - - if (ctx->hidden.androidio.assetFileDescriptorRef) { - jobject inputStream = (jobject)ctx->hidden.androidio.assetFileDescriptorRef; - jmethodID mid = (*mEnv)->GetMethodID(mEnv, (*mEnv)->GetObjectClass(mEnv, inputStream), - "close", "()V"); - (*mEnv)->CallVoidMethod(mEnv, inputStream, mid); - (*mEnv)->DeleteGlobalRef(mEnv, (jobject)ctx->hidden.androidio.assetFileDescriptorRef); - if (Android_JNI_ExceptionOccurred(SDL_FALSE)) { - result = -1; - } - } - else { - jobject inputStream = (jobject)ctx->hidden.androidio.inputStreamRef; - - /* inputStream.close(); */ - jmethodID mid = (*mEnv)->GetMethodID(mEnv, (*mEnv)->GetObjectClass(mEnv, inputStream), - "close", "()V"); - (*mEnv)->CallVoidMethod(mEnv, inputStream, mid); - (*mEnv)->DeleteGlobalRef(mEnv, (jobject)ctx->hidden.androidio.inputStreamRef); - (*mEnv)->DeleteGlobalRef(mEnv, (jobject)ctx->hidden.androidio.readableByteChannelRef); - if (Android_JNI_ExceptionOccurred(SDL_FALSE)) { - result = -1; - } - } - - if (release) { - SDL_FreeRW(ctx); - } - } - - LocalReferenceHolder_Cleanup(&refs); - return result; -} - - -Sint64 Android_JNI_FileSize(SDL_RWops* ctx) -{ - return ctx->hidden.androidio.size; -} - -Sint64 Android_JNI_FileSeek(SDL_RWops* ctx, Sint64 offset, int whence) -{ - if (ctx->hidden.androidio.assetFileDescriptorRef) { - off_t ret; - switch (whence) { - case RW_SEEK_SET: - if (ctx->hidden.androidio.size != -1 /* UNKNOWN_LENGTH */ && offset > ctx->hidden.androidio.size) offset = ctx->hidden.androidio.size; - offset += ctx->hidden.androidio.offset; - break; - case RW_SEEK_CUR: - offset += ctx->hidden.androidio.position; - if (ctx->hidden.androidio.size != -1 /* UNKNOWN_LENGTH */ && offset > ctx->hidden.androidio.size) offset = ctx->hidden.androidio.size; - offset += ctx->hidden.androidio.offset; - break; - case RW_SEEK_END: - offset = ctx->hidden.androidio.offset + ctx->hidden.androidio.size + offset; - break; - default: - return SDL_SetError("Unknown value for 'whence'"); - } - whence = SEEK_SET; - - ret = lseek(ctx->hidden.androidio.fd, (off_t)offset, SEEK_SET); - if (ret == -1) return -1; - ctx->hidden.androidio.position = ret - ctx->hidden.androidio.offset; - } else { - Sint64 newPosition; - Sint64 movement; - - switch (whence) { - case RW_SEEK_SET: - newPosition = offset; - break; - case RW_SEEK_CUR: - newPosition = ctx->hidden.androidio.position + offset; - break; - case RW_SEEK_END: - newPosition = ctx->hidden.androidio.size + offset; - break; - default: - return SDL_SetError("Unknown value for 'whence'"); - } - - /* Validate the new position */ - if (newPosition < 0) { - return SDL_Error(SDL_EFSEEK); - } - if (newPosition > ctx->hidden.androidio.size) { - newPosition = ctx->hidden.androidio.size; - } - - movement = newPosition - ctx->hidden.androidio.position; - if (movement > 0) { - unsigned char buffer[4096]; - - /* The easy case where we're seeking forwards */ - while (movement > 0) { - Sint64 amount = sizeof (buffer); - size_t result; - if (amount > movement) { - amount = movement; - } - result = Android_JNI_FileRead(ctx, buffer, 1, amount); - if (result <= 0) { - /* Failed to read/skip the required amount, so fail */ - return -1; - } - - movement -= result; - } - - } else if (movement < 0) { - /* We can't seek backwards so we have to reopen the file and seek */ - /* forwards which obviously isn't very efficient */ - Internal_Android_JNI_FileClose(ctx, SDL_FALSE); - Internal_Android_JNI_FileOpen(ctx); - Android_JNI_FileSeek(ctx, newPosition, RW_SEEK_SET); - } - } - - return ctx->hidden.androidio.position; - -} - -int Android_JNI_FileClose(SDL_RWops* ctx) -{ - return Internal_Android_JNI_FileClose(ctx, SDL_TRUE); -} - -int Android_JNI_SetClipboardText(const char* text) -{ - JNIEnv* env = Android_JNI_GetEnv(); - jstring string = (*env)->NewStringUTF(env, text); - (*env)->CallStaticVoidMethod(env, mActivityClass, midClipboardSetText, string); - (*env)->DeleteLocalRef(env, string); - return 0; -} - -char* Android_JNI_GetClipboardText(void) -{ - JNIEnv* env = Android_JNI_GetEnv(); - char* text = NULL; - jstring string; - - string = (*env)->CallStaticObjectMethod(env, mActivityClass, midClipboardGetText); - if (string) { - const char* utf = (*env)->GetStringUTFChars(env, string, 0); - if (utf) { - text = SDL_strdup(utf); - (*env)->ReleaseStringUTFChars(env, string, utf); - } - (*env)->DeleteLocalRef(env, string); - } - - return (text == NULL) ? SDL_strdup("") : text; -} - -SDL_bool Android_JNI_HasClipboardText(void) -{ - JNIEnv* env = Android_JNI_GetEnv(); - jboolean retval = (*env)->CallStaticBooleanMethod(env, mActivityClass, midClipboardHasText); - return (retval == JNI_TRUE) ? SDL_TRUE : SDL_FALSE; -} - -/* returns 0 on success or -1 on error (others undefined then) - * returns truthy or falsy value in plugged, charged and battery - * returns the value in seconds and percent or -1 if not available - */ -int Android_JNI_GetPowerInfo(int* plugged, int* charged, int* battery, int* seconds, int* percent) -{ - struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__); - JNIEnv* env = Android_JNI_GetEnv(); - jmethodID mid; - jobject context; - jstring action; - jclass cls; - jobject filter; - jobject intent; - jstring iname; - jmethodID imid; - jstring bname; - jmethodID bmid; - if (!LocalReferenceHolder_Init(&refs, env)) { - LocalReferenceHolder_Cleanup(&refs); - return -1; - } - - - /* context = SDLActivity.getContext(); */ - context = (*env)->CallStaticObjectMethod(env, mActivityClass, midGetContext); - - action = (*env)->NewStringUTF(env, "android.intent.action.BATTERY_CHANGED"); - - cls = (*env)->FindClass(env, "android/content/IntentFilter"); - - mid = (*env)->GetMethodID(env, cls, "<init>", "(Ljava/lang/String;)V"); - filter = (*env)->NewObject(env, cls, mid, action); - - (*env)->DeleteLocalRef(env, action); - - mid = (*env)->GetMethodID(env, mActivityClass, "registerReceiver", "(Landroid/content/BroadcastReceiver;Landroid/content/IntentFilter;)Landroid/content/Intent;"); - intent = (*env)->CallObjectMethod(env, context, mid, NULL, filter); - - (*env)->DeleteLocalRef(env, filter); - - cls = (*env)->GetObjectClass(env, intent); - - imid = (*env)->GetMethodID(env, cls, "getIntExtra", "(Ljava/lang/String;I)I"); - - /* Watch out for C89 scoping rules because of the macro */ -#define GET_INT_EXTRA(var, key) \ - int var; \ - iname = (*env)->NewStringUTF(env, key); \ - var = (*env)->CallIntMethod(env, intent, imid, iname, -1); \ - (*env)->DeleteLocalRef(env, iname); - - bmid = (*env)->GetMethodID(env, cls, "getBooleanExtra", "(Ljava/lang/String;Z)Z"); - - /* Watch out for C89 scoping rules because of the macro */ -#define GET_BOOL_EXTRA(var, key) \ - int var; \ - bname = (*env)->NewStringUTF(env, key); \ - var = (*env)->CallBooleanMethod(env, intent, bmid, bname, JNI_FALSE); \ - (*env)->DeleteLocalRef(env, bname); - - if (plugged) { - /* Watch out for C89 scoping rules because of the macro */ - GET_INT_EXTRA(plug, "plugged") /* == BatteryManager.EXTRA_PLUGGED (API 5) */ - if (plug == -1) { - LocalReferenceHolder_Cleanup(&refs); - return -1; - } - /* 1 == BatteryManager.BATTERY_PLUGGED_AC */ - /* 2 == BatteryManager.BATTERY_PLUGGED_USB */ - *plugged = (0 < plug) ? 1 : 0; - } - - if (charged) { - /* Watch out for C89 scoping rules because of the macro */ - GET_INT_EXTRA(status, "status") /* == BatteryManager.EXTRA_STATUS (API 5) */ - if (status == -1) { - LocalReferenceHolder_Cleanup(&refs); - return -1; - } - /* 5 == BatteryManager.BATTERY_STATUS_FULL */ - *charged = (status == 5) ? 1 : 0; - } - - if (battery) { - GET_BOOL_EXTRA(present, "present") /* == BatteryManager.EXTRA_PRESENT (API 5) */ - *battery = present ? 1 : 0; - } - - if (seconds) { - *seconds = -1; /* not possible */ - } - - if (percent) { - int level; - int scale; - - /* Watch out for C89 scoping rules because of the macro */ - { - GET_INT_EXTRA(level_temp, "level") /* == BatteryManager.EXTRA_LEVEL (API 5) */ - level = level_temp; - } - /* Watch out for C89 scoping rules because of the macro */ - { - GET_INT_EXTRA(scale_temp, "scale") /* == BatteryManager.EXTRA_SCALE (API 5) */ - scale = scale_temp; - } - - if ((level == -1) || (scale == -1)) { - LocalReferenceHolder_Cleanup(&refs); - return -1; - } - *percent = level * 100 / scale; - } - - (*env)->DeleteLocalRef(env, intent); - - LocalReferenceHolder_Cleanup(&refs); - return 0; -} - -/* returns number of found touch devices as return value and ids in parameter ids */ -int Android_JNI_GetTouchDeviceIds(int **ids) { - JNIEnv *env = Android_JNI_GetEnv(); - jint sources = 4098; /* == InputDevice.SOURCE_TOUCHSCREEN */ - jintArray array = (jintArray) (*env)->CallStaticObjectMethod(env, mActivityClass, midInputGetInputDeviceIds, sources); - int number = 0; - *ids = NULL; - if (array) { - number = (int) (*env)->GetArrayLength(env, array); - if (0 < number) { - jint* elements = (*env)->GetIntArrayElements(env, array, NULL); - if (elements) { - int i; - *ids = SDL_malloc(number * sizeof (**ids)); - for (i = 0; i < number; ++i) { /* not assuming sizeof (jint) == sizeof (int) */ - (*ids)[i] = elements[i]; - } - (*env)->ReleaseIntArrayElements(env, array, elements, JNI_ABORT); - } - } - (*env)->DeleteLocalRef(env, array); - } - return number; -} - -/* sets the mSeparateMouseAndTouch field */ -void Android_JNI_SetSeparateMouseAndTouch(SDL_bool new_value) -{ - JNIEnv *env = Android_JNI_GetEnv(); - (*env)->SetStaticBooleanField(env, mActivityClass, fidSeparateMouseAndTouch, new_value ? JNI_TRUE : JNI_FALSE); -} - -void Android_JNI_PollInputDevices(void) -{ - JNIEnv *env = Android_JNI_GetEnv(); - (*env)->CallStaticVoidMethod(env, mControllerManagerClass, midPollInputDevices); -} - -void Android_JNI_PollHapticDevices(void) -{ - JNIEnv *env = Android_JNI_GetEnv(); - (*env)->CallStaticVoidMethod(env, mControllerManagerClass, midPollHapticDevices); -} - -void Android_JNI_HapticRun(int device_id, float intensity, int length) -{ - JNIEnv *env = Android_JNI_GetEnv(); - (*env)->CallStaticVoidMethod(env, mControllerManagerClass, midHapticRun, device_id, intensity, length); -} - -void Android_JNI_HapticStop(int device_id) -{ - JNIEnv *env = Android_JNI_GetEnv(); - (*env)->CallStaticVoidMethod(env, mControllerManagerClass, midHapticStop, device_id); -} - -/* See SDLActivity.java for constants. */ -#define COMMAND_SET_KEEP_SCREEN_ON 5 - -/* sends message to be handled on the UI event dispatch thread */ -int Android_JNI_SendMessage(int command, int param) -{ - JNIEnv *env = Android_JNI_GetEnv(); - jboolean success; - success = (*env)->CallStaticBooleanMethod(env, mActivityClass, midSendMessage, command, param); - return success ? 0 : -1; -} - -void Android_JNI_SuspendScreenSaver(SDL_bool suspend) -{ - Android_JNI_SendMessage(COMMAND_SET_KEEP_SCREEN_ON, (suspend == SDL_FALSE) ? 0 : 1); -} - -void Android_JNI_ShowTextInput(SDL_Rect *inputRect) -{ - JNIEnv *env = Android_JNI_GetEnv(); - (*env)->CallStaticBooleanMethod(env, mActivityClass, midShowTextInput, - inputRect->x, - inputRect->y, - inputRect->w, - inputRect->h ); -} - -void Android_JNI_HideTextInput(void) -{ - /* has to match Activity constant */ - const int COMMAND_TEXTEDIT_HIDE = 3; - Android_JNI_SendMessage(COMMAND_TEXTEDIT_HIDE, 0); -} - -SDL_bool Android_JNI_IsScreenKeyboardShown() -{ - JNIEnv *mEnv = Android_JNI_GetEnv(); - jboolean is_shown = 0; - is_shown = (*mEnv)->CallStaticBooleanMethod(mEnv, mActivityClass, midIsScreenKeyboardShown); - return is_shown; -} - - -int Android_JNI_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid) -{ - JNIEnv *env; - jclass clazz; - jmethodID mid; - jobject context; - jstring title; - jstring message; - jintArray button_flags; - jintArray button_ids; - jobjectArray button_texts; - jintArray colors; - jobject text; - jint temp; - int i; - - env = Android_JNI_GetEnv(); - - /* convert parameters */ - - clazz = (*env)->FindClass(env, "java/lang/String"); - - title = (*env)->NewStringUTF(env, messageboxdata->title); - message = (*env)->NewStringUTF(env, messageboxdata->message); - - button_flags = (*env)->NewIntArray(env, messageboxdata->numbuttons); - button_ids = (*env)->NewIntArray(env, messageboxdata->numbuttons); - button_texts = (*env)->NewObjectArray(env, messageboxdata->numbuttons, - clazz, NULL); - for (i = 0; i < messageboxdata->numbuttons; ++i) { - temp = messageboxdata->buttons[i].flags; - (*env)->SetIntArrayRegion(env, button_flags, i, 1, &temp); - temp = messageboxdata->buttons[i].buttonid; - (*env)->SetIntArrayRegion(env, button_ids, i, 1, &temp); - text = (*env)->NewStringUTF(env, messageboxdata->buttons[i].text); - (*env)->SetObjectArrayElement(env, button_texts, i, text); - (*env)->DeleteLocalRef(env, text); - } - - if (messageboxdata->colorScheme) { - colors = (*env)->NewIntArray(env, SDL_MESSAGEBOX_COLOR_MAX); - for (i = 0; i < SDL_MESSAGEBOX_COLOR_MAX; ++i) { - temp = (0xFF << 24) | - (messageboxdata->colorScheme->colors[i].r << 16) | - (messageboxdata->colorScheme->colors[i].g << 8) | - (messageboxdata->colorScheme->colors[i].b << 0); - (*env)->SetIntArrayRegion(env, colors, i, 1, &temp); - } - } else { - colors = NULL; - } - - (*env)->DeleteLocalRef(env, clazz); - - /* context = SDLActivity.getContext(); */ - context = (*env)->CallStaticObjectMethod(env, mActivityClass, midGetContext); - - clazz = (*env)->GetObjectClass(env, context); - - mid = (*env)->GetMethodID(env, clazz, - "messageboxShowMessageBox", "(ILjava/lang/String;Ljava/lang/String;[I[I[Ljava/lang/String;[I)I"); - *buttonid = (*env)->CallIntMethod(env, context, mid, - messageboxdata->flags, - title, - message, - button_flags, - button_ids, - button_texts, - colors); - - (*env)->DeleteLocalRef(env, context); - (*env)->DeleteLocalRef(env, clazz); - - /* delete parameters */ - - (*env)->DeleteLocalRef(env, title); - (*env)->DeleteLocalRef(env, message); - (*env)->DeleteLocalRef(env, button_flags); - (*env)->DeleteLocalRef(env, button_ids); - (*env)->DeleteLocalRef(env, button_texts); - (*env)->DeleteLocalRef(env, colors); - - return 0; -} - -/* -////////////////////////////////////////////////////////////////////////////// -// -// Functions exposed to SDL applications in SDL_system.h -////////////////////////////////////////////////////////////////////////////// -*/ - -void *SDL_AndroidGetJNIEnv(void) -{ - return Android_JNI_GetEnv(); -} - -void *SDL_AndroidGetActivity(void) -{ - /* See SDL_system.h for caveats on using this function. */ - - JNIEnv *env = Android_JNI_GetEnv(); - if (!env) { - return NULL; - } - - /* return SDLActivity.getContext(); */ - return (*env)->CallStaticObjectMethod(env, mActivityClass, midGetContext); -} - -SDL_bool SDL_IsAndroidTablet(void) -{ - JNIEnv *env = Android_JNI_GetEnv(); - return (*env)->CallStaticBooleanMethod(env, mActivityClass, midIsTablet); -} - -SDL_bool SDL_IsAndroidTV(void) -{ - JNIEnv *env = Android_JNI_GetEnv(); - return (*env)->CallStaticBooleanMethod(env, mActivityClass, midIsAndroidTV); -} - -SDL_bool SDL_IsChromebook(void) -{ - JNIEnv *env = Android_JNI_GetEnv(); - return (*env)->CallStaticBooleanMethod(env, mActivityClass, midIsChromebook); -} - -SDL_bool SDL_IsDeXMode(void) -{ - JNIEnv *env = Android_JNI_GetEnv(); - return (*env)->CallStaticBooleanMethod(env, mActivityClass, midIsDeXMode); -} - -void SDL_AndroidBackButton(void) -{ - JNIEnv *env = Android_JNI_GetEnv(); - return (*env)->CallStaticVoidMethod(env, mActivityClass, midManualBackButton); -} - -const char * SDL_AndroidGetInternalStoragePath(void) -{ - static char *s_AndroidInternalFilesPath = NULL; - - if (!s_AndroidInternalFilesPath) { - struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__); - jmethodID mid; - jobject context; - jobject fileObject; - jstring pathString; - const char *path; - - JNIEnv *env = Android_JNI_GetEnv(); - if (!LocalReferenceHolder_Init(&refs, env)) { - LocalReferenceHolder_Cleanup(&refs); - return NULL; - } - - /* context = SDLActivity.getContext(); */ - context = (*env)->CallStaticObjectMethod(env, mActivityClass, midGetContext); - if (!context) { - SDL_SetError("Couldn't get Android context!"); - LocalReferenceHolder_Cleanup(&refs); - return NULL; - } - - /* fileObj = context.getFilesDir(); */ - mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, context), - "getFilesDir", "()Ljava/io/File;"); - fileObject = (*env)->CallObjectMethod(env, context, mid); - if (!fileObject) { - SDL_SetError("Couldn't get internal directory"); - LocalReferenceHolder_Cleanup(&refs); - return NULL; - } - - /* path = fileObject.getCanonicalPath(); */ - mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, fileObject), - "getCanonicalPath", "()Ljava/lang/String;"); - pathString = (jstring)(*env)->CallObjectMethod(env, fileObject, mid); - if (Android_JNI_ExceptionOccurred(SDL_FALSE)) { - LocalReferenceHolder_Cleanup(&refs); - return NULL; - } - - path = (*env)->GetStringUTFChars(env, pathString, NULL); - s_AndroidInternalFilesPath = SDL_strdup(path); - (*env)->ReleaseStringUTFChars(env, pathString, path); - - LocalReferenceHolder_Cleanup(&refs); - } - return s_AndroidInternalFilesPath; -} - -int SDL_AndroidGetExternalStorageState(void) -{ - struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__); - jmethodID mid; - jclass cls; - jstring stateString; - const char *state; - int stateFlags; - - JNIEnv *env = Android_JNI_GetEnv(); - if (!LocalReferenceHolder_Init(&refs, env)) { - LocalReferenceHolder_Cleanup(&refs); - return 0; - } - - cls = (*env)->FindClass(env, "android/os/Environment"); - mid = (*env)->GetStaticMethodID(env, cls, - "getExternalStorageState", "()Ljava/lang/String;"); - stateString = (jstring)(*env)->CallStaticObjectMethod(env, cls, mid); - - state = (*env)->GetStringUTFChars(env, stateString, NULL); - - /* Print an info message so people debugging know the storage state */ - __android_log_print(ANDROID_LOG_INFO, "SDL", "external storage state: %s", state); - - if (SDL_strcmp(state, "mounted") == 0) { - stateFlags = SDL_ANDROID_EXTERNAL_STORAGE_READ | - SDL_ANDROID_EXTERNAL_STORAGE_WRITE; - } else if (SDL_strcmp(state, "mounted_ro") == 0) { - stateFlags = SDL_ANDROID_EXTERNAL_STORAGE_READ; - } else { - stateFlags = 0; - } - (*env)->ReleaseStringUTFChars(env, stateString, state); - - LocalReferenceHolder_Cleanup(&refs); - return stateFlags; -} - -const char * SDL_AndroidGetExternalStoragePath(void) -{ - static char *s_AndroidExternalFilesPath = NULL; - - if (!s_AndroidExternalFilesPath) { - struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__); - jmethodID mid; - jobject context; - jobject fileObject; - jstring pathString; - const char *path; - - JNIEnv *env = Android_JNI_GetEnv(); - if (!LocalReferenceHolder_Init(&refs, env)) { - LocalReferenceHolder_Cleanup(&refs); - return NULL; - } - - /* context = SDLActivity.getContext(); */ - context = (*env)->CallStaticObjectMethod(env, mActivityClass, midGetContext); - - /* fileObj = context.getExternalFilesDir(); */ - mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, context), - "getExternalFilesDir", "(Ljava/lang/String;)Ljava/io/File;"); - fileObject = (*env)->CallObjectMethod(env, context, mid, NULL); - if (!fileObject) { - SDL_SetError("Couldn't get external directory"); - LocalReferenceHolder_Cleanup(&refs); - return NULL; - } - - /* path = fileObject.getAbsolutePath(); */ - mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, fileObject), - "getAbsolutePath", "()Ljava/lang/String;"); - pathString = (jstring)(*env)->CallObjectMethod(env, fileObject, mid); - - path = (*env)->GetStringUTFChars(env, pathString, NULL); - s_AndroidExternalFilesPath = SDL_strdup(path); - (*env)->ReleaseStringUTFChars(env, pathString, path); - - LocalReferenceHolder_Cleanup(&refs); - } - return s_AndroidExternalFilesPath; -} - -void Android_JNI_GetManifestEnvironmentVariables(void) -{ - if (!mActivityClass || !midGetManifestEnvironmentVariables) { - __android_log_print(ANDROID_LOG_WARN, "SDL", "Request to get environment variables before JNI is ready"); - return; - } - - if (!bHasEnvironmentVariables) { - JNIEnv *env = Android_JNI_GetEnv(); - SDL_bool ret = (*env)->CallStaticBooleanMethod(env, mActivityClass, midGetManifestEnvironmentVariables); - if (ret) { - bHasEnvironmentVariables = SDL_TRUE; - } - } -} - -int Android_JNI_CreateCustomCursor(SDL_Surface *surface, int hot_x, int hot_y) -{ - JNIEnv *mEnv = Android_JNI_GetEnv(); - int custom_cursor = 0; - jintArray pixels; - pixels = (*mEnv)->NewIntArray(mEnv, surface->w * surface->h); - if (pixels) { - (*mEnv)->SetIntArrayRegion(mEnv, pixels, 0, surface->w * surface->h, (int *)surface->pixels); - custom_cursor = (*mEnv)->CallStaticIntMethod(mEnv, mActivityClass, midCreateCustomCursor, pixels, surface->w, surface->h, hot_x, hot_y); - (*mEnv)->DeleteLocalRef(mEnv, pixels); - } else { - SDL_OutOfMemory(); - } - return custom_cursor; -} - - -SDL_bool Android_JNI_SetCustomCursor(int cursorID) -{ - JNIEnv *mEnv = Android_JNI_GetEnv(); - return (*mEnv)->CallStaticBooleanMethod(mEnv, mActivityClass, midSetCustomCursor, cursorID); -} - -SDL_bool Android_JNI_SetSystemCursor(int cursorID) -{ - JNIEnv *mEnv = Android_JNI_GetEnv(); - return (*mEnv)->CallStaticBooleanMethod(mEnv, mActivityClass, midSetSystemCursor, cursorID); -} - -SDL_bool Android_JNI_SupportsRelativeMouse() -{ - JNIEnv *mEnv = Android_JNI_GetEnv(); - return (*mEnv)->CallStaticBooleanMethod(mEnv, mActivityClass, midSupportsRelativeMouse); -} - -SDL_bool Android_JNI_SetRelativeMouseEnabled(SDL_bool enabled) -{ - JNIEnv *mEnv = Android_JNI_GetEnv(); - return (*mEnv)->CallStaticBooleanMethod(mEnv, mActivityClass, midSetRelativeMouseEnabled, (enabled == 1)); -} - - -#endif /* __ANDROID__ */ - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Source/3rdParty/SDL2/src/core/android/SDL_android.h b/Source/3rdParty/SDL2/src/core/android/SDL_android.h deleted file mode 100644 index b2ff32e..0000000 --- a/Source/3rdParty/SDL2/src/core/android/SDL_android.h +++ /dev/null @@ -1,135 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2018 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_system.h" - -/* Set up for C function definitions, even when using C++ */ -#ifdef __cplusplus -/* *INDENT-OFF* */ -extern "C" { -/* *INDENT-ON* */ -#endif - -#include <EGL/eglplatform.h> -#include <android/native_window_jni.h> - -#include "SDL_audio.h" -#include "SDL_rect.h" - -/* Interface from the SDL library into the Android Java activity */ -extern void Android_JNI_SetActivityTitle(const char *title); -extern void Android_JNI_SetWindowStyle(SDL_bool fullscreen); -extern void Android_JNI_SetOrientation(int w, int h, int resizable, const char *hint); - -extern SDL_bool Android_JNI_GetAccelerometerValues(float values[3]); -extern void Android_JNI_ShowTextInput(SDL_Rect *inputRect); -extern void Android_JNI_HideTextInput(void); -extern SDL_bool Android_JNI_IsScreenKeyboardShown(void); -extern ANativeWindow* Android_JNI_GetNativeWindow(void); - -extern int Android_JNI_GetDisplayDPI(float *ddpi, float *xdpi, float *ydpi); - -/* Audio support */ -extern int Android_JNI_OpenAudioDevice(int iscapture, SDL_AudioSpec *spec); -extern void* Android_JNI_GetAudioBuffer(void); -extern void Android_JNI_WriteAudioBuffer(void); -extern int Android_JNI_CaptureAudioBuffer(void *buffer, int buflen); -extern void Android_JNI_FlushCapturedAudio(void); -extern void Android_JNI_CloseAudioDevice(const int iscapture); - -/* Detecting device type */ -extern SDL_bool Android_IsDeXMode(); -extern SDL_bool Android_IsChromebook(); - -#include "SDL_rwops.h" - -int Android_JNI_FileOpen(SDL_RWops* ctx, const char* fileName, const char* mode); -Sint64 Android_JNI_FileSize(SDL_RWops* ctx); -Sint64 Android_JNI_FileSeek(SDL_RWops* ctx, Sint64 offset, int whence); -size_t Android_JNI_FileRead(SDL_RWops* ctx, void* buffer, size_t size, size_t maxnum); -size_t Android_JNI_FileWrite(SDL_RWops* ctx, const void* buffer, size_t size, size_t num); -int Android_JNI_FileClose(SDL_RWops* ctx); - -/* Environment support */ -void Android_JNI_GetManifestEnvironmentVariables(void); - -/* Clipboard support */ -int Android_JNI_SetClipboardText(const char* text); -char* Android_JNI_GetClipboardText(void); -SDL_bool Android_JNI_HasClipboardText(void); - -/* Power support */ -int Android_JNI_GetPowerInfo(int* plugged, int* charged, int* battery, int* seconds, int* percent); - -/* Joystick support */ -void Android_JNI_PollInputDevices(void); - -/* Haptic support */ -void Android_JNI_PollHapticDevices(void); -void Android_JNI_HapticRun(int device_id, float intensity, int length); -void Android_JNI_HapticStop(int device_id); - -/* Video */ -void Android_JNI_SuspendScreenSaver(SDL_bool suspend); - -/* Touch support */ -int Android_JNI_InitTouch(void); -void Android_JNI_SetSeparateMouseAndTouch(SDL_bool new_value); -int Android_JNI_GetTouchDeviceIds(int **ids); - -/* Threads */ -#include <jni.h> -JNIEnv *Android_JNI_GetEnv(void); -int Android_JNI_SetupThread(void); - -/* Generic messages */ -int Android_JNI_SendMessage(int command, int param); - -/* Init */ -JNIEXPORT void JNICALL SDL_Android_Init(JNIEnv* mEnv, jclass cls); - -/* MessageBox */ -#include "SDL_messagebox.h" -int Android_JNI_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid); - -/* Cursor support */ -int Android_JNI_CreateCustomCursor(SDL_Surface *surface, int hot_x, int hot_y); -SDL_bool Android_JNI_SetCustomCursor(int cursorID); -SDL_bool Android_JNI_SetSystemCursor(int cursorID); - -/* Relative mouse support */ -SDL_bool Android_JNI_SupportsRelativeMouse(void); -SDL_bool Android_JNI_SetRelativeMouseEnabled(SDL_bool enabled); - - -SDL_bool SDL_IsAndroidTablet(void); -SDL_bool SDL_IsAndroidTV(void); -SDL_bool SDL_IsChromebook(void); -SDL_bool SDL_IsDeXMode(void); - -/* Ends C function definitions when using C++ */ -#ifdef __cplusplus -/* *INDENT-OFF* */ -} -/* *INDENT-ON* */ -#endif - -/* vi: set ts=4 sw=4 expandtab: */ diff --git a/Source/3rdParty/SDL2/src/core/android/keyinfotable.h b/Source/3rdParty/SDL2/src/core/android/keyinfotable.h deleted file mode 100644 index 4437121..0000000 --- a/Source/3rdParty/SDL2/src/core/android/keyinfotable.h +++ /dev/null @@ -1,175 +0,0 @@ -/* - Simple DirectMedia Layer - Copyright (C) 1997-2018 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 _ANDROID_KeyInfo -#define _ANDROID_KeyInfo - -#include "SDL_scancode.h" -#include "SDL_keycode.h" - -/* - This file is used by the keyboard code in SDL_uikitview.m to convert between characters - passed in from the iPhone's virtual keyboard, and tuples of SDL_Scancode and SDL_keymods. - For example unicharToUIKeyInfoTable['a'] would give you the scan code and keymod for lower - case a. -*/ - -typedef struct -{ - SDL_Scancode code; - uint16_t mod; -} AndroidKeyInfo; - -/* So far only ASCII characters here */ -static AndroidKeyInfo unicharToAndroidKeyInfoTable[] = { -/* 0 */ { SDL_SCANCODE_UNKNOWN, 0 }, -/* 1 */ { SDL_SCANCODE_UNKNOWN, 0 }, -/* 2 */ { SDL_SCANCODE_UNKNOWN, 0 }, -/* 3 */ { SDL_SCANCODE_UNKNOWN, 0 }, -/* 4 */ { SDL_SCANCODE_UNKNOWN, 0 }, -/* 5 */ { SDL_SCANCODE_UNKNOWN, 0 }, -/* 6 */ { SDL_SCANCODE_UNKNOWN, 0 }, -/* 7 */ { SDL_SCANCODE_UNKNOWN, 0 }, -/* 8 */ { SDL_SCANCODE_UNKNOWN, 0 }, -/* 9 */ { SDL_SCANCODE_UNKNOWN, 0 }, -/* 10 */ { SDL_SCANCODE_UNKNOWN, 0 }, -/* 11 */ { SDL_SCANCODE_UNKNOWN, 0 }, -/* 12 */ { SDL_SCANCODE_UNKNOWN, 0 }, -/* 13 */ { SDL_SCANCODE_RETURN, 0 }, -/* 14 */ { SDL_SCANCODE_UNKNOWN, 0 }, -/* 15 */ { SDL_SCANCODE_UNKNOWN, 0 }, -/* 16 */ { SDL_SCANCODE_UNKNOWN, 0 }, -/* 17 */ { SDL_SCANCODE_UNKNOWN, 0 }, -/* 18 */ { SDL_SCANCODE_UNKNOWN, 0 }, -/* 19 */ { SDL_SCANCODE_UNKNOWN, 0 }, -/* 20 */ { SDL_SCANCODE_UNKNOWN, 0 }, -/* 21 */ { SDL_SCANCODE_UNKNOWN, 0 }, -/* 22 */ { SDL_SCANCODE_UNKNOWN, 0 }, -/* 23 */ { SDL_SCANCODE_UNKNOWN, 0 }, -/* 24 */ { SDL_SCANCODE_UNKNOWN, 0 }, -/* 25 */ { SDL_SCANCODE_UNKNOWN, 0 }, -/* 26 */ { SDL_SCANCODE_UNKNOWN, 0 }, -/* 27 */ { SDL_SCANCODE_UNKNOWN, 0 }, -/* 28 */ { SDL_SCANCODE_UNKNOWN, 0 }, -/* 29 */ { SDL_SCANCODE_UNKNOWN, 0 }, -/* 30 */ { SDL_SCANCODE_UNKNOWN, 0 }, -/* 31 */ { SDL_SCANCODE_UNKNOWN, 0 }, -/* 32 */ { SDL_SCANCODE_SPACE, 0 }, -/* 33 */ { SDL_SCANCODE_1, KMOD_SHIFT }, /* plus shift modifier '!' */ -/* 34 */ { SDL_SCANCODE_APOSTROPHE, KMOD_SHIFT }, /* plus shift modifier '"' */ -/* 35 */ { SDL_SCANCODE_3, KMOD_SHIFT }, /* plus shift modifier '#' */ -/* 36 */ { SDL_SCANCODE_4, KMOD_SHIFT }, /* plus shift modifier '$' */ -/* 37 */ { SDL_SCANCODE_5, KMOD_SHIFT }, /* plus shift modifier '%' */ -/* 38 */ { SDL_SCANCODE_7, KMOD_SHIFT }, /* plus shift modifier '&' */ -/* 39 */ { SDL_SCANCODE_APOSTROPHE, 0 }, /* ''' */ -/* 40 */ { SDL_SCANCODE_9, KMOD_SHIFT }, /* plus shift modifier '(' */ -/* 41 */ { SDL_SCANCODE_0, KMOD_SHIFT }, /* plus shift modifier ')' */ -/* 42 */ { SDL_SCANCODE_8, KMOD_SHIFT }, /* '*' */ -/* 43 */ { SDL_SCANCODE_EQUALS, KMOD_SHIFT }, /* plus shift modifier '+' */ -/* 44 */ { SDL_SCANCODE_COMMA, 0 }, /* ',' */ -/* 45 */ { SDL_SCANCODE_MINUS, 0 }, /* '-' */ -/* 46 */ { SDL_SCANCODE_PERIOD, 0 }, /* '.' */ -/* 47 */ { SDL_SCANCODE_SLASH, 0 }, /* '/' */ -/* 48 */ { SDL_SCANCODE_0, 0 }, -/* 49 */ { SDL_SCANCODE_1, 0 }, -/* 50 */ { SDL_SCANCODE_2, 0 }, -/* 51 */ { SDL_SCANCODE_3, 0 }, -/* 52 */ { SDL_SCANCODE_4, 0 }, -/* 53 */ { SDL_SCANCODE_5, 0 }, -/* 54 */ { SDL_SCANCODE_6, 0 }, -/* 55 */ { SDL_SCANCODE_7, 0 }, -/* 56 */ { SDL_SCANCODE_8, 0 }, -/* 57 */ { SDL_SCANCODE_9, 0 }, -/* 58 */ { SDL_SCANCODE_SEMICOLON, KMOD_SHIFT }, /* plus shift modifier ';' */ -/* 59 */ { SDL_SCANCODE_SEMICOLON, 0 }, -/* 60 */ { SDL_SCANCODE_COMMA, KMOD_SHIFT }, /* plus shift modifier '<' */ -/* 61 */ { SDL_SCANCODE_EQUALS, 0 }, -/* 62 */ { SDL_SCANCODE_PERIOD, KMOD_SHIFT }, /* plus shift modifier '>' */ -/* 63 */ { SDL_SCANCODE_SLASH, KMOD_SHIFT }, /* plus shift modifier '?' */ -/* 64 */ { SDL_SCANCODE_2, KMOD_SHIFT }, /* plus shift modifier '@' */ -/* 65 */ { SDL_SCANCODE_A, KMOD_SHIFT }, /* all the following need shift modifiers */ -/* 66 */ { SDL_SCANCODE_B, KMOD_SHIFT }, -/* 67 */ { SDL_SCANCODE_C, KMOD_SHIFT }, -/* 68 */ { SDL_SCANCODE_D, KMOD_SHIFT }, -/* 69 */ { SDL_SCANCODE_E, KMOD_SHIFT }, -/* 70 */ { SDL_SCANCODE_F, KMOD_SHIFT }, -/* 71 */ { SDL_SCANCODE_G, KMOD_SHIFT }, -/* 72 */ { SDL_SCANCODE_H, KMOD_SHIFT }, -/* 73 */ { SDL_SCANCODE_I, KMOD_SHIFT }, -/* 74 */ { SDL_SCANCODE_J, KMOD_SHIFT }, -/* 75 */ { SDL_SCANCODE_K, KMOD_SHIFT }, -/* 76 */ { SDL_SCANCODE_L, KMOD_SHIFT }, -/* 77 */ { SDL_SCANCODE_M, KMOD_SHIFT }, -/* 78 */ { SDL_SCANCODE_N, KMOD_SHIFT }, -/* 79 */ { SDL_SCANCODE_O, KMOD_SHIFT }, -/* 80 */ { SDL_SCANCODE_P, KMOD_SHIFT }, -/* 81 */ { SDL_SCANCODE_Q, KMOD_SHIFT }, -/* 82 */ { SDL_SCANCODE_R, KMOD_SHIFT }, -/* 83 */ { SDL_SCANCODE_S, KMOD_SHIFT }, -/* 84 */ { SDL_SCANCODE_T, KMOD_SHIFT }, -/* 85 */ { SDL_SCANCODE_U, KMOD_SHIFT }, -/* 86 */ { SDL_SCANCODE_V, KMOD_SHIFT }, -/* 87 */ { SDL_SCANCODE_W, KMOD_SHIFT }, -/* 88 */ { SDL_SCANCODE_X, KMOD_SHIFT }, -/* 89 */ { SDL_SCANCODE_Y, KMOD_SHIFT }, -/* 90 */ { SDL_SCANCODE_Z, KMOD_SHIFT }, -/* 91 */ { SDL_SCANCODE_LEFTBRACKET, 0 }, -/* 92 */ { SDL_SCANCODE_BACKSLASH, 0 }, -/* 93 */ { SDL_SCANCODE_RIGHTBRACKET, 0 }, -/* 94 */ { SDL_SCANCODE_6, KMOD_SHIFT }, /* plus shift modifier '^' */ -/* 95 */ { SDL_SCANCODE_MINUS, KMOD_SHIFT }, /* plus shift modifier '_' */ -/* 96 */ { SDL_SCANCODE_GRAVE, KMOD_SHIFT }, /* '`' */ -/* 97 */ { SDL_SCANCODE_A, 0 }, -/* 98 */ { SDL_SCANCODE_B, 0 }, -/* 99 */ { SDL_SCANCODE_C, 0 }, -/* 100 */{ SDL_SCANCODE_D, 0 }, -/* 101 */{ SDL_SCANCODE_E, 0 }, -/* 102 */{ SDL_SCANCODE_F, 0 }, -/* 103 */{ SDL_SCANCODE_G, 0 }, -/* 104 */{ SDL_SCANCODE_H, 0 }, -/* 105 */{ SDL_SCANCODE_I, 0 }, -/* 106 */{ SDL_SCANCODE_J, 0 }, -/* 107 */{ SDL_SCANCODE_K, 0 }, -/* 108 */{ SDL_SCANCODE_L, 0 }, -/* 109 */{ SDL_SCANCODE_M, 0 }, -/* 110 */{ SDL_SCANCODE_N, 0 }, -/* 111 */{ SDL_SCANCODE_O, 0 }, -/* 112 */{ SDL_SCANCODE_P, 0 }, -/* 113 */{ SDL_SCANCODE_Q, 0 }, -/* 114 */{ SDL_SCANCODE_R, 0 }, -/* 115 */{ SDL_SCANCODE_S, 0 }, -/* 116 */{ SDL_SCANCODE_T, 0 }, -/* 117 */{ SDL_SCANCODE_U, 0 }, -/* 118 */{ SDL_SCANCODE_V, 0 }, -/* 119 */{ SDL_SCANCODE_W, 0 }, -/* 120 */{ SDL_SCANCODE_X, 0 }, -/* 121 */{ SDL_SCANCODE_Y, 0 }, -/* 122 */{ SDL_SCANCODE_Z, 0 }, -/* 123 */{ SDL_SCANCODE_LEFTBRACKET, KMOD_SHIFT }, /* plus shift modifier '{' */ -/* 124 */{ SDL_SCANCODE_BACKSLASH, KMOD_SHIFT }, /* plus shift modifier '|' */ -/* 125 */{ SDL_SCANCODE_RIGHTBRACKET, KMOD_SHIFT }, /* plus shift modifier '}' */ -/* 126 */{ SDL_SCANCODE_GRAVE, KMOD_SHIFT }, /* plus shift modifier '~' */ -/* 127 */{ SDL_SCANCODE_BACKSPACE, KMOD_SHIFT } -}; - -#endif /* _ANDROID_KeyInfo */ - -/* vi: set ts=4 sw=4 expandtab: */ |