[PATCH 0/3] MR10710: wineandroid: prepare ioctl dispatch for Java-only thread execution (part of !10569)
Part of !10569. This series prepares wineandroid ioctl dispatch paths for execution on Java-originated threads that do not have a Wine TEB. It does three things: * pass JNIEnv explicitly through the ioctl dispatch path instead of relying on the global jni_env value in handlers * move native window registration from the APC/unixlib callback path to the direct JNI surface_changed callback on the Android UI thread * make logging in device.c context-aware so the same code remains safe both on Wine threads and on Java-only threads The JNIEnv change is a preparatory refactoring. It does not by itself complete the thread model transition, but it removes one of the major implicit dependencies on Wine thread context and makes follow-up changes smaller and easier to review. Moving native window registration to surface_changed removes another dependency on APC-based execution in the desktop process and puts window attachment on the thread that actually receives the Android surface callbacks. A shared lock is used to serialize registration against ioctl dispatch. Finally, logging in device.c is made context-aware. Upcoming changes will run parts of ioctl dispatch on Java-only threads, where the standard Wine TRACE/WARN/FIXME/ERR macros are unsafe because they depend on Wine TEB state. The local logging wrapper preserves normal Wine logging semantics on Wine threads and falls back to Android logging on non-Wine threads, allowing the existing code to keep using the standard logging macros without invasive per-call-site changes. Taken together, these patches remove several implicit Wine-thread-only assumptions from wineandroid ioctl dispatch code and prepare the path for running more of it directly on Java-side threads. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10710
From: Twaik Yont <9674930+twaik@users.noreply.github.com> Upcoming changes will move parts of ioctl dispatch execution to threads originating purely from the Java/Android side, without a Wine TEB. In such contexts, the standard Wine debug macros (TRACE/WARN/FIXME/ERR) are unsafe, as they rely on TEB-backed state and may crash. Prepare for this by making logging context-aware in device.c without requiring invasive changes across all call sites. Introduce a lightweight helper to detect whether the current thread has a Wine TEB, and use it to route logging accordingly: * on Wine threads, preserve the standard Wine debug behavior * on non-Wine threads, fall back to Android logging via __android_log_print Override TRACE/WARN/FIXME/ERR locally so existing code continues to work unchanged while remaining safe in both execution contexts. Also provide a local wine_dbgstr_rect implementation that avoids dependencies on Wine thread state, and force early initialization of debug channel flags for use outside Wine threads. This keeps logging semantics consistent while allowing ioctl dispatch code to run on Java-only threads without requiring widespread changes. Signed-off-by: Twaik Yont <9674930+twaik@users.noreply.github.com> --- dlls/wineandroid.drv/device.c | 45 +++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/dlls/wineandroid.drv/device.c b/dlls/wineandroid.drv/device.c index 0032224560d..5315af13747 100644 --- a/dlls/wineandroid.drv/device.c +++ b/dlls/wineandroid.drv/device.c @@ -46,6 +46,50 @@ #include <dlfcn.h> +BOOL __is_wine_thread(void) +{ + static __thread signed char cached = -1; + + if (cached == -1) + cached = NtCurrentTeb() ? 1 : 0; + + return cached ? TRUE : FALSE; +} + +static inline const char *_wine_dbgstr_rect( const RECT *rect ) +{ + enum { N = 4 }; + static __thread char buf[N][64]; + static __thread int idx; + char *ret = buf[idx++ % N]; + + if (!rect) return "(null)"; + snprintf( ret, 64, "(%d,%d)-(%d,%d)", (int)rect->left, (int)rect->top, (int)rect->right, (int)rect->bottom ); + return ret; +} + +#undef TRACE +#undef WARN +#undef FIXME +#undef ERR + +#define __LOG(cls, prio, fmt, ...) \ + do { \ + if (__is_wine_thread()) \ + WINE ## cls (fmt, ##__VA_ARGS__); \ + else if (!(__wine_dbch_android.flags & (1 << __WINE_DBCL_INIT)) || \ + __WINE_GET_DEBUGGING(cls, &__wine_dbch_android)) \ + p__android_log_print(ANDROID_LOG_##prio, "wineandroid.drv", "%s: " fmt, __FUNCTION__, ##__VA_ARGS__); \ + } while (0) + +#define TRACE(...) __LOG(_TRACE, VERBOSE, __VA_ARGS__) +#define WARN(...) __LOG(_WARN, WARN, __VA_ARGS__) +#define FIXME(...) __LOG(_FIXME, WARN, "FIXME: " __VA_ARGS__) +#define ERR(...) __LOG(_ERR, ERROR, __VA_ARGS__) + +#define wine_dbgstr_rect _wine_dbgstr_rect + + WINE_DEFAULT_DEBUG_CHANNEL(android); #ifndef SYNC_IOC_WAIT @@ -1032,6 +1076,7 @@ void start_android_device(void) void *ret_ptr; ULONG ret_len; struct dispatch_callback_params params = {.callback = start_device_callback}; + __wine_dbg_get_channel_flags(&__wine_dbch_android); // force lazy init of debug channel flags for use outside Wine thread context if (KeUserDispatchCallback( ¶ms, sizeof(params), &ret_ptr, &ret_len )) return; if (ret_len == sizeof(thread)) thread = *(HANDLE *)ret_ptr; } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10710
From: Twaik Yont <9674930+twaik@users.noreply.github.com> Move native window registration from the APC/unixlib callback path to the direct JNI surface_changed callback, so it runs on the Android UI thread. Replace the APC-based register_window_callback mechanism with a direct call to register_native_window(), and remove the associated unixlib plumbing. Serialize native window registration with ioctl dispatch using a shared lock to avoid races between the GUI thread and the ioctl handling thread. Keep WM_ANDROID_REFRESH posted from process_events() after updating the window state. This removes the dependency on the Wine thread/APC execution path for this callback and relocates it to the Android GUI thread. Signed-off-by: Twaik Yont <9674930+twaik@users.noreply.github.com> --- dlls/wineandroid.drv/android.h | 3 --- dlls/wineandroid.drv/device.c | 33 ++++++++++++++------------------- dlls/wineandroid.drv/dllmain.c | 13 +------------ dlls/wineandroid.drv/init.c | 6 +----- dlls/wineandroid.drv/unixlib.h | 17 ----------------- dlls/wineandroid.drv/window.c | 13 +++++++------ 6 files changed, 23 insertions(+), 62 deletions(-) diff --git a/dlls/wineandroid.drv/android.h b/dlls/wineandroid.drv/android.h index 0bd25de8e9e..f30cf849c41 100644 --- a/dlls/wineandroid.drv/android.h +++ b/dlls/wineandroid.drv/android.h @@ -119,8 +119,6 @@ extern BOOL has_client_surface( HWND hwnd ); extern NTSTATUS android_dispatch_ioctl( void *arg ); extern NTSTATUS android_java_init( void *arg ); extern NTSTATUS android_java_uninit( void *arg ); -extern NTSTATUS android_register_window( void *arg ); -extern PNTAPCFUNC register_window_callback; extern UINT64 start_device_callback; extern unsigned int screen_width; @@ -175,7 +173,6 @@ union event_data { enum event_type type; HWND hwnd; - ANativeWindow *window; BOOL client; unsigned int width; unsigned int height; diff --git a/dlls/wineandroid.drv/device.c b/dlls/wineandroid.drv/device.c index 5315af13747..5b4e5c0fd5c 100644 --- a/dlls/wineandroid.drv/device.c +++ b/dlls/wineandroid.drv/device.c @@ -101,6 +101,8 @@ static JNIEnv *jni_env; static HWND capture_window; static HWND desktop_window; +static pthread_mutex_t dispatch_ioctl_lock = PTHREAD_MUTEX_INITIALIZER; + #define ANDROIDCONTROLTYPE ((ULONG)'A') #define ANDROID_IOCTL(n) CTL_CODE(ANDROIDCONTROLTYPE, n, METHOD_BUFFERED, FILE_READ_ACCESS) @@ -473,41 +475,32 @@ static struct native_win_data *create_native_win_data( HWND hwnd, BOOL opengl ) return data; } -NTSTATUS android_register_window( void *arg ) +/* register a native window received from the UI thread for use in ioctls */ +void register_native_window( HWND hwnd, struct ANativeWindow *win, BOOL opengl ) { - struct register_window_params *params = arg; - HWND hwnd = (HWND)params->arg1; - struct ANativeWindow *win = (struct ANativeWindow *)params->arg2; - BOOL opengl = params->arg3; - struct native_win_data *data = get_native_win_data( hwnd, opengl ); + struct native_win_data *data = NULL; + + pthread_mutex_lock(&dispatch_ioctl_lock); + data = get_native_win_data( hwnd, opengl ); - if (!win) return 0; /* do nothing and hold on to the window until we get a new surface */ + if (!win) goto end; /* do nothing and hold on to the window until we get a new surface */ if (!data || data->parent == win) { pANativeWindow_release( win ); - if (data) NtUserPostMessage( hwnd, WM_ANDROID_REFRESH, opengl, 0 ); TRACE( "%p -> %p win %p (unchanged)\n", hwnd, data, win ); - return 0; + goto end; } release_native_window( data ); data->parent = win; data->generation++; - wrap_java_call(); if (data->api) win->perform( win, NATIVE_WINDOW_API_CONNECT, data->api ); win->perform( win, NATIVE_WINDOW_SET_BUFFERS_FORMAT, data->buffer_format ); win->setSwapInterval( win, data->swap_interval ); - unwrap_java_call(); - NtUserPostMessage( hwnd, WM_ANDROID_REFRESH, opengl, 0 ); TRACE( "%p -> %p win %p\n", hwnd, data, win ); - return 0; -} - -/* register a native window received from the Java side for use in ioctls */ -void register_native_window( HWND hwnd, struct ANativeWindow *win, BOOL opengl ) -{ - NtQueueApcThread( thread, register_window_callback, (ULONG_PTR)hwnd, (ULONG_PTR)win, opengl ); +end: + pthread_mutex_unlock(&dispatch_ioctl_lock); } /* get the capture window stored in the desktop process */ @@ -1038,9 +1031,11 @@ NTSTATUS android_dispatch_ioctl( void *arg ) if (in_size >= sizeof(*header)) { irp->IoStatus.Information = 0; + pthread_mutex_lock(&dispatch_ioctl_lock); irp->IoStatus.Status = func( irp->AssociatedIrp.SystemBuffer, in_size, irpsp->Parameters.DeviceIoControl.OutputBufferLength, &irp->IoStatus.Information ); + pthread_mutex_unlock(&dispatch_ioctl_lock); } else irp->IoStatus.Status = STATUS_INVALID_PARAMETER; } diff --git a/dlls/wineandroid.drv/dllmain.c b/dlls/wineandroid.drv/dllmain.c index 7f6d04e83df..dd2493c6f55 100644 --- a/dlls/wineandroid.drv/dllmain.c +++ b/dlls/wineandroid.drv/dllmain.c @@ -90,26 +90,15 @@ static NTSTATUS WINAPI android_start_device(void *param, ULONG size) } -static void CALLBACK register_window_callback( ULONG_PTR arg1, ULONG_PTR arg2, ULONG_PTR arg3 ) -{ - struct register_window_params params = { .arg1 = arg1, .arg2 = arg2, .arg3 = arg3 }; - ANDROID_CALL( register_window, ¶ms ); -} - - /*********************************************************************** * dll initialisation routine */ BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, LPVOID reserved ) { - struct init_params params; - if (reason != DLL_PROCESS_ATTACH) return TRUE; DisableThreadLibraryCalls( inst ); if (__wine_init_unix_call()) return FALSE; - params.register_window_callback = register_window_callback; - params.start_device_callback = (UINT_PTR)android_start_device; - return !ANDROID_CALL( init, ¶ms ); + return !ANDROID_CALL( init, (void *)(UINT_PTR)android_start_device ); } diff --git a/dlls/wineandroid.drv/init.c b/dlls/wineandroid.drv/init.c index 0dbd6c11785..8e6c700870a 100644 --- a/dlls/wineandroid.drv/init.c +++ b/dlls/wineandroid.drv/init.c @@ -50,7 +50,6 @@ static const unsigned int screen_bpp = 32; /* we don't support other modes */ static RECT monitor_rc_work; static int device_init_done; -PNTAPCFUNC register_window_callback; UINT64 start_device_callback; typedef struct @@ -386,7 +385,6 @@ static void load_android_libs(void) static HRESULT android_init( void *arg ) { - struct init_params *params = arg; pthread_mutexattr_t attr; jclass class; JNIEnv *jni_env; @@ -398,8 +396,7 @@ static HRESULT android_init( void *arg ) pthread_mutex_init( &win_data_mutex, &attr ); pthread_mutexattr_destroy( &attr ); - register_window_callback = params->register_window_callback; - start_device_callback = params->start_device_callback; + start_device_callback = (UINT64)(UINT_PTR)arg; if (java_vm) /* running under Java */ { @@ -426,7 +423,6 @@ const unixlib_entry_t __wine_unix_call_funcs[] = android_init, android_java_init, android_java_uninit, - android_register_window, }; diff --git a/dlls/wineandroid.drv/unixlib.h b/dlls/wineandroid.drv/unixlib.h index 39a4df58283..7549541e48e 100644 --- a/dlls/wineandroid.drv/unixlib.h +++ b/dlls/wineandroid.drv/unixlib.h @@ -25,24 +25,7 @@ enum android_funcs unix_init, unix_java_init, unix_java_uninit, - unix_register_window, unix_funcs_count }; #define ANDROID_CALL(func, params) WINE_UNIX_CALL( unix_ ## func, params ) - -/* android_init params */ -struct init_params -{ - PNTAPCFUNC register_window_callback; - UINT64 start_device_callback; -}; - - -/* android_register_window params */ -struct register_window_params -{ - UINT_PTR arg1; - UINT_PTR arg2; - UINT_PTR arg3; -}; diff --git a/dlls/wineandroid.drv/window.c b/dlls/wineandroid.drv/window.c index 97eb3004ba8..b3f3aeea955 100644 --- a/dlls/wineandroid.drv/window.c +++ b/dlls/wineandroid.drv/window.c @@ -246,11 +246,12 @@ void surface_changed( JNIEnv *env, jobject obj, jint win, jobject surface, jbool if (win->query( win, NATIVE_WINDOW_WIDTH, &width ) < 0) width = 0; if (win->query( win, NATIVE_WINDOW_HEIGHT, &height ) < 0) height = 0; - data.surface.window = win; data.surface.width = width; data.surface.height = height; - p__android_log_print( ANDROID_LOG_INFO, "wine", "surface_changed: %p %s %ux%u", - data.surface.hwnd, client ? "client" : "whole", width, height ); + p__android_log_print( ANDROID_LOG_INFO, "wine", "surface_changed: %p %p %s %ux%u", + data.surface.hwnd, win, client ? "client" : "whole", width, height ); + + register_native_window( data.surface.hwnd, win, data.surface.client ); } data.type = SURFACE_CHANGED; send_event( &data ); @@ -452,11 +453,11 @@ static int process_events( DWORD mask ) break; case SURFACE_CHANGED: - TRACE("SURFACE_CHANGED %p %p %s size %ux%u\n", event->data.surface.hwnd, - event->data.surface.window, event->data.surface.client ? "client" : "whole", + TRACE("SURFACE_CHANGED %p %s size %ux%u\n", event->data.surface.hwnd, + event->data.surface.client ? "client" : "whole", event->data.surface.width, event->data.surface.height ); - register_native_window( event->data.surface.hwnd, event->data.surface.window, event->data.surface.client ); + NtUserPostMessage( event->data.surface.hwnd, WM_ANDROID_REFRESH, event->data.surface.client, 0 ); break; case MOTION_EVENT: -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10710
From: Twaik Yont <9674930+twaik@users.noreply.github.com> Pass JNIEnv *env explicitly through the ioctl dispatch path and all ioctl handlers, and stop relying on the global jni_env variable in these code paths. Update all JNI call sites in the ioctl dispatch and related functions to use the passed env parameter, including method lookup and CallVoidMethod invocations, aligning these JNI interaction paths with the canonical usage pattern where JNIEnv is strictly per-thread and not stored globally. Other uses of the global jni_env remain and will be addressed in follow-up changes, so this is a preparatory refactoring, not the final thread-safety fix. This change is mechanically large but does not introduce functional changes, and is kept separate to simplify review of subsequent changes. Signed-off-by: Twaik Yont <9674930+twaik@users.noreply.github.com> --- dlls/wineandroid.drv/device.c | 88 +++++++++++++++++------------------ 1 file changed, 44 insertions(+), 44 deletions(-) diff --git a/dlls/wineandroid.drv/device.c b/dlls/wineandroid.drv/device.c index 5b4e5c0fd5c..0a4b24acae6 100644 --- a/dlls/wineandroid.drv/device.c +++ b/dlls/wineandroid.drv/device.c @@ -261,12 +261,12 @@ static inline BOOL is_in_desktop_process(void) static WORD orig_fs, java_fs; static inline void wrap_java_call(void) { __asm__( "mov %0,%%fs" :: "r" (java_fs) ); } static inline void unwrap_java_call(void) { __asm__( "mov %0,%%fs" :: "r" (orig_fs) ); } -static inline void init_java_thread( JavaVM *java_vm ) +static inline void init_java_thread( JavaVM *java_vm, JNIEnv** env ) { java_fs = java_gdt_sel; __asm__( "mov %%fs,%0" : "=r" (orig_fs) ); __asm__( "mov %0,%%fs" :: "r" (java_fs) ); - (*java_vm)->AttachCurrentThread( java_vm, &jni_env, 0 ); + (*java_vm)->AttachCurrentThread( java_vm, env, 0 ); if (!java_gdt_sel) __asm__( "mov %%fs,%0" : "=r" (java_fs) ); __asm__( "mov %0,%%fs" :: "r" (orig_fs) ); } @@ -279,10 +279,10 @@ static void *orig_teb, *java_teb; static inline int arch_prctl( int func, void *ptr ) { return syscall( __NR_arch_prctl, func, ptr ); } static inline void wrap_java_call(void) { arch_prctl( ARCH_SET_GS, java_teb ); } static inline void unwrap_java_call(void) { arch_prctl( ARCH_SET_GS, orig_teb ); } -static inline void init_java_thread( JavaVM *java_vm ) +static inline void init_java_thread( JavaVM *java_vm, JNIEnv** env ) { arch_prctl( ARCH_GET_GS, &orig_teb ); - (*java_vm)->AttachCurrentThread( java_vm, &jni_env, 0 ); + (*java_vm)->AttachCurrentThread( java_vm, env, 0 ); arch_prctl( ARCH_GET_GS, &java_teb ); arch_prctl( ARCH_SET_GS, orig_teb ); } @@ -290,7 +290,7 @@ static inline void init_java_thread( JavaVM *java_vm ) #else static inline void wrap_java_call(void) { } static inline void unwrap_java_call(void) { } -static inline void init_java_thread( JavaVM *java_vm ) { (*java_vm)->AttachCurrentThread( java_vm, &jni_env, 0 ); } +static inline void init_java_thread( JavaVM *java_vm, JNIEnv** env ) { (*java_vm)->AttachCurrentThread( java_vm, env, 0 ); } #endif /* __i386__ */ static struct native_win_data *data_map[65536]; @@ -556,15 +556,15 @@ static int status_to_android_error( unsigned int status ) } } -static jobject load_java_method( jmethodID *method, const char *name, const char *args ) +static jobject load_java_method( JNIEnv* env, jmethodID *method, const char *name, const char *args ) { if (!*method) { jclass class; wrap_java_call(); - class = (*jni_env)->GetObjectClass( jni_env, java_object ); - *method = (*jni_env)->GetMethodID( jni_env, class, name, args ); + class = (*env)->GetObjectClass( env, java_object ); + *method = (*env)->GetMethodID( env, class, name, args ); unwrap_java_call(); if (!*method) { @@ -575,19 +575,19 @@ static jobject load_java_method( jmethodID *method, const char *name, const char return java_object; } -static void create_desktop_view(void) +static void create_desktop_view( JNIEnv* env ) { static jmethodID method; jobject object; - if (!(object = load_java_method( &method, "createDesktopView", "()V" ))) return; + if (!(object = load_java_method( env, &method, "createDesktopView", "()V" ))) return; wrap_java_call(); - (*jni_env)->CallVoidMethod( jni_env, object, method ); + (*env)->CallVoidMethod( env, object, method ); unwrap_java_call(); } -static NTSTATUS createWindow_ioctl( void *data, DWORD in_size, DWORD out_size, ULONG_PTR *ret_size ) +static NTSTATUS createWindow_ioctl( JNIEnv* env, void *data, DWORD in_size, DWORD out_size, ULONG_PTR *ret_size ) { static jmethodID method; jobject object; @@ -601,15 +601,15 @@ static NTSTATUS createWindow_ioctl( void *data, DWORD in_size, DWORD out_size, U TRACE( "hwnd %08x opengl %u parent %08x\n", res->hdr.hwnd, res->hdr.opengl, res->parent ); - if (!(object = load_java_method( &method, "createWindow", "(IZZI)V" ))) return STATUS_NOT_SUPPORTED; + if (!(object = load_java_method( env, &method, "createWindow", "(IZZI)V" ))) return STATUS_NOT_SUPPORTED; wrap_java_call(); - (*jni_env)->CallVoidMethod( jni_env, object, method, res->hdr.hwnd, res->is_desktop, res->hdr.opengl, res->parent ); + (*env)->CallVoidMethod( env, object, method, res->hdr.hwnd, res->is_desktop, res->hdr.opengl, res->parent ); unwrap_java_call(); return STATUS_SUCCESS; } -static NTSTATUS destroyWindow_ioctl( void *data, DWORD in_size, DWORD out_size, ULONG_PTR *ret_size ) +static NTSTATUS destroyWindow_ioctl( JNIEnv* env, void *data, DWORD in_size, DWORD out_size, ULONG_PTR *ret_size ) { static jmethodID method; jobject object; @@ -622,16 +622,16 @@ static NTSTATUS destroyWindow_ioctl( void *data, DWORD in_size, DWORD out_size, TRACE( "hwnd %08x opengl %u\n", res->hdr.hwnd, res->hdr.opengl ); - if (!(object = load_java_method( &method, "destroyWindow", "(I)V" ))) return STATUS_NOT_SUPPORTED; + if (!(object = load_java_method( env, &method, "destroyWindow", "(I)V" ))) return STATUS_NOT_SUPPORTED; wrap_java_call(); - (*jni_env)->CallVoidMethod( jni_env, object, method, res->hdr.hwnd ); + (*env)->CallVoidMethod( env, object, method, res->hdr.hwnd ); unwrap_java_call(); if (win_data) free_native_win_data( win_data ); return STATUS_SUCCESS; } -static NTSTATUS windowPosChanged_ioctl( void *data, DWORD in_size, DWORD out_size, ULONG_PTR *ret_size ) +static NTSTATUS windowPosChanged_ioctl( JNIEnv* env, void *data, DWORD in_size, DWORD out_size, ULONG_PTR *ret_size ) { static jmethodID method; jobject object; @@ -643,19 +643,19 @@ static NTSTATUS windowPosChanged_ioctl( void *data, DWORD in_size, DWORD out_siz res->hdr.hwnd, wine_dbgstr_rect(&res->window_rect), wine_dbgstr_rect(&res->client_rect), wine_dbgstr_rect(&res->visible_rect), res->style, res->flags, res->after, res->owner ); - if (!(object = load_java_method( &method, "windowPosChanged", "(IIIIIIIIIIIIIIIII)V" ))) + if (!(object = load_java_method( env, &method, "windowPosChanged", "(IIIIIIIIIIIIIIIII)V" ))) return STATUS_NOT_SUPPORTED; wrap_java_call(); - (*jni_env)->CallVoidMethod( jni_env, object, method, res->hdr.hwnd, res->flags, res->after, res->owner, res->style, - res->window_rect.left, res->window_rect.top, res->window_rect.right, res->window_rect.bottom, - res->client_rect.left, res->client_rect.top, res->client_rect.right, res->client_rect.bottom, - res->visible_rect.left, res->visible_rect.top, res->visible_rect.right, res->visible_rect.bottom ); + (*env)->CallVoidMethod( env, object, method, res->hdr.hwnd, res->flags, res->after, res->owner, res->style, + res->window_rect.left, res->window_rect.top, res->window_rect.right, res->window_rect.bottom, + res->client_rect.left, res->client_rect.top, res->client_rect.right, res->client_rect.bottom, + res->visible_rect.left, res->visible_rect.top, res->visible_rect.right, res->visible_rect.bottom ); unwrap_java_call(); return STATUS_SUCCESS; } -static NTSTATUS dequeueBuffer_ioctl( void *data, DWORD in_size, DWORD out_size, ULONG_PTR *ret_size ) +static NTSTATUS dequeueBuffer_ioctl( JNIEnv* env, void *data, DWORD in_size, DWORD out_size, ULONG_PTR *ret_size ) { struct ANativeWindow *parent; struct ioctl_android_dequeueBuffer *res = data; @@ -754,7 +754,7 @@ static NTSTATUS dequeueBuffer_ioctl( void *data, DWORD in_size, DWORD out_size, return STATUS_SUCCESS; } -static NTSTATUS cancelBuffer_ioctl( void *data, DWORD in_size, DWORD out_size, ULONG_PTR *ret_size ) +static NTSTATUS cancelBuffer_ioctl( JNIEnv* env, void *data, DWORD in_size, DWORD out_size, ULONG_PTR *ret_size ) { struct ioctl_android_cancelBuffer *res = data; struct ANativeWindow *parent; @@ -777,7 +777,7 @@ static NTSTATUS cancelBuffer_ioctl( void *data, DWORD in_size, DWORD out_size, U return android_error_to_status( ret ); } -static NTSTATUS queueBuffer_ioctl( void *data, DWORD in_size, DWORD out_size, ULONG_PTR *ret_size ) +static NTSTATUS queueBuffer_ioctl( JNIEnv* env, void *data, DWORD in_size, DWORD out_size, ULONG_PTR *ret_size ) { struct ioctl_android_queueBuffer *res = data; struct ANativeWindow *parent; @@ -800,7 +800,7 @@ static NTSTATUS queueBuffer_ioctl( void *data, DWORD in_size, DWORD out_size, UL return android_error_to_status( ret ); } -static NTSTATUS query_ioctl( void *data, DWORD in_size, DWORD out_size, ULONG_PTR *ret_size ) +static NTSTATUS query_ioctl( JNIEnv* env, void *data, DWORD in_size, DWORD out_size, ULONG_PTR *ret_size ) { struct ioctl_android_query *res = data; struct ANativeWindow *parent; @@ -820,7 +820,7 @@ 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 ) +static NTSTATUS perform_ioctl( JNIEnv* env, void *data, DWORD in_size, DWORD out_size, ULONG_PTR *ret_size ) { struct ioctl_android_perform *res = data; struct ANativeWindow *parent; @@ -907,7 +907,7 @@ static NTSTATUS perform_ioctl( void *data, DWORD in_size, DWORD out_size, ULONG_ return android_error_to_status( ret ); } -static NTSTATUS setSwapInterval_ioctl( void *data, DWORD in_size, DWORD out_size, ULONG_PTR *ret_size ) +static NTSTATUS setSwapInterval_ioctl( JNIEnv* env, void *data, DWORD in_size, DWORD out_size, ULONG_PTR *ret_size ) { struct ioctl_android_set_swap_interval *res = data; struct ANativeWindow *parent; @@ -926,7 +926,7 @@ static NTSTATUS setSwapInterval_ioctl( void *data, DWORD in_size, DWORD out_size return android_error_to_status( ret ); } -static NTSTATUS setWindowParent_ioctl( void *data, DWORD in_size, DWORD out_size, ULONG_PTR *ret_size ) +static NTSTATUS setWindowParent_ioctl( JNIEnv* env, void *data, DWORD in_size, DWORD out_size, ULONG_PTR *ret_size ) { static jmethodID method; jobject object; @@ -939,15 +939,15 @@ static NTSTATUS setWindowParent_ioctl( void *data, DWORD in_size, DWORD out_size TRACE( "hwnd %08x parent %08x\n", res->hdr.hwnd, res->parent ); - if (!(object = load_java_method( &method, "setParent", "(II)V" ))) return STATUS_NOT_SUPPORTED; + if (!(object = load_java_method( env, &method, "setParent", "(II)V" ))) return STATUS_NOT_SUPPORTED; wrap_java_call(); - (*jni_env)->CallVoidMethod( jni_env, object, method, res->hdr.hwnd, res->parent ); + (*env)->CallVoidMethod( env, object, method, res->hdr.hwnd, res->parent ); unwrap_java_call(); return STATUS_SUCCESS; } -static NTSTATUS setCapture_ioctl( void *data, DWORD in_size, DWORD out_size, ULONG_PTR *ret_size ) +static NTSTATUS setCapture_ioctl( JNIEnv* env, void *data, DWORD in_size, DWORD out_size, ULONG_PTR *ret_size ) { struct ioctl_android_set_capture *res = data; @@ -961,7 +961,7 @@ static NTSTATUS setCapture_ioctl( void *data, DWORD in_size, DWORD out_size, ULO return STATUS_SUCCESS; } -static NTSTATUS setCursor_ioctl( void *data, DWORD in_size, DWORD out_size, ULONG_PTR *ret_size ) +static NTSTATUS setCursor_ioctl( JNIEnv* env, void *data, DWORD in_size, DWORD out_size, ULONG_PTR *ret_size ) { static jmethodID method; jobject object; @@ -979,27 +979,27 @@ static NTSTATUS setCursor_ioctl( void *data, DWORD in_size, DWORD out_size, ULON TRACE( "hwnd %08x size %d\n", res->hdr.hwnd, size ); - if (!(object = load_java_method( &method, "setCursor", "(IIIII[I)V" ))) + if (!(object = load_java_method( env, &method, "setCursor", "(IIIII[I)V" ))) return STATUS_NOT_SUPPORTED; wrap_java_call(); if (size) { - jintArray array = (*jni_env)->NewIntArray( jni_env, size ); - (*jni_env)->SetIntArrayRegion( jni_env, array, 0, size, (jint *)res->bits ); - (*jni_env)->CallVoidMethod( jni_env, object, method, 0, res->width, res->height, + jintArray array = (*env)->NewIntArray( env, size ); + (*env)->SetIntArrayRegion( env, array, 0, size, (jint *)res->bits ); + (*env)->CallVoidMethod( env, object, method, 0, res->width, res->height, res->hotspotx, res->hotspoty, array ); - (*jni_env)->DeleteLocalRef( jni_env, array ); + (*env)->DeleteLocalRef( env, array ); } - else (*jni_env)->CallVoidMethod( jni_env, object, method, res->id, 0, 0, 0, 0, NULL ); + else (*env)->CallVoidMethod( env, object, method, res->id, 0, 0, 0, 0, NULL ); unwrap_java_call(); return STATUS_SUCCESS; } -typedef NTSTATUS (*ioctl_func)( void *in, DWORD in_size, DWORD out_size, ULONG_PTR *ret_size ); +typedef NTSTATUS (*ioctl_func)( JNIEnv* env, void *in, DWORD in_size, DWORD out_size, ULONG_PTR *ret_size ); static const ioctl_func ioctl_funcs[] = { createWindow_ioctl, /* IOCTL_CREATE_WINDOW */ @@ -1032,7 +1032,7 @@ NTSTATUS android_dispatch_ioctl( void *arg ) { irp->IoStatus.Information = 0; pthread_mutex_lock(&dispatch_ioctl_lock); - irp->IoStatus.Status = func( irp->AssociatedIrp.SystemBuffer, in_size, + irp->IoStatus.Status = func( jni_env, irp->AssociatedIrp.SystemBuffer, in_size, irpsp->Parameters.DeviceIoControl.OutputBufferLength, &irp->IoStatus.Information ); pthread_mutex_unlock(&dispatch_ioctl_lock); @@ -1051,8 +1051,8 @@ NTSTATUS android_java_init( void *arg ) { if (!java_vm) return STATUS_UNSUCCESSFUL; /* not running under Java */ - init_java_thread( java_vm ); - create_desktop_view(); + init_java_thread( java_vm, &jni_env ); + create_desktop_view( jni_env ); return STATUS_SUCCESS; } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10710
participants (2)
-
Twaik Yont -
Twaik Yont (@twaik)