From fd06292d4a208cbd613f4bdce7cae12e075e70ec Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Thu, 5 Jul 2012 14:32:00 +0200 Subject: NativeWindow/Newt X11ErrorHandler enhancement / unification - don't throw exceptions. Handles also XAWT BadMatch X_SetInputFocus. X11ErrorHandler code now dumps proper information about the opcode and error message and the running Java thread. Having propery "nativewindow.debug.X11Util.XErrorStackDump" or "nativewindow.debug=all' set, a stack trace is dumped. Since the X11ErrorHandler may catch an XAWT error: BadMatch X_SetInputFocus, we cannot throw an exception and better keep running. --- src/newt/native/NewtCommon.h | 1 + 1 file changed, 1 insertion(+) (limited to 'src/newt/native/NewtCommon.h') diff --git a/src/newt/native/NewtCommon.h b/src/newt/native/NewtCommon.h index f5ca73b74..9a4e5ac70 100644 --- a/src/newt/native/NewtCommon.h +++ b/src/newt/native/NewtCommon.h @@ -34,6 +34,7 @@ void NewtCommon_init(JNIEnv *env); +const char * NewtCommon_GetStaticStringMethod(JNIEnv *jniEnv, jclass clazz, jmethodID jGetStrID, char *dest, int destSize, const char *altText); jchar* NewtCommon_GetNullTerminatedStringChars(JNIEnv* env, jstring str); void NewtCommon_FatalError(JNIEnv *env, const char* msg, ...); -- cgit v1.2.3 From 64fd6eef879f7453b491a9df421faf2d47da9d7f Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Mon, 8 Apr 2013 02:48:57 +0200 Subject: NEWT/Native: NewtCommon_GetJNIEnv(..) adding 'asDaemon' flag, used by all OSX JNI attachments to save time since detachment is skipped. --- src/newt/native/NewtCommon.c | 9 +++++-- src/newt/native/NewtCommon.h | 2 +- src/newt/native/NewtMacWindow.m | 54 ++++++++++++++++++++--------------------- 3 files changed, 35 insertions(+), 30 deletions(-) (limited to 'src/newt/native/NewtCommon.h') diff --git a/src/newt/native/NewtCommon.c b/src/newt/native/NewtCommon.c index 7f070e7d3..c294b6e0b 100644 --- a/src/newt/native/NewtCommon.c +++ b/src/newt/native/NewtCommon.c @@ -72,7 +72,7 @@ jchar* NewtCommon_GetNullTerminatedStringChars(JNIEnv* env, jstring str) return strChars; } -JNIEnv* NewtCommon_GetJNIEnv(JavaVM * jvmHandle, int jvmVersion, int * shallBeDetached) { +JNIEnv* NewtCommon_GetJNIEnv(JavaVM * jvmHandle, int jvmVersion, int asDaemon, int * shallBeDetached) { JNIEnv* curEnv = NULL; JNIEnv* newEnv = NULL; int envRes; @@ -81,7 +81,12 @@ JNIEnv* NewtCommon_GetJNIEnv(JavaVM * jvmHandle, int jvmVersion, int * shallBeDe envRes = (*jvmHandle)->GetEnv(jvmHandle, (void **) &curEnv, jvmVersion) ; if( JNI_EDETACHED == envRes ) { // detached thread - attach to JVM - if( JNI_OK != ( envRes = (*jvmHandle)->AttachCurrentThread(jvmHandle, (void**) &newEnv, NULL) ) ) { + if( asDaemon ) { + envRes = (*jvmHandle)->AttachCurrentThreadAsDaemon(jvmHandle, (void**) &newEnv, NULL); + } else { + envRes = (*jvmHandle)->AttachCurrentThread(jvmHandle, (void**) &newEnv, NULL); + } + if( JNI_OK != envRes ) { fprintf(stderr, "JNIEnv: can't attach thread: %d\n", envRes); return NULL; } diff --git a/src/newt/native/NewtCommon.h b/src/newt/native/NewtCommon.h index 9a4e5ac70..9cc9e93a6 100644 --- a/src/newt/native/NewtCommon.h +++ b/src/newt/native/NewtCommon.h @@ -76,6 +76,6 @@ void NewtCommon_throwNewRuntimeException(JNIEnv *env, const char* msg, ...); (*jvmHandle)->DetachCurrentThread(jvmHandle); } */ -JNIEnv* NewtCommon_GetJNIEnv (JavaVM * jvmHandle, int jvmVersion, int * shallBeDetached); +JNIEnv* NewtCommon_GetJNIEnv (JavaVM * jvmHandle, int jvmVersion, int asDaemon, int * shallBeDetached); #endif diff --git a/src/newt/native/NewtMacWindow.m b/src/newt/native/NewtMacWindow.m index d7b357349..6e8721a33 100644 --- a/src/newt/native/NewtMacWindow.m +++ b/src/newt/native/NewtMacWindow.m @@ -286,7 +286,7 @@ static jmethodID windowRepaintID = NULL; return; } int shallBeDetached = 0; - JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, jvmVersion, &shallBeDetached); + JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, jvmVersion, 1 /* asDaemon */, &shallBeDetached); if(NULL==env) { DBG_PRINT("drawRect: null JNIEnv\n"); return; @@ -298,9 +298,9 @@ static jmethodID windowRepaintID = NULL; dirtyRect.origin.x, viewFrame.size.height - dirtyRect.origin.y, dirtyRect.size.width, dirtyRect.size.height); - if (shallBeDetached) { + /* if (shallBeDetached) { (*jvmHandle)->DetachCurrentThread(jvmHandle); - } + } */ } - (void) viewDidHide @@ -310,7 +310,7 @@ static jmethodID windowRepaintID = NULL; return; } int shallBeDetached = 0; - JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, jvmVersion, &shallBeDetached); + JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, jvmVersion, 1 /* asDaemon */, &shallBeDetached); if(NULL==env) { DBG_PRINT("viewDidHide: null JNIEnv\n"); return; @@ -318,9 +318,9 @@ static jmethodID windowRepaintID = NULL; (*env)->CallVoidMethod(env, javaWindowObject, visibleChangedID, JNI_FALSE, JNI_FALSE); - if (shallBeDetached) { + /* if (shallBeDetached) { (*jvmHandle)->DetachCurrentThread(jvmHandle); - } + } */ [super viewDidHide]; } @@ -332,7 +332,7 @@ static jmethodID windowRepaintID = NULL; return; } int shallBeDetached = 0; - JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, jvmVersion, &shallBeDetached); + JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, jvmVersion, 1 /* asDaemon */, &shallBeDetached); if(NULL==env) { DBG_PRINT("viewDidUnhide: null JNIEnv\n"); return; @@ -340,9 +340,9 @@ static jmethodID windowRepaintID = NULL; (*env)->CallVoidMethod(env, javaWindowObject, visibleChangedID, JNI_FALSE, JNI_TRUE); - if (shallBeDetached) { + /* if (shallBeDetached) { (*jvmHandle)->DetachCurrentThread(jvmHandle); - } + } */ [super viewDidUnhide]; } @@ -675,7 +675,7 @@ static jint mods2JavaMods(NSUInteger mods) } int shallBeDetached = 0; JavaVM *jvmHandle = [view getJVMHandle]; - JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], &shallBeDetached); + JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], 1 /* asDaemon */, &shallBeDetached); if(NULL==env) { DBG_PRINT("sendKeyEvent: null JNIEnv\n"); return; @@ -716,9 +716,9 @@ static jint mods2JavaMods(NSUInteger mods) #endif } - if (shallBeDetached) { + /* if (shallBeDetached) { (*jvmHandle)->DetachCurrentThread(jvmHandle); - } + } */ } - (void) sendMouseEvent: (NSEvent*) event eventType: (jshort) evType @@ -735,7 +735,7 @@ static jint mods2JavaMods(NSUInteger mods) } int shallBeDetached = 0; JavaVM *jvmHandle = [view getJVMHandle]; - JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], &shallBeDetached); + JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], 1 /* asDaemon */, &shallBeDetached); if(NULL==env) { DBG_PRINT("sendMouseEvent: null JNIEnv\n"); return; @@ -792,9 +792,9 @@ static jint mods2JavaMods(NSUInteger mods) javaButtonNum, scrollDeltaY); #endif - if (shallBeDetached) { + /* if (shallBeDetached) { (*jvmHandle)->DetachCurrentThread(jvmHandle); - } + } */ } - (void) focusChanged: (BOOL) gained @@ -812,7 +812,7 @@ static jint mods2JavaMods(NSUInteger mods) } int shallBeDetached = 0; JavaVM *jvmHandle = [view getJVMHandle]; - JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], &shallBeDetached); + JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], 1 /* asDaemon */, &shallBeDetached); if(NULL==env) { DBG_PRINT("focusChanged: null JNIEnv\n"); return; @@ -820,9 +820,9 @@ static jint mods2JavaMods(NSUInteger mods) (*env)->CallVoidMethod(env, javaWindowObject, focusChangedID, JNI_FALSE, (gained == YES) ? JNI_TRUE : JNI_FALSE); - if (shallBeDetached) { + /* if (shallBeDetached) { (*jvmHandle)->DetachCurrentThread(jvmHandle); - } + } */ } - (BOOL) becomeFirstResponder @@ -1010,7 +1010,7 @@ static jint mods2JavaMods(NSUInteger mods) javaWindowObject = [view getJavaWindowObject]; if (javaWindowObject != NULL) { jvmHandle = [view getJVMHandle]; - env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], &shallBeDetached); + env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], 1 /* asDaemon */, &shallBeDetached); } } @@ -1025,9 +1025,9 @@ static jint mods2JavaMods(NSUInteger mods) (jint) contentRect.size.width, (jint) contentRect.size.height, JNI_FALSE); - if (shallBeDetached) { + /* if (shallBeDetached) { (*jvmHandle)->DetachCurrentThread(jvmHandle); - } + } */ } } @@ -1045,7 +1045,7 @@ static jint mods2JavaMods(NSUInteger mods) } int shallBeDetached = 0; JavaVM *jvmHandle = [view getJVMHandle]; - JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], &shallBeDetached); + JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], 1 /* asDaemon */, &shallBeDetached); if(NULL==env) { DBG_PRINT("windowDidMove: null JNIEnv\n"); return; @@ -1055,9 +1055,9 @@ static jint mods2JavaMods(NSUInteger mods) p0 = [self getLocationOnScreen: p0]; (*env)->CallVoidMethod(env, javaWindowObject, positionChangedID, JNI_FALSE, (jint) p0.x, (jint) p0.y); - if (shallBeDetached) { + /* if (shallBeDetached) { (*jvmHandle)->DetachCurrentThread(jvmHandle); - } + } */ } - (BOOL)windowShouldClose: (id) sender @@ -1092,7 +1092,7 @@ static jint mods2JavaMods(NSUInteger mods) } int shallBeDetached = 0; JavaVM *jvmHandle = [view getJVMHandle]; - JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], &shallBeDetached); + JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], 1 /* asDaemon */, &shallBeDetached); if(NULL==env) { DBG_PRINT("windowWillClose: null JNIEnv\n"); return NO; @@ -1105,9 +1105,9 @@ static jint mods2JavaMods(NSUInteger mods) [view setDestroyNotifySent: false]; } - if (shallBeDetached) { + /* if (shallBeDetached) { (*jvmHandle)->DetachCurrentThread(jvmHandle); - } + } */ DBG_PRINT( "*************** windowWillClose.X: %p, closed %d\n", (void *)(intptr_t)javaWindowObject, (int)closed); } else { DBG_PRINT( "*************** windowWillClose (skip)\n"); -- cgit v1.2.3 From 6647b4a63866a554c738e0b7b61e6dc40a6fb511 Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Sat, 11 Jan 2014 02:11:47 +0100 Subject: [Jogl|Nativewindow|Newt]Common: Align all *Common_GetJNIEnv()/_ReleaseJNIEnv() Methods and Usage / Check arguments .. Since we still don't use inter-module native code sharing, align the JNIEnv get/release methods and usage. Most beneficary here is OSX and the GLDebugMessageHandle, both managed the JVM handle on their own - removed now. Also ensuring that *Common_init(..) is called for all modules on all platforms. --- src/jogl/native/GLContext.c | 2 +- src/jogl/native/GLDebugMessageHandler.c | 95 ++++--------- src/jogl/native/JoglCommon.c | 97 ++++++------- src/jogl/native/JoglCommon.h | 55 ++++++-- src/jogl/native/libav/ffmpeg_impl_template.c | 4 +- .../macosx/MacOSXWindowSystemInterface-calayer.m | 1 + .../jogamp_opengl_util_av_impl_OMXGLMediaPlayer.c | 5 +- src/nativewindow/native/NativewindowCommon.c | 110 ++++++++++----- src/nativewindow/native/NativewindowCommon.h | 61 ++++++++- src/nativewindow/native/macosx/OSXmisc.m | 34 ++--- src/nativewindow/native/win32/GDImisc.c | 2 +- src/nativewindow/native/x11/Xmisc.c | 126 +++++++---------- src/newt/native/MacWindow.m | 13 +- src/newt/native/NewtCommon.c | 96 +++++++++---- src/newt/native/NewtCommon.h | 26 ++-- src/newt/native/NewtMacWindow.h | 10 -- src/newt/native/NewtMacWindow.m | 152 ++++++--------------- 17 files changed, 431 insertions(+), 458 deletions(-) (limited to 'src/newt/native/NewtCommon.h') diff --git a/src/jogl/native/GLContext.c b/src/jogl/native/GLContext.c index f10d0e421..9be9f82af 100644 --- a/src/jogl/native/GLContext.c +++ b/src/jogl/native/GLContext.c @@ -19,7 +19,7 @@ Java_jogamp_opengl_GLContextImpl_glGetStringInt(JNIEnv *env, jclass _unused, jin assert(ptr_glGetString != NULL); _res = (* ptr_glGetString) ((unsigned int) name); if (NULL == _res) return NULL; - return (*env)->NewStringUTF(env, _res); + return (*env)->NewStringUTF(env, (const char *)_res); } /* diff --git a/src/jogl/native/GLDebugMessageHandler.c b/src/jogl/native/GLDebugMessageHandler.c index 2e9d6033a..0aa7a01e7 100644 --- a/src/jogl/native/GLDebugMessageHandler.c +++ b/src/jogl/native/GLDebugMessageHandler.c @@ -49,8 +49,6 @@ JNIEXPORT jboolean JNICALL Java_jogamp_opengl_GLDebugMessageHandler_initIDs0 } typedef struct { - JavaVM *vm; - int version; jobject obj; int extType; } DebugHandlerType; @@ -60,39 +58,21 @@ typedef struct { static void GLDebugMessageARBCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, GLvoid *userParam) { DebugHandlerType * handle = (DebugHandlerType*) (intptr_t) userParam; - JavaVM *vm = handle->vm; - int version = handle->version; jobject obj = handle->obj; - JNIEnv *curEnv = NULL; - JNIEnv *newEnv = NULL; - int envRes ; - DBG_PRINT("GLDebugMessageARBCallback: 00 - %s, vm %p, version 0x%X, jobject %p, extType %d\n", - message, handle->vm, handle->version, (void*)handle->obj, handle->extType); - - // retrieve this thread's JNIEnv curEnv - or detect it's detached - envRes = (*vm)->GetEnv(vm, (void **) &curEnv, version) ; - DBG_PRINT("GLDebugMessageARBCallback: 01 - JVM Env: curEnv %p, res 0x%X\n", curEnv, envRes); - if( JNI_EDETACHED == envRes ) { - // detached thread - attach to JVM - if( JNI_OK != ( envRes = (*vm)->AttachCurrentThread(vm, (void**) &newEnv, NULL) ) ) { - fprintf(stderr, "GLDebugMessageARBCallback: can't attach thread: %d\n", envRes); - return; - } - curEnv = newEnv; - DBG_PRINT("GLDebugMessageARBCallback: 02 - attached .. \n"); - } else if( JNI_OK != envRes ) { - // oops .. - fprintf(stderr, "GLDebugMessageARBCallback: can't GetEnv: %d\n", envRes); + JNIEnv *env = NULL; + int shallBeDetached ; + DBG_PRINT("GLDebugMessageARBCallback: 00 - %s, jobject %p, extType %d\n", message, (void*)handle->obj, handle->extType); + + env = JoglCommon_GetJNIEnv (1 /* asDaemon */, &shallBeDetached); + if( NULL == env ) { + DBG_PRINT("GLDebugMessageARBCallback: Null JNIEnv\n"); return; } - (*curEnv)->CallVoidMethod(curEnv, obj, glDebugMessageARB, + (*env)->CallVoidMethod(env, obj, glDebugMessageARB, (jint) source, (jint) type, (jint) id, (jint) severity, - (*curEnv)->NewStringUTF(curEnv, message)); - if( NULL != newEnv ) { - // detached attached thread - (*vm)->DetachCurrentThread(vm); - DBG_PRINT("GLDebugMessageARBCallback: 04 - detached .. \n"); - } + (*env)->NewStringUTF(env, message)); + // detaching thread not required - daemon + // JoglCommon_ReleaseJNIEnv(shallBeDetached); DBG_PRINT("GLDebugMessageARBCallback: 0X\n"); /** * On Java 32bit on 64bit Windows and w/ GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB disables, @@ -104,39 +84,21 @@ static void GLDebugMessageARBCallback(GLenum source, GLenum type, GLuint id, GLe static void GLDebugMessageAMDCallback(GLuint id, GLenum category, GLenum severity, GLsizei length, const GLchar *message, GLvoid *userParam) { DebugHandlerType * handle = (DebugHandlerType*) (intptr_t) userParam; - JavaVM *vm = handle->vm; - int version = handle->version; jobject obj = handle->obj; - JNIEnv *curEnv = NULL; - JNIEnv *newEnv = NULL; - int envRes ; - DBG_PRINT("GLDebugMessageAMDCallback: 00 - %s, vm %p, version 0x%X, jobject %p, extType %d\n", - message, handle->vm, handle->version, (void*)handle->obj, handle->extType); - - // retrieve this thread's JNIEnv curEnv - or detect it's detached - envRes = (*vm)->GetEnv(vm, (void **) &curEnv, version) ; - DBG_PRINT("GLDebugMessageAMDCallback: 01 - JVM Env: curEnv %p, res 0x%X\n", curEnv, envRes); - if( JNI_EDETACHED == envRes ) { - // detached thread - attach to JVM - if( JNI_OK != ( envRes = (*vm)->AttachCurrentThread(vm, (void**) &newEnv, NULL) ) ) { - fprintf(stderr, "GLDebugMessageAMDCallback: can't attach thread: %d\n", envRes); - return; - } - curEnv = newEnv; - DBG_PRINT("GLDebugMessageAMDCallback: 02 - attached .. \n"); - } else if( JNI_OK != envRes ) { - // oops .. - fprintf(stderr, "GLDebugMessageAMDCallback: can't GetEnv: %d\n", envRes); + JNIEnv *env = NULL; + int shallBeDetached ; + DBG_PRINT("GLDebugMessageAMDCallback: 00 - %s, jobject %p, extType %d\n", message, (void*)handle->obj, handle->extType); + + env = JoglCommon_GetJNIEnv (1 /* asDaemon */, &shallBeDetached); + if( NULL == env ) { + DBG_PRINT("GLDebugMessageARBCallback: Null JNIEnv\n"); return; } - (*curEnv)->CallVoidMethod(curEnv, obj, glDebugMessageAMD, + (*env)->CallVoidMethod(env, obj, glDebugMessageAMD, (jint) id, (jint) category, (jint) severity, - (*curEnv)->NewStringUTF(curEnv, message)); - if( NULL != newEnv ) { - // detached attached thread - (*vm)->DetachCurrentThread(vm); - DBG_PRINT("GLDebugMessageAMDCallback: 04 - detached .. \n"); - } + (*env)->NewStringUTF(env, message)); + // detached attached thread not required - daemon + // JoglCommon_ReleaseJNIEnv(shallBeDetached); DBG_PRINT("GLDebugMessageAMDCallback: 0X\n"); /** * On Java 32bit on 64bit Windows, @@ -153,18 +115,10 @@ static void GLDebugMessageAMDCallback(GLuint id, GLenum category, GLenum severit JNIEXPORT jlong JNICALL Java_jogamp_opengl_GLDebugMessageHandler_register0 (JNIEnv *env, jobject obj, jlong procAddress, jint extType) { - JavaVM *vm; DebugHandlerType * handle = malloc(sizeof(DebugHandlerType)); - if(0 != (*env)->GetJavaVM(env, &vm)) { - vm = NULL; - JoglCommon_throwNewRuntimeException(env, "GetJavaVM failed"); - } - handle->vm = vm; - handle->version = (*env)->GetVersion(env); handle->obj = (*env)->NewGlobalRef(env, obj); handle->extType = extType; - DBG_PRINT("GLDebugMessageHandler.register0: vm %p, version 0x%X, jobject %p, extType %d\n", - handle->vm, handle->version, (void*)handle->obj, handle->extType); + DBG_PRINT("GLDebugMessageHandler.register0: jobject %p, extType %d\n", (void*)handle->obj, handle->extType); if(jogamp_opengl_GLDebugMessageHandler_EXT_ARB == extType) { _local_PFNGLDEBUGMESSAGECALLBACKARBPROC ptr_glDebugMessageCallbackARB; @@ -191,8 +145,7 @@ JNIEXPORT void JNICALL Java_jogamp_opengl_GLDebugMessageHandler_unregister0 { DebugHandlerType * handle = (DebugHandlerType*) (intptr_t) jhandle; - DBG_PRINT("GLDebugMessageHandler.unregister0: vm %p, version 0x%X, jobject %p, extType %d\n", - handle->vm, handle->version, (void*)handle->obj, handle->extType); + DBG_PRINT("GLDebugMessageHandler.unregister0: jobject %p, extType %d\n", (void*)handle->obj, handle->extType); if(JNI_FALSE == (*env)->IsSameObject(env, obj, handle->obj)) { JoglCommon_throwNewRuntimeException(env, "wrong handle (obj doesn't match)"); diff --git a/src/jogl/native/JoglCommon.c b/src/jogl/native/JoglCommon.c index 4170b13ec..e9984ada2 100644 --- a/src/jogl/native/JoglCommon.c +++ b/src/jogl/native/JoglCommon.c @@ -11,42 +11,38 @@ static JavaVM *_jvmHandle = NULL; static int _jvmVersion = 0; void JoglCommon_init(JNIEnv *env) { - if(NULL==runtimeExceptionClz) { + if(NULL==_jvmHandle) { + if(0 != (*env)->GetJavaVM(env, &_jvmHandle)) { + JoglCommon_FatalError(env, "JOGL: Can't fetch JavaVM handle"); + } else { + _jvmVersion = (*env)->GetVersion(env); + } jclass c = (*env)->FindClass(env, ClazzNameRuntimeException); if(NULL==c) { - JoglCommon_FatalError(env, "JOGL: can't find %s", ClazzNameRuntimeException); + JoglCommon_FatalError(env, "JOGL: Can't find %s", ClazzNameRuntimeException); } runtimeExceptionClz = (jclass)(*env)->NewGlobalRef(env, c); (*env)->DeleteLocalRef(env, c); if(NULL==runtimeExceptionClz) { - JoglCommon_FatalError(env, "JOGL: can't use %s", ClazzNameRuntimeException); + JoglCommon_FatalError(env, "JOGL: Can't use %s", ClazzNameRuntimeException); } } - if(0 != (*env)->GetJavaVM(env, &_jvmHandle)) { - JoglCommon_FatalError(env, "JOGL: can't fetch JavaVM handle"); - } else { - _jvmVersion = (*env)->GetVersion(env); - } } void JoglCommon_FatalError(JNIEnv *env, const char* msg, ...) { char buffer[512]; va_list ap; - int shallBeDetached = 0; - - if(NULL == env) { - env = JoglCommon_GetJNIEnv (&shallBeDetached); - } - va_start(ap, msg); - vsnprintf(buffer, sizeof(buffer), msg, ap); - va_end(ap); + if( NULL != msg ) { + va_start(ap, msg); + vsnprintf(buffer, sizeof(buffer), msg, ap); + va_end(ap); - fprintf(stderr, "%s\n", buffer); - if(NULL != env) { - (*env)->FatalError(env, buffer); - JoglCommon_ReleaseJNIEnv (shallBeDetached); + fprintf(stderr, "%s\n", buffer); + if(NULL != env) { + (*env)->FatalError(env, buffer); + } } } @@ -54,48 +50,42 @@ void JoglCommon_throwNewRuntimeException(JNIEnv *env, const char* msg, ...) { char buffer[512]; va_list ap; - int shallBeDetached = 0; - if(NULL == env) { - env = JoglCommon_GetJNIEnv (&shallBeDetached); + if(NULL==_jvmHandle) { + JoglCommon_FatalError(env, "JOGL: NULL JVM handle, call JoglCommon_init 1st\n"); + return; } - va_start(ap, msg); - vsnprintf(buffer, sizeof(buffer), msg, ap); - va_end(ap); + if( NULL != msg ) { + va_start(ap, msg); + vsnprintf(buffer, sizeof(buffer), msg, ap); + va_end(ap); - if(NULL != env) { - (*env)->ThrowNew(env, runtimeExceptionClz, buffer); - JoglCommon_ReleaseJNIEnv (shallBeDetached); + if(NULL != env) { + (*env)->ThrowNew(env, runtimeExceptionClz, buffer); + } } } -JavaVM *JoglCommon_GetJVMHandle() { - return _jvmHandle; -} - -int JoglCommon_GetJVMVersion() { - return _jvmVersion; -} - jchar* JoglCommon_GetNullTerminatedStringChars(JNIEnv* env, jstring str) { jchar* strChars = NULL; - strChars = calloc((*env)->GetStringLength(env, str) + 1, sizeof(jchar)); - if (strChars != NULL) { - (*env)->GetStringRegion(env, str, 0, (*env)->GetStringLength(env, str), strChars); + if( NULL != env && 0 != str ) { + strChars = calloc((*env)->GetStringLength(env, str) + 1, sizeof(jchar)); + if (strChars != NULL) { + (*env)->GetStringRegion(env, str, 0, (*env)->GetStringLength(env, str), strChars); + } } return strChars; } -JNIEnv* JoglCommon_GetJNIEnv (int * shallBeDetached) -{ +JNIEnv* JoglCommon_GetJNIEnv (int asDaemon, int * shallBeDetached) { JNIEnv* curEnv = NULL; JNIEnv* newEnv = NULL; int envRes; - if(NULL == _jvmHandle) { - fprintf(stderr, "JOGL: No JavaVM handle registered, call JoglCommon_init(..) 1st"); + if(NULL==_jvmHandle) { + fprintf(stderr, "JOGL GetJNIEnv: NULL JVM handle, call JoglCommon_init 1st\n"); return NULL; } @@ -103,18 +93,23 @@ JNIEnv* JoglCommon_GetJNIEnv (int * shallBeDetached) envRes = (*_jvmHandle)->GetEnv(_jvmHandle, (void **) &curEnv, _jvmVersion) ; if( JNI_EDETACHED == envRes ) { // detached thread - attach to JVM - if( JNI_OK != ( envRes = (*_jvmHandle)->AttachCurrentThread(_jvmHandle, (void**) &newEnv, NULL) ) ) { - fprintf(stderr, "JNIEnv: can't attach thread: %d\n", envRes); + if( asDaemon ) { + envRes = (*_jvmHandle)->AttachCurrentThreadAsDaemon(_jvmHandle, (void**) &newEnv, NULL); + } else { + envRes = (*_jvmHandle)->AttachCurrentThread(_jvmHandle, (void**) &newEnv, NULL); + } + if( JNI_OK != envRes ) { + fprintf(stderr, "JOGL GetJNIEnv: Can't attach thread: %d\n", envRes); return NULL; } curEnv = newEnv; } else if( JNI_OK != envRes ) { // oops .. - fprintf(stderr, "can't GetEnv: %d\n", envRes); + fprintf(stderr, "JOGL GetJNIEnv: Can't GetEnv: %d\n", envRes); return NULL; } if (curEnv==NULL) { - fprintf(stderr, "env is NULL\n"); + fprintf(stderr, "JOGL GetJNIEnv: env is NULL\n"); return NULL; } *shallBeDetached = NULL != newEnv; @@ -123,10 +118,8 @@ JNIEnv* JoglCommon_GetJNIEnv (int * shallBeDetached) void JoglCommon_ReleaseJNIEnv (int shallBeDetached) { if(NULL == _jvmHandle) { - fprintf(stderr, "JOGL: No JavaVM handle registered, call JoglCommon_init(..) 1st"); - } - - if(shallBeDetached) { + fprintf(stderr, "JOGL ReleaseJNIEnv: No JavaVM handle registered, call JoglCommon_init(..) 1st"); + } else if(shallBeDetached) { (*_jvmHandle)->DetachCurrentThread(_jvmHandle); } } diff --git a/src/jogl/native/JoglCommon.h b/src/jogl/native/JoglCommon.h index 023b4be03..2aeaf7d1d 100644 --- a/src/jogl/native/JoglCommon.h +++ b/src/jogl/native/JoglCommon.h @@ -1,3 +1,30 @@ +/** + * Copyright 2011 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ #ifndef JOGL_COMMON_H #define JOGL_COMMON_H 1 @@ -7,29 +34,25 @@ void JoglCommon_init(JNIEnv *env); -/** Set by JoglCommon_init */ -JavaVM *JoglCommon_GetJVMHandle(); - -/** Set by JoglCommon_init */ -int JoglCommon_GetJVMVersion(); - jchar* JoglCommon_GetNullTerminatedStringChars(JNIEnv* env, jstring str); -/** env may be NULL, in which case JoglCommon_GetJNIEnv() is being used. */ void JoglCommon_FatalError(JNIEnv *env, const char* msg, ...); - -/** env may be NULL, in which case JoglCommon_GetJNIEnv() is being used. */ void JoglCommon_throwNewRuntimeException(JNIEnv *env, const char* msg, ...); /** * - * 1) Store jvmHandle and jvmVersion is done by 'JoglCommon_init(JNIEnv*)' - * and internally used by 'JoglCommon_GetJNIEnv(..)' and 'JoglCommon_ReleaseJNIEnv(..)'. + * 1) Init static jvmHandle, jvmVersion and clazz references + * from an early initialization call w/ valid 'JNIEnv * env' + + JoglCommon_init(env); + * * 2) Use current thread JNIEnv or attach current thread to JVM, generating new JNIEnv * + + int asDaemon = 0; int shallBeDetached = 0; - JNIEnv* env = NewtCommon_GetJNIEnv(&shallBeDetached); + JNIEnv* env = JoglCommon_GetJNIEnv(asDaemon, &shallBeDetached); if(NULL==env) { DBG_PRINT("drawRect: null JNIEnv\n"); return; @@ -41,11 +64,13 @@ void JoglCommon_throwNewRuntimeException(JNIEnv *env, const char* msg, ...); .. your JNIEnv code here .. * - * 4) Detach thread from JVM, if required + * 4) Detach thread from JVM if required, i.e. not attached as daemon! + * Not recommended for recurring _daemon_ threads (performance) * - JoglCommon_ReleaseJNIEnv (shallBeDetached); + JoglCommon_ReleaseJNIEnv(shallBeDetached); */ -JNIEnv* JoglCommon_GetJNIEnv (int * shallBeDetached); +JNIEnv* JoglCommon_GetJNIEnv (int asDaemon, int * shallBeDetached); + void JoglCommon_ReleaseJNIEnv (int shallBeDetached); #endif diff --git a/src/jogl/native/libav/ffmpeg_impl_template.c b/src/jogl/native/libav/ffmpeg_impl_template.c index 44acfe46a..e86b2a542 100644 --- a/src/jogl/native/libav/ffmpeg_impl_template.c +++ b/src/jogl/native/libav/ffmpeg_impl_template.c @@ -1499,7 +1499,7 @@ JNIEXPORT jint JNICALL FF_FUNC(seek0) int64_t pts1 = (int64_t) (pos1 * (int64_t) time_base.den) / (1000 * (int64_t) time_base.num); if(pAV->verbose) { - fprintf(stderr, "SEEK: vid %d, aid %d, pos0 %d, pos1 %d, pts: %"PRId64" -> %"PRId64"\n", pAV->vid, pAV->aid, pos0, pos1, pts0, pts1); + fprintf(stderr, "SEEK: vid %d, aid %d, pos0 %"PRId64", pos1 %d, pts: %"PRId64" -> %"PRId64"\n", pAV->vid, pAV->aid, pos0, pos1, pts0, pts1); } int flags = 0; if(pos1 < pos0) { @@ -1508,7 +1508,7 @@ JNIEXPORT jint JNICALL FF_FUNC(seek0) int res = -2; if(HAS_FUNC(sp_av_seek_frame)) { if(pAV->verbose) { - fprintf(stderr, "SEEK.0: pre : s %d / %"PRId64" -> t %d / %"PRId64"\n", pos0, pts0, pos1, pts1); + fprintf(stderr, "SEEK.0: pre : s %"PRId64" / %"PRId64" -> t %d / %"PRId64"\n", pos0, pts0, pos1, pts1); } sp_av_seek_frame(pAV->pFormatCtx, streamID, pts1, flags); } else if(HAS_FUNC(sp_avformat_seek_file)) { diff --git a/src/jogl/native/macosx/MacOSXWindowSystemInterface-calayer.m b/src/jogl/native/macosx/MacOSXWindowSystemInterface-calayer.m index 75917d2dc..7ce8c58cf 100644 --- a/src/jogl/native/macosx/MacOSXWindowSystemInterface-calayer.m +++ b/src/jogl/native/macosx/MacOSXWindowSystemInterface-calayer.m @@ -578,6 +578,7 @@ static const GLfloat gl_verts[] = { quirks, dedicatedFramePosSet, dedicatedFrameSizeSet, dedicatedLayoutSet, self, texWidth, texHeight, lRect.origin.x, lRect.origin.y, lRect.size.width, lRect.size.height, dFrame.origin.x, dFrame.origin.y, dFrame.size.width, dFrame.size.height); + (void)lRect; // silence if( dedicatedFrameSet ) { [super setFrame: dedicatedFrame]; diff --git a/src/jogl/native/openmax/jogamp_opengl_util_av_impl_OMXGLMediaPlayer.c b/src/jogl/native/openmax/jogamp_opengl_util_av_impl_OMXGLMediaPlayer.c index ec68a24aa..3166306ba 100644 --- a/src/jogl/native/openmax/jogamp_opengl_util_av_impl_OMXGLMediaPlayer.c +++ b/src/jogl/native/openmax/jogamp_opengl_util_av_impl_OMXGLMediaPlayer.c @@ -67,7 +67,7 @@ void OMXInstance_UpdateJavaAttributes(OMXToolBasicAV_t *pAV) return; } int shallBeDetached = 0; - JNIEnv * env = JoglCommon_GetJNIEnv (&shallBeDetached); + JNIEnv * env = JoglCommon_GetJNIEnv (1 /* daemon */, &shallBeDetached); if(NULL!=env) { (*env)->CallVoidMethod(env, (jobject)pAV->jni_instance, jni_mid_updateAttributes, pAV->width, pAV->height, @@ -75,7 +75,8 @@ void OMXInstance_UpdateJavaAttributes(OMXToolBasicAV_t *pAV) pAV->framerate, (uint32_t)(pAV->length*pAV->framerate), pAV->length, (*env)->NewStringUTF(env, pAV->videoCodec), (*env)->NewStringUTF(env, pAV->audioCodec) ); - JoglCommon_ReleaseJNIEnv (shallBeDetached); + // detaching thread not required - daemon + // JoglCommon_ReleaseJNIEnv(shallBeDetached); } } diff --git a/src/nativewindow/native/NativewindowCommon.c b/src/nativewindow/native/NativewindowCommon.c index ec7ee7728..e65f87272 100644 --- a/src/nativewindow/native/NativewindowCommon.c +++ b/src/nativewindow/native/NativewindowCommon.c @@ -8,41 +8,24 @@ static const char * const ClazzNameRuntimeException = "java/lang/RuntimeException"; static jclass runtimeExceptionClz=NULL; -void NativewindowCommon_FatalError(JNIEnv *env, const char* msg, ...) -{ - char buffer[512]; - va_list ap; - - va_start(ap, msg); - vsnprintf(buffer, sizeof(buffer), msg, ap); - va_end(ap); - - fprintf(stderr, "%s\n", buffer); - (*env)->FatalError(env, buffer); -} - -void NativewindowCommon_throwNewRuntimeException(JNIEnv *env, const char* msg, ...) -{ - char buffer[512]; - va_list ap; - - va_start(ap, msg); - vsnprintf(buffer, sizeof(buffer), msg, ap); - va_end(ap); - - (*env)->ThrowNew(env, runtimeExceptionClz, buffer); -} +static JavaVM *_jvmHandle = NULL; +static int _jvmVersion = 0; int NativewindowCommon_init(JNIEnv *env) { - if(NULL==runtimeExceptionClz) { + if(NULL==_jvmHandle) { + if(0 != (*env)->GetJavaVM(env, &_jvmHandle)) { + NativewindowCommon_FatalError(env, "Nativewindow: Can't fetch JavaVM handle"); + } else { + _jvmVersion = (*env)->GetVersion(env); + } jclass c = (*env)->FindClass(env, ClazzNameRuntimeException); if(NULL==c) { - NativewindowCommon_FatalError(env, "Nativewindow: can't find %s", ClazzNameRuntimeException); + NativewindowCommon_FatalError(env, "Nativewindow: Can't find %s", ClazzNameRuntimeException); } runtimeExceptionClz = (jclass)(*env)->NewGlobalRef(env, c); (*env)->DeleteLocalRef(env, c); if(NULL==runtimeExceptionClz) { - NativewindowCommon_FatalError(env, "Nativewindow: can't use %s", ClazzNameRuntimeException); + NativewindowCommon_FatalError(env, "Nativewindow: Can't use %s", ClazzNameRuntimeException); } #ifdef STDERR_TO_FILE FILE * old_stderr = stderr; @@ -54,6 +37,44 @@ int NativewindowCommon_init(JNIEnv *env) { return 0; } +void NativewindowCommon_FatalError(JNIEnv *env, const char* msg, ...) +{ + char buffer[512]; + va_list ap; + + if( NULL != msg ) { + va_start(ap, msg); + vsnprintf(buffer, sizeof(buffer), msg, ap); + va_end(ap); + + fprintf(stderr, "%s\n", buffer); + if(NULL != env) { + (*env)->FatalError(env, buffer); + } + } +} + +void NativewindowCommon_throwNewRuntimeException(JNIEnv *env, const char* msg, ...) +{ + char buffer[512]; + va_list ap; + + if(NULL==_jvmHandle) { + NativewindowCommon_FatalError(env, "Nativewindow: NULL JVM handle, call NativewindowCommon_init 1st\n"); + return; + } + + if( NULL != msg ) { + va_start(ap, msg); + vsnprintf(buffer, sizeof(buffer), msg, ap); + va_end(ap); + + if(NULL != env) { + (*env)->ThrowNew(env, runtimeExceptionClz, buffer); + } + } +} + const char * NativewindowCommon_GetStaticStringMethod(JNIEnv *jniEnv, jclass clazz, jmethodID jGetStrID, char *dest, int destSize, const char *altText) { if(NULL != jniEnv && NULL != clazz && NULL != jGetStrID) { jstring jstr = (jstring) (*jniEnv)->CallStaticObjectMethod(jniEnv, clazz, jGetStrID); @@ -75,45 +96,60 @@ const char * NativewindowCommon_GetStaticStringMethod(JNIEnv *jniEnv, jclass cla jchar* NativewindowCommon_GetNullTerminatedStringChars(JNIEnv* env, jstring str) { jchar* strChars = NULL; - strChars = calloc((*env)->GetStringLength(env, str) + 1, sizeof(jchar)); - if (strChars != NULL) { - (*env)->GetStringRegion(env, str, 0, (*env)->GetStringLength(env, str), strChars); + if( NULL != env && 0 != str ) { + strChars = calloc((*env)->GetStringLength(env, str) + 1, sizeof(jchar)); + if (strChars != NULL) { + (*env)->GetStringRegion(env, str, 0, (*env)->GetStringLength(env, str), strChars); + } } return strChars; } -JNIEnv* NativewindowCommon_GetJNIEnv (JavaVM * jvmHandle, int jvmVersion, int asDaemon, int * shallBeDetached) { +JNIEnv* NativewindowCommon_GetJNIEnv (int asDaemon, int * shallBeDetached) { JNIEnv* curEnv = NULL; JNIEnv* newEnv = NULL; int envRes; + if(NULL==_jvmHandle) { + fprintf(stderr, "Nativewindow GetJNIEnv: NULL JVM handle, call NativewindowCommon_init 1st\n"); + return NULL; + } + // retrieve this thread's JNIEnv curEnv - or detect it's detached - envRes = (*jvmHandle)->GetEnv(jvmHandle, (void **) &curEnv, jvmVersion) ; + envRes = (*_jvmHandle)->GetEnv(_jvmHandle, (void **) &curEnv, _jvmVersion) ; if( JNI_EDETACHED == envRes ) { // detached thread - attach to JVM if( asDaemon ) { - envRes = (*jvmHandle)->AttachCurrentThreadAsDaemon(jvmHandle, (void**) &newEnv, NULL); + envRes = (*_jvmHandle)->AttachCurrentThreadAsDaemon(_jvmHandle, (void**) &newEnv, NULL); } else { - envRes = (*jvmHandle)->AttachCurrentThread(jvmHandle, (void**) &newEnv, NULL); + envRes = (*_jvmHandle)->AttachCurrentThread(_jvmHandle, (void**) &newEnv, NULL); } if( JNI_OK != envRes ) { - fprintf(stderr, "JNIEnv: can't attach thread: %d\n", envRes); + fprintf(stderr, "Nativewindow GetJNIEnv: Can't attach thread: %d\n", envRes); return NULL; } curEnv = newEnv; } else if( JNI_OK != envRes ) { // oops .. - fprintf(stderr, "can't GetEnv: %d\n", envRes); + fprintf(stderr, "Nativewindow GetJNIEnv: Can't GetEnv: %d\n", envRes); return NULL; } if (curEnv==NULL) { - fprintf(stderr, "env is NULL\n"); + fprintf(stderr, "Nativewindow GetJNIEnv: env is NULL\n"); return NULL; } *shallBeDetached = NULL != newEnv; return curEnv; } +void NativewindowCommon_ReleaseJNIEnv (int shallBeDetached) { + if(NULL == _jvmHandle) { + fprintf(stderr, "Nativewindow ReleaseJNIEnv: No JavaVM handle registered, call NativewindowCommon_init(..) 1st"); + } else if(shallBeDetached) { + (*_jvmHandle)->DetachCurrentThread(_jvmHandle); + } +} + int64_t NativewindowCommon_CurrentTimeMillis() { struct timeval tv; gettimeofday(&tv,NULL); diff --git a/src/nativewindow/native/NativewindowCommon.h b/src/nativewindow/native/NativewindowCommon.h index a23fad9fd..f19552e33 100644 --- a/src/nativewindow/native/NativewindowCommon.h +++ b/src/nativewindow/native/NativewindowCommon.h @@ -1,3 +1,30 @@ +/** + * Copyright 2011 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + */ #ifndef NATIVEWINDOW_COMMON_H #define NATIVEWINDOW_COMMON_H 1 @@ -14,7 +41,39 @@ jchar* NativewindowCommon_GetNullTerminatedStringChars(JNIEnv* env, jstring str) void NativewindowCommon_FatalError(JNIEnv *env, const char* msg, ...); void NativewindowCommon_throwNewRuntimeException(JNIEnv *env, const char* msg, ...); -JNIEnv* NativewindowCommon_GetJNIEnv (JavaVM * jvmHandle, int jvmVersion, int asDaemon, int * shallBeDetached); +/** + * + * 1) Init static jvmHandle, jvmVersion and clazz references + * from an early initialization call w/ valid 'JNIEnv * env' + + NativewindowCommon_init(env); + + * + * 2) Use current thread JNIEnv or attach current thread to JVM, generating new JNIEnv + * + + int asDaemon = 0; + int shallBeDetached = 0; + JNIEnv* env = NewtCommon_GetJNIEnv(asDaemon, &shallBeDetached); + if(NULL==env) { + DBG_PRINT("drawRect: null JNIEnv\n"); + return; + } + + * + * 3) Use JNIEnv .. + * + .. your JNIEnv code here .. + + * + * 4) Detach thread from JVM if required, i.e. not attached as daemon! + * Not recommended for recurring _daemon_ threads (performance) + * + NewtCommon_ReleaseJNIEnv(shallBeDetached); + */ +JNIEnv* NativewindowCommon_GetJNIEnv (int asDaemon, int * shallBeDetached); + +void NativewindowCommon_ReleaseJNIEnv (int shallBeDetached); int64_t NativewindowCommon_CurrentTimeMillis(); diff --git a/src/nativewindow/native/macosx/OSXmisc.m b/src/nativewindow/native/macosx/OSXmisc.m index 6a7952eaf..4887cc3cf 100644 --- a/src/nativewindow/native/macosx/OSXmisc.m +++ b/src/nativewindow/native/macosx/OSXmisc.m @@ -75,11 +75,9 @@ static const char * const ClazzNameInsetsCstrSignature = "(IIII)V"; static jclass insetsClz = NULL; static jmethodID insetsCstr = NULL; -static int _initialized=0; - JNIEXPORT jboolean JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_initIDs0(JNIEnv *env, jclass _unused) { - if(0==_initialized) { + if( NativewindowCommon_init(env) ) { jclass c; c = (*env)->FindClass(env, ClazzNamePoint); if(NULL==c) { @@ -119,7 +117,6 @@ Java_jogamp_nativewindow_macosx_OSXUtil_initIDs0(JNIEnv *env, jclass _unused) { if(NULL==runnableRunID) { NativewindowCommon_FatalError(env, "FatalError Java_jogamp_newt_driver_macosx_MacWindow_initIDs0: can't fetch %s.run()V", ClazzNameRunnable); } - _initialized=1; } return JNI_TRUE; } @@ -775,12 +772,10 @@ JNIEXPORT void JNICALL Java_jogamp_nativewindow_jawt_macosx_MacOSXJAWTWindow_Uns @interface MainRunnable : NSObject { - JavaVM *jvmHandle; - int jvmVersion; jobject runnableObj; } -- (id) initWithRunnable: (jobject)runnable jvmHandle: (JavaVM*)jvm jvmVersion: (int)jvmVers; +- (id) initWithRunnable: (jobject)runnable; - (void) jRun; #ifdef DBG_LIFECYCLE @@ -794,10 +789,8 @@ JNIEXPORT void JNICALL Java_jogamp_nativewindow_jawt_macosx_MacOSXJAWTWindow_Uns @implementation MainRunnable -- (id) initWithRunnable: (jobject)runnable jvmHandle: (JavaVM*)jvm jvmVersion: (int)jvmVers +- (id) initWithRunnable: (jobject)runnable { - jvmHandle = jvm; - jvmVersion = jvmVers; runnableObj = runnable; return [super init]; } @@ -805,7 +798,7 @@ JNIEXPORT void JNICALL Java_jogamp_nativewindow_jawt_macosx_MacOSXJAWTWindow_Uns - (void) jRun { int shallBeDetached = 0; - JNIEnv* env = NativewindowCommon_GetJNIEnv(jvmHandle, jvmVersion, 1 /* asDaemon */, &shallBeDetached); + JNIEnv* env = NativewindowCommon_GetJNIEnv(1 /* asDaemon */, &shallBeDetached); DBG_PRINT2("MainRunnable.1 env: %d\n", (int)(NULL!=env)); if(NULL!=env) { DBG_PRINT2("MainRunnable.1.0\n"); @@ -813,11 +806,9 @@ JNIEXPORT void JNICALL Java_jogamp_nativewindow_jawt_macosx_MacOSXJAWTWindow_Uns DBG_PRINT2("MainRunnable.1.1\n"); (*env)->DeleteGlobalRef(env, runnableObj); - if (shallBeDetached) { - DBG_PRINT2("MainRunnable.1.3\n"); - // Keep attached on main thread ! - // (*jvmHandle)->DetachCurrentThread(jvmHandle); - } + DBG_PRINT2("MainRunnable.1.3\n"); + // detaching thread not required - daemon + // NativewindowCommon_ReleaseJNIEnv(shallBeDetached); } DBG_PRINT2("MainRunnable.X\n"); } @@ -861,17 +852,8 @@ static void RunOnThread (JNIEnv *env, jobject runnable, BOOL onMain, jint delayI if ( forkOnMain ) { jobject runnableObj = (*env)->NewGlobalRef(env, runnable); - JavaVM *jvmHandle = NULL; - int jvmVersion = 0; - - if(0 != (*env)->GetJavaVM(env, &jvmHandle)) { - jvmHandle = NULL; - } else { - jvmVersion = (*env)->GetVersion(env); - } - DBG_PRINT2( "RunOnThread.1.0\n"); - MainRunnable * mr = [[MainRunnable alloc] initWithRunnable: runnableObj jvmHandle: jvmHandle jvmVersion: jvmVersion]; + MainRunnable * mr = [[MainRunnable alloc] initWithRunnable: runnableObj]; if( onMain ) { [mr performSelectorOnMainThread:@selector(jRun) withObject:nil waitUntilDone:NO]; diff --git a/src/nativewindow/native/win32/GDImisc.c b/src/nativewindow/native/win32/GDImisc.c index e28f68e7d..bec1d4922 100644 --- a/src/nativewindow/native/win32/GDImisc.c +++ b/src/nativewindow/native/win32/GDImisc.c @@ -487,7 +487,7 @@ JNIEXPORT jboolean JNICALL Java_jogamp_nativewindow_windows_GDIUtil_DestroyWindo JNIEXPORT jboolean JNICALL Java_jogamp_nativewindow_windows_GDIUtil_initIDs0 (JNIEnv *env, jclass gdiClazz) { - if(NativewindowCommon_init(env)) { + if( NativewindowCommon_init(env) ) { jclass c = (*env)->FindClass(env, ClazzNamePoint); if(NULL==c) { NativewindowCommon_FatalError(env, "FatalError jogamp_nativewindow_windows_GDIUtil: can't find %s", ClazzNamePoint); diff --git a/src/nativewindow/native/x11/Xmisc.c b/src/nativewindow/native/x11/Xmisc.c index 5e6909f6e..247dc1311 100644 --- a/src/nativewindow/native/x11/Xmisc.c +++ b/src/nativewindow/native/x11/Xmisc.c @@ -113,68 +113,56 @@ static jmethodID pointCstr = NULL; static void _initClazzAccess(JNIEnv *env) { jclass c; - if(!NativewindowCommon_init(env)) return; - - getCurrentThreadNameID = (*env)->GetStaticMethodID(env, X11UtilClazz, "getCurrentThreadName", "()Ljava/lang/String;"); - if(NULL==getCurrentThreadNameID) { - NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_x11_X11Lib: can't get method getCurrentThreadName"); - } - dumpStackID = (*env)->GetStaticMethodID(env, X11UtilClazz, "dumpStack", "()V"); - if(NULL==dumpStackID) { - NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_x11_X11Lib: can't get method dumpStack"); - } - - c = (*env)->FindClass(env, ClazzNameBuffers); - if(NULL==c) { - NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_x11_X11Lib: can't find %s", ClazzNameBuffers); - } - clazzBuffers = (jclass)(*env)->NewGlobalRef(env, c); - (*env)->DeleteLocalRef(env, c); - if(NULL==clazzBuffers) { - NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_x11_X11Lib: can't use %s", ClazzNameBuffers); - } - c = (*env)->FindClass(env, ClazzNameByteBuffer); - if(NULL==c) { - NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_x11_X11Lib: can't find %s", ClazzNameByteBuffer); - } - clazzByteBuffer = (jclass)(*env)->NewGlobalRef(env, c); - (*env)->DeleteLocalRef(env, c); - if(NULL==c) { - NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_x11_X11Lib: can't use %s", ClazzNameByteBuffer); - } - - cstrBuffers = (*env)->GetStaticMethodID(env, clazzBuffers, - ClazzNameBuffersStaticCstrName, ClazzNameBuffersStaticCstrSignature); - if(NULL==cstrBuffers) { - NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_x11_X11Lib: can't create %s.%s %s", - ClazzNameBuffers, ClazzNameBuffersStaticCstrName, ClazzNameBuffersStaticCstrSignature); - } + if( NativewindowCommon_init(env) ) { + getCurrentThreadNameID = (*env)->GetStaticMethodID(env, X11UtilClazz, "getCurrentThreadName", "()Ljava/lang/String;"); + if(NULL==getCurrentThreadNameID) { + NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_x11_X11Lib: can't get method getCurrentThreadName"); + } + dumpStackID = (*env)->GetStaticMethodID(env, X11UtilClazz, "dumpStack", "()V"); + if(NULL==dumpStackID) { + NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_x11_X11Lib: can't get method dumpStack"); + } - c = (*env)->FindClass(env, ClazzNamePoint); - if(NULL==c) { - NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_x11_X11Lib: can't find %s", ClazzNamePoint); - } - pointClz = (jclass)(*env)->NewGlobalRef(env, c); - (*env)->DeleteLocalRef(env, c); - if(NULL==pointClz) { - NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_x11_X11Lib: can't use %s", ClazzNamePoint); - } - pointCstr = (*env)->GetMethodID(env, pointClz, ClazzAnyCstrName, ClazzNamePointCstrSignature); - if(NULL==pointCstr) { - NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_x11_X11Lib: can't fetch %s.%s %s", - ClazzNamePoint, ClazzAnyCstrName, ClazzNamePointCstrSignature); - } -} + c = (*env)->FindClass(env, ClazzNameBuffers); + if(NULL==c) { + NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_x11_X11Lib: can't find %s", ClazzNameBuffers); + } + clazzBuffers = (jclass)(*env)->NewGlobalRef(env, c); + (*env)->DeleteLocalRef(env, c); + if(NULL==clazzBuffers) { + NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_x11_X11Lib: can't use %s", ClazzNameBuffers); + } + c = (*env)->FindClass(env, ClazzNameByteBuffer); + if(NULL==c) { + NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_x11_X11Lib: can't find %s", ClazzNameByteBuffer); + } + clazzByteBuffer = (jclass)(*env)->NewGlobalRef(env, c); + (*env)->DeleteLocalRef(env, c); + if(NULL==c) { + NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_x11_X11Lib: can't use %s", ClazzNameByteBuffer); + } -static JavaVM *jvmHandle = NULL; -static int jvmVersion = 0; + cstrBuffers = (*env)->GetStaticMethodID(env, clazzBuffers, + ClazzNameBuffersStaticCstrName, ClazzNameBuffersStaticCstrSignature); + if(NULL==cstrBuffers) { + NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_x11_X11Lib: can't create %s.%s %s", + ClazzNameBuffers, ClazzNameBuffersStaticCstrName, ClazzNameBuffersStaticCstrSignature); + } -static void setupJVMVars(JNIEnv * env) { - if( NULL != env && NULL == jvmHandle ) { - if(0 != (*env)->GetJavaVM(env, &jvmHandle)) { - jvmHandle = NULL; + c = (*env)->FindClass(env, ClazzNamePoint); + if(NULL==c) { + NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_x11_X11Lib: can't find %s", ClazzNamePoint); + } + pointClz = (jclass)(*env)->NewGlobalRef(env, c); + (*env)->DeleteLocalRef(env, c); + if(NULL==pointClz) { + NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_x11_X11Lib: can't use %s", ClazzNamePoint); + } + pointCstr = (*env)->GetMethodID(env, pointClz, ClazzAnyCstrName, ClazzNamePointCstrSignature); + if(NULL==pointCstr) { + NativewindowCommon_FatalError(env, "FatalError Java_jogamp_nativewindow_x11_X11Lib: can't fetch %s.%s %s", + ClazzNamePoint, ClazzAnyCstrName, ClazzNamePointCstrSignature); } - jvmVersion = (*env)->GetVersion(env); } } @@ -201,8 +189,8 @@ static int x11ErrorHandler(Display *dpy, XErrorEvent *e) (int)e->request_code, (int)e->minor_code, reqCodeStr); fflush(stderr); - if( NULL != jvmHandle && ( errorHandlerDebug || errorHandlerThrowException ) ) { - jniEnv = NativewindowCommon_GetJNIEnv(jvmHandle, jvmVersion, 0 /* asDaemon */, &shallBeDetached); + if( errorHandlerDebug || errorHandlerThrowException ) { + jniEnv = NativewindowCommon_GetJNIEnv(0 /* asDaemon */, &shallBeDetached); if(NULL == jniEnv) { fprintf(stderr, "Nativewindow X11 Error: null JNIEnv"); fflush(stderr); @@ -219,9 +207,7 @@ static int x11ErrorHandler(Display *dpy, XErrorEvent *e) e->error_code, errCodeStr, e->display, (int)e->resourceid, (int)e->serial, (int)e->request_code, (int)e->minor_code, reqCodeStr); } - if (shallBeDetached) { - (*jvmHandle)->DetachCurrentThread(jvmHandle); - } + NativewindowCommon_ReleaseJNIEnv(shallBeDetached); } } @@ -233,7 +219,6 @@ static void NativewindowCommon_x11ErrorHandlerEnable(JNIEnv * env, Display *dpy, if(onoff) { if(force || NULL==origErrorHandler) { XErrorHandler prevErrorHandler; - setupJVMVars(env); prevErrorHandler = XSetErrorHandler(x11ErrorHandler); if(x11ErrorHandler != prevErrorHandler) { // if forced don't overwrite w/ orig w/ our handler origErrorHandler = prevErrorHandler; @@ -265,14 +250,10 @@ static int x11IOErrorHandler(Display *dpy) fprintf(stderr, "Nativewindow X11 IOError: Display %p (%s): %s\n", dpy, dpyName, errnoStr); fflush(stderr); - if( NULL != jvmHandle ) { - jniEnv = NativewindowCommon_GetJNIEnv(jvmHandle, jvmVersion, 0 /* asDaemon */, &shallBeDetached); - if (NULL != jniEnv) { - NativewindowCommon_FatalError(jniEnv, "Nativewindow X11 IOError: Display %p (%s): %s", dpy, dpyName, errnoStr); - if (shallBeDetached) { - (*jvmHandle)->DetachCurrentThread(jvmHandle); - } - } + jniEnv = NativewindowCommon_GetJNIEnv(0 /* asDaemon */, &shallBeDetached); + if (NULL != jniEnv) { + NativewindowCommon_FatalError(jniEnv, "Nativewindow X11 IOError: Display %p (%s): %s", dpy, dpyName, errnoStr); + NativewindowCommon_ReleaseJNIEnv(shallBeDetached); } if(NULL!=origIOErrorHandler) { origIOErrorHandler(dpy); @@ -283,7 +264,6 @@ static int x11IOErrorHandler(Display *dpy) static void x11IOErrorHandlerEnable(int onoff, JNIEnv * env) { if(onoff) { if(NULL==origIOErrorHandler) { - setupJVMVars(env); origIOErrorHandler = XSetIOErrorHandler(x11IOErrorHandler); } } else { diff --git a/src/newt/native/MacWindow.m b/src/newt/native/MacWindow.m index c6fd805a5..130b2e3e3 100644 --- a/src/newt/native/MacWindow.m +++ b/src/newt/native/MacWindow.m @@ -113,18 +113,6 @@ static void setJavaWindowObject(JNIEnv *env, jobject newJavaWindowObject, NewtVi DBG_PRINT( "setJavaWindowObject.2: View %p - Set new javaWindowObject %p\n", view, newJavaWindowObject); jobject globJavaWindowObject = (*env)->NewGlobalRef(env, newJavaWindowObject); [view setJavaWindowObject: globJavaWindowObject]; - { - JavaVM *jvmHandle = NULL; - int jvmVersion = 0; - - if(0 != (*env)->GetJavaVM(env, &jvmHandle)) { - jvmHandle = NULL; - } else { - jvmVersion = (*env)->GetVersion(env); - } - [view setJVMHandle: jvmHandle]; - [view setJVMVersion: jvmVersion]; - } } DBG_PRINT( "setJavaWindowObject.X: View %p\n", view); } @@ -979,6 +967,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_close0 BOOL isNewtWin = [mWin isKindOfClass:[NewtMacWindow class]]; NSWindow *pWin = [mWin parentWindow]; DBG_PRINT( "windowClose.0 - %p [isNSWindow %d, isNewtWin %d], parent %p\n", mWin, isNSWin, isNewtWin, pWin); + (void)isNSWin; // silence if( !isNewtWin ) { NewtCommon_throwNewRuntimeException(env, "Not a NewtMacWindow %p", mWin); return; diff --git a/src/newt/native/NewtCommon.c b/src/newt/native/NewtCommon.c index c294b6e0b..231d6182f 100644 --- a/src/newt/native/NewtCommon.c +++ b/src/newt/native/NewtCommon.c @@ -5,17 +5,43 @@ static const char * const ClazzNameRuntimeException = "java/lang/RuntimeException"; static jclass runtimeExceptionClz=NULL; +static JavaVM *_jvmHandle = NULL; +static int _jvmVersion = 0; + +void NewtCommon_init(JNIEnv *env) { + if(NULL==_jvmHandle) { + if(0 != (*env)->GetJavaVM(env, &_jvmHandle)) { + NewtCommon_FatalError(env, "NEWT: Can't fetch JavaVM handle"); + } else { + _jvmVersion = (*env)->GetVersion(env); + } + jclass c = (*env)->FindClass(env, ClazzNameRuntimeException); + if(NULL==c) { + NewtCommon_FatalError(env, "NEWT: Can't find %s", ClazzNameRuntimeException); + } + runtimeExceptionClz = (jclass)(*env)->NewGlobalRef(env, c); + (*env)->DeleteLocalRef(env, c); + if(NULL==runtimeExceptionClz) { + NewtCommon_FatalError(env, "NEWT: Can't use %s", ClazzNameRuntimeException); + } + } +} + void NewtCommon_FatalError(JNIEnv *env, const char* msg, ...) { char buffer[512]; va_list ap; - va_start(ap, msg); - vsnprintf(buffer, sizeof(buffer), msg, ap); - va_end(ap); + if( NULL != msg ) { + va_start(ap, msg); + vsnprintf(buffer, sizeof(buffer), msg, ap); + va_end(ap); - fprintf(stderr, "%s\n", buffer); - (*env)->FatalError(env, buffer); + fprintf(stderr, "%s\n", buffer); + if(NULL != env) { + (*env)->FatalError(env, buffer); + } + } } void NewtCommon_throwNewRuntimeException(JNIEnv *env, const char* msg, ...) @@ -23,23 +49,18 @@ void NewtCommon_throwNewRuntimeException(JNIEnv *env, const char* msg, ...) char buffer[512]; va_list ap; - va_start(ap, msg); - vsnprintf(buffer, sizeof(buffer), msg, ap); - va_end(ap); + if(NULL==_jvmHandle) { + NewtCommon_FatalError(env, "NEWT: NULL JVM handle, call NewtCommon_init 1st\n"); + return; + } - (*env)->ThrowNew(env, runtimeExceptionClz, buffer); -} + if( NULL != msg ) { + va_start(ap, msg); + vsnprintf(buffer, sizeof(buffer), msg, ap); + va_end(ap); -void NewtCommon_init(JNIEnv *env) { - if(NULL==runtimeExceptionClz) { - jclass c = (*env)->FindClass(env, ClazzNameRuntimeException); - if(NULL==c) { - NewtCommon_FatalError(env, "NEWT: can't find %s", ClazzNameRuntimeException); - } - runtimeExceptionClz = (jclass)(*env)->NewGlobalRef(env, c); - (*env)->DeleteLocalRef(env, c); - if(NULL==runtimeExceptionClz) { - NewtCommon_FatalError(env, "NEWT: can't use %s", ClazzNameRuntimeException); + if(NULL != env) { + (*env)->ThrowNew(env, runtimeExceptionClz, buffer); } } } @@ -65,42 +86,57 @@ const char * NewtCommon_GetStaticStringMethod(JNIEnv *jniEnv, jclass clazz, jmet jchar* NewtCommon_GetNullTerminatedStringChars(JNIEnv* env, jstring str) { jchar* strChars = NULL; - strChars = calloc((*env)->GetStringLength(env, str) + 1, sizeof(jchar)); - if (strChars != NULL) { - (*env)->GetStringRegion(env, str, 0, (*env)->GetStringLength(env, str), strChars); + if( NULL != env && 0 != str ) { + strChars = calloc((*env)->GetStringLength(env, str) + 1, sizeof(jchar)); + if (strChars != NULL) { + (*env)->GetStringRegion(env, str, 0, (*env)->GetStringLength(env, str), strChars); + } } return strChars; } -JNIEnv* NewtCommon_GetJNIEnv(JavaVM * jvmHandle, int jvmVersion, int asDaemon, int * shallBeDetached) { +JNIEnv* NewtCommon_GetJNIEnv(int asDaemon, int * shallBeDetached) { JNIEnv* curEnv = NULL; JNIEnv* newEnv = NULL; int envRes; + if(NULL==_jvmHandle) { + fprintf(stderr, "NEWT GetJNIEnv: NULL JVM handle, call NewtCommon_init 1st\n"); + return NULL; + } + // retrieve this thread's JNIEnv curEnv - or detect it's detached - envRes = (*jvmHandle)->GetEnv(jvmHandle, (void **) &curEnv, jvmVersion) ; + envRes = (*_jvmHandle)->GetEnv(_jvmHandle, (void **) &curEnv, _jvmVersion) ; if( JNI_EDETACHED == envRes ) { // detached thread - attach to JVM if( asDaemon ) { - envRes = (*jvmHandle)->AttachCurrentThreadAsDaemon(jvmHandle, (void**) &newEnv, NULL); + envRes = (*_jvmHandle)->AttachCurrentThreadAsDaemon(_jvmHandle, (void**) &newEnv, NULL); } else { - envRes = (*jvmHandle)->AttachCurrentThread(jvmHandle, (void**) &newEnv, NULL); + envRes = (*_jvmHandle)->AttachCurrentThread(_jvmHandle, (void**) &newEnv, NULL); } if( JNI_OK != envRes ) { - fprintf(stderr, "JNIEnv: can't attach thread: %d\n", envRes); + fprintf(stderr, "NEWT GetJNIEnv: Can't attach thread: %d\n", envRes); return NULL; } curEnv = newEnv; } else if( JNI_OK != envRes ) { // oops .. - fprintf(stderr, "can't GetEnv: %d\n", envRes); + fprintf(stderr, "NEWT GetJNIEnv: Can't GetEnv: %d\n", envRes); return NULL; } if (curEnv==NULL) { - fprintf(stderr, "env is NULL\n"); + fprintf(stderr, "NEWT GetJNIEnv: env is NULL\n"); return NULL; } *shallBeDetached = NULL != newEnv; return curEnv; } +void NewtCommon_ReleaseJNIEnv (int shallBeDetached) { + if(NULL == _jvmHandle) { + fprintf(stderr, "NEWT ReleaseJNIEnv: No JavaVM handle registered, call NewtCommon_init(..) 1st"); + } else if(shallBeDetached) { + (*_jvmHandle)->DetachCurrentThread(_jvmHandle); + } +} + diff --git a/src/newt/native/NewtCommon.h b/src/newt/native/NewtCommon.h index 9cc9e93a6..43db72b5b 100644 --- a/src/newt/native/NewtCommon.h +++ b/src/newt/native/NewtCommon.h @@ -42,23 +42,18 @@ void NewtCommon_throwNewRuntimeException(JNIEnv *env, const char* msg, ...); /** * - * 1) Store jvmHandle and jvmVersion + * 1) Init static jvmHandle, jvmVersion and clazz references + * from an early initialization call w/ valid 'JNIEnv * env' - JavaVM *jvmHandle = NULL; - int jvmVersion = 0; - - if(0 != (*env)->GetJavaVM(env, &jvmHandle)) { - jvmHandle = NULL; - } else { - jvmVersion = (*env)->GetVersion(env); - } + NewtCommon_init(env); * * 2) Use current thread JNIEnv or attach current thread to JVM, generating new JNIEnv * + int asDaemon = 0; int shallBeDetached = 0; - JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, jvmVersion, &shallBeDetached); + JNIEnv* env = NewtCommon_GetJNIEnv(asDaemon, &shallBeDetached); if(NULL==env) { DBG_PRINT("drawRect: null JNIEnv\n"); return; @@ -70,12 +65,13 @@ void NewtCommon_throwNewRuntimeException(JNIEnv *env, const char* msg, ...); .. your JNIEnv code here .. * - * 4) Detach thread from JVM, if required + * 4) Detach thread from JVM if required, i.e. not attached as daemon! + * Not recommended for recurring _daemon_ threads (performance) * - if (shallBeDetached) { - (*jvmHandle)->DetachCurrentThread(jvmHandle); - } + NativewindowCommon_ReleaseJNIEnv(shallBeDetached); */ -JNIEnv* NewtCommon_GetJNIEnv (JavaVM * jvmHandle, int jvmVersion, int asDaemon, int * shallBeDetached); +JNIEnv* NewtCommon_GetJNIEnv (int asDaemon, int * shallBeDetached); + +void NewtCommon_ReleaseJNIEnv (int shallBeDetached); #endif diff --git a/src/newt/native/NewtMacWindow.h b/src/newt/native/NewtMacWindow.h index daf75bec7..8f6362ac2 100644 --- a/src/newt/native/NewtMacWindow.h +++ b/src/newt/native/NewtMacWindow.h @@ -53,10 +53,6 @@ { jobject javaWindowObject; - // This is set while messages are being dispatched and cleared afterward - JavaVM *jvmHandle; - int jvmVersion; - volatile BOOL destroyNotifySent; volatile int softLockCount; pthread_mutex_t softLockSync; @@ -80,12 +76,6 @@ #endif - (void) dealloc; -/* Set during event dispatching cycle */ -- (void) setJVMHandle: (JavaVM*) vm; -- (JavaVM*) getJVMHandle; -- (void) setJVMVersion: (int) ver; -- (int) getJVMVersion; - /* Register or deregister (NULL) the java Window object, ie, if NULL, no events are send */ - (void) setJavaWindowObject: (jobject) javaWindowObj; diff --git a/src/newt/native/NewtMacWindow.m b/src/newt/native/NewtMacWindow.m index 5ccd9c658..b4133ac7e 100644 --- a/src/newt/native/NewtMacWindow.m +++ b/src/newt/native/NewtMacWindow.m @@ -193,8 +193,6 @@ static jmethodID windowRepaintID = NULL; id res = [super initWithFrame:frameRect]; javaWindowObject = NULL; - jvmHandle = NULL; - jvmVersion = 0; destroyNotifySent = NO; softLockCount = 0; @@ -244,25 +242,6 @@ static jmethodID windowRepaintID = NULL; [super dealloc]; } -- (void) setJVMHandle: (JavaVM*) vm -{ - jvmHandle = vm; -} -- (JavaVM*) getJVMHandle -{ - return jvmHandle; -} - -- (void) setJVMVersion: (int) ver -{ - jvmVersion = ver; -} - -- (int) getJVMVersion -{ - return jvmVersion; -} - - (void) setJavaWindowObject: (jobject) javaWindowObj { javaWindowObject = javaWindowObj; @@ -342,7 +321,7 @@ static jmethodID windowRepaintID = NULL; return; } int shallBeDetached = 0; - JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, jvmVersion, 1 /* asDaemon */, &shallBeDetached); + JNIEnv* env = NewtCommon_GetJNIEnv(1 /* asDaemon */, &shallBeDetached); if(NULL==env) { DBG_PRINT("drawRect: null JNIEnv\n"); return; @@ -354,9 +333,8 @@ static jmethodID windowRepaintID = NULL; dirtyRect.origin.x, viewFrame.size.height - dirtyRect.origin.y, dirtyRect.size.width, dirtyRect.size.height); - /* if (shallBeDetached) { - (*jvmHandle)->DetachCurrentThread(jvmHandle); - } */ + // detaching thread not required - daemon + // NewtCommon_ReleaseJNIEnv(shallBeDetached); } - (void) viewDidHide @@ -366,7 +344,7 @@ static jmethodID windowRepaintID = NULL; return; } int shallBeDetached = 0; - JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, jvmVersion, 1 /* asDaemon */, &shallBeDetached); + JNIEnv* env = NewtCommon_GetJNIEnv(1 /* asDaemon */, &shallBeDetached); if(NULL==env) { DBG_PRINT("viewDidHide: null JNIEnv\n"); return; @@ -374,9 +352,8 @@ static jmethodID windowRepaintID = NULL; (*env)->CallVoidMethod(env, javaWindowObject, visibleChangedID, JNI_FALSE, JNI_FALSE); - /* if (shallBeDetached) { - (*jvmHandle)->DetachCurrentThread(jvmHandle); - } */ + // detaching thread not required - daemon + // NewtCommon_ReleaseJNIEnv(shallBeDetached); [super viewDidHide]; } @@ -388,7 +365,7 @@ static jmethodID windowRepaintID = NULL; return; } int shallBeDetached = 0; - JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, jvmVersion, 1 /* asDaemon */, &shallBeDetached); + JNIEnv* env = NewtCommon_GetJNIEnv(1 /* asDaemon */, &shallBeDetached); if(NULL==env) { DBG_PRINT("viewDidUnhide: null JNIEnv\n"); return; @@ -396,9 +373,8 @@ static jmethodID windowRepaintID = NULL; (*env)->CallVoidMethod(env, javaWindowObject, visibleChangedID, JNI_FALSE, JNI_TRUE); - /* if (shallBeDetached) { - (*jvmHandle)->DetachCurrentThread(jvmHandle); - } */ + // detaching thread not required - daemon + // NewtCommon_ReleaseJNIEnv(shallBeDetached); [super viewDidUnhide]; } @@ -645,14 +621,9 @@ static jmethodID windowRepaintID = NULL; return; } int shallBeDetached = 0; - JNIEnv* env; - if( NULL != jvmHandle ) { - env = NewtCommon_GetJNIEnv(jvmHandle, [self getJVMVersion], 1 /* asDaemon */, &shallBeDetached); - } else { - env = NULL; - } + JNIEnv* env = NewtCommon_GetJNIEnv(1 /* asDaemon */, &shallBeDetached); if(NULL==env) { - DBG_PRINT("sendMouseEvent: JVM %p JNIEnv %p\n", jvmHandle, env); + DBG_PRINT("sendMouseEvent: null JNIEnv\n"); return; } jint javaMods[] = { 0 } ; @@ -700,9 +671,8 @@ static jmethodID windowRepaintID = NULL; (jint) location.x, (jint) location.y, javaButtonNum, scrollDeltaY); - /* if (shallBeDetached) { - (*jvmHandle)->DetachCurrentThread(jvmHandle); - } */ + // detaching thread not required - daemon + // NewtCommon_ReleaseJNIEnv(shallBeDetached); } - (NSPoint) screenPos2NewtClientWinPos: (NSPoint) p @@ -754,14 +724,9 @@ static jmethodID windowRepaintID = NULL; return; } int shallBeDetached = 0; - JNIEnv* env; - if( NULL != jvmHandle ) { - env = NewtCommon_GetJNIEnv(jvmHandle, [self getJVMVersion], 1 /* asDaemon */, &shallBeDetached); - } else { - env = NULL; - } + JNIEnv* env = NewtCommon_GetJNIEnv(1 /* asDaemon */, &shallBeDetached); if(NULL==env) { - DBG_PRINT("sendKeyEvent: JVM %p JNIEnv %p\n", jvmHandle, env); + DBG_PRINT("sendKeyEvent: null JNIEnv\n"); return; } @@ -792,9 +757,8 @@ static jmethodID windowRepaintID = NULL; evType, javaMods, keyCode, keyChar, keyChar); } - /* if (shallBeDetached) { - (*jvmHandle)->DetachCurrentThread(jvmHandle); - } */ + // detaching thread not required - daemon + // NewtCommon_ReleaseJNIEnv(shallBeDetached); } @end @@ -1038,23 +1002,16 @@ static jmethodID windowRepaintID = NULL; return; } int shallBeDetached = 0; - JavaVM *jvmHandle = [newtView getJVMHandle]; - JNIEnv* env; - if( NULL != jvmHandle ) { - env = NewtCommon_GetJNIEnv(jvmHandle, [newtView getJVMVersion], 1 /* asDaemon */, &shallBeDetached); - } else { - env = NULL; - } + JNIEnv* env = NewtCommon_GetJNIEnv(1 /* asDaemon */, &shallBeDetached); if(NULL==env) { - DBG_PRINT("focusChanged: JVM %p JNIEnv %p\n", jvmHandle, env); + DBG_PRINT("focusChanged: null JNIEnv\n"); return; } (*env)->CallVoidMethod(env, javaWindowObject, focusChangedID, JNI_FALSE, (gained == YES) ? JNI_TRUE : JNI_FALSE); - /* if (shallBeDetached) { - (*jvmHandle)->DetachCurrentThread(jvmHandle); - } */ + // detaching thread not required - daemon + // NewtCommon_ReleaseJNIEnv(shallBeDetached); } - (void) keyDown: (NSEvent*) theEvent @@ -1147,37 +1104,31 @@ static jmethodID windowRepaintID = NULL; - (void)windowDidResize: (NSNotification*) notification { - JNIEnv* env = NULL; jobject javaWindowObject = NULL; int shallBeDetached = 0; - JavaVM *jvmHandle = NULL; + JNIEnv* env = NewtCommon_GetJNIEnv(1 /* asDaemon */, &shallBeDetached); + if( NULL == env ) { + DBG_PRINT("windowDidResize: null JNIEnv\n"); + return; + } NewtView* newtView = (NewtView *) [self contentView]; if( [newtView isKindOfClass:[NewtView class]] ) { javaWindowObject = [newtView getJavaWindowObject]; - if (javaWindowObject != NULL) { - jvmHandle = [newtView getJVMHandle]; - if( NULL != jvmHandle ) { - env = NewtCommon_GetJNIEnv(jvmHandle, [newtView getJVMVersion], 1 /* asDaemon */, &shallBeDetached); - } - } } + if( NULL != javaWindowObject ) { + // update insets on every window resize for lack of better hook place + [self updateInsets: env jwin:javaWindowObject]; - // update insets on every window resize for lack of better hook place - [self updateInsets: env jwin:javaWindowObject]; - - if( NULL != env && NULL != javaWindowObject ) { NSRect frameRect = [self frame]; NSRect contentRect = [self contentRectForFrameRect: frameRect]; (*env)->CallVoidMethod(env, javaWindowObject, sizeChangedID, JNI_FALSE, (jint) contentRect.size.width, (jint) contentRect.size.height, JNI_FALSE); - - /* if (shallBeDetached) { - (*jvmHandle)->DetachCurrentThread(jvmHandle); - } */ } + // detaching thread not required - daemon + // NewtCommon_ReleaseJNIEnv(shallBeDetached); } - (void)windowDidMove: (NSNotification*) notification @@ -1192,15 +1143,9 @@ static jmethodID windowRepaintID = NULL; return; } int shallBeDetached = 0; - JavaVM *jvmHandle = [newtView getJVMHandle]; - JNIEnv* env; - if( NULL != jvmHandle ) { - env = NewtCommon_GetJNIEnv(jvmHandle, [newtView getJVMVersion], 1 /* asDaemon */, &shallBeDetached); - } else { - env = NULL; - } + JNIEnv* env = NewtCommon_GetJNIEnv(1 /* asDaemon */, &shallBeDetached); if(NULL==env) { - DBG_PRINT("windowDidMove: JVM %p JNIEnv %p\n", jvmHandle, env); + DBG_PRINT("windowDidMove: null JNIEnv\n"); return; } @@ -1208,9 +1153,8 @@ static jmethodID windowRepaintID = NULL; p0 = [self getLocationOnScreen: p0]; (*env)->CallVoidMethod(env, javaWindowObject, positionChangedID, JNI_FALSE, (jint) p0.x, (jint) p0.y); - /* if (shallBeDetached) { - (*jvmHandle)->DetachCurrentThread(jvmHandle); - } */ + // detaching thread not required - daemon + // NewtCommon_ReleaseJNIEnv(shallBeDetached); } - (BOOL)windowShouldClose: (id) sender @@ -1226,13 +1170,12 @@ static jmethodID windowRepaintID = NULL; - (BOOL) windowClosingImpl: (BOOL) force { jboolean closed = JNI_FALSE; - NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; NewtView* newtView = (NewtView *) [self contentView]; if( ! [newtView isKindOfClass:[NewtView class]] ) { return NO; } - + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; [newtView cursorHide: NO enter: -1]; if( false == [newtView getDestroyNotifySent] ) { @@ -1240,26 +1183,16 @@ static jmethodID windowRepaintID = NULL; DBG_PRINT( "*************** windowWillClose.0: %p\n", (void *)(intptr_t)javaWindowObject); if (javaWindowObject == NULL) { DBG_PRINT("windowWillClose: null javaWindowObject\n"); + [pool release]; return NO; } int shallBeDetached = 0; - JavaVM *jvmHandle = [newtView getJVMHandle]; - JNIEnv* env = NULL; -NS_DURING - if( NULL != jvmHandle ) { - env = NewtCommon_GetJNIEnv(jvmHandle, [newtView getJVMVersion], 1 /* asDaemon */, &shallBeDetached); - } -NS_HANDLER - jvmHandle = NULL; - env = NULL; - [newtView setJVMHandle: NULL]; - DBG_PRINT("windowWillClose: JVMHandler Exception\n"); -NS_ENDHANDLER - DBG_PRINT("windowWillClose: JVM %p JNIEnv %p\n", jvmHandle, env); + JNIEnv* env = NewtCommon_GetJNIEnv(1 /* asDaemon */, &shallBeDetached); if(NULL==env) { + DBG_PRINT("windowWillClose: null JNIEnv\n"); + [pool release]; return NO; } - [newtView setDestroyNotifySent: true]; // earmark assumption of being closed closed = (*env)->CallBooleanMethod(env, javaWindowObject, windowDestroyNotifyID, force ? JNI_TRUE : JNI_FALSE); if(!force && !closed) { @@ -1267,9 +1200,8 @@ NS_ENDHANDLER [newtView setDestroyNotifySent: false]; } - /* if (shallBeDetached) { - (*jvmHandle)->DetachCurrentThread(jvmHandle); - } */ + // detaching thread not required - daemon + // NewtCommon_ReleaseJNIEnv(shallBeDetached); DBG_PRINT( "*************** windowWillClose.X: %p, closed %d\n", (void *)(intptr_t)javaWindowObject, (int)closed); } else { DBG_PRINT( "*************** windowWillClose (skip)\n"); -- cgit v1.2.3