wineandroid: Allocate a native window wrapper in the client process for every window.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2017-06-05 12:21:26 +02:00
parent 5b57a6a52f
commit fbc482db1d
3 changed files with 119 additions and 4 deletions

View File

@ -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,

View File

@ -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 )

View File

@ -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 );
}