diff --git a/dlls/wineandroid.drv/WineActivity.java b/dlls/wineandroid.drv/WineActivity.java index b0a8541d3f0..36964932713 100644 --- a/dlls/wineandroid.drv/WineActivity.java +++ b/dlls/wineandroid.drv/WineActivity.java @@ -22,11 +22,14 @@ import android.app.Activity; import android.app.ProgressDialog; +import android.content.Context; import android.content.SharedPreferences; import android.os.Build; import android.os.Bundle; import android.preference.PreferenceManager; import android.util.Log; +import android.view.View; +import android.view.ViewGroup; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; @@ -42,6 +45,7 @@ public class WineActivity extends Activity { private native String wine_init( String[] cmdline, String[] env ); + public native void wine_desktop_changed( int width, int height ); private final String LOGTAG = "wine"; private ProgressDialog progress_dialog; @@ -263,4 +267,47 @@ private final void copyAssetFiles() progress_dialog.incrementProgressBy( 1 ); }}); } } + + // The top-level desktop view group + + protected class TopView extends ViewGroup + { + private int desktop_hwnd; + + public TopView( Context context, int hwnd ) + { + super( context ); + desktop_hwnd = hwnd; + } + + @Override + protected void onSizeChanged( int width, int height, int old_width, int old_height ) + { + Log.i( LOGTAG, String.format( "desktop size %dx%d", width, height )); + wine_desktop_changed( width, height ); + } + + @Override + protected void onLayout( boolean changed, int left, int top, int right, int bottom ) + { + // nothing to do + } + } + + protected TopView top_view; + + // Entry points for the device driver + + public void create_desktop_window( int hwnd ) + { + Log.i( LOGTAG, String.format( "create desktop view %08x", hwnd )); + top_view = new TopView( this, hwnd ); + setContentView( top_view ); + progress_dialog.dismiss(); + } + + public void createDesktopWindow( final int hwnd ) + { + runOnUiThread( new Runnable() { public void run() { create_desktop_window( hwnd ); }} ); + } } diff --git a/dlls/wineandroid.drv/device.c b/dlls/wineandroid.drv/device.c index 3180d691c0d..f5655344522 100644 --- a/dlls/wineandroid.drv/device.c +++ b/dlls/wineandroid.drv/device.c @@ -48,10 +48,48 @@ static HANDLE stop_event; static HANDLE thread; static JNIEnv *jni_env; -#ifdef __i386__ +#ifdef __i386__ /* the Java VM uses %fs for its own purposes, so we need to wrap the calls */ static WORD orig_fs, java_fs; +static inline void wrap_java_call(void) { wine_set_fs( java_fs ); } +static inline void unwrap_java_call(void) { wine_set_fs( orig_fs ); } +#else +static inline void wrap_java_call(void) { } +static inline void unwrap_java_call(void) { } #endif /* __i386__ */ +static jobject load_java_method( jmethodID *method, const char *name, const char *args ) +{ + jobject object = wine_get_java_object(); + + if (!*method) + { + jclass class; + + wrap_java_call(); + class = (*jni_env)->GetObjectClass( jni_env, object ); + *method = (*jni_env)->GetMethodID( jni_env, class, name, args ); + unwrap_java_call(); + if (!*method) + { + FIXME( "method %s not found\n", name ); + return NULL; + } + } + return object; +} + +static void create_desktop_window( HWND hwnd ) +{ + static jmethodID method; + jobject object; + + if (!(object = load_java_method( &method, "createDesktopWindow", "(I)V" ))) return; + + wrap_java_call(); + (*jni_env)->CallVoidMethod( jni_env, object, method, HandleToLong( hwnd )); + unwrap_java_call(); +} + static NTSTATUS WINAPI ioctl_callback( DEVICE_OBJECT *device, IRP *irp ) { IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation( irp ); @@ -105,6 +143,8 @@ static DWORD CALLBACK device_thread( void *arg ) (*java_vm)->AttachCurrentThread( java_vm, &jni_env, 0 ); #endif + create_desktop_window( GetDesktopWindow() ); + RtlInitUnicodeString( &nameW, driver_nameW ); if ((status = IoCreateDriver( &nameW, init_android_driver ))) {