Alexandre Julliard : wineandroid: Implement SetParent and forward it to Java.
Alexandre Julliard
julliard at winehq.org
Wed Jun 7 16:24:09 CDT 2017
Module: wine
Branch: master
Commit: be285af54fc5dcbd8a3f47fa5f60240451a88692
URL: http://source.winehq.org/git/wine.git/?a=commit;h=be285af54fc5dcbd8a3f47fa5f60240451a88692
Author: Alexandre Julliard <julliard at winehq.org>
Date: Wed Jun 7 11:27:54 2017 +0200
wineandroid: Implement SetParent and forward it to Java.
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/wineandroid.drv/WineActivity.java | 26 +++++++++++++++++++++
dlls/wineandroid.drv/android.h | 1 +
dlls/wineandroid.drv/device.c | 39 +++++++++++++++++++++++++++++++
dlls/wineandroid.drv/window.c | 18 ++++++++++++++
dlls/wineandroid.drv/wineandroid.drv.spec | 1 +
5 files changed, 85 insertions(+)
diff --git a/dlls/wineandroid.drv/WineActivity.java b/dlls/wineandroid.drv/WineActivity.java
index 50ff0bf..f12de98 100644
--- a/dlls/wineandroid.drv/WineActivity.java
+++ b/dlls/wineandroid.drv/WineActivity.java
@@ -337,6 +337,20 @@ public class WineActivity extends Activity
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 class WineActivity extends Activity
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 class WineActivity extends Activity
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,
diff --git a/dlls/wineandroid.drv/android.h b/dlls/wineandroid.drv/android.h
index 3c2500e..f3dd019 100644
--- a/dlls/wineandroid.drv/android.h
+++ b/dlls/wineandroid.drv/android.h
@@ -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;
/**************************************************************************
diff --git a/dlls/wineandroid.drv/device.c b/dlls/wineandroid.drv/device.c
index 1af59be..eafaf04 100644
--- a/dlls/wineandroid.drv/device.c
+++ b/dlls/wineandroid.drv/device.c
@@ -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 );
+}
diff --git a/dlls/wineandroid.drv/window.c b/dlls/wineandroid.drv/window.c
index 94f23e0..7dff297 100644
--- a/dlls/wineandroid.drv/window.c
+++ b/dlls/wineandroid.drv/window.c
@@ -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
*/
diff --git a/dlls/wineandroid.drv/wineandroid.drv.spec b/dlls/wineandroid.drv/wineandroid.drv.spec
index ed3138a..3605241 100644
--- a/dlls/wineandroid.drv/wineandroid.drv.spec
+++ b/dlls/wineandroid.drv/wineandroid.drv.spec
@@ -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
More information about the wine-cvs
mailing list