Alexandre Julliard : wineandroid: Forward native window perform() calls to the desktop process.
Alexandre Julliard
julliard at winehq.org
Mon Jun 5 16:56:31 CDT 2017
Module: wine
Branch: master
Commit: 4c1f541c13b38d9523753afb9e2ddb2f5431f7ce
URL: http://source.winehq.org/git/wine.git/?a=commit;h=4c1f541c13b38d9523753afb9e2ddb2f5431f7ce
Author: Alexandre Julliard <julliard at winehq.org>
Date: Mon Jun 5 12:26:40 2017 +0200
wineandroid: Forward native window perform() calls to the desktop process.
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/wineandroid.drv/device.c | 182 +++++++++++++++++++++++++++++++++++++++++-
1 file changed, 180 insertions(+), 2 deletions(-)
diff --git a/dlls/wineandroid.drv/device.c b/dlls/wineandroid.drv/device.c
index 48b595f..7b4e348 100644
--- a/dlls/wineandroid.drv/device.c
+++ b/dlls/wineandroid.drv/device.c
@@ -57,6 +57,7 @@ enum android_ioctl
IOCTL_DESTROY_WINDOW,
IOCTL_WINDOW_POS_CHANGED,
IOCTL_QUERY,
+ IOCTL_PERFORM,
NB_IOCTLS
};
@@ -65,6 +66,8 @@ struct native_win_data
{
struct ANativeWindow *parent;
HWND hwnd;
+ int api;
+ int buffer_format;
};
/* wrapper for a native window in the context of the client (non-Java) process */
@@ -110,6 +113,13 @@ struct ioctl_android_query
int value;
};
+struct ioctl_android_perform
+{
+ struct ioctl_header hdr;
+ int operation;
+ int args[4];
+};
+
static inline DWORD current_client_id(void)
{
return HandleToUlong( PsGetCurrentProcessId() );
@@ -171,6 +181,8 @@ static struct native_win_data *create_native_win_data( HWND hwnd )
}
if (!(data = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*data) ))) return NULL;
data->hwnd = hwnd;
+ data->api = NATIVE_WINDOW_API_CPU;
+ data->buffer_format = PF_BGRA_8888;
data_map[idx] = data;
return data;
}
@@ -193,7 +205,8 @@ static void CALLBACK register_native_window_callback( ULONG_PTR arg1, ULONG_PTR
if (win)
{
wrap_java_call();
- win->perform( win, NATIVE_WINDOW_API_CONNECT, NATIVE_WINDOW_API_CPU );
+ if (data->api) win->perform( win, NATIVE_WINDOW_API_CONNECT, data->api );
+ win->perform( win, NATIVE_WINDOW_SET_BUFFERS_FORMAT, data->buffer_format );
unwrap_java_call();
}
TRACE( "%p -> %p win %p\n", hwnd, data, win );
@@ -374,6 +387,93 @@ static NTSTATUS query_ioctl( void *data, DWORD in_size, DWORD out_size, ULONG_PT
return android_error_to_status( ret );
}
+static NTSTATUS perform_ioctl( void *data, DWORD in_size, DWORD out_size, ULONG_PTR *ret_size )
+{
+ struct ioctl_android_perform *res = data;
+ struct ANativeWindow *parent;
+ struct native_win_data *win_data;
+ int ret = -ENOENT;
+
+ if (in_size < sizeof(*res)) return STATUS_INVALID_PARAMETER;
+
+ if (!(win_data = get_ioctl_native_win_data( &res->hdr ))) return STATUS_INVALID_HANDLE;
+ if (!(parent = win_data->parent)) return STATUS_DEVICE_NOT_READY;
+
+ switch (res->operation)
+ {
+ case NATIVE_WINDOW_SET_BUFFERS_FORMAT:
+ wrap_java_call();
+ ret = parent->perform( parent, res->operation, res->args[0] );
+ unwrap_java_call();
+ if (!ret) win_data->buffer_format = res->args[0];
+ break;
+ case NATIVE_WINDOW_API_CONNECT:
+ wrap_java_call();
+ ret = parent->perform( parent, res->operation, res->args[0] );
+ unwrap_java_call();
+ if (!ret) win_data->api = res->args[0];
+ break;
+ case NATIVE_WINDOW_API_DISCONNECT:
+ wrap_java_call();
+ ret = parent->perform( parent, res->operation, res->args[0] );
+ unwrap_java_call();
+ if (!ret) win_data->api = 0;
+ break;
+ case NATIVE_WINDOW_SET_USAGE:
+ case NATIVE_WINDOW_SET_BUFFERS_TRANSFORM:
+ case NATIVE_WINDOW_SET_SCALING_MODE:
+ wrap_java_call();
+ ret = parent->perform( parent, res->operation, res->args[0] );
+ unwrap_java_call();
+ break;
+ case NATIVE_WINDOW_SET_BUFFER_COUNT:
+ wrap_java_call();
+ ret = parent->perform( parent, res->operation, (size_t)res->args[0] );
+ unwrap_java_call();
+ break;
+ case NATIVE_WINDOW_SET_BUFFERS_DIMENSIONS:
+ case NATIVE_WINDOW_SET_BUFFERS_USER_DIMENSIONS:
+ wrap_java_call();
+ ret = parent->perform( parent, res->operation, res->args[0], res->args[1] );
+ unwrap_java_call();
+ break;
+ case NATIVE_WINDOW_SET_BUFFERS_GEOMETRY:
+ wrap_java_call();
+ ret = parent->perform( parent, res->operation, res->args[0], res->args[1], res->args[2] );
+ unwrap_java_call();
+ break;
+ case NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP:
+ wrap_java_call();
+ ret = parent->perform( parent, res->operation, res->args[0] | ((int64_t)res->args[1] << 32) );
+ unwrap_java_call();
+ break;
+ case NATIVE_WINDOW_CONNECT:
+ case NATIVE_WINDOW_DISCONNECT:
+ case NATIVE_WINDOW_UNLOCK_AND_POST:
+ wrap_java_call();
+ ret = parent->perform( parent, res->operation );
+ unwrap_java_call();
+ break;
+ case NATIVE_WINDOW_SET_CROP:
+ {
+ android_native_rect_t rect;
+ rect.left = res->args[0];
+ rect.top = res->args[1];
+ rect.right = res->args[2];
+ rect.bottom = res->args[3];
+ wrap_java_call();
+ ret = parent->perform( parent, res->operation, &rect );
+ unwrap_java_call();
+ break;
+ }
+ case NATIVE_WINDOW_LOCK:
+ default:
+ FIXME( "unsupported perform op %d\n", res->operation );
+ break;
+ }
+ return android_error_to_status( ret );
+}
+
typedef NTSTATUS (*ioctl_func)( void *in, DWORD in_size, DWORD out_size, ULONG_PTR *ret_size );
static const ioctl_func ioctl_funcs[] =
{
@@ -381,6 +481,7 @@ static const ioctl_func ioctl_funcs[] =
destroyWindow_ioctl, /* IOCTL_DESTROY_WINDOW */
windowPosChanged_ioctl, /* IOCTL_WINDOW_POS_CHANGED */
query_ioctl, /* IOCTL_QUERY */
+ perform_ioctl, /* IOCTL_PERFORM */
};
static NTSTATUS WINAPI ioctl_callback( DEVICE_OBJECT *device, IRP *irp )
@@ -581,7 +682,84 @@ static int query( const ANativeWindow *window, int what, int *value )
static int perform( ANativeWindow *window, int operation, ... )
{
- return 0;
+ static const char * const names[] =
+ {
+ "SET_USAGE", "CONNECT", "DISCONNECT", "SET_CROP", "SET_BUFFER_COUNT", "SET_BUFFERS_GEOMETRY",
+ "SET_BUFFERS_TRANSFORM", "SET_BUFFERS_TIMESTAMP", "SET_BUFFERS_DIMENSIONS", "SET_BUFFERS_FORMAT",
+ "SET_SCALING_MODE", "LOCK", "UNLOCK_AND_POST", "API_CONNECT", "API_DISCONNECT",
+ "SET_BUFFERS_USER_DIMENSIONS", "SET_POST_TRANSFORM_CROP"
+ };
+
+ struct native_win_wrapper *win = (struct native_win_wrapper *)window;
+ struct ioctl_android_perform perf;
+ va_list args;
+
+ perf.hdr.hwnd = HandleToLong( win->hwnd );
+ perf.operation = operation;
+ memset( perf.args, 0, sizeof(perf.args) );
+
+ va_start( args, operation );
+ switch (operation)
+ {
+ case NATIVE_WINDOW_SET_USAGE:
+ case NATIVE_WINDOW_SET_BUFFERS_TRANSFORM:
+ case NATIVE_WINDOW_SET_BUFFERS_FORMAT:
+ case NATIVE_WINDOW_SET_SCALING_MODE:
+ case NATIVE_WINDOW_API_CONNECT:
+ case NATIVE_WINDOW_API_DISCONNECT:
+ perf.args[0] = va_arg( args, int );
+ TRACE( "hwnd %p %s arg %d\n", win->hwnd, names[operation], perf.args[0] );
+ break;
+ case NATIVE_WINDOW_SET_BUFFER_COUNT:
+ perf.args[0] = va_arg( args, size_t );
+ TRACE( "hwnd %p %s count %d\n", win->hwnd, names[operation], perf.args[0] );
+ break;
+ case NATIVE_WINDOW_SET_BUFFERS_DIMENSIONS:
+ case NATIVE_WINDOW_SET_BUFFERS_USER_DIMENSIONS:
+ perf.args[0] = va_arg( args, int );
+ perf.args[1] = va_arg( args, int );
+ TRACE( "hwnd %p %s arg %dx%d\n", win->hwnd, names[operation], perf.args[0], perf.args[1] );
+ break;
+ case NATIVE_WINDOW_SET_BUFFERS_GEOMETRY:
+ perf.args[0] = va_arg( args, int );
+ perf.args[1] = va_arg( args, int );
+ perf.args[2] = va_arg( args, int );
+ TRACE( "hwnd %p %s arg %dx%d %d\n", win->hwnd, names[operation],
+ perf.args[0], perf.args[1], perf.args[2] );
+ break;
+ case NATIVE_WINDOW_SET_CROP:
+ {
+ android_native_rect_t *rect = va_arg( args, android_native_rect_t * );
+ perf.args[0] = rect->left;
+ perf.args[1] = rect->top;
+ perf.args[2] = rect->right;
+ perf.args[3] = rect->bottom;
+ TRACE( "hwnd %p %s rect %d,%d-%d,%d\n", win->hwnd, names[operation],
+ perf.args[0], perf.args[1], perf.args[2], perf.args[3] );
+ break;
+ }
+ case NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP:
+ {
+ int64_t timestamp = va_arg( args, int64_t );
+ perf.args[0] = timestamp;
+ perf.args[1] = timestamp >> 32;
+ TRACE( "hwnd %p %s arg %08x%08x\n", win->hwnd, names[operation], perf.args[1], perf.args[0] );
+ break;
+ }
+ case NATIVE_WINDOW_LOCK:
+ case NATIVE_WINDOW_UNLOCK_AND_POST:
+ case NATIVE_WINDOW_CONNECT:
+ case NATIVE_WINDOW_DISCONNECT:
+ TRACE( "hwnd %p %s\n", win->hwnd, names[operation] );
+ break;
+ case NATIVE_WINDOW_SET_POST_TRANSFORM_CROP:
+ default:
+ FIXME( "unsupported perform hwnd %p op %d %s\n", win->hwnd, operation,
+ operation < sizeof(names)/sizeof(names[0]) ? names[operation] : "???" );
+ break;
+ }
+ va_end( args );
+ return android_ioctl( IOCTL_PERFORM, &perf, sizeof(perf), NULL, NULL );
}
struct ANativeWindow *create_ioctl_window( HWND hwnd )
More information about the wine-cvs
mailing list