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

libwine: Move the Android JNI initialization to ntdll.

parent 99ef6faf
...@@ -74,6 +74,9 @@ ...@@ -74,6 +74,9 @@
# define _POSIX_SPAWN_DISABLE_ASLR 0x0100 # define _POSIX_SPAWN_DISABLE_ASLR 0x0100
# endif # endif
#endif #endif
#ifdef __ANDROID__
# include <jni.h>
#endif
#include "ntstatus.h" #include "ntstatus.h"
#define WIN32_NO_STATUS #define WIN32_NO_STATUS
...@@ -1579,6 +1582,123 @@ static void start_main_thread(void) ...@@ -1579,6 +1582,123 @@ static void start_main_thread(void)
server_init_process_done(); 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__ #ifdef __APPLE__
static void *apple_wine_thread( void *arg ) static void *apple_wine_thread( void *arg )
......
...@@ -138,14 +138,7 @@ public class WineActivity extends Activity ...@@ -138,14 +138,7 @@ public class WineActivity extends Activity
createProgressDialog( 0, "Setting up the Windows environment..." ); createProgressDialog( 0, "Setting up the Windows environment..." );
try System.load( dlldir.toString() + "/ntdll.so" );
{
System.loadLibrary( "wine" );
}
catch (java.lang.UnsatisfiedLinkError e)
{
System.load( libdir.toString() + "/libwine.so" );
}
prefix.mkdirs(); prefix.mkdirs();
runWine( cmdline, env ); runWine( cmdline, env );
......
...@@ -155,7 +155,8 @@ union event_data ...@@ -155,7 +155,8 @@ union event_data
int send_event( const union event_data *data ) DECLSPEC_HIDDEN; int send_event( const union event_data *data ) DECLSPEC_HIDDEN;
extern JavaVM * (*p_wine_get_java_vm)(void); extern JavaVM **p_java_vm;
extern jobject (*p_wine_get_java_object)(void); extern jobject *p_java_object;
extern unsigned short *p_java_gdt_sel;
#endif /* __WINE_ANDROID_H */ #endif /* __WINE_ANDROID_H */
...@@ -687,7 +687,7 @@ static int status_to_android_error( NTSTATUS status ) ...@@ -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 ) 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) if (!*method)
{ {
...@@ -1163,7 +1163,7 @@ static DWORD CALLBACK device_thread( void *arg ) ...@@ -1163,7 +1163,7 @@ static DWORD CALLBACK device_thread( void *arg )
TRACE( "starting process %x\n", GetCurrentProcessId() ); 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 ); init_java_thread( java_vm );
......
...@@ -104,7 +104,7 @@ void set_screen_dpi( DWORD dpi ) ...@@ -104,7 +104,7 @@ void set_screen_dpi( DWORD dpi )
*/ */
static void fetch_display_metrics(void) 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 ) SERVER_START_REQ( get_window_rectangles )
{ {
...@@ -620,8 +620,8 @@ static void load_android_libs(void) ...@@ -620,8 +620,8 @@ static void load_android_libs(void)
#undef DECL_FUNCPTR #undef DECL_FUNCPTR
#undef LOAD_FUNCPTR #undef LOAD_FUNCPTR
JavaVM * (*p_wine_get_java_vm)(void) = NULL; JavaVM **p_java_vm = NULL;
jobject (*p_wine_get_java_object)(void) = NULL; jobject *p_java_object = NULL;
static BOOL process_attach(void) static BOOL process_attach(void)
{ {
...@@ -629,18 +629,18 @@ static BOOL process_attach(void) ...@@ -629,18 +629,18 @@ static BOOL process_attach(void)
jobject object; jobject object;
JNIEnv *jni_env; JNIEnv *jni_env;
JavaVM *java_vm; 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_java_vm = dlsym( ntdll, "java_vm" );
p_wine_get_java_object = dlsym( libwine, "wine_get_java_object" ); p_java_object = dlsym( ntdll, "java_object" );
object = p_wine_get_java_object(); object = *p_java_object;
load_hardware_libs(); 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__ #ifdef __i386__
WORD old_fs; WORD old_fs;
......
...@@ -54,10 +54,6 @@ ...@@ -54,10 +54,6 @@
extern char **environ; extern char **environ;
#endif #endif
#ifdef __ANDROID__
#include <jni.h>
#endif
#define NONAMELESSUNION #define NONAMELESSUNION
#define NONAMELESSSTRUCT #define NONAMELESSSTRUCT
#include "windef.h" #include "windef.h"
...@@ -102,7 +98,6 @@ static int dll_path_maxlen; ...@@ -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_anon_mmap( void *start, size_t size, int prot, int flags );
extern void wine_init_argv0_path( const char *argv0 ); 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 void mmap_init(void);
extern const char *get_dlldir( const char **default_dlldir ); extern const char *get_dlldir( const char **default_dlldir );
...@@ -958,131 +953,6 @@ static void apple_main_thread( void (*init_func)(void) ) ...@@ -958,131 +953,6 @@ static void apple_main_thread( void (*init_func)(void) )
#endif #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 * 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