From: Twaik Yont <9674930+twaik@users.noreply.github.com> Move desktop view creation and event pipe setup to a dedicated ioctl. The dispatch thread now creates the pipe and returns the read end to the caller, while keeping the write end locally. This makes ownership of the event path explicit and prepares it to be transferred cleanly through the transport. Also pass the Wine debug channel state together with the request so the dispatch side can preserve the caller's logging configuration. This prepares the event path for the upcoming process split. Signed-off-by: Twaik Yont <9674930+twaik@users.noreply.github.com> --- dlls/wineandroid.drv/android.h | 1 + dlls/wineandroid.drv/device.c | 35 ++++++++++++++++++++++++++++------ dlls/wineandroid.drv/window.c | 22 ++++++++++----------- 3 files changed, 40 insertions(+), 18 deletions(-) diff --git a/dlls/wineandroid.drv/android.h b/dlls/wineandroid.drv/android.h index c79ce31a046..853c8318601 100644 --- a/dlls/wineandroid.drv/android.h +++ b/dlls/wineandroid.drv/android.h @@ -82,6 +82,7 @@ extern UINT ANDROID_OpenGLInit( UINT version, const struct opengl_funcs *opengl_ */ extern void start_android_device(void); +extern void createDesktopView( int *event_source ); extern void register_native_window( HWND hwnd, struct ANativeWindow *win, BOOL client ); extern struct ANativeWindow *create_ioctl_window( HWND hwnd, BOOL opengl ); extern struct ANativeWindow *grab_ioctl_window( struct ANativeWindow *window ); diff --git a/dlls/wineandroid.drv/device.c b/dlls/wineandroid.drv/device.c index fc9fecf231b..fe16634ce67 100644 --- a/dlls/wineandroid.drv/device.c +++ b/dlls/wineandroid.drv/device.c @@ -80,6 +80,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(android); static HWND capture_window; static HWND desktop_window; +int event_sink = -1; static pthread_mutex_t dispatch_ioctl_lock = PTHREAD_MUTEX_INITIALIZER; #define ANDROIDCONTROLTYPE ((ULONG)'A') @@ -87,6 +88,7 @@ static pthread_mutex_t dispatch_ioctl_lock = PTHREAD_MUTEX_INITIALIZER; enum android_ioctl { + IOCTL_CREATE_DESKTOP_VIEW, IOCTL_CREATE_WINDOW, IOCTL_DESTROY_WINDOW, IOCTL_WINDOW_POS_CHANGED, @@ -468,14 +470,32 @@ static jobject load_java_method( JNIEnv* env, jmethodID *method, const char *nam return java_object; } -static void create_desktop_view( JNIEnv* env ) +static int createDesktopView_ioctl( JNIEnv* env, void *data, DWORD in_size, DWORD out_size, ULONG_PTR *ret_size, int *reply_fd ) { + static int event_pipe[2]; static jmethodID method; jobject object; + struct __wine_debug_channel *res = data; - if (!(object = load_java_method( env, &method, "createDesktopView", "()V" ))) return; + if (in_size < sizeof(*res)) return -EINVAL; + + if (event_sink != -1) close(event_sink); + + if (pipe2( event_pipe, O_CLOEXEC | O_NONBLOCK ) == -1) + { + _ERR( "could not create data event pipe\n" ); + return -1; + } + + event_sink = event_pipe[1]; + *reply_fd = event_pipe[0]; + + __wine_dbch_android = *res; // Copy logging levels from client + + if (!(object = load_java_method( env, &method, "createDesktopView", "()V" ))) return -ENOSYS; (*env)->CallVoidMethod( env, object, method ); + return 0; } static int createWindow_ioctl( JNIEnv* env, void *data, DWORD in_size, DWORD out_size, ULONG_PTR *ret_size, int *reply_fd ) @@ -822,6 +842,7 @@ static int setCursor_ioctl( JNIEnv* env, void *data, DWORD in_size, DWORD out_si typedef int (*ioctl_func)( JNIEnv* env, void *in, DWORD in_size, DWORD out_size, ULONG_PTR *ret_size, int *reply_fd ); static const ioctl_func ioctl_funcs[] = { + createDesktopView_ioctl, /* IOCTL_CREATE_DESKTOP_VIEW */ createWindow_ioctl, /* IOCTL_CREATE_WINDOW */ destroyWindow_ioctl, /* IOCTL_DESTROY_WINDOW */ windowPosChanged_ioctl, /* IOCTL_WINDOW_POS_CHANGED */ @@ -994,8 +1015,6 @@ static void *bootstrap_looper_thread( void *arg ) abort(); } - create_desktop_view( env ); - (*java_vm)->DetachCurrentThread( java_vm ); return NULL; } @@ -1004,8 +1023,6 @@ void start_android_device(void) { pthread_t t; - __wine_dbg_get_channel_flags(&__wine_dbch_android); // force lazy init of debug channel flags for use outside Wine thread context - /* Use a temporary bootstrap thread to request the main thread looper * without interfering with the current Wine/JVM execution context * (including register and thread-state assumptions). Actual ioctl @@ -1096,6 +1113,12 @@ static void win_decRef( struct android_native_base_t *base ) InterlockedDecrement( &win->ref ); } +void createDesktopView( int *event_source ) +{ + __wine_dbg_get_channel_flags(&__wine_dbch_android); // force lazy init of debug channel flags for use outside Wine thread context + android_ioctl( IOCTL_CREATE_DESKTOP_VIEW, &__wine_dbch_android, sizeof(__wine_dbch_android), NULL, NULL, event_source ); +} + static int dequeueBuffer( struct ANativeWindow *window, struct ANativeWindowBuffer **buffer, int *fence ) { struct native_win_wrapper *win = (struct native_win_wrapper *)window; diff --git a/dlls/wineandroid.drv/window.c b/dlls/wineandroid.drv/window.c index b3f3aeea955..98a0e3dd066 100644 --- a/dlls/wineandroid.drv/window.c +++ b/dlls/wineandroid.drv/window.c @@ -173,9 +173,11 @@ struct java_event static struct list event_queue = LIST_INIT( event_queue ); static struct java_event *current_event; -static int event_pipe[2]; +static int event_source; static DWORD desktop_tid; +extern int event_sink; + /*********************************************************************** * send_event */ @@ -183,7 +185,7 @@ int send_event( const union event_data *data ) { int res; - if ((res = write( event_pipe[1], data, sizeof(*data) )) != sizeof(*data)) + if ((res = write( event_sink, data, sizeof(*data) )) != sizeof(*data)) { p__android_log_print( ANDROID_LOG_ERROR, "wine", "failed to send event" ); return -1; @@ -343,12 +345,7 @@ static void init_event_queue(void) HANDLE handle; int ret; - if (pipe2( event_pipe, O_CLOEXEC | O_NONBLOCK ) == -1) - { - ERR( "could not create data\n" ); - NtTerminateProcess( 0, 1 ); - } - if (wine_server_fd_to_handle( event_pipe[0], GENERIC_READ | SYNCHRONIZE, 0, &handle )) + if (wine_server_fd_to_handle( event_source, GENERIC_READ | SYNCHRONIZE, 0, &handle )) { ERR( "Can't allocate handle for event fd\n" ); NtTerminateProcess( 0, 1 ); @@ -383,7 +380,7 @@ static void pull_events(void) { if (!(event = malloc( sizeof(*event) ))) break; - res = read( event_pipe[0], &event->data, sizeof(event->data) ); + res = read( event_source, &event->data, sizeof(event->data) ); if (res != sizeof(event->data)) break; list_add_tail( &event_queue, &event->entry ); } @@ -515,7 +512,7 @@ static int process_events( DWORD mask ) next = LIST_ENTRY( event_queue.next, struct java_event, entry ); } current_event = previous; - return list_empty( &event_queue ) && !check_fd_events( event_pipe[0], POLLIN ); + return list_empty( &event_queue ) && !check_fd_events( event_source, POLLIN ); } @@ -531,7 +528,7 @@ static int wait_events( int timeout ) struct pollfd pollfd; int ret; - pollfd.fd = event_pipe[0]; + pollfd.fd = event_source; pollfd.events = POLLIN | POLLHUP; ret = poll( &pollfd, 1, timeout ); if (ret == -1 && errno == EINTR) continue; @@ -1238,8 +1235,9 @@ BOOL has_client_surface( HWND hwnd ) */ BOOL ANDROID_CreateDesktop( const WCHAR *name, UINT width, UINT height ) { - init_event_queue(); start_android_device(); + createDesktopView( &event_source ); + init_event_queue(); /* wait until we receive the surface changed event */ while (!screen_width) { -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10569