src/core/android/SDL_android.c
changeset 11395 a8c29f5b679f
parent 11393 3e57ce45a890
child 11397 e2f696fc76e1
     1.1 --- a/src/core/android/SDL_android.c	Mon Aug 28 13:40:32 2017 -0700
     1.2 +++ b/src/core/android/SDL_android.c	Mon Aug 28 14:34:15 2017 -0700
     1.3 @@ -43,6 +43,7 @@
     1.4  #include <pthread.h>
     1.5  #include <sys/types.h>
     1.6  #include <unistd.h>
     1.7 +#include <dlfcn.h>
     1.8  /* #define LOG_TAG "SDL_android" */
     1.9  /* #define LOGI(...)  __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__) */
    1.10  /* #define LOGE(...)  __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__) */
    1.11 @@ -58,6 +59,13 @@
    1.12  
    1.13  
    1.14  /* Java class SDLActivity */
    1.15 +JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetupJNI)(
    1.16 +        JNIEnv* mEnv, jclass cls);
    1.17 +
    1.18 +JNIEXPORT int JNICALL SDL_JAVA_INTERFACE(nativeRunMain)(
    1.19 +        JNIEnv* env, jclass cls,
    1.20 +        jstring library, jstring function, jobject array);
    1.21 +
    1.22  JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeDropFile)(
    1.23          JNIEnv* env, jclass jcls,
    1.24          jstring filename);
    1.25 @@ -237,9 +245,9 @@
    1.26  }
    1.27  
    1.28  /* Called before SDL_main() to initialize JNI bindings */
    1.29 -JNIEXPORT void JNICALL SDL_Android_Init(JNIEnv* mEnv, jclass cls)
    1.30 +JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetupJNI)(JNIEnv* mEnv, jclass cls)
    1.31  {
    1.32 -    __android_log_print(ANDROID_LOG_INFO, "SDL", "SDL_Android_Init()");
    1.33 +    __android_log_print(ANDROID_LOG_VERBOSE, "SDL", "nativeSetupJNI()");
    1.34  
    1.35      Android_JNI_SetupThread();
    1.36  
    1.37 @@ -299,16 +307,95 @@
    1.38         !midSetActivityTitle || !midSetOrientation || !midGetContext || !midInputGetInputDeviceIds ||
    1.39         !midSendMessage || !midShowTextInput || !midIsScreenKeyboardShown || 
    1.40         !midClipboardSetText || !midClipboardGetText || !midClipboardHasText) {
    1.41 -        __android_log_print(ANDROID_LOG_WARN, "SDL", "SDL: Couldn't locate Java callbacks, check that they're named and typed correctly");
    1.42 +        __android_log_print(ANDROID_LOG_WARN, "SDL", "Missing some Java callbacks, do you have the latest version of SDLActivity.java?");
    1.43      }
    1.44  
    1.45      fidSeparateMouseAndTouch = (*mEnv)->GetStaticFieldID(mEnv, mActivityClass, "mSeparateMouseAndTouch", "Z");
    1.46  
    1.47      if (!fidSeparateMouseAndTouch) {
    1.48 -        __android_log_print(ANDROID_LOG_WARN, "SDL", "SDL: Couldn't locate Java static fields, check that they're named and typed correctly");
    1.49 +        __android_log_print(ANDROID_LOG_WARN, "SDL", "Missing some Java static fields, do you have the latest version of SDLActivity.java?");
    1.50      }
    1.51  
    1.52 -    __android_log_print(ANDROID_LOG_INFO, "SDL", "SDL_Android_Init() finished!");
    1.53 +    SDL_SetMainReady();
    1.54 +}
    1.55 +
    1.56 +/* SDL main function prototype */
    1.57 +typedef int (*SDL_main_func)(int argc, char *argv[]);
    1.58 +
    1.59 +/* Start up the SDL app */
    1.60 +JNIEXPORT int JNICALL SDL_JAVA_INTERFACE(nativeRunMain)(JNIEnv* env, jclass cls, jstring library, jstring function, jobject array)
    1.61 +{
    1.62 +    int status = -1;
    1.63 +    const char *library_file;
    1.64 +    void *library_handle;
    1.65 +
    1.66 +    library_file = (*env)->GetStringUTFChars(env, library, NULL);
    1.67 +    library_handle = dlopen(library_file, RTLD_GLOBAL);
    1.68 +    if (library_handle) {
    1.69 +        const char *function_name;
    1.70 +        SDL_main_func SDL_main;
    1.71 +
    1.72 +        function_name = (*env)->GetStringUTFChars(env, function, NULL);
    1.73 +        SDL_main = (SDL_main_func)dlsym(library_handle, function_name);
    1.74 +        if (SDL_main) {
    1.75 +            int i;
    1.76 +            int argc;
    1.77 +            int len;
    1.78 +            char **argv;
    1.79 +
    1.80 +            /* Prepare the arguments. */
    1.81 +            len = (*env)->GetArrayLength(env, array);
    1.82 +            argv = SDL_stack_alloc(char*, 1 + len + 1);
    1.83 +            argc = 0;
    1.84 +            /* Use the name "app_process" so PHYSFS_platformCalcBaseDir() works.
    1.85 +               https://bitbucket.org/MartinFelis/love-android-sdl2/issue/23/release-build-crash-on-start
    1.86 +             */
    1.87 +            argv[argc++] = SDL_strdup("app_process");
    1.88 +            for (i = 0; i < len; ++i) {
    1.89 +                const char* utf;
    1.90 +                char* arg = NULL;
    1.91 +                jstring string = (*env)->GetObjectArrayElement(env, array, i);
    1.92 +                if (string) {
    1.93 +                    utf = (*env)->GetStringUTFChars(env, string, 0);
    1.94 +                    if (utf) {
    1.95 +                        arg = SDL_strdup(utf);
    1.96 +                        (*env)->ReleaseStringUTFChars(env, string, utf);
    1.97 +                    }
    1.98 +                    (*env)->DeleteLocalRef(env, string);
    1.99 +                }
   1.100 +                if (!arg) {
   1.101 +                    arg = SDL_strdup("");
   1.102 +                }
   1.103 +                argv[argc++] = arg;
   1.104 +            }
   1.105 +            argv[argc] = NULL;
   1.106 +
   1.107 +
   1.108 +            /* Run the application. */
   1.109 +            status = SDL_main(argc, argv);
   1.110 +
   1.111 +            /* Release the arguments. */
   1.112 +            for (i = 0; i < argc; ++i) {
   1.113 +                SDL_free(argv[i]);
   1.114 +            }
   1.115 +            SDL_stack_free(argv);
   1.116 +
   1.117 +        } else {
   1.118 +            __android_log_print(ANDROID_LOG_ERROR, "SDL", "nativeRunMain(): Couldn't find function %s in library %s", function_name, library_file);
   1.119 +        }
   1.120 +        (*env)->ReleaseStringUTFChars(env, function, function_name);
   1.121 +
   1.122 +        dlclose(library_handle);
   1.123 +
   1.124 +    } else {
   1.125 +        __android_log_print(ANDROID_LOG_ERROR, "SDL", "nativeRunMain(): Couldn't load library %s", library_file);
   1.126 +    }
   1.127 +    (*env)->ReleaseStringUTFChars(env, library, library_file);
   1.128 +
   1.129 +    /* Do not issue an exit or the whole application will terminate instead of just the SDL thread */
   1.130 +    /* exit(status); */
   1.131 +
   1.132 +    return status;
   1.133  }
   1.134  
   1.135  /* Drop file */
   1.136 @@ -548,6 +635,7 @@
   1.137                                      JNIEnv* env, jclass cls)
   1.138  {
   1.139      __android_log_print(ANDROID_LOG_VERBOSE, "SDL", "nativePause()");
   1.140 +
   1.141      if (Android_Window) {
   1.142          SDL_SendWindowEvent(Android_Window, SDL_WINDOWEVENT_FOCUS_LOST, 0, 0);
   1.143          SDL_SendWindowEvent(Android_Window, SDL_WINDOWEVENT_MINIMIZED, 0, 0);