libwine: Add JNI initialisation support to start Wine from an Android activity.

oldstable
Alexandre Julliard 2013-10-01 13:47:40 +02:00
parent 7226c49098
commit c30923f25b
1 changed files with 103 additions and 0 deletions

View File

@ -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
*