diff --git a/dlls/wineandroid.drv/android.h b/dlls/wineandroid.drv/android.h index f3dd019177b..3d1a676b027 100644 --- a/dlls/wineandroid.drv/android.h +++ b/dlls/wineandroid.drv/android.h @@ -61,6 +61,7 @@ extern int ioctl_window_pos_changed( HWND hwnd, const RECT *window_rect, const R const RECT *visible_rect, UINT style, UINT flags, HWND after, HWND owner ) DECLSPEC_HIDDEN; extern int ioctl_set_window_parent( HWND hwnd, HWND parent ) DECLSPEC_HIDDEN; +extern int ioctl_set_capture( HWND hwnd ) DECLSPEC_HIDDEN; /************************************************************************** @@ -77,6 +78,7 @@ enum android_window_messages WM_ANDROID_REFRESH = 0x80001000, }; +extern HWND get_capture_window(void) DECLSPEC_HIDDEN; extern void init_monitors( int width, int height ) DECLSPEC_HIDDEN; /* JNI entry points */ diff --git a/dlls/wineandroid.drv/device.c b/dlls/wineandroid.drv/device.c index eafaf0474a0..3829e695369 100644 --- a/dlls/wineandroid.drv/device.c +++ b/dlls/wineandroid.drv/device.c @@ -52,6 +52,7 @@ extern NTSTATUS CDECL wine_ntoskrnl_main_loop( HANDLE stop_event ); static HANDLE stop_event; static HANDLE thread; static JNIEnv *jni_env; +static HWND capture_window; #define ANDROIDCONTROLTYPE ((ULONG)'A') #define ANDROID_IOCTL(n) CTL_CODE(ANDROIDCONTROLTYPE, n, METHOD_BUFFERED, FILE_READ_ACCESS) @@ -68,6 +69,7 @@ enum android_ioctl IOCTL_QUERY, IOCTL_PERFORM, IOCTL_SET_SWAP_INT, + IOCTL_SET_CAPTURE, NB_IOCTLS }; @@ -195,6 +197,11 @@ struct ioctl_android_set_window_parent int parent; }; +struct ioctl_android_set_capture +{ + struct ioctl_header hdr; +}; + static inline BOOL is_in_desktop_process(void) { return thread != NULL; @@ -407,6 +414,7 @@ static void free_native_win_data( struct native_win_data *data ) { unsigned int idx = data_map_idx( data->hwnd ); + InterlockedCompareExchangePointer( (void **)&capture_window, 0, data->hwnd ); release_native_window( data ); HeapFree( GetProcessHeap(), 0, data ); data_map[idx] = NULL; @@ -465,6 +473,12 @@ void register_native_window( HWND hwnd, struct ANativeWindow *win ) NtQueueApcThread( thread, register_native_window_callback, (ULONG_PTR)hwnd, (ULONG_PTR)win, 0 ); } +/* get the capture window stored in the desktop process */ +HWND get_capture_window(void) +{ + return capture_window; +} + static NTSTATUS android_error_to_status( int err ) { switch (err) @@ -861,6 +875,20 @@ static NTSTATUS setWindowParent_ioctl( void *data, DWORD in_size, DWORD out_size return STATUS_SUCCESS; } +static NTSTATUS setCapture_ioctl( void *data, DWORD in_size, DWORD out_size, ULONG_PTR *ret_size ) +{ + struct ioctl_android_set_capture *res = data; + + if (in_size < sizeof(*res)) return STATUS_INVALID_PARAMETER; + + if (res->hdr.hwnd && !get_ioctl_native_win_data( &res->hdr )) return STATUS_INVALID_HANDLE; + + TRACE( "hwnd %08x\n", res->hdr.hwnd ); + + InterlockedExchangePointer( (void **)&capture_window, LongToHandle( res->hdr.hwnd )); + return STATUS_SUCCESS; +} + typedef NTSTATUS (*ioctl_func)( void *in, DWORD in_size, DWORD out_size, ULONG_PTR *ret_size ); static const ioctl_func ioctl_funcs[] = { @@ -874,6 +902,7 @@ static const ioctl_func ioctl_funcs[] = query_ioctl, /* IOCTL_QUERY */ perform_ioctl, /* IOCTL_PERFORM */ setSwapInterval_ioctl, /* IOCTL_SET_SWAP_INT */ + setCapture_ioctl, /* IOCTL_SET_CAPTURE */ }; static NTSTATUS WINAPI ioctl_callback( DEVICE_OBJECT *device, IRP *irp ) @@ -1395,3 +1424,11 @@ int ioctl_set_window_parent( HWND hwnd, HWND parent ) req.parent = parent == GetDesktopWindow() ? 0 : HandleToLong( parent ); return android_ioctl( IOCTL_SET_WINDOW_PARENT, &req, sizeof(req), NULL, NULL ); } + +int ioctl_set_capture( HWND hwnd ) +{ + struct ioctl_android_set_capture req; + + req.hdr.hwnd = HandleToLong( hwnd ); + return android_ioctl( IOCTL_SET_CAPTURE, &req, sizeof(req), NULL, NULL ); +} diff --git a/dlls/wineandroid.drv/window.c b/dlls/wineandroid.drv/window.c index a663505ddcc..a8a16236807 100644 --- a/dlls/wineandroid.drv/window.c +++ b/dlls/wineandroid.drv/window.c @@ -1033,6 +1033,16 @@ void CDECL ANDROID_SetParent( HWND hwnd, HWND parent, HWND old_parent ) } +/*********************************************************************** + * ANDROID_SetCapture + */ +void CDECL ANDROID_SetCapture( HWND hwnd, UINT flags ) +{ + if (!(flags & (GUI_INMOVESIZE | GUI_INMENUMODE))) return; + ioctl_set_capture( hwnd ); +} + + /*********************************************************************** * ANDROID_SetWindowStyle */ diff --git a/dlls/wineandroid.drv/wineandroid.drv.spec b/dlls/wineandroid.drv/wineandroid.drv.spec index 36052419b0e..f8932994808 100644 --- a/dlls/wineandroid.drv/wineandroid.drv.spec +++ b/dlls/wineandroid.drv/wineandroid.drv.spec @@ -9,6 +9,7 @@ @ cdecl CreateWindow(long) ANDROID_CreateWindow @ cdecl DestroyWindow(long) ANDROID_DestroyWindow @ cdecl MsgWaitForMultipleObjectsEx(long ptr long long long) ANDROID_MsgWaitForMultipleObjectsEx +@ cdecl SetCapture(long long) ANDROID_SetCapture @ cdecl SetLayeredWindowAttributes(long long long long) ANDROID_SetLayeredWindowAttributes @ cdecl SetParent(long long long) ANDROID_SetParent @ cdecl SetWindowRgn(long long long) ANDROID_SetWindowRgn