libwine: Add JNI initialisation support to start Wine from an Android activity.
This commit is contained in:
parent
7226c49098
commit
c30923f25b
|
@ -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
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue