wineandroid: Add a Java callback for setting window position.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2017-06-02 11:34:23 +02:00
parent 4e0c3707c3
commit 97005de151
4 changed files with 117 additions and 2 deletions

View file

@ -24,6 +24,7 @@
import android.app.ProgressDialog;
import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.Rect;
import android.os.Build;
import android.os.Bundle;
import android.preference.PreferenceManager;
@ -277,21 +278,46 @@ private final void copyAssetFiles()
protected class WineWindow extends Object
{
static protected final int WS_VISIBLE = 0x10000000;
protected int hwnd;
protected int owner;
protected int style;
protected boolean visible;
protected Rect visible_rect;
protected Rect client_rect;
public WineWindow( int w, WineWindow parent )
{
Log.i( LOGTAG, String.format( "create hwnd %08x", w ));
hwnd = w;
owner = 0;
style = 0;
visible = false;
visible_rect = client_rect = new Rect( 0, 0, 0, 0 );
win_map.put( w, this );
}
public void destroy()
{
Log.i( LOGTAG, String.format( "destroy hwnd %08x", hwnd ));
visible = false;
win_map.remove( this );
}
public void pos_changed( int flags, int insert_after, int owner, int style,
Rect window_rect, Rect client_rect, Rect visible_rect )
{
this.visible_rect = visible_rect;
this.client_rect = client_rect;
this.style = style;
this.owner = owner;
Log.i( LOGTAG, String.format( "pos changed hwnd %08x after %08x owner %08x style %08x win %s client %s visible %s flags %08x",
hwnd, insert_after, owner, style, window_rect, client_rect, visible_rect, flags ));
visible = (style & WS_VISIBLE) != 0;
}
public int get_hwnd()
{
return hwnd;
@ -353,6 +379,14 @@ public void destroy_window( int hwnd )
if (win != null) win.destroy();
}
public void window_pos_changed( int hwnd, int flags, int insert_after, int owner, int style,
Rect window_rect, Rect client_rect, Rect visible_rect )
{
WineWindow win = get_window( hwnd );
if (win != null)
win.pos_changed( flags, insert_after, owner, style, window_rect, client_rect, visible_rect );
}
public void createDesktopWindow( final int hwnd )
{
runOnUiThread( new Runnable() { public void run() { create_desktop_window( hwnd ); }} );
@ -367,4 +401,21 @@ public void destroyWindow( final int hwnd )
{
runOnUiThread( new Runnable() { public void run() { destroy_window( hwnd ); }} );
}
public void windowPosChanged( final int hwnd, final int flags, final int insert_after,
final int owner, final int style,
final int window_left, final int window_top,
final int window_right, final int window_bottom,
final int client_left, final int client_top,
final int client_right, final int client_bottom,
final int visible_left, final int visible_top,
final int visible_right, final int visible_bottom )
{
final Rect window_rect = new Rect( window_left, window_top, window_right, window_bottom );
final Rect client_rect = new Rect( client_left, client_top, client_right, client_bottom );
final Rect visible_rect = new Rect( visible_left, visible_top, visible_right, visible_bottom );
runOnUiThread( new Runnable() {
public void run() { window_pos_changed( hwnd, flags, insert_after, owner, style,
window_rect, client_rect, visible_rect ); }} );
}
}

View file

@ -50,6 +50,9 @@ DECL_FUNCPTR( __android_log_print );
extern void start_android_device(void) DECLSPEC_HIDDEN;
extern void create_ioctl_window( HWND hwnd ) DECLSPEC_HIDDEN;
extern void destroy_ioctl_window( HWND hwnd ) DECLSPEC_HIDDEN;
extern int ioctl_window_pos_changed( HWND hwnd, const RECT *window_rect, const RECT *client_rect,
const RECT *visible_rect, UINT style, UINT flags,
HWND after, HWND owner ) DECLSPEC_HIDDEN;
/**************************************************************************

View file

@ -55,6 +55,7 @@ enum android_ioctl
{
IOCTL_CREATE_WINDOW,
IOCTL_DESTROY_WINDOW,
IOCTL_WINDOW_POS_CHANGED,
NB_IOCTLS
};
@ -74,6 +75,17 @@ struct ioctl_android_destroy_window
struct ioctl_header hdr;
};
struct ioctl_android_window_pos_changed
{
struct ioctl_header hdr;
RECT window_rect;
RECT client_rect;
RECT visible_rect;
int style;
int flags;
int after;
int owner;
};
static inline DWORD current_client_id(void)
{
@ -184,11 +196,36 @@ static NTSTATUS destroyWindow_ioctl( void *data, DWORD in_size, DWORD out_size,
return STATUS_SUCCESS;
}
static NTSTATUS windowPosChanged_ioctl( void *data, DWORD in_size, DWORD out_size, ULONG_PTR *ret_size )
{
static jmethodID method;
jobject object;
struct ioctl_android_window_pos_changed *res = data;
if (in_size < sizeof(*res)) return STATUS_INVALID_PARAMETER;
TRACE( "hwnd %08x win %s client %s visible %s style %08x flags %08x after %08x owner %08x\n",
res->hdr.hwnd, wine_dbgstr_rect(&res->window_rect), wine_dbgstr_rect(&res->client_rect),
wine_dbgstr_rect(&res->visible_rect), res->style, res->flags, res->after, res->owner );
if (!(object = load_java_method( &method, "windowPosChanged", "(IIIIIIIIIIIIIIIII)V" )))
return STATUS_NOT_SUPPORTED;
wrap_java_call();
(*jni_env)->CallVoidMethod( jni_env, object, method, res->hdr.hwnd, res->flags, res->after, res->owner, res->style,
res->window_rect.left, res->window_rect.top, res->window_rect.right, res->window_rect.bottom,
res->client_rect.left, res->client_rect.top, res->client_rect.right, res->client_rect.bottom,
res->visible_rect.left, res->visible_rect.top, res->visible_rect.right, res->visible_rect.bottom );
unwrap_java_call();
return STATUS_SUCCESS;
}
typedef NTSTATUS (*ioctl_func)( void *in, DWORD in_size, DWORD out_size, ULONG_PTR *ret_size );
static const ioctl_func ioctl_funcs[] =
{
createWindow_ioctl, /* IOCTL_CREATE_WINDOW */
destroyWindow_ioctl, /* IOCTL_DESTROY_WINDOW */
windowPosChanged_ioctl, /* IOCTL_WINDOW_POS_CHANGED */
};
static NTSTATUS WINAPI ioctl_callback( DEVICE_OBJECT *device, IRP *irp )
@ -337,3 +374,19 @@ void destroy_ioctl_window( HWND hwnd )
req.hdr.hwnd = HandleToLong( hwnd );
android_ioctl( IOCTL_DESTROY_WINDOW, &req, sizeof(req), NULL, NULL );
}
int ioctl_window_pos_changed( HWND hwnd, const RECT *window_rect, const RECT *client_rect,
const RECT *visible_rect, UINT style, UINT flags, HWND after, HWND owner )
{
struct ioctl_android_window_pos_changed req;
req.hdr.hwnd = HandleToLong( hwnd );
req.window_rect = *window_rect;
req.client_rect = *client_rect;
req.visible_rect = *visible_rect;
req.style = style;
req.flags = flags;
req.after = HandleToLong( after );
req.owner = HandleToLong( owner );
return android_ioctl( IOCTL_WINDOW_POS_CHANGED, &req, sizeof(req), NULL, NULL );
}

View file

@ -407,6 +407,9 @@ static struct android_win_data *create_win_data( HWND hwnd, const RECT *window_r
data->whole_rect = data->window_rect;
GetClientRect( hwnd, &data->client_rect );
MapWindowPoints( hwnd, parent, (POINT *)&data->client_rect, 2 );
ioctl_window_pos_changed( hwnd, &data->window_rect, &data->client_rect, &data->whole_rect,
GetWindowLongW( hwnd, GWL_STYLE ), SWP_NOACTIVATE,
GetWindow( hwnd, GW_HWNDPREV ), GetWindow( hwnd, GW_OWNER ));
}
return data;
}
@ -443,6 +446,7 @@ void CDECL ANDROID_WindowPosChanged( HWND hwnd, HWND insert_after, UINT swp_flag
{
struct android_win_data *data;
DWORD new_style = GetWindowLongW( hwnd, GWL_STYLE );
HWND owner = 0;
if (!(data = get_win_data( hwnd ))) return;
@ -450,10 +454,14 @@ void CDECL ANDROID_WindowPosChanged( HWND hwnd, HWND insert_after, UINT swp_flag
data->whole_rect = *visible_rect;
data->client_rect = *client_rect;
if (!data->parent) owner = GetWindow( hwnd, GW_OWNER );
release_win_data( data );
TRACE( "win %p window %s client %s style %08x flags %08x\n",
hwnd, wine_dbgstr_rect(window_rect), wine_dbgstr_rect(client_rect), new_style, swp_flags );
TRACE( "win %p window %s client %s style %08x owner %p flags %08x\n", hwnd,
wine_dbgstr_rect(window_rect), wine_dbgstr_rect(client_rect), new_style, owner, swp_flags );
ioctl_window_pos_changed( hwnd, window_rect, client_rect, visible_rect,
new_style, swp_flags, insert_after, owner );
}