Module: wine Branch: master Commit: c30923f25b8db32c25ffaf8279c9d61b70887d44 URL: http://source.winehq.org/git/wine.git/?a=commit;h=c30923f25b8db32c25ffaf8279...
Author: Alexandre Julliard julliard@winehq.org Date: Tue Oct 1 13:47:40 2013 +0200
libwine: Add JNI initialisation support to start Wine from an Android activity.
---
libs/wine/loader.c | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 103 insertions(+), 0 deletions(-)
diff --git a/libs/wine/loader.c b/libs/wine/loader.c index 5891a20..f59942d 100644 --- a/libs/wine/loader.c +++ b/libs/wine/loader.c @@ -53,6 +53,10 @@ extern char **environ; #endif
+#ifdef __ANDROID__ +#include <jni.h> +#endif + #define NONAMELESSUNION #define NONAMELESSSTRUCT #include "windef.h" @@ -803,6 +807,105 @@ static void apple_main_thread( void (*init_func)(void) ) #endif
+#ifdef __ANDROID__ + +#ifndef WINE_JAVA_CLASS +#define WINE_JAVA_CLASS "org/winehq/wine/WineActivity" +#endif + +static JavaVM *java_vm; +static jobject java_object; + +/* return the Java VM that was used for JNI initialisation */ +JavaVM *wine_get_java_vm(void) +{ + return java_vm; +} + +/* return the Java object that called the wine_init method */ +jobject wine_get_java_object(void) +{ + return java_object; +} + +/* main Wine initialisation */ +static jstring wine_init_jni( JNIEnv *env, jobject obj, jobjectArray cmdline, jobjectArray environment ) +{ + char **argv; + char *str; + char error[1024]; + int i, argc, length; + + /* get the command line array */ + + argc = (*env)->GetArrayLength( env, cmdline ); + for (i = length = 0; i < argc; i++) + { + jobject str_obj = (*env)->GetObjectArrayElement( env, cmdline, i ); + length += (*env)->GetStringUTFLength( env, str_obj ) + 1; + } + + argv = malloc( (argc + 1) * sizeof(*argv) + length ); + str = (char *)(argv + argc + 1); + for (i = 0; i < argc; i++) + { + jobject str_obj = (*env)->GetObjectArrayElement( env, cmdline, i ); + length = (*env)->GetStringUTFLength( env, str_obj ); + (*env)->GetStringUTFRegion( env, str_obj, 0, length, str ); + argv[i] = str; + str[length] = 0; + str += length + 1; + } + argv[argc] = NULL; + + /* set the environment variables */ + + if (environment) + { + int count = (*env)->GetArrayLength( env, environment ); + for (i = 0; i < count - 1; i += 2) + { + jobject var_obj = (*env)->GetObjectArrayElement( env, environment, i ); + jobject val_obj = (*env)->GetObjectArrayElement( env, environment, i + 1 ); + const char *var = (*env)->GetStringUTFChars( env, var_obj, NULL ); + + if (val_obj) + { + const char *val = (*env)->GetStringUTFChars( env, val_obj, NULL ); + setenv( var, val, 1 ); + (*env)->ReleaseStringUTFChars( env, val_obj, val ); + } + else unsetenv( var ); + + (*env)->ReleaseStringUTFChars( env, var_obj, var ); + } + } + + java_object = (*env)->NewGlobalRef( env, obj ); + + wine_init( argc, argv, error, sizeof(error) ); + return (*env)->NewStringUTF( env, error ); +} + +jint JNI_OnLoad( JavaVM *vm, void *reserved ) +{ + static const JNINativeMethod method = + { + "wine_init", "([Ljava/lang/String;[Ljava/lang/String;)Ljava/lang/String;", wine_init_jni + }; + + JNIEnv *env; + jclass class; + + java_vm = vm; + if ((*vm)->AttachCurrentThread( vm, &env, NULL ) != JNI_OK) return JNI_ERR; + if (!(class = (*env)->FindClass( env, WINE_JAVA_CLASS ))) return JNI_ERR; + (*env)->RegisterNatives( env, class, &method, 1 ); + return JNI_VERSION_1_6; +} + +#endif /* __ANDROID__ */ + /*********************************************************************** * wine_init *