aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--make/stub_includes/opengl/macosx-window-system.h1
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java1
-rw-r--r--src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java2
-rw-r--r--src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java1
-rw-r--r--src/jogl/native/macosx/MacOSXWindowSystemInterface.m5
-rw-r--r--src/newt/classes/com/jogamp/newt/util/MainThread.java331
-rw-r--r--src/newt/classes/jogamp/newt/DisplayImpl.java19
-rw-r--r--src/newt/classes/jogamp/newt/WindowImpl.java7
-rw-r--r--src/newt/classes/jogamp/newt/driver/awt/AWTEDTUtil.java61
-rw-r--r--src/newt/classes/jogamp/newt/driver/macosx/MacDisplay.java36
-rw-r--r--src/newt/classes/jogamp/newt/driver/macosx/MacWindow.java165
-rw-r--r--src/newt/native/MacWindow.m235
-rw-r--r--src/newt/native/NewtCommon.c27
-rw-r--r--src/newt/native/NewtCommon.h2
-rw-r--r--src/newt/native/NewtMacWindow.h24
-rw-r--r--src/newt/native/NewtMacWindow.m189
-rw-r--r--src/newt/native/X11Window.c26
17 files changed, 618 insertions, 514 deletions
diff --git a/make/stub_includes/opengl/macosx-window-system.h b/make/stub_includes/opengl/macosx-window-system.h
index 7d2704be4..18cf6c719 100644
--- a/make/stub_includes/opengl/macosx-window-system.h
+++ b/make/stub_includes/opengl/macosx-window-system.h
@@ -24,6 +24,7 @@ void *getNSView(void* nsContext);
void* createContext(void* shareContext,
void* nsView,
void* pixelFormat,
+ Bool opaque,
int* viewNotReady);
void *getCGLContext(void* nsContext);
Bool makeCurrentContext(void* nsContext);
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java b/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java
index ed5b88455..14e67a2c1 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java
@@ -75,6 +75,7 @@ public class EGLGraphicsConfiguration extends DefaultGraphicsConfiguration imple
GLProfile glp = capsRequested.getGLProfile();
long cfg = EGLConfigId2EGLConfig(glp, dpy, cfgID);
EGLGLCapabilities caps = EGLConfig2Capabilities(glp, dpy, cfg, false, capsRequested.isOnscreen(), capsRequested.isPBuffer());
+ caps = (EGLGLCapabilities) GLGraphicsConfigurationUtil.fixOpaqueGLCapabilities(caps, capsRequested.isBackgroundOpaque()); // FIXME: valid to override EGL transparency ?
return new EGLGraphicsConfiguration(absScreen, caps, capsRequested, new DefaultGLCapabilitiesChooser());
}
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java
index 150a5e105..6d6b79b42 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java
@@ -143,6 +143,7 @@ public abstract class MacOSXCGLContext extends GLContextImpl
contextHandle = CGL.createContext(share,
drawable.getHandle(),
pixelFormat,
+ capabilities.isBackgroundOpaque(),
viewNotReady, 0);
if (contextHandle == 0) {
if (viewNotReady[0] == 1) {
@@ -161,6 +162,7 @@ public abstract class MacOSXCGLContext extends GLContextImpl
}
GLCapabilitiesImmutable caps = MacOSXCGLGraphicsConfiguration.NSPixelFormat2GLCapabilities(glProfile, pixelFormat);
+ caps = GLGraphicsConfigurationUtil.fixOpaqueGLCapabilities(caps, capabilities.isBackgroundOpaque());
config.setChosenCapabilities(caps);
} finally {
CGL.deletePixelFormat(pixelFormat);
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java
index 178f2777c..a485f8ce8 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java
@@ -42,7 +42,6 @@ import javax.media.nativewindow.GraphicsConfigurationFactory;
import javax.media.nativewindow.CapabilitiesImmutable;
import javax.media.nativewindow.NativeSurface;
import javax.media.nativewindow.NativeWindowFactory;
-import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLCapabilitiesImmutable;
import javax.media.opengl.GLCapabilitiesChooser;
import javax.media.opengl.GLContext;
diff --git a/src/jogl/native/macosx/MacOSXWindowSystemInterface.m b/src/jogl/native/macosx/MacOSXWindowSystemInterface.m
index 9a7356b7c..5973ca45b 100644
--- a/src/jogl/native/macosx/MacOSXWindowSystemInterface.m
+++ b/src/jogl/native/macosx/MacOSXWindowSystemInterface.m
@@ -470,6 +470,7 @@ void deletePixelFormat(void* pixelFormat) {
void* createContext(void* shareContext,
void* view,
void* pixelFormat,
+ Bool opaque,
int* viewNotReady)
{
getRendererInfo();
@@ -520,6 +521,10 @@ void* createContext(void* shareContext,
if (nsContext != nil) {
if (nsView != nil) {
+ if(!opaque) {
+ long zeroOpacity = 0;
+ [nsContext setValues:&zeroOpacity forParameter:NSOpenGLCPSurfaceOpacity];
+ }
[nsContext setView:nsView];
[nsView unlockFocus];
}
diff --git a/src/newt/classes/com/jogamp/newt/util/MainThread.java b/src/newt/classes/com/jogamp/newt/util/MainThread.java
index 07c58d731..f74845afc 100644
--- a/src/newt/classes/com/jogamp/newt/util/MainThread.java
+++ b/src/newt/classes/com/jogamp/newt/util/MainThread.java
@@ -41,22 +41,19 @@ import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;
import java.security.AccessControlContext;
import java.security.AccessController;
-import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
-import java.util.Timer;
-import java.util.TimerTask;
-import javax.media.nativewindow.NativeWindowException;
import javax.media.nativewindow.NativeWindowFactory;
+import com.jogamp.common.os.Platform;
import com.jogamp.common.util.ReflectionUtil;
-import com.jogamp.common.util.RunnableTask;
import com.jogamp.newt.Display;
+
import jogamp.newt.Debug;
+import jogamp.newt.DefaultEDTUtil;
import jogamp.newt.NEWTJNILibLoader;
-import jogamp.newt.driver.awt.AWTEDTUtil;
/**
* NEWT Utility class MainThread<P>
@@ -92,26 +89,26 @@ import jogamp.newt.driver.awt.AWTEDTUtil;
* Which starts 4 threads, each with a window and OpenGL rendering.<br>
*/
public class MainThread implements EDTUtil {
- private static final AccessControlContext localACC = AccessController.getContext();
+ private static final String MACOSXDisplayClassName = "jogamp.newt.driver.macosx.MacDisplay";
/** if true, use the main thread EDT, otherwise AWT's EDT */
- public static final boolean HINT_USE_MAIN_THREAD = !NativeWindowFactory.isAWTAvailable() ||
- Debug.getBooleanProperty("newt.MainThread.force", true, localACC);
+ public static final boolean HINT_USE_MAIN_THREAD;
+
+ static {
+ final AccessControlContext localACC = AccessController.getContext();
+ Platform.initSingleton();
+ NativeWindowFactory.initSingleton(true);
+ NEWTJNILibLoader.loadNEWT();
+ HINT_USE_MAIN_THREAD = !NativeWindowFactory.isAWTAvailable() ||
+ Debug.getBooleanProperty("newt.MainThread.force", true, localACC);
+ }
+
public static boolean useMainThread = false;
protected static final boolean DEBUG = Debug.debug("MainThread");
private static final MainThread singletonMainThread = new MainThread(); // one singleton MainThread
- private static boolean isExit=false;
- private static volatile boolean isRunning=false;
- private static final Object edtLock=new Object();
- private static boolean shouldStop;
- private static ArrayList<RunnableTask> tasks;
- private static Thread mainThread;
-
- private static Timer pumpMessagesTimer=null;
- private static TimerTask pumpMessagesTimerTask=null;
private static final Map<Display, Runnable> pumpMessageDisplayMap = new HashMap<Display, Runnable>();
static class MainAction extends Thread {
@@ -127,11 +124,7 @@ public class MainThread implements EDTUtil {
@Override
public void run() {
- if ( useMainThread ) {
- // we have to start first to provide the service ..
- singletonMainThread.waitUntilRunning();
- }
-
+ if(DEBUG) System.err.println("MainAction.run(): "+Thread.currentThread().getName()+" start");
// start user app ..
try {
Class<?> mainClass = ReflectionUtil.getClass(mainClassName, true, getClass().getClassLoader());
@@ -166,15 +159,20 @@ public class MainThread implements EDTUtil {
}
private static MainAction mainAction;
+ private static EDTUtil internalEDT;
+
/** Your new java application main entry, which pipelines your application */
public static void main(String[] args) {
useMainThread = HINT_USE_MAIN_THREAD;
+ final Platform.OSType osType = Platform.getOSType();
+ final boolean isMacOSX = osType == Platform.OSType.MACOS;
+
if(DEBUG) {
System.err.println("MainThread.main(): "+Thread.currentThread().getName()+
", useMainThread "+ useMainThread +
", HINT_USE_MAIN_THREAD "+ HINT_USE_MAIN_THREAD +
- ", isAWTAvailable " + NativeWindowFactory.isAWTAvailable());
+ ", isAWTAvailable " + NativeWindowFactory.isAWTAvailable() + ", ostype "+osType+", isMacOSX "+isMacOSX);
}
if(!useMainThread && !NativeWindowFactory.isAWTAvailable()) {
@@ -191,25 +189,34 @@ public class MainThread implements EDTUtil {
System.arraycopy(args, 1, mainClassArgs, 0, args.length-1);
}
- NEWTJNILibLoader.loadNEWT();
-
mainAction = new MainAction(mainClassName, mainClassArgs);
- if(NativeWindowFactory.TYPE_MACOSX.equals(NativeWindowFactory.getNativeWindowType(false))) {
- ReflectionUtil.callStaticMethod("jogamp.newt.macosx.MacDisplay", "initSingleton",
+ if(isMacOSX) {
+ ReflectionUtil.callStaticMethod(MACOSXDisplayClassName, "initSingleton",
null, null, MainThread.class.getClassLoader());
}
if ( useMainThread ) {
- shouldStop = false;
- tasks = new ArrayList<RunnableTask>();
- mainThread = Thread.currentThread();
+ final Thread current = Thread.currentThread();
+ internalEDT = new DefaultEDTUtil(current.getThreadGroup(), "MainThread", new Runnable() {
+ public void run() { dispatchMessages(); } });
+ if(DEBUG) System.err.println("MainThread - run: "+internalEDT.toString());
+ internalEDT.start(); // forever !
+
// dispatch user's main thread ..
mainAction.start();
-
- // do our main thread task scheduling
- singletonMainThread.run();
+
+ if(isMacOSX) {
+ try {
+ if(DEBUG) System.err.println("MainThread - runNSApp");
+ ReflectionUtil.callStaticMethod(MACOSXDisplayClassName, "runNSApplication",
+ null, null, MainThread.class.getClassLoader());
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ if(DEBUG) System.err.println("MainThread - wait until last non daemon thread ends ...");
} else {
// run user's main in this thread
mainAction.run();
@@ -227,273 +234,49 @@ public class MainThread implements EDTUtil {
}
public static void addPumpMessage(Display dpy, Runnable pumpMessage) {
- if(DEBUG) {
- System.err.println("MainThread.addPumpMessage(): "+Thread.currentThread().getName()+
- " - dpy "+dpy+", USE_MAIN_THREAD " + useMainThread +
- " - hasAWT " + NativeWindowFactory.isAWTAvailable() );
- }
- if(!useMainThread && !NativeWindowFactory.isAWTAvailable()) {
- throw new RuntimeException("!USE_MAIN_THREAD and no AWT available");
- }
-
synchronized (pumpMessageDisplayMap) {
- if(!useMainThread && null == pumpMessagesTimer) {
- // AWT pump messages .. MAIN_THREAD uses main thread
- pumpMessagesTimer = new Timer();
- pumpMessagesTimerTask = new TimerTask() {
- public void run() {
- synchronized(pumpMessageDisplayMap) {
- for(Iterator<Runnable> i = pumpMessageDisplayMap.values().iterator(); i.hasNext(); ) {
- i.next().run();
- }
- }
- }
- };
- pumpMessagesTimer.scheduleAtFixedRate(pumpMessagesTimerTask, 0, defaultEDTPollGranularity);
- }
pumpMessageDisplayMap.put(dpy, pumpMessage);
}
}
- final public void reset() {
- if(NativeWindowFactory.isAWTAvailable()) {
- AWTEDTUtil.getSingleton().reset();
+ private static void dispatchMessages() {
+ synchronized(pumpMessageDisplayMap) {
+ for(Iterator<Runnable> i = pumpMessageDisplayMap.values().iterator(); i.hasNext(); ) {
+ i.next().run();
+ }
}
- // nop
+ }
+
+ final public void reset() {
+ // nop: ALWAYS RUNNING
}
final public void start() {
- if(NativeWindowFactory.isAWTAvailable()) {
- AWTEDTUtil.getSingleton().start();
- }
- // nop
+ // nop: ALWAYS RUNNING
}
final public boolean isCurrentThreadEDT() {
- if(NativeWindowFactory.isAWTAvailable()) {
- return AWTEDTUtil.getSingleton().isCurrentThreadEDT();
- }
- return isRunning() && mainThread == Thread.currentThread() ;
+ return internalEDT.isCurrentThreadEDT();
}
final public boolean isRunning() {
- if( useMainThread ) {
- return isRunning;
- }
- return true; // AWT is always running
+ return true; // ALWAYS RUNNING
}
final public void invokeStop(Runnable r) {
- invokeImpl(true, r, true);
+ internalEDT.invoke(true, r); // ALWAYS RUNNING
}
final public void invoke(boolean wait, Runnable r) {
- invokeImpl(wait, r, false);
- }
-
- private void invokeImpl(boolean wait, Runnable task, boolean stop) {
- if(task == null) {
- return;
- }
-
- if(NativeWindowFactory.isAWTAvailable()) {
- AWTEDTUtil.getSingleton().invokeImpl(wait, task, stop);
- return;
- }
-
- // if this main thread is not being used or
- // if this is already the main thread .. just execute.
- // FIXME: start if not started .. sync logic with DefaultEDTUtil!!!
- if( !isRunning() || mainThread == Thread.currentThread() ) {
- task.run();
- return;
- }
-
- Throwable throwable = null;
- RunnableTask rTask = null;
- Object rTaskLock = new Object();
- synchronized(rTaskLock) {
- synchronized(edtLock) {
- if( shouldStop ) {
- // drop task ..
- if(DEBUG) {
- System.err.println("Warning: EDT about (1) to stop, won't enqueue new task: "+this);
- Thread.dumpStack();
- }
- return;
- }
- // System.err.println(Thread.currentThread()+" XXX stop: "+stop+", tasks: "+tasks.size()+", task: "+task);
- // Thread.dumpStack();
- if(stop) {
- shouldStop = true;
- if(DEBUG) System.err.println("MainThread.stop(): "+Thread.currentThread().getName()+" start");
- }
- if( isCurrentThreadEDT() ) {
- task.run();
- wait = false; // running in same thread (EDT) -> no wait
- if(stop && tasks.size()>0) {
- System.err.println("Warning: EDT about (2) to stop, having remaining tasks: "+tasks.size()+" - "+this);
- if(DEBUG) {
- Thread.dumpStack();
- }
- }
- } else {
- synchronized(tasks) {
- start(); // start if not started yet and !shouldStop
- wait = wait && isRunning();
- rTask = new RunnableTask(task,
- wait ? rTaskLock : null,
- true /* always catch and report Exceptions, don't disturb EDT */);
- if(stop) {
- rTask.setAttachment(new Boolean(true)); // mark final task
- }
- // append task ..
- tasks.add(rTask);
- tasks.notifyAll();
- }
- }
- }
- if( wait ) {
- try {
- rTaskLock.wait(); // free lock, allow execution of rTask
- } catch (InterruptedException ie) {
- throwable = ie;
- }
- if(null==throwable) {
- throwable = rTask.getThrowable();
- }
- if(null!=throwable) {
- if(throwable instanceof NativeWindowException) {
- throw (NativeWindowException)throwable;
- }
- throw new RuntimeException(throwable);
- }
- }
- }
- if(DEBUG && stop) {
- System.err.println(Thread.currentThread()+": EDT signal STOP X edt: "+this);
- }
+ internalEDT.invoke(wait, r);
}
final public void waitUntilIdle() {
- if(NativeWindowFactory.isAWTAvailable()) {
- AWTEDTUtil.getSingleton().waitUntilIdle();
- }
+ internalEDT.waitUntilIdle();
}
final public void waitUntilStopped() {
- if(NativeWindowFactory.isAWTAvailable()) {
- AWTEDTUtil.getSingleton().waitUntilStopped();
- }
- }
-
- private void waitUntilRunning() {
- synchronized(edtLock) {
- if(isExit) return;
-
- while(!isRunning) {
- try {
- edtLock.wait();
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
- }
-
- public void run() {
- if(DEBUG) System.err.println("MainThread.run(): "+Thread.currentThread().getName());
- synchronized(edtLock) {
- isRunning = true;
- edtLock.notifyAll();
- }
-
- RuntimeException error = null;
- try {
- do {
- // event dispatch
- if(!shouldStop) {
- synchronized(pumpMessageDisplayMap) {
- for(Iterator<Runnable> i = pumpMessageDisplayMap.values().iterator(); i.hasNext(); ) {
- i.next().run();
- }
- }
- }
- // wait for something todo ..
- Runnable task = null;
- synchronized(tasks) {
- // wait for tasks
- if(!shouldStop && tasks.size()==0) {
- try {
- tasks.wait(defaultEDTPollGranularity);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- // execute one task, if available
- if(tasks.size()>0) {
- task = tasks.remove(0);
- tasks.notifyAll();
- }
- }
- if(null!=task) {
- // Exceptions are always catched, see Runnable creation above
- task.run();
- }
- } while(!shouldStop) ;
- } catch (Throwable t) {
- // handle errors ..
- shouldStop = true;
- if(t instanceof RuntimeException) {
- error = (RuntimeException) t;
- } else {
- error = new RuntimeException("Within EDT", t);
- }
- } finally {
- if(DEBUG) {
- RunnableTask rt = ( tasks.size() > 0 ) ? tasks.get(0) : null ;
- System.err.println(/* getName()+*/"EDT run() END, tasks: "+tasks.size()+", "+rt+", "+error);
- }
- synchronized(edtLock) {
- if(null==error) {
- synchronized(tasks) {
- // drain remaining tasks (stop not on EDT),
- // while having tasks and no previous-task, or previous-task is non final
- RunnableTask task = null;
- while ( ( null == task || task.getAttachment() == null ) && tasks.size() > 0 ) {
- task = tasks.remove(0);
- task.run();
- tasks.notifyAll();
- }
- if(DEBUG) {
- if(null!=task && task.getAttachment()==null) {
- System.err.println("Warning: EDT exit: Last task Not Final: "+tasks.size()+", "+task);
- } else if(tasks.size()>0) {
- System.err.println("Warning: EDT exit: Remaining tasks Post Final: "+tasks.size());
- }
- Thread.dumpStack();
- }
- }
- }
- isRunning = !shouldStop;
- if(!isRunning) {
- edtLock.notifyAll();
- }
- }
- if(DEBUG) {
- System.err.println("EDT run() EXIT "+ error);
- }
- if(null!=error) {
- throw error;
- }
- } // finally
-
- if(DEBUG) System.err.println("MainThread.run(): "+Thread.currentThread().getName()+" fin");
- synchronized(edtLock) {
- isRunning = false;
- isExit = true;
- edtLock.notifyAll();
- }
+ // nop: ALWAYS RUNNING
}
}
diff --git a/src/newt/classes/jogamp/newt/DisplayImpl.java b/src/newt/classes/jogamp/newt/DisplayImpl.java
index 92add6a4e..ee370029e 100644
--- a/src/newt/classes/jogamp/newt/DisplayImpl.java
+++ b/src/newt/classes/jogamp/newt/DisplayImpl.java
@@ -39,6 +39,7 @@ import com.jogamp.newt.NewtFactory;
import com.jogamp.newt.event.NEWTEvent;
import com.jogamp.newt.event.NEWTEventConsumer;
+import jogamp.newt.driver.awt.AWTEDTUtil;
import jogamp.newt.event.NEWTEventTask;
import com.jogamp.newt.util.EDTUtil;
import com.jogamp.newt.util.MainThread;
@@ -171,12 +172,24 @@ public abstract class DisplayImpl extends Display {
protected void createEDTUtil() {
if(NewtFactory.useEDT()) {
if ( ! DEBUG_TEST_EDT_MAINTHREAD ) {
- Thread current = Thread.currentThread();
+ final Thread current = Thread.currentThread();
edtUtil = new DefaultEDTUtil(current.getThreadGroup(), "Display-"+getFQName(), dispatchMessagesRunnable);
} else {
// Begin JAU EDT Test ..
- MainThread.addPumpMessage(this, dispatchMessagesRunnable);
- edtUtil = MainThread.getSingleton();
+ final Display f_dpy = this;
+ final Runnable dispatchRunner = new Runnable() {
+ public void run() {
+ if(null!=f_dpy.getGraphicsDevice()) {
+ f_dpy.dispatchMessages();
+ } } };
+
+ if(NativeWindowFactory.isAWTAvailable()) {
+ AWTEDTUtil.addPumpMessage(this, dispatchRunner);
+ edtUtil = AWTEDTUtil.getSingleton();
+ } else {
+ MainThread.addPumpMessage(this, dispatchRunner);
+ edtUtil = MainThread.getSingleton();
+ }
// End JAU EDT Test ..
}
if(DEBUG) {
diff --git a/src/newt/classes/jogamp/newt/WindowImpl.java b/src/newt/classes/jogamp/newt/WindowImpl.java
index 9d54954b0..77e69fef7 100644
--- a/src/newt/classes/jogamp/newt/WindowImpl.java
+++ b/src/newt/classes/jogamp/newt/WindowImpl.java
@@ -478,6 +478,13 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
sb.append(0 != ( FLAG_IS_UNDECORATED & flags));
sb.append(", ");
+ if( 0 != ( FLAG_CHANGE_ALWAYSONTOP & flags) ) {
+ sb.append("*");
+ }
+ sb.append("ALWAYSONTOP_");
+ sb.append(0 != ( FLAG_IS_ALWAYSONTOP & flags));
+ sb.append(", ");
+
if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) ) {
sb.append("*");
}
diff --git a/src/newt/classes/jogamp/newt/driver/awt/AWTEDTUtil.java b/src/newt/classes/jogamp/newt/driver/awt/AWTEDTUtil.java
index 0737e3281..cca1e321c 100644
--- a/src/newt/classes/jogamp/newt/driver/awt/AWTEDTUtil.java
+++ b/src/newt/classes/jogamp/newt/driver/awt/AWTEDTUtil.java
@@ -29,13 +29,25 @@
package jogamp.newt.driver.awt;
import java.awt.EventQueue;
+import java.lang.reflect.InvocationTargetException;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Timer;
+import java.util.TimerTask;
+
import javax.media.nativewindow.NativeWindowException;
+
+import com.jogamp.newt.Display;
import com.jogamp.newt.util.EDTUtil;
import jogamp.newt.Debug;
public class AWTEDTUtil implements EDTUtil {
public static final boolean DEBUG = Debug.debug("EDT");
+ private static Timer pumpMessagesTimer=null;
+ private static TimerTask pumpMessagesTimerTask=null;
+ private static final Map<Display, Runnable> pumpMessageDisplayMap = new HashMap<Display, Runnable>();
private static AWTEDTUtil singletonMainThread = new AWTEDTUtil(); // one singleton MainThread
public static AWTEDTUtil getSingleton() {
@@ -47,11 +59,11 @@ public class AWTEDTUtil implements EDTUtil {
}
final public void reset() {
- // nop
+ // nop AWT is always running
}
final public void start() {
- // nop
+ // nop AWT is always running
}
final public boolean isCurrentThreadEDT() {
@@ -63,20 +75,10 @@ public class AWTEDTUtil implements EDTUtil {
}
final public void invokeStop(Runnable r) {
- invokeImpl(true, r, true);
+ invoke(true, r); // AWT is always running
}
final public void invoke(boolean wait, Runnable r) {
- invokeImpl(wait, r, false);
- }
-
- /**
- * Public access to provide simple dispatching from other EDTUtil implementations
- * @param wait true if invokeLater
- * @param r the Runnable action
- * @param stop true if EDT shall stop (ignored with AWT)
- */
- final public void invokeImpl(boolean wait, Runnable r, boolean stop) {
if(r == null) {
return;
}
@@ -98,9 +100,42 @@ public class AWTEDTUtil implements EDTUtil {
}
final public void waitUntilIdle() {
+ // wait until previous events are processed, at least ..
+ try {
+ EventQueue.invokeAndWait( new Runnable() {
+ public void run() { }
+ });
+ } catch (Exception e) { }
}
final public void waitUntilStopped() {
+ // nop: AWT is always running
+ }
+
+ public static void addPumpMessage(Display dpy, Runnable pumpMessage) {
+ if(DEBUG) {
+ System.err.println("AWTEDTUtil.addPumpMessage(): "+Thread.currentThread().getName()+" - dpy "+dpy);
+ }
+
+ synchronized (pumpMessageDisplayMap) {
+ if(null == pumpMessagesTimer) {
+ // AWT pump messages .. MAIN_THREAD uses main thread
+ pumpMessagesTimer = new Timer();
+ pumpMessagesTimerTask = new TimerTask() {
+ public void run() {
+ synchronized(pumpMessageDisplayMap) {
+ for(Iterator<Runnable> i = pumpMessageDisplayMap.values().iterator(); i.hasNext(); ) {
+ AWTEDTUtil.getSingleton().invoke(true, i.next());
+ // AWTEDTUtil.getSingleton().invoke(false, i.next());
+ // i.next().run();
+ }
+ }
+ }
+ };
+ pumpMessagesTimer.scheduleAtFixedRate(pumpMessagesTimerTask, 0, defaultEDTPollGranularity);
+ }
+ pumpMessageDisplayMap.put(dpy, pumpMessage);
+ }
}
}
diff --git a/src/newt/classes/jogamp/newt/driver/macosx/MacDisplay.java b/src/newt/classes/jogamp/newt/driver/macosx/MacDisplay.java
index db8577562..572d37efe 100644
--- a/src/newt/classes/jogamp/newt/driver/macosx/MacDisplay.java
+++ b/src/newt/classes/jogamp/newt/driver/macosx/MacDisplay.java
@@ -37,6 +37,8 @@ import javax.media.nativewindow.*;
import javax.media.nativewindow.macosx.*;
import com.jogamp.newt.*;
import jogamp.newt.*;
+import jogamp.newt.driver.awt.AWTEDTUtil;
+
import com.jogamp.newt.util.MainThread;
public class MacDisplay extends DisplayImpl {
@@ -62,7 +64,7 @@ public class MacDisplay extends DisplayImpl {
}
protected void dispatchMessagesNative() {
- dispatchMessages0();
+ // nop
}
protected void createNativeImpl() {
@@ -71,20 +73,26 @@ public class MacDisplay extends DisplayImpl {
protected void closeNativeImpl() { }
+ /**
@Override
protected void createEDTUtil() {
- if(NewtFactory.useEDT()) {
+ if(NewtFactory.useEDT()) {
final Display f_dpy = this;
- MainThread.addPumpMessage(this,
- new Runnable() {
- public void run() {
- if(null!=f_dpy.getGraphicsDevice()) {
- f_dpy.dispatchMessages();
- } } } );
- edtUtil = MainThread.getSingleton();
- edtUtil.start();
+ final Runnable dispatchRunner = new Runnable() {
+ public void run() {
+ if(null!=f_dpy.getGraphicsDevice()) {
+ f_dpy.dispatchMessages();
+ } } };
+
+ if(NativeWindowFactory.isAWTAvailable()) {
+ AWTEDTUtil.addPumpMessage(this, dispatchRunner);
+ edtUtil = AWTEDTUtil.getSingleton();
+ } else {
+ MainThread.addPumpMessage(this, dispatchRunner);
+ edtUtil = MainThread.getSingleton();
+ }
}
- }
+ } */
protected void releaseEDTUtil() {
if(null!=edtUtil) {
@@ -93,8 +101,12 @@ public class MacDisplay extends DisplayImpl {
edtUtil=null;
}
}
+
+ public static void runNSApplication() {
+ runNSApplication0();
+ }
private static native boolean initNSApplication0();
- protected native void dispatchMessages0();
+ private static native void runNSApplication0();
}
diff --git a/src/newt/classes/jogamp/newt/driver/macosx/MacWindow.java b/src/newt/classes/jogamp/newt/driver/macosx/MacWindow.java
index 1f471b9b5..3265da1c1 100644
--- a/src/newt/classes/jogamp/newt/driver/macosx/MacWindow.java
+++ b/src/newt/classes/jogamp/newt/driver/macosx/MacWindow.java
@@ -40,10 +40,11 @@ import com.jogamp.common.util.locks.RecursiveLock;
import com.jogamp.newt.event.*;
-import jogamp.nativewindow.jawt.JAWTUtil;
+import jogamp.nativewindow.macosx.OSXUtil;
import jogamp.newt.*;
import javax.media.nativewindow.util.Insets;
+import javax.media.nativewindow.util.InsetsImmutable;
import javax.media.nativewindow.util.Point;
public class MacWindow extends WindowImpl {
@@ -160,6 +161,7 @@ public class MacWindow extends WindowImpl {
try {
if(DEBUG_IMPLEMENTATION) { System.err.println("MacWindow.CloseAction "+Thread.currentThread().getName()); }
if (getWindowHandle() != 0) {
+ orderOut0(getWindowHandle());
close0(getWindowHandle());
}
} catch (Throwable t) {
@@ -182,9 +184,6 @@ public class MacWindow extends WindowImpl {
@Override
protected int lockSurfaceImpl() {
- if(NativeWindowFactory.isAWTAvailable()) {
- JAWTUtil.lockToolkit();
- }
nsViewLock.lock();
return LOCK_SUCCESS;
}
@@ -192,9 +191,6 @@ public class MacWindow extends WindowImpl {
@Override
protected void unlockSurfaceImpl() {
nsViewLock.unlock();
- if(NativeWindowFactory.isAWTAvailable()) {
- JAWTUtil.unlockToolkit();
- }
}
@Override
@@ -212,7 +208,8 @@ public class MacWindow extends WindowImpl {
// FIXME: move nsViewLock up to window lock
nsViewLock.lock();
try {
- makeKey0(getWindowHandle());
+ makeKeyAndOrderFront0(getWindowHandle());
+ // makeKey0(getWindowHandle());
} finally {
nsViewLock.unlock();
}
@@ -221,33 +218,64 @@ public class MacWindow extends WindowImpl {
protected boolean reconfigureWindowImpl(int x, int y, int width, int height, int flags) {
nsViewLock.lock();
try {
+ int _x = x, _y = y;
+ if(0 == ( FLAG_IS_UNDECORATED & flags) && 0<=_x && 0<=_y) {
+ final InsetsImmutable i = getInsets();
+
+ // client position -> top-level window position
+ _x -= i.getLeftWidth() ;
+ _y -= i.getTopHeight() ;
+ if( 0 > _x ) { _x = 0; }
+ if( 0 > _y ) { _y = 0; }
+ }
+ final NativeWindow parent = getParent();
+ if(null != parent) {
+ final Point p = parent.getLocationOnScreen(null);
+ _x += p.getX();
+ _y += p.getY();
+ }
+
if(DEBUG_IMPLEMENTATION) {
- System.err.println("MacWindow reconfig: "+x+"/"+y+" "+width+"x"+height+", "+
+ System.err.println("MacWindow reconfig: "+x+"/"+y+" -> "+_x+"/"+_y+" - "+width+"x"+height+", "+
getReconfigureFlagsAsString(null, flags));
}
- if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) ) {
- if (0 != ( FLAG_IS_VISIBLE & flags)) {
- createWindow(false, x, y, width, height, 0 != ( FLAG_IS_FULLSCREEN & flags));
- } else {
- if (getWindowHandle() != 0) {
+ if( getWindowHandle() == 0 ) {
+ if( 0 != ( FLAG_IS_VISIBLE & flags) ) {
+ createWindow(false, _x, _y, width, height, 0 != ( FLAG_IS_FULLSCREEN & flags));
+ this.x = x;
+ this.y = y;
+ visibleChanged(true); // no native event ..
+ } /* else { ?? } */
+ } else {
+ if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) ) {
+ if( 0 != ( FLAG_IS_VISIBLE & flags) ) {
+ makeKeyAndOrderFront0(getWindowHandle());
+ visibleChanged(true); // no native event ..
+ enqueueWindowEvent(false, WindowEvent.EVENT_WINDOW_GAINED_FOCUS);
+ } else {
orderOut0(getWindowHandle());
+ visibleChanged(false); // no native event ..
+ enqueueWindowEvent(false, WindowEvent.EVENT_WINDOW_LOST_FOCUS);
}
- }
- visibleChanged(0 != ( FLAG_IS_VISIBLE & flags));
- } else {
- if( 0 != ( FLAG_CHANGE_DECORATION & flags) ||
- 0 != ( FLAG_CHANGE_PARENTING & flags) ||
- 0 != ( FLAG_CHANGE_FULLSCREEN & flags) ) {
+ } else if( 0 != ( FLAG_CHANGE_DECORATION & flags) ||
+ 0 != ( FLAG_CHANGE_PARENTING & flags) ||
+ 0 != ( FLAG_CHANGE_FULLSCREEN & flags) ) {
createWindow(true, x, y, width, height, 0 != ( FLAG_IS_FULLSCREEN & flags));
- } else {
- if(x>=0 || y>=0) {
- setFrameTopLeftPoint0(getParentWindowHandle(), getWindowHandle(), x, y);
- }
- if(width>0 || height>0) {
- setContentSize0(getWindowHandle(), width, height);
- }
}
+ if(x>=0 || y>=0) {
+ setFrameTopLeftPoint0(getParentWindowHandle(), getWindowHandle(), _x, _y);
+ this.x = x;
+ this.y = y;
+ enqueueWindowEvent(false, WindowEvent.EVENT_WINDOW_MOVED);
+ }
+ if(width>0 || height>0) {
+ setContentSize0(getWindowHandle(), width, height);
+ this.width = width;
+ this.height = height;
+ enqueueWindowEvent(false, WindowEvent.EVENT_WINDOW_RESIZED);
+ }
+ setAlwaysOnTop0(getWindowHandle(), 0 != ( FLAG_IS_ALWAYSONTOP & flags));
}
} finally {
nsViewLock.unlock();
@@ -256,7 +284,7 @@ public class MacWindow extends WindowImpl {
}
protected Point getLocationOnScreenImpl(int x, int y) {
- return null;
+ return OSXUtil.GetLocationOnScreen(getWindowHandle(), x, y);
}
protected void updateInsetsImpl(Insets insets) {
@@ -368,48 +396,60 @@ public class MacWindow extends WindowImpl {
width=(width>0)?width:this.width;
height=(height>0)?height:this.height;
+ final NativeWindow parent = getParent();
+ if(null != parent) {
+ final Point p = parent.getLocationOnScreen(null);
+ x += p.getX();
+ y += p.getY();
+ }
+
try {
- //runOnEDTIfAvail(true, new Runnable() {
- // public void run() {
- if(0!=getWindowHandle()) {
- // save the view .. close the window
- surfaceHandle = changeContentView0(getParentWindowHandle(), getWindowHandle(), 0);
- if(recreate && 0==surfaceHandle) {
- throw new NativeWindowException("Internal Error - recreate, window but no view");
- }
- close0(getWindowHandle());
- setWindowHandle(0);
- } else {
- surfaceHandle = 0;
- }
- setWindowHandle(createWindow0(getParentWindowHandle(),
- x, y, width, height, fullscreen,
- (isUndecorated() ?
- NSBorderlessWindowMask :
- NSTitledWindowMask|NSClosableWindowMask|NSMiniaturizableWindowMask|NSResizableWindowMask),
- NSBackingStoreBuffered,
- getScreen().getIndex(), surfaceHandle));
- if (getWindowHandle() == 0) {
- throw new NativeWindowException("Could create native window "+Thread.currentThread().getName()+" "+this);
- }
- surfaceHandle = contentView0(getWindowHandle());
- setTitle0(getWindowHandle(), getTitle());
- makeKeyAndOrderFront0(getWindowHandle());
- // } } );
+ if(0!=getWindowHandle()) {
+ // save the view .. close the window
+ surfaceHandle = changeContentView0(getParentWindowHandle(), getWindowHandle(), 0);
+ if(recreate && 0==surfaceHandle) {
+ throw new NativeWindowException("Internal Error - recreate, window but no view");
+ }
+ orderOut0(getWindowHandle());
+ close0(getWindowHandle());
+ setWindowHandle(0);
+ } else {
+ surfaceHandle = 0;
+ }
+ setWindowHandle(createWindow0(getParentWindowHandle(),
+ x, y, width, height,
+ config.getChosenCapabilities().isBackgroundOpaque(),
+ fullscreen,
+ (isUndecorated() ?
+ NSBorderlessWindowMask :
+ NSTitledWindowMask|NSClosableWindowMask|NSMiniaturizableWindowMask|NSResizableWindowMask),
+ NSBackingStoreBuffered,
+ getScreen().getIndex(), surfaceHandle));
+ if (getWindowHandle() == 0) {
+ throw new NativeWindowException("Could create native window "+Thread.currentThread().getName()+" "+this);
+ }
+ surfaceHandle = contentView0(getWindowHandle());
+ setTitle0(getWindowHandle(), getTitle());
+ makeKeyAndOrderFront0(getWindowHandle());
} catch (Exception ie) {
ie.printStackTrace();
}
-
- if(recreate) {
- enqueueWindowEvent(false, WindowEvent.EVENT_WINDOW_MOVED);
- enqueueWindowEvent(false, WindowEvent.EVENT_WINDOW_RESIZED);
- enqueueWindowEvent(false, WindowEvent.EVENT_WINDOW_GAINED_FOCUS);
+ }
+
+ @Override
+ protected void positionChanged(int newX, int newY) {
+ final NativeWindow parent = getParent();
+ if(null != parent) {
+ final Point p = parent.getLocationOnScreen(null);
+ newX -= p.getX();
+ newY -= p.getY();
}
+ super.positionChanged(newX, newY);
}
protected static native boolean initIDs0();
private native long createWindow0(long parentWindowHandle, int x, int y, int w, int h,
- boolean fullscreen, int windowStyle,
+ boolean opaque, boolean fullscreen, int windowStyle,
int backingStoreType,
int screen_idx, long view);
private native void makeKeyAndOrderFront0(long window);
@@ -418,7 +458,8 @@ public class MacWindow extends WindowImpl {
private native void close0(long window);
private native void setTitle0(long window, String title);
private native long contentView0(long window);
- private native long changeContentView0(long parentWindowHandle, long window, long view);
+ private native long changeContentView0(long parentWindowOrViewHandle, long window, long view);
private native void setContentSize0(long window, int w, int h);
private native void setFrameTopLeftPoint0(long parentWindowHandle, long window, int x, int y);
+ private native void setAlwaysOnTop0(long window, boolean atop);
}
diff --git a/src/newt/native/MacWindow.m b/src/newt/native/MacWindow.m
index 719acc927..946ac489c 100644
--- a/src/newt/native/MacWindow.m
+++ b/src/newt/native/MacWindow.m
@@ -43,7 +43,7 @@
#import <stdio.h>
-NSString* jstringToNSString(JNIEnv* env, jstring jstr)
+static NSString* jstringToNSString(JNIEnv* env, jstring jstr)
{
const jchar* jstrChars = (*env)->GetStringChars(env, jstr, NULL);
NSString* str = [[NSString alloc] initWithCharacters: jstrChars length: (*env)->GetStringLength(env, jstr)];
@@ -51,45 +51,23 @@ NSString* jstringToNSString(JNIEnv* env, jstring jstr)
return str;
}
-void setFrameTopLeftPoint(NSWindow* pwin, NSWindow* win, jint x, jint y)
-{
+static void setFrameTopLeftPoint(NSWindow* pWin, NSWindow* mWin, jint x, jint y) {
NSScreen* screen = [NSScreen mainScreen];
+ NSRect screenRect = [screen frame];
- // this allows for better compatibility with awt behavior
- NSRect visibleRect; // either screen or parent-window
- NSPoint pt;
- int d_pty=0; // parent titlebar height
- int d_ptx=0;
-
- if(NULL==pwin) {
- visibleRect = [screen frame];
- } else {
- visibleRect = [pwin frame];
- NSView* pview = [pwin contentView];
- NSRect viewRect = [pview frame];
- d_pty = visibleRect.size.height - viewRect.size.height;
- (void) d_ptx;
- //d_pty = visibleRect.origin.y - viewRect.size.height;
- //d_ptx = visibleRect.size.height - viewRect.size.height;
- fprintf(stderr, "pwin %lf/%lf %lfx%lf, pview %lf/%lf %lfx%lf -> %d/%d\n",
- visibleRect.origin.x,
- visibleRect.origin.y,
- visibleRect.size.width,
- visibleRect.size.height,
- viewRect.origin.x,
- viewRect.origin.y,
- viewRect.size.width,
- viewRect.size.height,
- (int)x, (int)y);
-
- }
+ DBG_PRINT( "setFrameTopLeftPoint screen %lf/%lf %lfx%lf\n",
+ screenRect.origin.x,
+ screenRect.origin.y,
+ screenRect.size.width,
+ screenRect.size.height);
- pt = NSMakePoint(visibleRect.origin.x + x, visibleRect.origin.y + visibleRect.size.height - y - d_pty);
+ NSPoint pt = NSMakePoint(screenRect.origin.x + x, screenRect.origin.y + screenRect.size.height - y);
- [win setFrameTopLeftPoint: pt];
+ DBG_PRINT( "setFrameTopLeftPoint -> %lf/%lf\n", pt.x, pt.y);
+ [mWin setFrameTopLeftPoint: pt];
}
-static NewtView * changeContentView(JNIEnv *env, jobject javaWindowObject, NSWindow *pwin, NSWindow *win, NewtView *newView) {
+static NewtView * changeContentView(JNIEnv *env, jobject javaWindowObject, NSWindow *pwin, NSView *pview, NSWindow *win, NewtView *newView) {
NSView* oldNSView = [win contentView];
NewtView* oldView = NULL;
@@ -107,6 +85,7 @@ NS_ENDHANDLER
jobject globJavaWindowObject = [oldView getJavaWindowObject];
(*env)->DeleteGlobalRef(env, globJavaWindowObject);
[oldView setJavaWindowObject: NULL];
+ [oldView setDestroyNotifySent: false];
}
/** FIXME: Tried child window: auto clip or message reception ..
if(NULL!=pwin) {
@@ -116,12 +95,23 @@ NS_ENDHANDLER
if(NULL!=newView) {
jobject globJavaWindowObject = (*env)->NewGlobalRef(env, javaWindowObject);
[newView setJavaWindowObject: globJavaWindowObject];
- [newView setJNIEnv: env];
+ [newView setDestroyNotifySent: false];
+ {
+ JavaVM *jvmHandle = NULL;
+ int jvmVersion = 0;
+
+ if(0 != (*env)->GetJavaVM(env, &jvmHandle)) {
+ jvmHandle = NULL;
+ } else {
+ jvmVersion = (*env)->GetVersion(env);
+ }
+ [newView setJVMHandle: jvmHandle];
+ [newView setJVMVersion: jvmVersion];
+ }
/** FIXME: Tried child window: auto clip or message reception ..
if(NULL!=pwin) {
- NSView* pview = [pwin contentView];
- [pview addSubview: newView];
+ [pview addSubview: newView positioned: NSWindowAbove relativeTo: nil];
} */
}
[win setContentView: newView];
@@ -169,40 +159,19 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_MacDisplay_initNSAppli
/*
* Class: jogamp_newt_driver_macosx_MacDisplay
- * Method: dispatchMessages0
+ * Method: runNSApplication0
* Signature: ()V
*/
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacDisplay_dispatchMessages0
- (JNIEnv *env, jobject unused)
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacDisplay_runNSApplication0
+ (JNIEnv *env, jclass clazz)
{
- NSEvent* event = NULL;
- NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
-
-NS_DURING
-
- int num_events = 0;
-
- // Periodically take a break
- do {
- // FIXME: ignoring event mask for the time being
- event = [NSApp nextEventMatchingMask: NSAnyEventMask
- untilDate: [NSDate distantPast]
- inMode: NSDefaultRunLoopMode
- dequeue: YES];
- if (event != NULL) {
- [NSApp sendEvent: event];
-
- num_events++;
- }
- } while (num_events<100 && event != NULL);
-
-NS_HANDLER
-
- // just ignore it ..
+ // NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ DBG_PRINT( "\nrunNSApplication0.0\n");
-NS_ENDHANDLER
+ [NSApp run];
- [pool release];
+ DBG_PRINT( "\nrunNSApplication0.X\n");
+ // [pool release];
}
/*
@@ -274,84 +243,107 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_MacWindow_initIDs0
* Signature: (JIIIIZIIIJ)J
*/
JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_MacWindow_createWindow0
- (JNIEnv *env, jobject jthis, jlong parent, jint x, jint y, jint w, jint h, jboolean fullscreen, jint styleMask,
+ (JNIEnv *env, jobject jthis, jlong parent, jint x, jint y, jint w, jint h, jboolean opaque, jboolean fullscreen, jint styleMask,
jint bufferingType, jint screen_idx, jlong jview)
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- NSRect rect = NSMakeRect(x, y, w, h);
+ NewtView* myView = (NewtView*) (intptr_t) jview ;
+
+ DBG_PRINT( "createWindow0 - %p (this), %p (parent), %d/%d %dx%d, opaque %d, fs %d, style %X, buffType %X, screenidx %d, view %p\n",
+ (void*)(intptr_t)jthis, (void*)(intptr_t)parent, (int)x, (int)y, (int)w, (int)h, (int) opaque, (int)fullscreen,
+ (int)styleMask, (int)bufferingType, (int)screen_idx, myView);
NSArray *screens = [NSScreen screens];
if(screen_idx<0) screen_idx=0;
if(screen_idx>=[screens count]) screen_idx=0;
- NSScreen *screen = (NSScreen *) [screens objectAtIndex: screen_idx];
+ NSScreen *myScreen = (NSScreen *) [screens objectAtIndex: screen_idx];
+ NSRect rect;
if (fullscreen) {
styleMask = NSBorderlessWindowMask;
- NSRect rect = [screen frame];
+ rect = [myScreen frame];
+ x = 0;
+ y = 0;
w = (jint) (rect.size.width);
h = (jint) (rect.size.height);
+ } else {
+ rect = NSMakeRect(x, y, w, h);
}
// Allocate the window
- NSWindow* window = [[[NewtMacWindow alloc] initWithContentRect: rect
+ NSWindow* myWindow = [[[NewtMacWindow alloc] initWithContentRect: rect
styleMask: (NSUInteger) styleMask
backing: (NSBackingStoreType) bufferingType
- screen: screen] retain];
+ screen: myScreen] retain];
NSObject *nsParentObj = (NSObject*) ((intptr_t) parent);
NSWindow* parentWindow = NULL;
+ NSView* parentView = NULL;
if( nsParentObj != NULL && [nsParentObj isKindOfClass:[NSWindow class]] ) {
parentWindow = (NSWindow*) nsParentObj;
+ parentView = [parentWindow contentView];
+ DBG_PRINT( "createWindow0 - Parent is NSWindow : %p (view) -> %p (win) \n", parentView, parentWindow);
} else if( nsParentObj != NULL && [nsParentObj isKindOfClass:[NSView class]] ) {
- NSView* view = (NSView*) nsParentObj;
- parentWindow = [view window];
- fprintf(stderr, "createWindow0 - Parent is NSView : %p -> %p (win) \n", nsParentObj, parentWindow);
+ parentView = (NSView*) nsParentObj;
+ parentWindow = [parentView window];
+ DBG_PRINT( "createWindow0 - Parent is NSView : %p -(view) > %p (win) \n", parentView, parentWindow);
} else {
- fprintf(stderr, "createWindow0 - Parent is neither NSWindow nor NSView : %p\n", nsParentObj);
+ DBG_PRINT( "createWindow0 - Parent is neither NSWindow nor NSView : %p\n", nsParentObj);
}
if(NULL!=parentWindow) {
- [parentWindow addChildWindow: window ordered: NSWindowAbove];
- [window setParentWindow: parentWindow];
+ [parentWindow addChildWindow: myWindow ordered: NSWindowAbove];
+ [myWindow setParentWindow: parentWindow];
+ }
+
+ if(opaque) {
+ [myWindow setOpaque: YES];
+ } else {
+ [myWindow setOpaque: NO];
+ [myWindow setBackgroundColor: [NSColor clearColor]];
}
+ /**
if (fullscreen) {
- [window setOpaque: YES];
+ [myWindow setOpaque: YES];
} else {
// If the window is undecorated, assume we want the possibility of
// a shaped window, so make it non-opaque and the background color clear
if ((styleMask & NSTitledWindowMask) == 0) {
- [window setOpaque: NO];
- [window setBackgroundColor: [NSColor clearColor]];
+ [myWindow setOpaque: NO];
+ [myWindow setBackgroundColor: [NSColor clearColor]];
}
- }
-
- // Immediately re-position the window based on an upper-left coordinate system
- setFrameTopLeftPoint(parentWindow, window, x, y);
+ } */
// specify we want mouse-moved events
- [window setAcceptsMouseMovedEvents:YES];
+ [myWindow setAcceptsMouseMovedEvents:YES];
// Use given NewtView or allocate an NewtView if NULL
- NewtView* view = (0==jview)? [[NewtView alloc] initWithFrame: rect] : (NewtView*) ((intptr_t) jview) ;
+ if(NULL == myView) {
+ myView = [[NewtView alloc] initWithFrame: rect] ;
+ DBG_PRINT( "createWindow0 - new own view: %p\n", myView);
+ }
// Set the content view
- (void) changeContentView(env, jthis, parentWindow, window, view);
+ (void) changeContentView(env, jthis, parentWindow, parentView, myWindow, myView);
+
+ // Immediately re-position the window based on an upper-left coordinate system
+ setFrameTopLeftPoint(parentWindow, myWindow, x, y);
NS_DURING
// Available >= 10.5 - Makes the menubar disapear
if(fullscreen) {
- [view enterFullScreenMode: screen withOptions:NULL];
+ [myView enterFullScreenMode: myScreen withOptions:NULL];
}
NS_HANDLER
NS_ENDHANDLER
// Set the next responder to be the window so that we can forward
// right mouse button down events
- [view setNextResponder: window];
+ [myView setNextResponder: myWindow];
[pool release];
- return (jlong) ((intptr_t) window);
+ return (jlong) ((intptr_t) myWindow);
}
/*
@@ -364,7 +356,8 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_makeKeyAndOrderF
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NSWindow* win = (NSWindow*) ((intptr_t) window);
- [win makeKeyAndOrderFront: win];
+ [win performSelectorOnMainThread:@selector(makeKeyAndOrderFront:) withObject:win waitUntilDone:NO];
+ // [win makeKeyAndOrderFront: win];
[pool release];
}
@@ -378,7 +371,8 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_makeKey0
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NSWindow* win = (NSWindow*) ((intptr_t) window);
- [win makeKeyWindow];
+ [win performSelectorOnMainThread:@selector(makeKeyWindow:) withObject:nil waitUntilDone:NO];
+ // [win makeKeyWindow];
[pool release];
}
@@ -392,7 +386,8 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_orderOut0
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NSWindow* win = (NSWindow*) ((intptr_t) window);
- [win orderOut: win];
+ [win performSelectorOnMainThread:@selector(orderOut:) withObject:win waitUntilDone:NO];
+ // [win orderOut: win];
[pool release];
}
@@ -407,7 +402,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_close0
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NSWindow* win = (NSWindow*) ((intptr_t) window);
NSView* view = [win contentView];
- [win orderOut: win];
+ DBG_PRINT( "*************** windowClose.0: 0x%p\n", (void *)win);
NS_DURING
if(NULL!=view) {
// Available >= 10.5 - Makes the menubar disapear
@@ -417,7 +412,12 @@ NS_DURING
}
NS_HANDLER
NS_ENDHANDLER
- [win close];
+ DBG_PRINT( "*************** windowClose.2: 0x%p\n", (void *)win);
+
+ [win performSelectorOnMainThread:@selector(close:) withObject:nil waitUntilDone:NO];
+ // [win close]
+
+ DBG_PRINT( "*************** windowClose.X: 0x%p\n", (void *)win);
[pool release];
}
@@ -433,7 +433,8 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_setTitle0
NSWindow* win = (NSWindow*) ((intptr_t) window);
NSString* str = jstringToNSString(env, title);
[str autorelease];
- [win setTitle: str];
+ [win performSelectorOnMainThread:@selector(setTitle:) withObject:str waitUntilDone:NO];
+ // [win setTitle: str];
[pool release];
}
@@ -458,14 +459,27 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_MacWindow_contentView0
* Signature: (J)J
*/
JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_MacWindow_changeContentView0
- (JNIEnv *env, jobject jthis, jlong parent, jlong window, jlong jview)
+ (JNIEnv *env, jobject jthis, jlong parentWindowOrView, jlong window, jlong jview)
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- NSWindow* pwin = (NewtMacWindow*) ((intptr_t) parent);
+
+ NSObject *nsParentObj = (NSObject*) ((intptr_t) parentWindowOrView);
+ NSWindow* pWin = NULL;
+ NSView* pView = NULL;
+ if( NULL != nsParentObj ) {
+ if( [nsParentObj isKindOfClass:[NSWindow class]] ) {
+ pWin = (NSWindow*) nsParentObj;
+ pView = [pWin contentView];
+ } else if( [nsParentObj isKindOfClass:[NSView class]] ) {
+ pView = (NSView*) nsParentObj;
+ pWin = [pView window];
+ }
+ }
+
NSWindow* win = (NewtMacWindow*) ((intptr_t) window);
NewtView* newView = (NewtView *) ((intptr_t) jview);
- NewtView* oldView = changeContentView(env, jthis, pwin, win, newView);
+ NewtView* oldView = changeContentView(env, jthis, pWin, pView, win, newView);
[pool release];
@@ -490,7 +504,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_setContentSize0
/*
* Class: jogamp_newt_driver_macosx_MacWindow
* Method: setFrameTopLeftPoint
- * Signature: (JII)V
+ * Signature: (JJII)V
*/
JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_setFrameTopLeftPoint0
(JNIEnv *env, jobject unused, jlong parent, jlong window, jint x, jint y)
@@ -502,3 +516,22 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_setFrameTopLeftP
[pool release];
}
+/*
+ * Class: jogamp_newt_driver_macosx_MacWindow
+ * Method: setAlwaysOnTop0
+ * Signature: (JZ)V
+ */
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_setAlwaysOnTop0
+ (JNIEnv *env, jobject unused, jlong window, jboolean atop)
+{
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ NSWindow* win = (NSWindow*) ((intptr_t) window);
+ if(atop) {
+ [win setLevel:NSFloatingWindowLevel];
+ } else {
+ [win setLevel:NSNormalWindowLevel];
+ }
+ [pool release];
+}
+
+
diff --git a/src/newt/native/NewtCommon.c b/src/newt/native/NewtCommon.c
index f44d71901..3713cfd6c 100644
--- a/src/newt/native/NewtCommon.c
+++ b/src/newt/native/NewtCommon.c
@@ -53,3 +53,30 @@ jchar* NewtCommon_GetNullTerminatedStringChars(JNIEnv* env, jstring str)
return strChars;
}
+JNIEnv* NewtCommon_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/newt/native/NewtCommon.h b/src/newt/native/NewtCommon.h
index f5835f7c8..91fceb310 100644
--- a/src/newt/native/NewtCommon.h
+++ b/src/newt/native/NewtCommon.h
@@ -12,4 +12,6 @@ jchar* NewtCommon_GetNullTerminatedStringChars(JNIEnv* env, jstring str);
void NewtCommon_FatalError(JNIEnv *env, const char* msg, ...);
void NewtCommon_throwNewRuntimeException(JNIEnv *env, const char* msg, ...);
+JNIEnv* NewtCommon_GetJNIEnv (JavaVM * jvmHandle, int jvmVersion, int * shallBeDetached);
+
#endif
diff --git a/src/newt/native/NewtMacWindow.h b/src/newt/native/NewtMacWindow.h
index 7f0cd60c6..a8931d6fc 100644
--- a/src/newt/native/NewtMacWindow.h
+++ b/src/newt/native/NewtMacWindow.h
@@ -34,23 +34,41 @@
#import <AppKit/AppKit.h>
#import "jni.h"
+#include "NewtCommon.h"
+
+// #define VERBOSE_ON 1
+
+#ifdef VERBOSE_ON
+ #define DBG_PRINT(...) fprintf(stderr, __VA_ARGS__); fflush(stderr)
+#else
+ #define DBG_PRINT(...)
+#endif
+
@interface NewtView : NSView
{
jobject javaWindowObject;
// This is set while messages are being dispatched and cleared afterward
- JNIEnv* env;
+ JavaVM *jvmHandle;
+ int jvmVersion;
+
+ BOOL destroyNotifySent;
}
/* Set during event dispatching cycle */
-- (void) setJNIEnv: (JNIEnv*) env;
-- (JNIEnv*) getJNIEnv;
+- (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;
- (jobject) getJavaWindowObject;
+- (void) setDestroyNotifySent: (BOOL) v;
+- (BOOL) getDestroyNotifySent;
+
- (void) rightMouseDown: (NSEvent*) theEvent;
@end
diff --git a/src/newt/native/NewtMacWindow.m b/src/newt/native/NewtMacWindow.m
index cd435eb1d..6125761e3 100644
--- a/src/newt/native/NewtMacWindow.m
+++ b/src/newt/native/NewtMacWindow.m
@@ -82,13 +82,24 @@ static jmethodID focusChangedID = NULL;
static jmethodID windowDestroyNotifyID = NULL;
@implementation NewtView
-- (void) setJNIEnv: (JNIEnv*) theEnv
+
+- (void) setJVMHandle: (JavaVM*) vm
{
- env = theEnv;
+ jvmHandle = vm;
}
-- (JNIEnv*) getJNIEnv
+- (JavaVM*) getJVMHandle
{
- return env;
+ return jvmHandle;
+}
+
+- (void) setJVMVersion: (int) ver
+{
+ jvmVersion = ver;
+}
+
+- (int) getJVMVersion
+{
+ return jvmVersion;
}
- (void) setJavaWindowObject: (jobject) javaWindowObj
@@ -101,6 +112,16 @@ static jmethodID windowDestroyNotifyID = NULL;
return javaWindowObject;
}
+- (void) setDestroyNotifySent: (BOOL) v
+{
+ destroyNotifySent = v;
+}
+
+- (BOOL) getDestroyNotifySent
+{
+ return destroyNotifySent;
+}
+
- (void) rightMouseDown: (NSEvent*) theEvent
{
NSResponder* next = [self nextResponder];
@@ -111,19 +132,43 @@ static jmethodID windowDestroyNotifyID = NULL;
- (void)viewWillDraw
{
- fprintf(stderr, "*************** viewWillDraw: 0x%p", javaWindowObject); fflush(stderr);
+ DBG_PRINT("*************** viewWillDraw: 0x%p\n", javaWindowObject);
[super viewWillDraw];
}
- (void)viewDidHide
{
+ int shallBeDetached = 0;
+ JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, jvmVersion, &shallBeDetached);
+ if(NULL==env) {
+ NSLog(@"viewDidHide: null JNIEnv");
+ return;
+ }
+
(*env)->CallVoidMethod(env, javaWindowObject, visibleChangedID, JNI_FALSE);
+
+ if (shallBeDetached) {
+ (*jvmHandle)->DetachCurrentThread(jvmHandle);
+ }
+
[super viewDidHide];
}
- (void)viewDidUnhide
{
+ int shallBeDetached = 0;
+ JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, jvmVersion, &shallBeDetached);
+ if(NULL==env) {
+ NSLog(@"viewDidHide: null JNIEnv");
+ return;
+ }
+
(*env)->CallVoidMethod(env, javaWindowObject, visibleChangedID, JNI_TRUE);
+
+ if (shallBeDetached) {
+ (*jvmHandle)->DetachCurrentThread(jvmHandle);
+ }
+
[super viewDidUnhide];
}
@@ -172,6 +217,8 @@ static jmethodID windowDestroyNotifyID = NULL;
jint bottom = (jint)(contentRect.origin.y - frameRect.origin.y);
jint right = (jint)(frameRect.size.width - (contentRect.size.width + l));
+ DBG_PRINT( "updateInsets: [ l %d, r %d, t %d, b %d ]\n", (int)left, (int)right, (int)top, (int)bottom);
+
(*env)->CallVoidMethod(env, javaWindowObject, insetsChangedID,
left, right, top, bottom);
}
@@ -225,8 +272,15 @@ static jint mods2JavaMods(NSUInteger mods)
}
NewtView* view = (NewtView *) nsview;
jobject javaWindowObject = [view getJavaWindowObject];
- JNIEnv* env = [view getJNIEnv];
- if (env==NULL || javaWindowObject == NULL) {
+ if (javaWindowObject == NULL) {
+ NSLog(@"sendKeyEvent: null javaWindowObject");
+ return;
+ }
+ int shallBeDetached = 0;
+ JavaVM *jvmHandle = [view getJVMHandle];
+ JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], &shallBeDetached);
+ if(NULL==env) {
+ NSLog(@"sendKeyEvent: null JNIEnv");
return;
}
@@ -243,6 +297,10 @@ static jint mods2JavaMods(NSUInteger mods)
(*env)->CallVoidMethod(env, javaWindowObject, sendKeyEventID,
evType, javaMods, keyCode, keyChar);
}
+
+ if (shallBeDetached) {
+ (*jvmHandle)->DetachCurrentThread(jvmHandle);
+ }
}
- (void) keyDown: (NSEvent*) theEvent
@@ -264,8 +322,15 @@ static jint mods2JavaMods(NSUInteger mods)
}
NewtView* view = (NewtView *) nsview;
jobject javaWindowObject = [view getJavaWindowObject];
- JNIEnv* env = [view getJNIEnv];
- if (env==NULL || javaWindowObject == NULL) {
+ if (javaWindowObject == NULL) {
+ NSLog(@"sendMouseEvent: null javaWindowObject");
+ return;
+ }
+ int shallBeDetached = 0;
+ JavaVM *jvmHandle = [view getJVMHandle];
+ JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], &shallBeDetached);
+ if(NULL==env) {
+ NSLog(@"sendMouseEvent: null JNIEnv");
return;
}
@@ -318,6 +383,10 @@ static jint mods2JavaMods(NSUInteger mods)
(jint) location.x,
(jint) (contentRect.size.height - location.y),
javaButtonNum, scrollDeltaY);
+
+ if (shallBeDetached) {
+ (*jvmHandle)->DetachCurrentThread(jvmHandle);
+ }
}
- (void) mouseEntered: (NSEvent*) theEvent
@@ -396,8 +465,15 @@ static jint mods2JavaMods(NSUInteger mods)
}
NewtView* view = (NewtView *) nsview;
jobject javaWindowObject = [view getJavaWindowObject];
- JNIEnv* env = [view getJNIEnv];
- if (env==NULL || javaWindowObject == NULL) {
+ if (javaWindowObject == NULL) {
+ NSLog(@"windowDidResize: null javaWindowObject");
+ return;
+ }
+ int shallBeDetached = 0;
+ JavaVM *jvmHandle = [view getJVMHandle];
+ JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], &shallBeDetached);
+ if(NULL==env) {
+ NSLog(@"windowDidResize: null JNIEnv");
return;
}
@@ -410,6 +486,10 @@ static jint mods2JavaMods(NSUInteger mods)
(*env)->CallVoidMethod(env, javaWindowObject, sizeChangedID,
(jint) contentRect.size.width,
(jint) contentRect.size.height, JNI_FALSE);
+
+ if (shallBeDetached) {
+ (*jvmHandle)->DetachCurrentThread(jvmHandle);
+ }
}
- (void)windowDidMove: (NSNotification*) notification
@@ -420,8 +500,15 @@ static jint mods2JavaMods(NSUInteger mods)
}
NewtView* view = (NewtView *) nsview;
jobject javaWindowObject = [view getJavaWindowObject];
- JNIEnv* env = [view getJNIEnv];
- if (env==NULL || javaWindowObject == NULL) {
+ if (javaWindowObject == NULL) {
+ NSLog(@"windowDidMove: null javaWindowObject");
+ return;
+ }
+ int shallBeDetached = 0;
+ JavaVM *jvmHandle = [view getJVMHandle];
+ JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], &shallBeDetached);
+ if(NULL==env) {
+ NSLog(@"windowDidMove: null JNIEnv");
return;
}
@@ -437,27 +524,53 @@ static jint mods2JavaMods(NSUInteger mods)
(*env)->CallVoidMethod(env, javaWindowObject, positionChangedID,
(jint) pt.x, (jint) pt.y);
+
+ if (shallBeDetached) {
+ (*jvmHandle)->DetachCurrentThread(jvmHandle);
+ }
}
- (void)windowWillClose: (NSNotification*) notification
{
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+
NSView* nsview = [self contentView];
if( ! [nsview isMemberOfClass:[NewtView class]] ) {
return;
}
NewtView* view = (NewtView *) nsview;
- jobject javaWindowObject = [view getJavaWindowObject];
- JNIEnv* env = [view getJNIEnv];
- if (env==NULL || javaWindowObject == NULL) {
- return;
- }
- (*env)->CallVoidMethod(env, javaWindowObject, windowDestroyNotifyID);
- // Can't issue call here - locked window state, done from Java method
+ if( false == [view getDestroyNotifySent] ) {
+ jobject javaWindowObject = [view getJavaWindowObject];
+ DBG_PRINT( "*************** windowWillClose.0: 0x%p\n", (void *)(intptr_t)javaWindowObject);
+ if (javaWindowObject == NULL) {
+ NSLog(@"windowWillClose: null javaWindowObject");
+ return;
+ }
+ int shallBeDetached = 0;
+ JavaVM *jvmHandle = [view getJVMHandle];
+ JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], &shallBeDetached);
+ if(NULL==env) {
+ NSLog(@"windowWillClose: null JNIEnv");
+ return;
+ }
+
+ [view setDestroyNotifySent: true];
+ (*env)->CallVoidMethod(env, javaWindowObject, windowDestroyNotifyID);
+ // Can't issue call here - locked window state, done from Java method
- // EOL ..
- (*env)->DeleteGlobalRef(env, javaWindowObject);
- [view setJavaWindowObject: NULL];
+ // EOL ..
+ (*env)->DeleteGlobalRef(env, javaWindowObject);
+ [view setJavaWindowObject: NULL];
+
+ if (shallBeDetached) {
+ (*jvmHandle)->DetachCurrentThread(jvmHandle);
+ }
+ DBG_PRINT( "*************** windowWillClose.X: 0x%p\n", (void *)(intptr_t)javaWindowObject);
+ } else {
+ DBG_PRINT( "*************** windowWillClose (skip)\n");
+ }
+ [pool release];
}
- (void) windowDidBecomeKey: (NSNotification *) notification
@@ -468,12 +581,23 @@ static jint mods2JavaMods(NSUInteger mods)
}
NewtView* view = (NewtView *) nsview;
jobject javaWindowObject = [view getJavaWindowObject];
- JNIEnv* env = [view getJNIEnv];
- if (env==NULL || javaWindowObject == NULL) {
+ if (javaWindowObject == NULL) {
+ NSLog(@"windowDidBecomeKey: null javaWindowObject");
+ return;
+ }
+ int shallBeDetached = 0;
+ JavaVM *jvmHandle = [view getJVMHandle];
+ JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], &shallBeDetached);
+ if(NULL==env) {
+ NSLog(@"windowDidBecomeKey: null JNIEnv");
return;
}
(*env)->CallVoidMethod(env, javaWindowObject, focusChangedID, JNI_TRUE);
+
+ if (shallBeDetached) {
+ (*jvmHandle)->DetachCurrentThread(jvmHandle);
+ }
}
- (void) windowDidResignKey: (NSNotification *) notification
@@ -484,12 +608,23 @@ static jint mods2JavaMods(NSUInteger mods)
}
NewtView* view = (NewtView *) nsview;
jobject javaWindowObject = [view getJavaWindowObject];
- JNIEnv* env = [view getJNIEnv];
- if (env==NULL || javaWindowObject == NULL) {
+ if (javaWindowObject == NULL) {
+ NSLog(@"windowDidResignKey: null javaWindowObject");
+ return;
+ }
+ int shallBeDetached = 0;
+ JavaVM *jvmHandle = [view getJVMHandle];
+ JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], &shallBeDetached);
+ if(NULL==env) {
+ NSLog(@"windowDidResignKey: null JNIEnv");
return;
}
(*env)->CallVoidMethod(env, javaWindowObject, focusChangedID, JNI_FALSE);
+
+ if (shallBeDetached) {
+ (*jvmHandle)->DetachCurrentThread(jvmHandle);
+ }
}
@end
diff --git a/src/newt/native/X11Window.c b/src/newt/native/X11Window.c
index 30ff7f6f3..e1a0071b5 100644
--- a/src/newt/native/X11Window.c
+++ b/src/newt/native/X11Window.c
@@ -208,32 +208,22 @@ static int displayDispatchErrorHandler(Display *dpy, XErrorEvent *e)
} else if (e->error_code == BadWindow) {
fprintf(stderr, " BadWindow (%p): Window probably already removed\n", (void*)e->resourceid);
} else {
- JNIEnv *curEnv = NULL;
- JNIEnv *newEnv = NULL;
- int envRes ;
+ int shallBeDetached = 0;
+ JNIEnv *jniEnv = NULL;
const char * errStr = strerror(errno);
fprintf(stderr, "Info: NEWT X11 Error: Display %p, Code 0x%X, errno %s\n", dpy, e->error_code, errStr);
- // 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, "NEWT X11 Error: can't attach thread: %d\n", envRes);
- return;
- }
- curEnv = newEnv;
- } else if( JNI_OK != envRes ) {
- // oops ..
- fprintf(stderr, "NEWT X11 Error: can't GetEnv: %d\n", envRes);
+ jniEnv = NewtCommon_GetJNIEnv(jvmHandle, jvmVersion, &shallBeDetached);
+ if(NULL==jniEnv) {
+ fprintf(stderr, "NEWT X11 Error: null JNIEnv");
return;
}
- NewtCommon_throwNewRuntimeException(curEnv, "Info: NEWT X11 Error: Display %p, Code 0x%X, errno %s",
+
+ NewtCommon_throwNewRuntimeException(jniEnv, "Info: NEWT X11 Error: Display %p, Code 0x%X, errno %s",
dpy, e->error_code, errStr);
- if( NULL != newEnv ) {
- // detached attached thread
+ if (shallBeDetached) {
(*jvmHandle)->DetachCurrentThread(jvmHandle);
}
}