wineandroid: Forward native window perform() calls to the desktop process.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
f69836eba9
commit
4c1f541c13
|
@ -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 )
|
||||
|
|
Loading…
Reference in New Issue