Module: wine Branch: master Commit: fbc482db1d011887468d11ef2fbac99e50af04a8 URL: http://source.winehq.org/git/wine.git/?a=commit;h=fbc482db1d011887468d11ef2f...
Author: Alexandre Julliard julliard@winehq.org Date: Mon Jun 5 12:21:26 2017 +0200
wineandroid: Allocate a native window wrapper in the client process for every window.
Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/wineandroid.drv/android.h | 4 +- dlls/wineandroid.drv/device.c | 114 ++++++++++++++++++++++++++++++++++++++++- dlls/wineandroid.drv/window.c | 5 +- 3 files changed, 119 insertions(+), 4 deletions(-)
diff --git a/dlls/wineandroid.drv/android.h b/dlls/wineandroid.drv/android.h index f03671a..3d9ac5a 100644 --- a/dlls/wineandroid.drv/android.h +++ b/dlls/wineandroid.drv/android.h @@ -53,7 +53,9 @@ DECL_FUNCPTR( ANativeWindow_release );
extern void start_android_device(void) DECLSPEC_HIDDEN; extern void register_native_window( HWND hwnd, struct ANativeWindow *win ) DECLSPEC_HIDDEN; -extern void create_ioctl_window( HWND hwnd ) DECLSPEC_HIDDEN; +extern struct ANativeWindow *create_ioctl_window( HWND hwnd ) DECLSPEC_HIDDEN; +extern struct ANativeWindow *grab_ioctl_window( struct ANativeWindow *window ) DECLSPEC_HIDDEN; +extern void release_ioctl_window( struct ANativeWindow *window ) 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, diff --git a/dlls/wineandroid.drv/device.c b/dlls/wineandroid.drv/device.c index 3dacd48..e6ddc50 100644 --- a/dlls/wineandroid.drv/device.c +++ b/dlls/wineandroid.drv/device.c @@ -66,6 +66,14 @@ struct native_win_data HWND hwnd; };
+/* wrapper for a native window in the context of the client (non-Java) process */ +struct native_win_wrapper +{ + struct ANativeWindow win; + HWND hwnd; + LONG ref; +}; + struct ioctl_header { int hwnd; @@ -452,14 +460,118 @@ static int android_ioctl( enum android_ioctl code, void *in, DWORD in_size, void return status_to_android_error( status ); }
-void create_ioctl_window( HWND hwnd ) +static void win_incRef( struct android_native_base_t *base ) +{ + struct native_win_wrapper *win = (struct native_win_wrapper *)base; + InterlockedIncrement( &win->ref ); +} + +static void win_decRef( struct android_native_base_t *base ) +{ + struct native_win_wrapper *win = (struct native_win_wrapper *)base; + InterlockedDecrement( &win->ref ); +} + +static int dequeueBuffer( struct ANativeWindow *window, struct ANativeWindowBuffer **buffer, int *fence ) +{ + return 0; +} + +static int cancelBuffer( struct ANativeWindow *window, struct ANativeWindowBuffer *buffer, int fence ) +{ + return 0; +} + +static int queueBuffer( struct ANativeWindow *window, struct ANativeWindowBuffer *buffer, int fence ) +{ + return 0; +} + +static int dequeueBuffer_DEPRECATED( struct ANativeWindow *window, struct ANativeWindowBuffer **buffer ) +{ + return 0; +} + +static int cancelBuffer_DEPRECATED( struct ANativeWindow *window, struct ANativeWindowBuffer *buffer ) +{ + return 0; +} + +static int lockBuffer_DEPRECATED( struct ANativeWindow *window, struct ANativeWindowBuffer *buffer ) +{ + return 0; /* nothing to do */ +} + +static int queueBuffer_DEPRECATED( struct ANativeWindow *window, struct ANativeWindowBuffer *buffer ) +{ + return 0; +} + +static int setSwapInterval( struct ANativeWindow *window, int interval ) +{ + return 0; +} + +static int query( const ANativeWindow *window, int what, int *value ) +{ + return 0; +} + +static int perform( ANativeWindow *window, int operation, ... ) +{ + return 0; +} + +struct ANativeWindow *create_ioctl_window( HWND hwnd ) { struct ioctl_android_create_window req; + struct native_win_wrapper *win = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*win) ); HWND parent = GetAncestor( hwnd, GA_PARENT );
+ if (!win) return NULL; + + win->win.common.magic = ANDROID_NATIVE_WINDOW_MAGIC; + win->win.common.version = sizeof(ANativeWindow); + win->win.common.incRef = win_incRef; + win->win.common.decRef = win_decRef; + win->win.setSwapInterval = setSwapInterval; + win->win.dequeueBuffer_DEPRECATED = dequeueBuffer_DEPRECATED; + win->win.lockBuffer_DEPRECATED = lockBuffer_DEPRECATED; + win->win.queueBuffer_DEPRECATED = queueBuffer_DEPRECATED; + win->win.query = query; + win->win.perform = perform; + win->win.cancelBuffer_DEPRECATED = cancelBuffer_DEPRECATED; + win->win.dequeueBuffer = dequeueBuffer; + win->win.queueBuffer = queueBuffer; + win->win.cancelBuffer = cancelBuffer; + win->ref = 1; + win->hwnd = hwnd; + TRACE( "-> %p %p\n", win, win->hwnd ); + req.hdr.hwnd = HandleToLong( hwnd ); req.parent = parent == GetDesktopWindow() ? 0 : HandleToLong( parent ); android_ioctl( IOCTL_CREATE_WINDOW, &req, sizeof(req), NULL, NULL ); + + return &win->win; +} + +struct ANativeWindow *grab_ioctl_window( struct ANativeWindow *window ) +{ + struct native_win_wrapper *win = (struct native_win_wrapper *)window; + InterlockedIncrement( &win->ref ); + return window; +} + +void release_ioctl_window( struct ANativeWindow *window ) +{ + struct native_win_wrapper *win = (struct native_win_wrapper *)window; + + if (InterlockedDecrement( &win->ref ) > 0) return; + + TRACE( "%p %p\n", win, win->hwnd ); + + destroy_ioctl_window( win->hwnd ); + HeapFree( GetProcessHeap(), 0, win ); }
void destroy_ioctl_window( HWND hwnd ) diff --git a/dlls/wineandroid.drv/window.c b/dlls/wineandroid.drv/window.c index 49520eb..65b37d8 100644 --- a/dlls/wineandroid.drv/window.c +++ b/dlls/wineandroid.drv/window.c @@ -57,6 +57,7 @@ struct android_win_data RECT window_rect; /* USER window rectangle relative to parent */ RECT whole_rect; /* X window rectangle for the whole window relative to parent */ RECT client_rect; /* client area relative to parent */ + ANativeWindow *window; /* native window wrapper that forwards calls to the desktop process */ };
#define SWP_AGG_NOPOSCHANGE (SWP_NOSIZE | SWP_NOMOVE | SWP_NOCLIENTSIZE | SWP_NOCLIENTMOVE | SWP_NOZORDER) @@ -88,7 +89,7 @@ static struct android_win_data *alloc_win_data( HWND hwnd ) if ((data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*data)))) { data->hwnd = hwnd; - create_ioctl_window( hwnd ); + data->window = create_ioctl_window( hwnd ); EnterCriticalSection( &win_data_section ); win_data_context[context_idx(hwnd)] = data; } @@ -103,7 +104,7 @@ static void free_win_data( struct android_win_data *data ) { win_data_context[context_idx( data->hwnd )] = NULL; LeaveCriticalSection( &win_data_section ); - destroy_ioctl_window( data->hwnd ); + if (data->window) release_ioctl_window( data->window ); HeapFree( GetProcessHeap(), 0, data ); }