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