Commit 758e75cc authored by Alexandre Julliard's avatar Alexandre Julliard

libwine: Move the Android JNI initialization to ntdll.

parent 99ef6faf
......@@ -74,6 +74,9 @@
# define _POSIX_SPAWN_DISABLE_ASLR 0x0100
# endif
#endif
#ifdef __ANDROID__
# include <jni.h>
#endif
#include "ntstatus.h"
#define WIN32_NO_STATUS
......@@ -1579,6 +1582,123 @@ static void start_main_thread(void)
server_init_process_done();
}
#ifdef __ANDROID__
#ifndef WINE_JAVA_CLASS
#define WINE_JAVA_CLASS "org/winehq/wine/WineActivity"
#endif
JavaVM *java_vm = NULL;
jobject java_object = 0;
unsigned short java_gdt_sel = 0;
/* 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,
(*env)->GetStringLength( env, str_obj ), 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 );
if (!strcmp( var, "LD_LIBRARY_PATH" ))
{
void (*update_func)( const char * ) = dlsym( RTLD_DEFAULT,
"android_update_LD_LIBRARY_PATH" );
if (update_func) update_func( val );
}
else if (!strcmp( var, "WINEDEBUGLOG" ))
{
int fd = open( val, O_WRONLY | O_CREAT | O_APPEND, 0666 );
if (fd != -1)
{
dup2( fd, 2 );
close( fd );
}
}
(*env)->ReleaseStringUTFChars( env, val_obj, val );
}
else unsetenv( var );
(*env)->ReleaseStringUTFChars( env, var_obj, var );
}
}
java_object = (*env)->NewGlobalRef( env, obj );
init_paths( argv );
virtual_init();
init_environment( argc, argv, environ );
#ifdef __i386__
{
unsigned short java_fs;
__asm__( "mov %%fs,%0" : "=r" (java_fs) );
__asm__( "mov %0,%%fs" :: "r" (0) );
start_main_thread();
__asm__( "mov %0,%%fs" :: "r" (java_fs) );
}
#else
start_main_thread();
#endif
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__ */
#ifdef __APPLE__
static void *apple_wine_thread( void *arg )
......
......@@ -138,14 +138,7 @@ public class WineActivity extends Activity
createProgressDialog( 0, "Setting up the Windows environment..." );
try
{
System.loadLibrary( "wine" );
}
catch (java.lang.UnsatisfiedLinkError e)
{
System.load( libdir.toString() + "/libwine.so" );
}
System.load( dlldir.toString() + "/ntdll.so" );
prefix.mkdirs();
runWine( cmdline, env );
......
......@@ -155,7 +155,8 @@ union event_data
int send_event( const union event_data *data ) DECLSPEC_HIDDEN;
extern JavaVM * (*p_wine_get_java_vm)(void);
extern jobject (*p_wine_get_java_object)(void);
extern JavaVM **p_java_vm;
extern jobject *p_java_object;
extern unsigned short *p_java_gdt_sel;
#endif /* __WINE_ANDROID_H */
......@@ -687,7 +687,7 @@ static int status_to_android_error( NTSTATUS status )
static jobject load_java_method( jmethodID *method, const char *name, const char *args )
{
jobject object = p_wine_get_java_object();
jobject object = *p_java_object;
if (!*method)
{
......@@ -1163,7 +1163,7 @@ static DWORD CALLBACK device_thread( void *arg )
TRACE( "starting process %x\n", GetCurrentProcessId() );
if (!(java_vm = p_wine_get_java_vm())) return 0; /* not running under Java */
if (!(java_vm = *p_java_vm)) return 0; /* not running under Java */
init_java_thread( java_vm );
......
......@@ -104,7 +104,7 @@ void set_screen_dpi( DWORD dpi )
*/
static void fetch_display_metrics(void)
{
if (p_wine_get_java_vm()) return; /* for Java threads it will be set when the top view is created */
if (*p_java_vm) return; /* for Java threads it will be set when the top view is created */
SERVER_START_REQ( get_window_rectangles )
{
......@@ -620,8 +620,8 @@ static void load_android_libs(void)
#undef DECL_FUNCPTR
#undef LOAD_FUNCPTR
JavaVM * (*p_wine_get_java_vm)(void) = NULL;
jobject (*p_wine_get_java_object)(void) = NULL;
JavaVM **p_java_vm = NULL;
jobject *p_java_object = NULL;
static BOOL process_attach(void)
{
......@@ -629,18 +629,18 @@ static BOOL process_attach(void)
jobject object;
JNIEnv *jni_env;
JavaVM *java_vm;
void *libwine;
void *ntdll;
if (!(libwine = dlopen( "libwine.so", RTLD_NOW ))) return FALSE;
if (!(ntdll = dlopen( "ntdll.so", RTLD_NOW ))) return FALSE;
p_wine_get_java_vm = dlsym( libwine, "wine_get_java_vm" );
p_wine_get_java_object = dlsym( libwine, "wine_get_java_object" );
p_java_vm = dlsym( ntdll, "java_vm" );
p_java_object = dlsym( ntdll, "java_object" );
object = p_wine_get_java_object();
object = *p_java_object;
load_hardware_libs();
if ((java_vm = p_wine_get_java_vm())) /* running under Java */
if ((java_vm = *p_java_vm)) /* running under Java */
{
#ifdef __i386__
WORD old_fs;
......
......@@ -54,10 +54,6 @@
extern char **environ;
#endif
#ifdef __ANDROID__
#include <jni.h>
#endif
#define NONAMELESSUNION
#define NONAMELESSSTRUCT
#include "windef.h"
......@@ -102,7 +98,6 @@ static int dll_path_maxlen;
extern void *wine_anon_mmap( void *start, size_t size, int prot, int flags );
extern void wine_init_argv0_path( const char *argv0 );
extern void wine_init( int argc, char *argv[], char *error, int error_size );
extern void mmap_init(void);
extern const char *get_dlldir( const char **default_dlldir );
......@@ -958,131 +953,6 @@ 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,
(*env)->GetStringLength( env, str_obj ), 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 );
if (!strcmp( var, "LD_LIBRARY_PATH" ))
{
void (*update_func)( const char * ) = dlsym( RTLD_DEFAULT,
"android_update_LD_LIBRARY_PATH" );
if (update_func) update_func( val );
}
else if (!strcmp( var, "WINEDEBUGLOG" ))
{
int fd = open( val, O_WRONLY | O_CREAT | O_APPEND, 0666 );
if (fd != -1)
{
dup2( fd, 2 );
close( fd );
}
}
(*env)->ReleaseStringUTFChars( env, val_obj, val );
}
else unsetenv( var );
(*env)->ReleaseStringUTFChars( env, var_obj, var );
}
}
java_object = (*env)->NewGlobalRef( env, obj );
#ifdef __i386__
{
unsigned short java_fs;
__asm__( "mov %%fs,%0" : "=r" (java_fs) );
__asm__( "mov %0,%%fs" :: "r" (0) );
wine_init( argc, argv, error, sizeof(error) );
__asm__( "mov %0,%%fs" :: "r" (java_fs) );
}
#else
wine_init( argc, argv, error, sizeof(error) );
#endif
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
*
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment