wineandroid: Implement SetParent and forward it to Java.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2017-06-07 11:27:54 +02:00
parent b6a00bc0eb
commit be285af54f
5 changed files with 85 additions and 0 deletions

View File

@ -337,6 +337,20 @@ public void pos_changed( int flags, int insert_after, int owner, int style,
visible = (style & WS_VISIBLE) != 0;
}
public void set_parent( WineWindow new_parent )
{
Log.i( LOGTAG, String.format( "set parent hwnd %08x parent %08x -> %08x",
hwnd, parent == null ? 0 : parent.hwnd,
new_parent == null ? 0 : new_parent.hwnd ));
parent = new_parent;
if (new_parent == null)
{
window_view = new WineView( WineActivity.this, this );
window_view.layout( 0, 0, 1, 1 ); // make sure the surface gets created
}
else window_view = null;
}
public int get_hwnd()
{
return hwnd;
@ -452,6 +466,13 @@ public void destroy_window( int hwnd )
if (win != null) win.destroy();
}
public void set_window_parent( int hwnd, int parent, int pid )
{
WineWindow win = get_window( hwnd );
if (win == null) return;
win.set_parent( get_window( parent ));
}
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 )
{
@ -475,6 +496,11 @@ public void destroyWindow( final int hwnd )
runOnUiThread( new Runnable() { public void run() { destroy_window( hwnd ); }} );
}
public void setParent( final int hwnd, final int parent, final int pid )
{
runOnUiThread( new Runnable() { public void run() { set_window_parent( hwnd, parent, pid ); }} );
}
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,

View File

@ -60,6 +60,7 @@ 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;
extern int ioctl_set_window_parent( HWND hwnd, HWND parent ) DECLSPEC_HIDDEN;
/**************************************************************************

View File

@ -61,6 +61,7 @@ enum android_ioctl
IOCTL_CREATE_WINDOW,
IOCTL_DESTROY_WINDOW,
IOCTL_WINDOW_POS_CHANGED,
IOCTL_SET_WINDOW_PARENT,
IOCTL_DEQUEUE_BUFFER,
IOCTL_QUEUE_BUFFER,
IOCTL_CANCEL_BUFFER,
@ -188,6 +189,12 @@ struct ioctl_android_set_swap_interval
int interval;
};
struct ioctl_android_set_window_parent
{
struct ioctl_header hdr;
int parent;
};
static inline BOOL is_in_desktop_process(void)
{
return thread != NULL;
@ -832,12 +839,35 @@ static NTSTATUS setSwapInterval_ioctl( void *data, DWORD in_size, DWORD out_size
return android_error_to_status( ret );
}
static NTSTATUS setWindowParent_ioctl( void *data, DWORD in_size, DWORD out_size, ULONG_PTR *ret_size )
{
static jmethodID method;
jobject object;
struct ioctl_android_set_window_parent *res = data;
struct native_win_data *win_data;
DWORD pid = current_client_id();
if (in_size < sizeof(*res)) return STATUS_INVALID_PARAMETER;
if (!(win_data = get_ioctl_native_win_data( &res->hdr ))) return STATUS_INVALID_HANDLE;
TRACE( "hwnd %08x parent %08x\n", res->hdr.hwnd, res->parent );
if (!(object = load_java_method( &method, "setParent", "(III)V" ))) return STATUS_NOT_SUPPORTED;
wrap_java_call();
(*jni_env)->CallVoidMethod( jni_env, object, method, res->hdr.hwnd, res->parent, pid );
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 */
setWindowParent_ioctl, /* IOCTL_SET_WINDOW_PARENT */
dequeueBuffer_ioctl, /* IOCTL_DEQUEUE_BUFFER */
queueBuffer_ioctl, /* IOCTL_QUEUE_BUFFER */
cancelBuffer_ioctl, /* IOCTL_CANCEL_BUFFER */
@ -1356,3 +1386,12 @@ int ioctl_window_pos_changed( HWND hwnd, const RECT *window_rect, const RECT *cl
req.owner = HandleToLong( owner );
return android_ioctl( IOCTL_WINDOW_POS_CHANGED, &req, sizeof(req), NULL, NULL );
}
int ioctl_set_window_parent( HWND hwnd, HWND parent )
{
struct ioctl_android_set_window_parent req;
req.hdr.hwnd = HandleToLong( hwnd );
req.parent = parent == GetDesktopWindow() ? 0 : HandleToLong( parent );
return android_ioctl( IOCTL_SET_WINDOW_PARENT, &req, sizeof(req), NULL, NULL );
}

View File

@ -1015,6 +1015,24 @@ UINT CDECL ANDROID_ShowWindow( HWND hwnd, INT cmd, RECT *rect, UINT swp )
}
/*****************************************************************
* ANDROID_SetParent
*/
void CDECL ANDROID_SetParent( HWND hwnd, HWND parent, HWND old_parent )
{
struct android_win_data *data;
if (parent == old_parent) return;
if (!(data = get_win_data( hwnd ))) return;
TRACE( "win %p parent %p -> %p\n", hwnd, old_parent, parent );
data->parent = (parent == GetDesktopWindow()) ? 0 : parent;
ioctl_set_window_parent( hwnd, parent );
release_win_data( data );
}
/***********************************************************************
* ANDROID_SetWindowStyle
*/

View File

@ -10,6 +10,7 @@
@ cdecl DestroyWindow(long) ANDROID_DestroyWindow
@ cdecl MsgWaitForMultipleObjectsEx(long ptr long long long) ANDROID_MsgWaitForMultipleObjectsEx
@ cdecl SetLayeredWindowAttributes(long long long long) ANDROID_SetLayeredWindowAttributes
@ cdecl SetParent(long long long) ANDROID_SetParent
@ cdecl SetWindowRgn(long long long) ANDROID_SetWindowRgn
@ cdecl SetWindowStyle(ptr long ptr) ANDROID_SetWindowStyle
@ cdecl ShowWindow(long long ptr long) ANDROID_ShowWindow