aboutsummaryrefslogtreecommitdiffstats
path: root/src/nativewindow
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2011-10-13 17:04:17 +0200
committerSven Gothel <[email protected]>2011-10-13 17:04:17 +0200
commitd186f6e945fd157b219231fb3861b3b0ce10ee75 (patch)
treeb3851f97222cf224251956cb8ad06508c7a9d090 /src/nativewindow
parent3fd89ccc138eddb915372cff4843f69f764048a7 (diff)
OSX/SWT: Adding OSXUtil: RunOnMainThread(), IsMainThread() / Utilizing those for SWT access/calls
Adding OSXUtil: RunOnMainThread(), IsMainThread() - Issuing a native call where the user Runnable is to be performed on the main thread - Enable query if we are on the main thread. Utilizing those for SWT access/calls - Using the above to call all SWT functions on the main thread if required (incomplete) TODO/Issues: - JOGL OSX CGL Context fails, ie expecting NS, but having CGL
Diffstat (limited to 'src/nativewindow')
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java10
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/swt/SWTAccessor.java65
-rw-r--r--src/nativewindow/native/NativewindowCommon.c27
-rw-r--r--src/nativewindow/native/NativewindowCommon.h2
-rw-r--r--src/nativewindow/native/macosx/OSXmisc.m (renamed from src/nativewindow/native/macosx/OSXmisc.c)103
5 files changed, 185 insertions, 22 deletions
diff --git a/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java b/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java
index ffd23fef7..ca303e6bc 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java
@@ -34,6 +34,16 @@ public class OSXUtil {
return (Point) GetLocationOnScreen0(windowOrView, src_x, src_y);
}
+ public static void RunOnMainThread(boolean waitUntilDone, Runnable runnable) {
+ RunOnMainThread0(waitUntilDone, runnable);
+ }
+
+ public static boolean IsMainThread() {
+ return IsMainThread0();
+ }
+
private static native boolean initIDs0();
private static native Object GetLocationOnScreen0(long windowOrView, int src_x, int src_y);
+ private static native void RunOnMainThread0(boolean waitUntilDone, Runnable runnable);
+ private static native boolean IsMainThread0();
}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/swt/SWTAccessor.java b/src/nativewindow/classes/jogamp/nativewindow/swt/SWTAccessor.java
index d1f5efc88..1ad909897 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/swt/SWTAccessor.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/swt/SWTAccessor.java
@@ -42,6 +42,8 @@ import javax.media.nativewindow.x11.X11GraphicsDevice;
import com.jogamp.common.util.ReflectionUtil;
import javax.media.nativewindow.macosx.MacOSXGraphicsDevice;
+import jogamp.nativewindow.macosx.OSXUtil;
+
public class SWTAccessor {
static final Field swt_control_handle;
static final boolean swt_uses_long_handles;
@@ -60,7 +62,7 @@ public class SWTAccessor {
static final String str_internal_dispose_GC = "internal_dispose_GC";
static final String str_OS_gtk_class = "org.eclipse.swt.internal.gtk.OS";
- static final Class OS_gtk_class;
+ static final Class<?> OS_gtk_class;
static final Method OS_gtk_widget_realize;
static final Method OS_gtk_widget_unrealize;
static final Method OS_GTK_WIDGET_WINDOW;
@@ -113,9 +115,9 @@ public class SWTAccessor {
}
swt_control_internal_dispose_GC = m;
- Class c=null;
+ Class<?> c=null;
Method m1=null, m2=null, m3=null, m4=null, m5=null;
- Class handleType = swt_uses_long_handles ? long.class : int.class ;
+ Class<?> handleType = swt_uses_long_handles ? long.class : int.class ;
if( NativeWindowFactory.TYPE_X11 == NativeWindowFactory.getNativeWindowType(false) ) {
try {
c = ReflectionUtil.getClass(str_OS_gtk_class, false, SWTAccessor.class.getClassLoader());
@@ -179,15 +181,19 @@ public class SWTAccessor {
return h;
}
- public static void setRealized(Control swtControl, boolean realize) {
- long handle = getHandle(swtControl);
+ public static void setRealized(final Control swtControl, final boolean realize) {
+ final long handle = getHandle(swtControl);
if(null != OS_gtk_class) {
- if(realize) {
- callStaticMethodL2V(OS_gtk_widget_realize, handle);
- } else {
- callStaticMethodL2V(OS_gtk_widget_unrealize, handle);
- }
+ invoke(true, new Runnable() {
+ public void run() {
+ if(realize) {
+ callStaticMethodL2V(OS_gtk_widget_realize, handle);
+ } else {
+ callStaticMethodL2V(OS_gtk_widget_unrealize, handle);
+ }
+ }
+ });
}
}
@@ -220,21 +226,38 @@ public class SWTAccessor {
throw new UnsupportedOperationException("n/a for this windowing system: "+NativeWindowFactory.getNativeWindowType(false));
}
- public static long newGC(Control swtControl, GCData gcData) {
- Object o = ReflectionUtil.callMethod(swtControl, swt_control_internal_new_GC, new Object[] { gcData });
- if(o instanceof Number) {
- return ((Number)o).longValue();
+ public static long newGC(final Control swtControl, final GCData gcData) {
+ final Object[] o = new Object[1];
+ invoke(true, new Runnable() {
+ public void run() {
+ o[0] = ReflectionUtil.callMethod(swtControl, swt_control_internal_new_GC, new Object[] { gcData });
+ }
+ });
+ if(o[0] instanceof Number) {
+ return ((Number)o[0]).longValue();
} else {
- throw new InternalError("SWT internal_new_GC did not return int or long but "+o.getClass());
+ throw new InternalError("SWT internal_new_GC did not return int or long but "+o[0].getClass());
}
}
- public static void disposeGC(Control swtControl, long gc, GCData gcData) {
- if(swt_uses_long_handles) {
- ReflectionUtil.callMethod(swtControl, swt_control_internal_dispose_GC, new Object[] { new Long(gc), gcData });
- } else {
- ReflectionUtil.callMethod(swtControl, swt_control_internal_dispose_GC, new Object[] { new Integer((int)gc), gcData });
- }
+ public static void disposeGC(final Control swtControl, final long gc, final GCData gcData) {
+ invoke(true, new Runnable() {
+ public void run() {
+ if(swt_uses_long_handles) {
+ ReflectionUtil.callMethod(swtControl, swt_control_internal_dispose_GC, new Object[] { new Long(gc), gcData });
+ } else {
+ ReflectionUtil.callMethod(swtControl, swt_control_internal_dispose_GC, new Object[] { new Integer((int)gc), gcData });
+ }
+ }
+ });
+ }
+
+ public static void invoke(boolean wait, Runnable runnable) {
+ if(Platform.OS_TYPE == Platform.OSType.MACOS) {
+ OSXUtil.RunOnMainThread(wait, runnable);
+ } else {
+ runnable.run();
+ }
}
}
diff --git a/src/nativewindow/native/NativewindowCommon.c b/src/nativewindow/native/NativewindowCommon.c
index e357045d6..b866646a6 100644
--- a/src/nativewindow/native/NativewindowCommon.c
+++ b/src/nativewindow/native/NativewindowCommon.c
@@ -55,3 +55,30 @@ jchar* NativewindowCommon_GetNullTerminatedStringChars(JNIEnv* env, jstring str)
return strChars;
}
+JNIEnv* NativewindowCommon_GetJNIEnv (JavaVM * jvmHandle, int jvmVersion, int * shallBeDetached) {
+ JNIEnv* curEnv = NULL;
+ JNIEnv* newEnv = NULL;
+ int envRes;
+
+ // retrieve this thread's JNIEnv curEnv - or detect it's detached
+ 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);
+ return NULL;
+ }
+ curEnv = newEnv;
+ } else if( JNI_OK != envRes ) {
+ // oops ..
+ fprintf(stderr, "can't GetEnv: %d\n", envRes);
+ return NULL;
+ }
+ if (curEnv==NULL) {
+ fprintf(stderr, "env is NULL\n");
+ return NULL;
+ }
+ *shallBeDetached = NULL != newEnv;
+ return curEnv;
+}
+
diff --git a/src/nativewindow/native/NativewindowCommon.h b/src/nativewindow/native/NativewindowCommon.h
index 5dc5debef..41c4bd0eb 100644
--- a/src/nativewindow/native/NativewindowCommon.h
+++ b/src/nativewindow/native/NativewindowCommon.h
@@ -12,4 +12,6 @@ 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 * shallBeDetached);
+
#endif
diff --git a/src/nativewindow/native/macosx/OSXmisc.c b/src/nativewindow/native/macosx/OSXmisc.m
index fe0d59bd7..af71b4a0a 100644
--- a/src/nativewindow/native/macosx/OSXmisc.c
+++ b/src/nativewindow/native/macosx/OSXmisc.m
@@ -36,6 +36,9 @@
#include "NativewindowCommon.h"
#include "jogamp_nativewindow_macosx_OSXUtil.h"
+static const char * const ClazzNameRunnable = "java/lang/Runnable";
+static jmethodID runnableRunID = NULL;
+
static const char * const ClazzNamePoint = "javax/media/nativewindow/util/Point";
static const char * const ClazzAnyCstrName = "<init>";
static const char * const ClazzNamePointCstrSignature = "(II)V";
@@ -63,6 +66,14 @@ Java_jogamp_nativewindow_macosx_OSXUtil_initIDs0(JNIEnv *env, jclass _unused) {
ClazzNamePoint, ClazzAnyCstrName, ClazzNamePointCstrSignature);
}
+ c = (*env)->FindClass(env, ClazzNameRunnable);
+ if(NULL==c) {
+ NativewindowCommon_FatalError(env, "FatalError Java_jogamp_newt_driver_macosx_MacWindow_initIDs0: can't find %s", ClazzNameRunnable);
+ }
+ runnableRunID = (*env)->GetMethodID(env, c, "run", "()V");
+ 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;
@@ -76,6 +87,8 @@ Java_jogamp_nativewindow_macosx_OSXUtil_initIDs0(JNIEnv *env, jclass _unused) {
JNIEXPORT jobject JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_GetLocationOnScreen0
(JNIEnv *env, jclass unused, jlong winOrView, jint src_x, jint src_y)
{
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+
/**
* return location in 0/0 top-left space,
* OSX is 0/0 bottom-left space naturally
@@ -111,6 +124,94 @@ JNIEXPORT jobject JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_GetLocationOnS
dest_x = (int) oS.x;
dest_y = (int) screenRect.origin.y + screenRect.size.height - oS.y;
- return (*env)->NewObject(env, pointClz, pointCstr, (jint)dest_x, (jint)dest_y);
+ jobject res = (*env)->NewObject(env, pointClz, pointCstr, (jint)dest_x, (jint)dest_y);
+
+ [pool release];
+
+ return res;
+}
+
+@interface MainRunnable : NSObject
+
+{
+ JavaVM *jvmHandle;
+ int jvmVersion;
+ jobject runnableObj;
+}
+
+- (id) initWithRunnable: (jobject)runnable jvmHandle: (JavaVM*)jvm jvmVersion: (int)jvmVers;
+- (void) jRun;
+
+@end
+
+@implementation MainRunnable
+
+- (id) initWithRunnable: (jobject)runnable jvmHandle: (JavaVM*)jvm jvmVersion: (int)jvmVers
+{
+ jvmHandle = jvm;
+ jvmVersion = jvmVers;
+ runnableObj = runnable;
+ return [super init];
+}
+
+- (void) jRun
+{
+ int shallBeDetached = 0;
+ JNIEnv* env = NativewindowCommon_GetJNIEnv(jvmHandle, jvmVersion, &shallBeDetached);
+ if(NULL!=env) {
+ (*env)->CallVoidMethod(env, runnableObj, runnableRunID);
+
+ if (shallBeDetached) {
+ (*jvmHandle)->DetachCurrentThread(jvmHandle);
+ }
+ }
}
+@end
+
+
+/*
+ * Class: Java_jogamp_nativewindow_macosx_OSXUtil
+ * Method: RunOnMainThread0
+ * Signature: (ZLjava/lang/Runnable;)V
+ */
+JNIEXPORT void JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_RunOnMainThread0
+ (JNIEnv *env, jclass unused, jboolean jwait, jobject runnable)
+{
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+
+ if ( NO == [NSThread isMainThread] ) {
+ jobject runnableGlob = (*env)->NewGlobalRef(env, runnable);
+
+ BOOL wait = (JNI_TRUE == jwait) ? YES : NO;
+ JavaVM *jvmHandle = NULL;
+ int jvmVersion = 0;
+
+ if(0 != (*env)->GetJavaVM(env, &jvmHandle)) {
+ jvmHandle = NULL;
+ } else {
+ jvmVersion = (*env)->GetVersion(env);
+ }
+
+ MainRunnable * mr = [[MainRunnable alloc] initWithRunnable: runnableGlob jvmHandle: jvmHandle jvmVersion: jvmVersion];
+ [mr performSelectorOnMainThread:@selector(jRun) withObject:nil waitUntilDone:wait];
+ [mr release];
+
+ (*env)->DeleteGlobalRef(env, runnableGlob);
+ } else {
+ (*env)->CallVoidMethod(env, runnable, runnableRunID);
+ }
+
+ [pool release];
+}
+
+/*
+ * Class: Java_jogamp_nativewindow_macosx_OSXUtil
+ * Method: RunOnMainThread0
+ * Signature: (ZLjava/lang/Runnable;)V
+ */
+JNIEXPORT jboolean JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_IsMainThread0
+ (JNIEnv *env, jclass unused)
+{
+ return ( [NSThread isMainThread] == YES ) ? JNI_TRUE : JNI_FALSE ;
+}