aboutsummaryrefslogtreecommitdiffstats
path: root/src/newt/classes/jogamp
diff options
context:
space:
mode:
Diffstat (limited to 'src/newt/classes/jogamp')
-rw-r--r--src/newt/classes/jogamp/newt/Debug.java34
-rw-r--r--src/newt/classes/jogamp/newt/DefaultEDTUtil.java115
-rw-r--r--src/newt/classes/jogamp/newt/DisplayImpl.java199
-rw-r--r--src/newt/classes/jogamp/newt/MonitorDeviceImpl.java12
-rw-r--r--src/newt/classes/jogamp/newt/ScreenImpl.java99
-rw-r--r--src/newt/classes/jogamp/newt/WindowImpl.java269
-rw-r--r--src/newt/classes/jogamp/newt/driver/android/DisplayDriver.java2
-rw-r--r--src/newt/classes/jogamp/newt/driver/android/NewtVersionActivity.java2
-rw-r--r--src/newt/classes/jogamp/newt/driver/awt/AWTEDTUtil.java135
-rw-r--r--src/newt/classes/jogamp/newt/driver/awt/DisplayDriver.java4
-rw-r--r--src/newt/classes/jogamp/newt/driver/bcm/egl/DisplayDriver.java2
-rw-r--r--src/newt/classes/jogamp/newt/driver/bcm/vc/iv/DisplayDriver.java2
-rw-r--r--src/newt/classes/jogamp/newt/driver/intel/gdl/DisplayDriver.java2
-rw-r--r--src/newt/classes/jogamp/newt/driver/kd/DisplayDriver.java2
-rw-r--r--src/newt/classes/jogamp/newt/driver/macosx/DisplayDriver.java2
-rw-r--r--src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java4
-rw-r--r--src/newt/classes/jogamp/newt/driver/windows/DisplayDriver.java2
-rw-r--r--src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java13
-rw-r--r--src/newt/classes/jogamp/newt/driver/x11/DisplayDriver.java10
-rw-r--r--src/newt/classes/jogamp/newt/driver/x11/RandR.java12
-rw-r--r--src/newt/classes/jogamp/newt/driver/x11/RandR11.java26
-rw-r--r--src/newt/classes/jogamp/newt/driver/x11/RandR13.java63
-rw-r--r--src/newt/classes/jogamp/newt/driver/x11/ScreenDriver.java61
-rw-r--r--src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java73
-rw-r--r--src/newt/classes/jogamp/newt/swt/SWTEDTUtil.java170
-rw-r--r--src/newt/classes/jogamp/newt/swt/event/SWTNewtEventFactory.java1
26 files changed, 827 insertions, 489 deletions
diff --git a/src/newt/classes/jogamp/newt/Debug.java b/src/newt/classes/jogamp/newt/Debug.java
index 3c83da4d9..4b0a98216 100644
--- a/src/newt/classes/jogamp/newt/Debug.java
+++ b/src/newt/classes/jogamp/newt/Debug.java
@@ -1,5 +1,6 @@
/*
- * Copyright (c) 2003-2005 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright (c) 2010 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
@@ -39,6 +40,9 @@
package jogamp.newt;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
import com.jogamp.common.util.PropertyAccess;
/** Helper routines for logging and debugging. */
@@ -49,7 +53,12 @@ public class Debug extends PropertyAccess {
private static final boolean debugAll;
static {
- PropertyAccess.addTrustedPrefix("newt.", Debug.class);
+ AccessController.doPrivileged(new PrivilegedAction<Object>() {
+ public Object run() {
+ PropertyAccess.addTrustedPrefix("newt.");
+ return null;
+ } } );
+
verbose = isPropertyDefined("newt.verbose", true);
debugAll = isPropertyDefined("newt.debug", true);
if (verbose) {
@@ -60,27 +69,18 @@ public class Debug extends PropertyAccess {
}
}
- public static final boolean isPropertyDefined(final String property, final boolean jnlpAlias) {
- return PropertyAccess.isPropertyDefined(property, jnlpAlias, null);
- }
-
- public static final int getIntProperty(final String property, final boolean jnlpAlias, int defaultValue) {
- return PropertyAccess.getIntProperty(property, jnlpAlias, null, defaultValue);
- }
-
- public static final boolean getBooleanProperty(final String property, final boolean jnlpAlias) {
- return PropertyAccess.getBooleanProperty(property, jnlpAlias, null);
- }
-
- public static boolean verbose() {
+ /** Ensures static init block has been issues, i.e. if calling through to {@link PropertyAccess#isPropertyDefined(String, boolean)}. */
+ public static final void initSingleton() {}
+
+ public static final boolean verbose() {
return verbose;
}
- public static boolean debugAll() {
+ public static final boolean debugAll() {
return debugAll;
}
- public static boolean debug(String subcomponent) {
+ public static final boolean debug(String subcomponent) {
return debugAll() || isPropertyDefined("newt.debug." + subcomponent, true);
}
}
diff --git a/src/newt/classes/jogamp/newt/DefaultEDTUtil.java b/src/newt/classes/jogamp/newt/DefaultEDTUtil.java
index 651522799..a229a0512 100644
--- a/src/newt/classes/jogamp/newt/DefaultEDTUtil.java
+++ b/src/newt/classes/jogamp/newt/DefaultEDTUtil.java
@@ -53,7 +53,7 @@ public class DefaultEDTUtil implements EDTUtil {
private final ThreadGroup threadGroup;
private final String name;
private final Runnable dispatchMessages;
- private EventDispatchThread edt = null;
+ private NEDT edt = null;
private int start_iter=0;
private static long pollPeriod = EDTUtil.defaultEDTPollPeriod;
@@ -61,7 +61,7 @@ public class DefaultEDTUtil implements EDTUtil {
this.threadGroup = tg;
this.name=Thread.currentThread().getName()+"-"+name+"-EDT-";
this.dispatchMessages=dispatchMessages;
- this.edt = new EventDispatchThread(threadGroup, name);
+ this.edt = new NEDT(threadGroup, name);
this.edt.setDaemon(true); // don't stop JVM from shutdown ..
}
@@ -76,31 +76,34 @@ public class DefaultEDTUtil implements EDTUtil {
}
@Override
- public final void reset() {
- synchronized(edtLock) {
- waitUntilStopped();
+ public final boolean restart() throws IllegalStateException {
+ synchronized(edtLock) {
+ if( edt.isRunning() ) {
+ throw new IllegalStateException("EDT still running and not subject to stop. Curr "+Thread.currentThread().getName()+", EDT "+edt.getName()+", isRunning "+edt.isRunning+", shouldStop "+edt.shouldStop);
+ }
if(DEBUG) {
if(edt.tasks.size()>0) {
System.err.println(Thread.currentThread()+": Default-EDT reset, remaining tasks: "+edt.tasks.size()+" - "+edt);
- // Thread.dumpStack();
}
System.err.println(Thread.currentThread()+": Default-EDT reset - edt: "+edt);
}
- this.edt = new EventDispatchThread(threadGroup, name);
- this.edt.setDaemon(true); // don't stop JVM from shutdown ..
+ if( edt.getState() != Thread.State.NEW ) {
+ edt = new NEDT(threadGroup, name);
+ edt.setDaemon(true); // don't stop JVM from shutdown ..
+ }
+ startImpl();
}
+ return invoke(true, nullTask);
}
private final void startImpl() {
if(edt.isAlive()) {
- throw new RuntimeException("Default-EDT Thread.isAlive(): true, isRunning: "+edt.isRunning()+", edt: "+edt+", tasks: "+edt.tasks.size());
+ throw new RuntimeException("Default-EDT Thread.isAlive(): true, isRunning: "+edt.isRunning+", shouldStop "+edt.shouldStop+", edt: "+edt+", tasks: "+edt.tasks.size());
}
start_iter++;
edt.setName(name+start_iter);
- edt.shouldStop = false;
if(DEBUG) {
System.err.println(Thread.currentThread()+": Default-EDT START - edt: "+edt);
- // Thread.dumpStack();
}
edt.start();
}
@@ -126,13 +129,13 @@ public class DefaultEDTUtil implements EDTUtil {
}
@Override
- public final void invokeStop(Runnable task) {
- invokeImpl(true, task, true);
+ public final boolean invokeStop(boolean wait, Runnable task) {
+ return invokeImpl(wait, task, true);
}
@Override
- public final void invoke(boolean wait, Runnable task) {
- invokeImpl(wait, task, false);
+ public final boolean invoke(boolean wait, Runnable task) {
+ return invokeImpl(wait, task, false);
}
private static Runnable nullTask = new Runnable() {
@@ -140,28 +143,26 @@ public class DefaultEDTUtil implements EDTUtil {
public void run() { }
};
- private void invokeImpl(boolean wait, Runnable task, boolean stop) {
+ private final boolean invokeImpl(boolean wait, Runnable task, boolean stop) {
Throwable throwable = null;
RunnableTask rTask = null;
- Object rTaskLock = new Object();
+ final Object rTaskLock = new Object();
synchronized(rTaskLock) { // lock the optional task execution
synchronized(edtLock) { // lock the EDT status
if( edt.shouldStop ) {
// drop task ..
+ System.err.println(Thread.currentThread()+": Warning: Default-EDT about (1) to stop, won't enqueue new task: "+edt);
if(DEBUG) {
- System.err.println(Thread.currentThread()+": Warning: Default-EDT about (1) to stop, won't enqueue new task: "+edt);
Thread.dumpStack();
}
- return;
+ return false;
}
- // System.err.println(Thread.currentThread()+" XXX stop: "+stop+", tasks: "+edt.tasks.size()+", task: "+task);
- // Thread.dumpStack();
if( isCurrentThreadEDT() ) {
if(null != task) {
task.run();
}
wait = false; // running in same thread (EDT) -> no wait
- if(stop) {
+ if( stop ) {
edt.shouldStop = true;
if( edt.tasks.size()>0 ) {
System.err.println(Thread.currentThread()+": Warning: Default-EDT about (2) to stop, task executed. Remaining tasks: "+edt.tasks.size()+" - "+edt);
@@ -171,19 +172,20 @@ public class DefaultEDTUtil implements EDTUtil {
}
}
} else {
- if( !edt.isRunning() ) {
- if( !stop ) {
- startImpl();
- } else {
- // drop task and don't wait
- task = null;
- System.err.println(Thread.currentThread()+": Warning: Default-EDT is about (3) to stop and stopped already, dropping task. Remaining tasks: "+edt.tasks.size()+" - "+edt);
+ if( !edt.isRunning ) {
+ if( null != task ) {
+ if( stop ) {
+ System.err.println(Thread.currentThread()+": Warning: Default-EDT is about (3) to stop and stopped already, dropping task. Remaining tasks: "+edt.tasks.size()+" - "+edt);
+ } else {
+ System.err.println(Thread.currentThread()+": Warning: Default-EDT is not running, dropping task. NEDT "+edt);
+ }
if(DEBUG) {
Thread.dumpStack();
}
}
- } else if(stop && null == task) {
- task = nullTask;
+ return false;
+ } else if( stop && null == task ) {
+ task = nullTask; // ensures execution triggering stop
}
if(null != task) {
@@ -220,23 +222,26 @@ public class DefaultEDTUtil implements EDTUtil {
throw new RuntimeException(throwable);
}
}
- }
- if(DEBUG && stop) {
- System.err.println(Thread.currentThread()+": Default-EDT signal STOP X edt: "+edt);
+ if(DEBUG) {
+ if( stop) {
+ System.err.println(Thread.currentThread()+": Default-EDT signal STOP X edt: "+edt);
+ }
+ }
+ return true;
}
}
@Override
- final public void waitUntilIdle() {
- final EventDispatchThread _edt;
+ final public boolean waitUntilIdle() {
+ final NEDT _edt;
synchronized(edtLock) {
_edt = edt;
}
- if(!_edt.isRunning() || _edt == Thread.currentThread()) {
- return;
+ if(!_edt.isRunning || _edt == Thread.currentThread()) {
+ return false;
}
synchronized(_edt.tasks) {
- while(_edt.isRunning() && _edt.tasks.size()>0) {
+ while(_edt.isRunning && _edt.tasks.size()>0) {
try {
_edt.tasks.notifyAll();
_edt.tasks.wait();
@@ -244,35 +249,39 @@ public class DefaultEDTUtil implements EDTUtil {
e.printStackTrace();
}
}
+ return true;
}
}
@Override
- final public void waitUntilStopped() {
+ final public boolean waitUntilStopped() {
synchronized(edtLock) {
- if(edt.isRunning() && edt != Thread.currentThread() ) {
- while(edt.isRunning()) {
+ if(edt.isRunning && edt != Thread.currentThread() ) {
+ while( edt.isRunning ) {
try {
edtLock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
+ return true;
+ } else {
+ return false;
}
}
}
- class EventDispatchThread extends Thread {
+ class NEDT extends Thread {
volatile boolean shouldStop = false;
volatile boolean isRunning = false;
ArrayList<RunnableTask> tasks = new ArrayList<RunnableTask>(); // one shot tasks
- public EventDispatchThread(ThreadGroup tg, String name) {
+ public NEDT(ThreadGroup tg, String name) {
super(tg, name);
}
final public boolean isRunning() {
- return isRunning;
+ return isRunning && !shouldStop;
}
@Override
@@ -282,11 +291,9 @@ public class DefaultEDTUtil implements EDTUtil {
}
private final void validateNoRecursiveLocksHold() {
- if(Lock.DEBUG) {
- if(LockDebugUtil.getRecursiveLockTrace().size()>0) {
- LockDebugUtil.dumpRecursiveLockTrace(System.err);
- throw new InternalError("XXX");
- }
+ if(LockDebugUtil.getRecursiveLockTrace().size()>0) {
+ LockDebugUtil.dumpRecursiveLockTrace(System.err);
+ throw new InternalError("XXX");
}
}
@@ -299,7 +306,9 @@ public class DefaultEDTUtil implements EDTUtil {
if(DEBUG) {
System.err.println(getName()+": Default-EDT run() START "+ getName());
}
- validateNoRecursiveLocksHold();
+ if(Lock.DEBUG) {
+ validateNoRecursiveLocksHold();
+ }
RuntimeException error = null;
try {
do {
@@ -329,7 +338,9 @@ public class DefaultEDTUtil implements EDTUtil {
}
if(null!=task) {
task.run();
- validateNoRecursiveLocksHold();
+ if(Lock.DEBUG) {
+ validateNoRecursiveLocksHold();
+ }
if(!task.hasWaiter() && null != task.getThrowable()) {
// at least dump stack-trace in case nobody waits for result
System.err.println("DefaultEDT.run(): Catched exception occured on thread "+Thread.currentThread().getName()+": "+task.toString());
diff --git a/src/newt/classes/jogamp/newt/DisplayImpl.java b/src/newt/classes/jogamp/newt/DisplayImpl.java
index d4842ba2f..8f792b23c 100644
--- a/src/newt/classes/jogamp/newt/DisplayImpl.java
+++ b/src/newt/classes/jogamp/newt/DisplayImpl.java
@@ -41,14 +41,29 @@ import com.jogamp.newt.event.NEWTEventConsumer;
import jogamp.newt.event.NEWTEventTask;
import com.jogamp.newt.util.EDTUtil;
+
import java.util.ArrayList;
import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.NativeWindowFactory;
public abstract class DisplayImpl extends Display {
private static int serialno = 1;
+ static {
+ NativeWindowFactory.addCustomShutdownHook(true /* head */, new Runnable() {
+ public void run() {
+ WindowImpl.shutdownAll();
+ ScreenImpl.shutdownAll();
+ DisplayImpl.shutdownAll();
+ }
+ });
+ }
+
+ /** Ensure static init has been run. */
+ /* pp */static void initSingleton() { }
+
private static Class<?> getDisplayClass(String type)
throws ClassNotFoundException
{
@@ -62,12 +77,12 @@ public abstract class DisplayImpl extends Display {
/** Make sure to reuse a Display with the same name */
public static Display create(String type, String name, final long handle, boolean reuse) {
try {
- Class<?> displayClass = getDisplayClass(type);
- DisplayImpl display = (DisplayImpl) displayClass.newInstance();
+ final Class<?> displayClass = getDisplayClass(type);
+ final DisplayImpl display = (DisplayImpl) displayClass.newInstance();
name = display.validateDisplayName(name, handle);
synchronized(displayList) {
if(reuse) {
- Display display0 = Display.getLastDisplayOf(type, name, -1, true /* shared only */);
+ final Display display0 = Display.getLastDisplayOf(type, name, -1, true /* shared only */);
if(null != display0) {
if(DEBUG) {
System.err.println("Display.create() REUSE: "+display0+" "+getThreadName());
@@ -82,9 +97,9 @@ public abstract class DisplayImpl extends Display {
display.id = serialno++;
display.fqname = getFQName(display.type, display.name, display.id);
display.hashCode = display.fqname.hashCode();
- displayList.add(display);
+ display.setEDTUtil( display.edtUtil ); // device's default if EDT is used, or null
+ Display.addDisplay2List(display);
}
- display.setEDTUtil(display.edtUtil); // device's default if EDT is used, or null
if(DEBUG) {
System.err.println("Display.create() NEW: "+display+" "+getThreadName());
@@ -122,10 +137,10 @@ public abstract class DisplayImpl extends Display {
}
@Override
- public synchronized final void createNative()
+ public synchronized final void createNative()
throws NativeWindowException
{
- if(null==aDevice) {
+ if( null == aDevice ) {
if(DEBUG) {
System.err.println("Display.createNative() START ("+getThreadName()+", "+this+")");
}
@@ -138,14 +153,14 @@ public abstract class DisplayImpl extends Display {
} catch (Throwable t) {
throw new NativeWindowException(t);
}
- if(null==aDevice) {
+ if( null == aDevice ) {
throw new NativeWindowException("Display.createNative() failed to instanciate an AbstractGraphicsDevice");
}
- if(DEBUG) {
- System.err.println("Display.createNative() END ("+getThreadName()+", "+this+")");
- }
synchronized(displayList) {
displaysActive++;
+ if(DEBUG) {
+ System.err.println("Display.createNative() END ("+getThreadName()+", "+this+", active "+displaysActive+")");
+ }
}
}
}
@@ -164,25 +179,23 @@ public abstract class DisplayImpl extends Display {
}
@Override
- public EDTUtil setEDTUtil(EDTUtil newEDTUtil) {
+ public synchronized EDTUtil setEDTUtil(final EDTUtil usrEDTUtil) {
final EDTUtil oldEDTUtil = edtUtil;
- if(null == newEDTUtil) {
- if(DEBUG) {
- System.err.println("Display.setEDTUtil(default): "+oldEDTUtil+" -> "+newEDTUtil);
+ final EDTUtil newEDTUtil;
+ if( null != usrEDTUtil && usrEDTUtil == oldEDTUtil ) {
+ if( DEBUG ) {
+ System.err.println("Display.setEDTUtil: "+usrEDTUtil+" - keep!");
}
- edtUtil = createEDTUtil();
- } else if( newEDTUtil != edtUtil ) {
+ newEDTUtil = oldEDTUtil;
+ } else {
if(DEBUG) {
- System.err.println("Display.setEDTUtil(custom): "+oldEDTUtil+" -> "+newEDTUtil);
+ final String msg = ( null == usrEDTUtil ) ? "default" : "custom";
+ System.err.println("Display.setEDTUtil("+msg+"): "+oldEDTUtil+" -> "+usrEDTUtil);
}
- removeEDT( null );
- edtUtil = newEDTUtil;
- } else if( DEBUG ) {
- System.err.println("Display.setEDTUtil: "+newEDTUtil+" - keep!");
- }
- if( !edtUtil.isRunning() ) { // start EDT if not running yet
- edtUtil.invoke(true, null);
+ stopEDT( oldEDTUtil, null );
+ newEDTUtil = ( null == usrEDTUtil ) ? createEDTUtil() : usrEDTUtil;
}
+ edtUtil = newEDTUtil;
return oldEDTUtil;
}
@@ -191,29 +204,61 @@ public abstract class DisplayImpl extends Display {
return edtUtil;
}
- private void removeEDT(final Runnable task) {
- if(null!=edtUtil) {
- edtUtil.invokeStop(task);
- // ready for restart ..
+ private static void stopEDT(final EDTUtil edtUtil, final Runnable task) {
+ if( null != edtUtil ) {
+ if( edtUtil.isRunning() ) {
+ final boolean res = edtUtil.invokeStop(true, task);
+ if( DEBUG ) {
+ if ( !res ) {
+ System.err.println("Warning: invokeStop() failed");
+ Thread.dumpStack();
+ }
+ }
+ }
edtUtil.waitUntilStopped();
- edtUtil.reset();
- } else {
+ // ready for restart ..
+ } else if( null != task ) {
task.run();
}
}
public void runOnEDTIfAvail(boolean wait, final Runnable task) {
- if( null!=edtUtil && !edtUtil.isCurrentThreadEDT()) {
- edtUtil.invoke(wait, task);
+ final EDTUtil _edtUtil = edtUtil;
+ if( null != _edtUtil && !_edtUtil.isCurrentThreadEDT() ) {
+ if( !_edtUtil.isRunning() ) { // start EDT if not running yet
+ synchronized( this ) {
+ if( !_edtUtil.isRunning() ) { // // volatile dbl-checked-locking OK
+ _edtUtil.restart();
+ if( DEBUG ) {
+ System.err.println("Info: EDT started "+Thread.currentThread().getName()+", "+this);
+ Thread.dumpStack();
+ }
+ }
+ }
+ }
+ if( !_edtUtil.invoke(wait, task) ) {
+ if( DEBUG ) {
+ System.err.println("Warning: invoke(wait "+wait+", ..) on EDT failed .. invoke on current thread "+Thread.currentThread().getName());
+ Thread.dumpStack();
+ }
+ task.run();
+ }
} else {
task.run();
}
}
public boolean validateEDT() {
- if(0==refCount && null==aDevice && null != edtUtil && edtUtil.isRunning()) {
- removeEDT( null );
- return true;
+ if( 0==refCount && null == aDevice ) {
+ final EDTUtil _edtUtil = edtUtil;
+ if( null != _edtUtil && _edtUtil.isRunning() ) {
+ synchronized( this ) {
+ if( null != edtUtil && edtUtil.isRunning() ) { // // volatile dbl-checked-locking OK
+ stopEDT( edtUtil, null );
+ return true;
+ }
+ }
+ }
}
return false;
}
@@ -224,29 +269,69 @@ public abstract class DisplayImpl extends Display {
dumpDisplayList("Display.destroy("+getFQName()+") BEGIN");
}
synchronized(displayList) {
- displayList.remove(this);
if(0 < displaysActive) {
displaysActive--;
}
- }
- if(DEBUG) {
- System.err.println("Display.destroy(): "+this+" "+getThreadName());
- }
- final AbstractGraphicsDevice f_aDevice = aDevice;
+ if(DEBUG) {
+ System.err.println("Display.destroy(): "+this+", active "+displaysActive+" "+getThreadName());
+ }
+ }
final DisplayImpl f_dpy = this;
- removeEDT( new Runnable() {
+ final AbstractGraphicsDevice f_aDevice = aDevice;
+ aDevice = null;
+ refCount=0;
+ stopEDT( edtUtil, new Runnable() { // blocks!
public void run() {
if ( null != f_aDevice ) {
- f_dpy.closeNativeImpl();
+ f_dpy.closeNativeImpl(f_aDevice);
}
}
} );
- aDevice = null;
- refCount=0;
if(DEBUG) {
dumpDisplayList("Display.destroy("+getFQName()+") END");
}
}
+
+ /** May be utilized at a shutdown hook, impl. does not block. */
+ /* pp */ static final void shutdownAll() {
+ final int dCount = displayList.size();
+ if(DEBUG) {
+ dumpDisplayList("Display.shutdownAll "+dCount+" instances, on thread "+getThreadName());
+ }
+ for(int i=0; i<dCount && displayList.size()>0; i++) { // be safe ..
+ final DisplayImpl d = (DisplayImpl) displayList.remove(0).get();
+ if(DEBUG) {
+ System.err.println("Display.shutdownAll["+(i+1)+"/"+dCount+"]: "+d+", GCed "+(null==d));
+ }
+ if( null != d ) { // GC'ed ?
+ if(0 < displaysActive) {
+ displaysActive--;
+ }
+ final EDTUtil edtUtil = d.getEDTUtil();
+ final AbstractGraphicsDevice f_aDevice = d.aDevice;
+ d.aDevice = null;
+ d.refCount=0;
+ final Runnable closeNativeTask = new Runnable() {
+ public void run() {
+ if ( null != d.getGraphicsDevice() ) {
+ d.closeNativeImpl(f_aDevice);
+ }
+ }
+ };
+ if(null != edtUtil) {
+ final long coopSleep = edtUtil.getPollPeriod() * 2;
+ if( edtUtil.isRunning() ) {
+ edtUtil.invokeStop(false, closeNativeTask); // don't block
+ }
+ try {
+ Thread.sleep( coopSleep < 50 ? coopSleep : 50 );
+ } catch (InterruptedException e) { }
+ } else {
+ closeNativeTask.run();
+ }
+ }
+ }
+ }
public synchronized final int addReference() {
if(DEBUG) {
@@ -279,7 +364,7 @@ public abstract class DisplayImpl extends Display {
}
protected abstract void createNativeImpl();
- protected abstract void closeNativeImpl();
+ protected abstract void closeNativeImpl(AbstractGraphicsDevice aDevice);
@Override
public final int getId() {
@@ -347,15 +432,18 @@ public abstract class DisplayImpl extends Display {
@Override
public boolean isEDTRunning() {
- if(null!=edtUtil) {
- return edtUtil.isRunning();
+ final EDTUtil _edtUtil = edtUtil;
+ if( null != _edtUtil ) {
+ return _edtUtil.isRunning();
}
return false;
}
@Override
public String toString() {
- return "NEWT-Display["+getFQName()+", excl "+exclusive+", refCount "+refCount+", hasEDT "+(null!=edtUtil)+", edtRunning "+isEDTRunning()+", "+aDevice+"]";
+ final EDTUtil _edtUtil = edtUtil;
+ final boolean _edtUtilRunning = ( null != _edtUtil ) ? _edtUtil.isRunning() : false;
+ return "NEWT-Display["+getFQName()+", excl "+exclusive+", refCount "+refCount+", hasEDT "+(null!=_edtUtil)+", edtRunning "+_edtUtilRunning+", "+aDevice+"]";
}
/** Dispatch native Toolkit messageges */
@@ -448,17 +536,18 @@ public abstract class DisplayImpl extends Display {
}
public void enqueueEvent(boolean wait, NEWTEvent e) {
- if(!isEDTRunning()) {
+ final EDTUtil _edtUtil = edtUtil;
+ if( !_edtUtil.isRunning() ) {
// oops .. we are already dead
if(DEBUG) {
- Throwable t = new Throwable("Warning: EDT already stopped: wait:="+wait+", "+e);
- t.printStackTrace();
+ System.err.println("Warning: EDT already stopped: wait:="+wait+", "+e);
+ Thread.dumpStack();
}
return;
}
// can't wait if we are on EDT or NEDT -> consume right away
- if(wait && edtUtil.isCurrentThreadEDTorNEDT() ) {
+ if(wait && _edtUtil.isCurrentThreadEDTorNEDT() ) {
dispatchMessage(e);
return;
}
@@ -505,7 +594,7 @@ public abstract class DisplayImpl extends Display {
return runWithLockedDevice(device, action);
}
- protected EDTUtil edtUtil = null;
+ protected volatile EDTUtil edtUtil = null;
protected int id;
protected String name;
protected String type;
diff --git a/src/newt/classes/jogamp/newt/MonitorDeviceImpl.java b/src/newt/classes/jogamp/newt/MonitorDeviceImpl.java
index db31cc83f..43d558515 100644
--- a/src/newt/classes/jogamp/newt/MonitorDeviceImpl.java
+++ b/src/newt/classes/jogamp/newt/MonitorDeviceImpl.java
@@ -94,20 +94,20 @@ public class MonitorDeviceImpl extends MonitorDevice {
}
final long tStart;
if(Screen.DEBUG) {
- tStart = System.nanoTime();
+ tStart = System.currentTimeMillis();
} else {
tStart = 0;
}
sms.fireMonitorModeChangeNotify(this, mmU);
if(Screen.DEBUG) {
- System.err.println("Screen.setCurrentMode ("+(System.nanoTime()-tStart)/1e6+"ms): fireModeChangeNotify() "+mmU);
+ System.err.println("Screen.setCurrentMode ("+(System.currentTimeMillis()-tStart)+"ms): fireModeChangeNotify() "+mmU);
}
-
+
boolean success = screenImpl.setCurrentMonitorModeImpl(this, mmU);
if(success) {
if(Screen.DEBUG) {
- System.err.println("Screen.setCurrentMode ("+(System.nanoTime()-tStart)/1e6+"ms): setCurrentModeImpl() "+mmU+", success(1): "+success);
+ System.err.println("Screen.setCurrentMode ("+(System.currentTimeMillis()-tStart)+"ms): setCurrentModeImpl() "+mmU+", success(1): "+success);
}
} else {
// 2nd attempt validate!
@@ -115,7 +115,7 @@ public class MonitorDeviceImpl extends MonitorDevice {
success = queriedCurrent.hashCode() == mmU.hashCode() ;
if(Screen.DEBUG) {
System.err.println("Screen.setCurrentMode.2: queried "+queriedCurrent);
- System.err.println("Screen.setCurrentMode ("+(System.nanoTime()-tStart)/1e6+"ms): setCurrentModeImpl() "+mmU+", success(2): "+success);
+ System.err.println("Screen.setCurrentMode ("+(System.currentTimeMillis()-tStart)+"ms): setCurrentModeImpl() "+mmU+", success(2): "+success);
}
}
if( success ) {
@@ -124,7 +124,7 @@ public class MonitorDeviceImpl extends MonitorDevice {
}
sms.fireMonitorModeChanged(this, mmU, success);
if(Screen.DEBUG) {
- System.err.println("Screen.setCurrentMode ("+(System.nanoTime()-tStart)/1e6+"ms): X.X "+this+", success: "+success);
+ System.err.println("Screen.setCurrentMode ("+(System.currentTimeMillis()-tStart)+"ms): X.X: success "+success+": "+this);
}
return success;
} finally {
diff --git a/src/newt/classes/jogamp/newt/ScreenImpl.java b/src/newt/classes/jogamp/newt/ScreenImpl.java
index 7edf7b63a..5ffa2ebbf 100644
--- a/src/newt/classes/jogamp/newt/ScreenImpl.java
+++ b/src/newt/classes/jogamp/newt/ScreenImpl.java
@@ -34,8 +34,6 @@
package jogamp.newt;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
@@ -54,9 +52,15 @@ import com.jogamp.newt.NewtFactory;
import com.jogamp.newt.Screen;
import com.jogamp.newt.event.MonitorEvent;
import com.jogamp.newt.event.MonitorModeListener;
+import com.jogamp.newt.util.MonitorModeUtil;
public abstract class ScreenImpl extends Screen implements MonitorModeListener {
- protected static final boolean DEBUG_TEST_SCREENMODE_DISABLED = Debug.isPropertyDefined("newt.test.Screen.disableScreenMode", true);
+ protected static final boolean DEBUG_TEST_SCREENMODE_DISABLED;
+
+ static {
+ Debug.initSingleton();
+ DEBUG_TEST_SCREENMODE_DISABLED = Debug.isPropertyDefined("newt.test.Screen.disableScreenMode", true);
+ }
public static final int default_sm_bpp = 32;
public static final int default_sm_widthmm = 519;
@@ -64,6 +68,13 @@ public abstract class ScreenImpl extends Screen implements MonitorModeListener {
public static final int default_sm_rate = 60;
public static final int default_sm_rotation = 0;
+ static {
+ DisplayImpl.initSingleton();
+ }
+
+ /** Ensure static init has been run. */
+ /* pp */static void initSingleton() { }
+
protected DisplayImpl display;
protected int screen_idx;
protected String fqname;
@@ -77,15 +88,6 @@ public abstract class ScreenImpl extends Screen implements MonitorModeListener {
private long tCreated; // creationTime
- static {
- AccessController.doPrivileged(new PrivilegedAction<Object>() {
- public Object run() {
- registerShutdownHook();
- return null;
- }
- });
- }
-
private static Class<?> getScreenClass(String type) throws ClassNotFoundException
{
final Class<?> screenClass = NewtFactory.getCustomClass(type, "ScreenDriver");
@@ -128,7 +130,7 @@ public abstract class ScreenImpl extends Screen implements MonitorModeListener {
screen.screen_idx = idx;
screen.fqname = display.getFQName()+"-s"+idx;
screen.hashCode = screen.fqname.hashCode();
- screenList.add(screen);
+ Screen.addScreen2List(screen);
if(DEBUG) {
System.err.println("Screen.create() NEW: "+screen+" "+Display.getThreadName());
}
@@ -172,39 +174,39 @@ public abstract class ScreenImpl extends Screen implements MonitorModeListener {
System.err.println("Screen.createNative() START ("+DisplayImpl.getThreadName()+", "+this+")");
} else {
tCreated = 0;
- }
-
+ }
display.addReference();
createNativeImpl();
if(null == aScreen) {
throw new NativeWindowException("Screen.createNative() failed to instanciate an AbstractGraphicsScreen");
}
-
+
initMonitorState();
- if(DEBUG) {
- System.err.println("Screen.createNative() END ("+DisplayImpl.getThreadName()+", "+this+"), total "+ (System.nanoTime()-tCreated)/1e6 +"ms");
- }
synchronized(screenList) {
screensActive++;
+ if(DEBUG) {
+ System.err.println("Screen.createNative() END ("+DisplayImpl.getThreadName()+", "+this+"), active "+screensActive+", total "+ (System.nanoTime()-tCreated)/1e6 +"ms");
+ }
}
+ ScreenMonitorState.getScreenMonitorState(this.getFQName()).addListener(this);
}
- ScreenMonitorState sms = ScreenMonitorState.getScreenMonitorState(this.getFQName());
- sms.addListener(this);
}
@Override
public synchronized final void destroy() {
- releaseMonitorState();
-
synchronized(screenList) {
- screenList.remove(this);
if(0 < screensActive) {
screensActive--;
}
+ if(DEBUG) {
+ System.err.println("Screen.destroy() ("+DisplayImpl.getThreadName()+"): active "+screensActive);
+ // Thread.dumpStack();
+ }
}
if ( null != aScreen ) {
+ releaseMonitorState();
closeNativeImpl();
aScreen = null;
}
@@ -220,8 +222,7 @@ public abstract class ScreenImpl extends Screen implements MonitorModeListener {
}
if ( 0 == refCount ) {
createNative();
- }
- if(null == aScreen) {
+ } else if(null == aScreen) {
throw new NativeWindowException("Screen.addReference() (refCount "+refCount+") null AbstractGraphicsScreen");
}
return ++refCount;
@@ -289,12 +290,12 @@ public abstract class ScreenImpl extends Screen implements MonitorModeListener {
vOriginSize.setWidth(usrSize.getWidth());
vOriginSize.setHeight(usrSize.getHeight());
if(DEBUG) {
- System.err.println("User virtual screen viewport "+vOriginSize);
+ System.err.println("Update user virtual screen viewport @ "+Thread.currentThread().getName()+": "+vOriginSize);
}
} else {
calcVirtualScreenOriginAndSize(vOriginSize);
if(DEBUG) {
- System.err.println("Detected virtual screen viewport "+vOriginSize);
+ System.err.println("Updated virtual screen viewport @ "+Thread.currentThread().getName()+": "+vOriginSize);
}
}
}
@@ -401,7 +402,7 @@ public abstract class ScreenImpl extends Screen implements MonitorModeListener {
@Override
public void monitorModeChangeNotify(MonitorEvent me) {
if(DEBUG) {
- System.err.println("monitorModeChangeNotify: "+me);
+ System.err.println("monitorModeChangeNotify @ "+Thread.currentThread().getName()+": "+me);
}
for(int i=0; i<refMonitorModeListener.size(); i++) {
((MonitorModeListener)refMonitorModeListener.get(i)).monitorModeChangeNotify(me);
@@ -414,7 +415,7 @@ public abstract class ScreenImpl extends Screen implements MonitorModeListener {
final MonitorDeviceImpl monitor = (MonitorDeviceImpl) monitors.get(i);
final Rectangle newViewport = getNativeMonitorDeviceViewportImpl(monitor);
if( DEBUG ) {
- System.err.println("Screen.updateMonitorViewport["+i+"]: "+monitor.getViewport()+" -> "+newViewport);
+ System.err.println("Screen.updateMonitorViewport["+i+"] @ "+Thread.currentThread().getName()+": "+monitor.getViewport()+" -> "+newViewport);
}
if( null != newViewport ) {
monitor.setViewportValue(newViewport);
@@ -429,7 +430,7 @@ public abstract class ScreenImpl extends Screen implements MonitorModeListener {
updateVirtualScreenOriginAndSize();
}
if(DEBUG) {
- System.err.println("monitorModeChanged: success "+success+", "+me);
+ System.err.println("monitorModeChangeNotify @ "+Thread.currentThread().getName()+": success "+success+", "+me);
}
for(int i=0; i<refMonitorModeListener.size(); i++) {
((MonitorModeListener)refMonitorModeListener.get(i)).monitorModeChanged(me, success);
@@ -540,6 +541,11 @@ public abstract class ScreenImpl extends Screen implements MonitorModeListener {
final MonitorDevice monitor = getVirtualMonitorDevice(cache, 0, mode);
cache.monitorDevices.getOrAdd(monitor);
}
+ // Sort MonitorModes (all and per device) in descending order - default!
+ MonitorModeUtil.sort(cache.monitorModes.getData(), false ); // descending order
+ for(Iterator<MonitorDevice> iMonitor=cache.monitorDevices.iterator(); iMonitor.hasNext(); ) {
+ MonitorModeUtil.sort(iMonitor.next().getSupportedModes(), false ); // descending order
+ }
if(DEBUG) {
int i=0;
for(Iterator<MonitorMode> iMode=cache.monitorModes.iterator(); iMode.hasNext(); i++) {
@@ -554,7 +560,7 @@ public abstract class ScreenImpl extends Screen implements MonitorModeListener {
System.err.println("["+i+"]["+j+"]: "+iMode.next());
}
}
- }
+ }
sms = new ScreenMonitorState(cache.monitorDevices, cache.monitorModes);
ScreenMonitorState.mapScreenMonitorState(this.getFQName(), sms);
}
@@ -609,7 +615,7 @@ public abstract class ScreenImpl extends Screen implements MonitorModeListener {
return cache.monitorDevices.size();
}
- private void releaseMonitorState() {
+ private final void releaseMonitorState() {
ScreenMonitorState sms;
ScreenMonitorState.lockScreenMonitorState();
try {
@@ -660,23 +666,20 @@ public abstract class ScreenImpl extends Screen implements MonitorModeListener {
ScreenMonitorState.unmapScreenMonitorStateUnlocked(getFQName());
}
}
- private static final void shutdownAll() {
- for(int i=0; i < screenList.size(); i++) {
- ((ScreenImpl)screenList.get(i)).shutdown();
- }
- }
- private static synchronized void registerShutdownHook() {
- final Thread shutdownHook = new Thread(new Runnable() {
- public void run() {
- ScreenImpl.shutdownAll();
+ /** pp */ static final void shutdownAll() {
+ final int sCount = screenList.size();
+ if(DEBUG) {
+ System.err.println("Screen.shutdownAll "+sCount+" instances, on thread "+Display.getThreadName());
+ }
+ for(int i=0; i<sCount && screenList.size()>0; i++) { // be safe ..
+ final ScreenImpl s = (ScreenImpl) screenList.remove(0).get();
+ if(DEBUG) {
+ System.err.println("Screen.shutdownAll["+(i+1)+"/"+sCount+"]: "+s+", GCed "+(null==s));
}
- });
- AccessController.doPrivileged(new PrivilegedAction<Object>() {
- public Object run() {
- Runtime.getRuntime().addShutdownHook(shutdownHook);
- return null;
+ if( null != s ) {
+ s.shutdown();
}
- });
+ }
}
}
diff --git a/src/newt/classes/jogamp/newt/WindowImpl.java b/src/newt/classes/jogamp/newt/WindowImpl.java
index 805ad08ad..caa461e41 100644
--- a/src/newt/classes/jogamp/newt/WindowImpl.java
+++ b/src/newt/classes/jogamp/newt/WindowImpl.java
@@ -36,6 +36,7 @@ package jogamp.newt;
import java.util.ArrayList;
import java.util.List;
+import java.lang.ref.WeakReference;
import java.lang.reflect.Method;
import com.jogamp.common.util.IntBitfield;
@@ -80,7 +81,52 @@ import jogamp.nativewindow.SurfaceUpdatedHelper;
public abstract class WindowImpl implements Window, NEWTEventConsumer
{
- public static final boolean DEBUG_TEST_REPARENT_INCOMPATIBLE = Debug.isPropertyDefined("newt.test.Window.reparent.incompatible", true);
+ public static final boolean DEBUG_TEST_REPARENT_INCOMPATIBLE;
+
+ static {
+ Debug.initSingleton();
+ DEBUG_TEST_REPARENT_INCOMPATIBLE = Debug.isPropertyDefined("newt.test.Window.reparent.incompatible", true);
+
+ ScreenImpl.initSingleton();
+ }
+
+ protected static final ArrayList<WeakReference<WindowImpl>> windowList = new ArrayList<WeakReference<WindowImpl>>();
+
+ /** Maybe utilized at a shutdown hook, impl. does not block. */
+ public static final void shutdownAll() {
+ final int wCount = windowList.size();
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Window.shutdownAll "+wCount+" instances, on thread "+getThreadName());
+ }
+ for(int i=0; i<wCount && windowList.size()>0; i++) { // be safe ..
+ final WindowImpl w = windowList.remove(0).get();
+ if(DEBUG_IMPLEMENTATION) {
+ final long wh = null != w ? w.getWindowHandle() : 0;
+ System.err.println("Window.shutdownAll["+(i+1)+"/"+wCount+"]: "+toHexString(wh)+", GCed "+(null==w));
+ }
+ if( null != w ) {
+ w.shutdown();
+ }
+ }
+ }
+ private static void addWindow2List(WindowImpl window) {
+ synchronized(windowList) {
+ // GC before add
+ int i=0, gced=0;
+ while( i < windowList.size() ) {
+ if( null == windowList.get(i).get() ) {
+ gced++;
+ windowList.remove(i);
+ } else {
+ i++;
+ }
+ }
+ windowList.add(new WeakReference<WindowImpl>(window));
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Window.addWindow2List: GCed "+gced+", size "+windowList.size());
+ }
+ }
+ }
/** Timeout of queued events (repaint and resize) */
static final long QUEUED_EVENT_TO = 1200; // ms
@@ -108,6 +154,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
private boolean fullscreen = false, brokenFocusChange = false;
private List<MonitorDevice> fullscreenMonitors = null;
private boolean fullscreenUseMainMonitor = true;
+ private boolean fullscreenUseSpanningMode = true; // spanning mode: fake full screen, only on certain platforms
private boolean autoPosition = true; // default: true (allow WM to choose top-level position, if not set by user)
private int nfs_width, nfs_height, nfs_x, nfs_y; // non fullscreen client-area size/pos w/o insets
@@ -186,6 +233,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
window.screen = (ScreenImpl) screen;
window.capsRequested = (CapabilitiesImmutable) caps.cloneMutable();
window.instantiationFinished();
+ addWindow2List(window);
return window;
} catch (Throwable t) {
t.printStackTrace();
@@ -207,12 +255,29 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
WindowImpl window = (WindowImpl) ReflectionUtil.createInstance( windowClass, cstrArgumentTypes, cstrArguments ) ;
window.screen = (ScreenImpl) screen;
window.capsRequested = (CapabilitiesImmutable) caps.cloneMutable();
+ window.instantiationFinished();
+ addWindow2List(window);
return window;
} catch (Throwable t) {
throw new NativeWindowException(t);
}
}
+ /** Fast invalidation of instance w/o any blocking function call. */
+ private final void shutdown() {
+ if(null!=lifecycleHook) {
+ lifecycleHook.shutdownRenderingAction();
+ }
+ setWindowHandle(0);
+ visible = false;
+ fullscreen = false;
+ fullscreenMonitors = null;
+ fullscreenUseMainMonitor = true;
+ fullscreenUseSpanningMode = false;
+ hasFocus = false;
+ parentWindowHandle = 0;
+ }
+
protected final void setGraphicsConfiguration(AbstractGraphicsConfiguration cfg) {
config = cfg;
}
@@ -233,9 +298,10 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
/**
* Notifies the receiver to preserve resources (GL, ..)
- * for the next destroy*() calls (only).
+ * for the next destroy*() calls (only), if supported and if <code>value</code> is <code>true</code>, otherwise clears preservation flag.
+ * @param value <code>true</code> to set the one-shot preservation if supported, otherwise clears it.
*/
- void preserveGLStateAtDestroy();
+ void preserveGLStateAtDestroy(boolean value);
/**
* Invoked before Window destroy action,
@@ -270,6 +336,14 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
* @see #pauseRenderingAction()
*/
void resumeRenderingAction();
+
+ /**
+ * Shutdown rendering action (thread) abnormally.
+ * <p>
+ * Should be called only at shutdown, if necessary.
+ * </p>
+ */
+ void shutdownRenderingAction();
}
private boolean createNative() {
@@ -321,9 +395,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
if(isFullscreen()) {
synchronized(fullScreenAction) {
fullscreen = false; // trigger a state change
- fullScreenAction.init(true, fullscreenUseMainMonitor, fullscreenMonitors);
- fullscreenMonitors = null; // release references ASAP
- fullscreenUseMainMonitor = true;
+ fullScreenAction.init(true);
fullScreenAction.run();
}
} else {
@@ -511,6 +583,16 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
* @see #positionChanged(boolean,int, int)
*/
protected abstract boolean reconfigureWindowImpl(int x, int y, int width, int height, int flags);
+
+ /**
+ * Tests whether a single reconfigure flag is supported by implementation.
+ * <p>
+ * Default is all but {@link #FLAG_IS_FULLSCREEN_SPAN}
+ * </p>
+ */
+ protected boolean isReconfigureFlagSupported(int changeFlags) {
+ return 0 == ( changeFlags & FLAG_IS_FULLSCREEN_SPAN );
+ }
protected int getReconfigureFlags(int changeFlags, boolean visible) {
return changeFlags |= ( ( 0 != getParentWindowHandle() ) ? FLAG_HAS_PARENT : 0 ) |
@@ -841,17 +923,19 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
private class SetSizeAction implements Runnable {
int width, height;
+ boolean disregardFS;
- private SetSizeAction(int w, int h) {
+ private SetSizeAction(int w, int h, boolean disregardFS) {
this.width = w;
this.height = h;
+ this.disregardFS = disregardFS;
}
public final void run() {
final RecursiveLock _lock = windowLock;
_lock.lock();
try {
- if ( !isFullscreen() && ( getWidth() != width || getHeight() != height ) ) {
+ if ( ( disregardFS || !isFullscreen() ) && ( getWidth() != width || getHeight() != height ) ) {
if(DEBUG_IMPLEMENTATION) {
System.err.println("Window setSize: START "+getWidth()+"x"+getHeight()+" -> "+width+"x"+height+", fs "+fullscreen+", windowHandle "+toHexString(windowHandle)+", visible "+visible);
}
@@ -886,9 +970,12 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
}
+ private void setFullscreenSize(int width, int height) {
+ runOnEDTIfAvail(true, new SetSizeAction(width, height, true));
+ }
@Override
public void setSize(int width, int height) {
- runOnEDTIfAvail(true, new SetSizeAction(width, height));
+ runOnEDTIfAvail(true, new SetSizeAction(width, height, false));
}
@Override
public void setTopLevelSize(int width, int height) {
@@ -964,6 +1051,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
fullscreen = false;
fullscreenMonitors = null;
fullscreenUseMainMonitor = true;
+ fullscreenUseSpanningMode = false;
hasFocus = false;
parentWindowHandle = 0;
@@ -1000,8 +1088,8 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
protected void destroy(boolean preserveResources) {
- if( preserveResources && null != WindowImpl.this.lifecycleHook ) {
- WindowImpl.this.lifecycleHook.preserveGLStateAtDestroy();
+ if( null != lifecycleHook ) {
+ lifecycleHook.preserveGLStateAtDestroy( preserveResources );
}
destroy();
}
@@ -1108,7 +1196,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
// Destroy this window and use parent's Screen.
// It may be created properly when the parent is made visible.
- destroy(false);
+ destroy( false );
setScreen( (ScreenImpl) newParentWindowNEWT.getScreen() );
operation = ReparentOperation.ACTION_NATIVE_CREATION_PENDING;
} else if(newParentWindow != getParent()) {
@@ -1796,25 +1884,13 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
private class FullScreenAction implements Runnable {
boolean fullscreen;
- List<MonitorDevice> monitors;
- boolean useMainMonitor;
- private boolean init(boolean fullscreen, boolean useMainMonitor, List<MonitorDevice> monitors) {
+ private boolean init(boolean fullscreen) {
if(isNativeValid()) {
this.fullscreen = fullscreen;
- if( isFullscreen() != fullscreen ) {
- this.monitors = monitors;
- this.useMainMonitor = useMainMonitor;
- return true;
- } else {
- this.monitors = null;
- this.useMainMonitor = true;
- return false;
- }
+ return isFullscreen() != fullscreen;
} else {
WindowImpl.this.fullscreen = fullscreen; // set current state for createNative(..)
- WindowImpl.this.fullscreenMonitors = monitors;
- WindowImpl.this.fullscreenUseMainMonitor = useMainMonitor;
return false;
}
}
@@ -1829,19 +1905,27 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
int x,y,w,h;
- final RectangleImmutable viewport;
+ final RectangleImmutable sviewport = screen.getViewport();
+ final RectangleImmutable viewport;
final int fs_span_flag;
if(fullscreen) {
- if( null == monitors ) {
- if( useMainMonitor ) {
- monitors = new ArrayList<MonitorDevice>();
- monitors.add( getMainMonitor() );
+ if( null == fullscreenMonitors ) {
+ if( fullscreenUseMainMonitor ) {
+ fullscreenMonitors = new ArrayList<MonitorDevice>();
+ fullscreenMonitors.add( getMainMonitor() );
} else {
- monitors = getScreen().getMonitorDevices();
+ fullscreenMonitors = getScreen().getMonitorDevices();
}
}
- fs_span_flag = monitors.size() > 1 ? FLAG_IS_FULLSCREEN_SPAN : 0 ;
- viewport = MonitorDevice.unionOfViewports(new Rectangle(), monitors);
+ viewport = MonitorDevice.unionOfViewports(new Rectangle(), fullscreenMonitors);
+ if( isReconfigureFlagSupported(FLAG_IS_FULLSCREEN_SPAN) &&
+ ( fullscreenMonitors.size() > 1 || sviewport.compareTo(viewport) > 0 ) ) {
+ fullscreenUseSpanningMode = true;
+ fs_span_flag = FLAG_IS_FULLSCREEN_SPAN;
+ } else {
+ fullscreenUseSpanningMode = false;
+ fs_span_flag = 0;
+ }
nfs_x = getX();
nfs_y = getY();
nfs_width = getWidth();
@@ -1851,6 +1935,9 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
w = viewport.getWidth();
h = viewport.getHeight();
} else {
+ fullscreenUseMainMonitor = true;
+ fullscreenUseSpanningMode = false;
+ fullscreenMonitors = null;
fs_span_flag = 0;
viewport = null;
x = nfs_x;
@@ -1872,16 +1959,15 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
}
}
- monitors = null; // clear references ASAP
- useMainMonitor = true;
if(DEBUG_IMPLEMENTATION) {
System.err.println("Window fs: "+fullscreen+" "+x+"/"+y+" "+w+"x"+h+", "+isUndecorated()+
- ", virtl-size: "+screen.getWidth()+"x"+screen.getHeight()+", monitorsViewport "+viewport);
+ ", virtl-screenSize: "+sviewport+", monitorsViewport "+viewport+
+ ", spanning "+fullscreenUseSpanningMode+" @ "+Thread.currentThread().getName());
}
- DisplayImpl display = (DisplayImpl) screen.getDisplay();
+ final DisplayImpl display = (DisplayImpl) screen.getDisplay();
display.dispatchMessagesNative(); // status up2date
- boolean wasVisible = isVisible();
+ final boolean wasVisible = isVisible();
// Lock parentWindow only during reparenting (attempt)
final NativeWindow parentWindowLocked;
@@ -1909,8 +1995,6 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
WindowImpl.this.waitForVisible(true, false);
display.dispatchMessagesNative(); // status up2date
WindowImpl.this.waitForSize(w, h, false, TIMEOUT_NATIVEWINDOW);
- display.dispatchMessagesNative(); // status up2date
-
if(DEBUG_IMPLEMENTATION) {
System.err.println("Window fs done: " + WindowImpl.this);
}
@@ -1921,7 +2005,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); // trigger a resize/relayout and repaint to listener
}
}
- private final FullScreenAction fullScreenAction = new FullScreenAction();
+ private final FullScreenAction fullScreenAction = new FullScreenAction();
@Override
public boolean setFullscreen(boolean fullscreen) {
@@ -1935,7 +2019,10 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
private boolean setFullscreenImpl(boolean fullscreen, boolean useMainMonitor, List<MonitorDevice> monitors) {
synchronized(fullScreenAction) {
- if( fullScreenAction.init(fullscreen, useMainMonitor, monitors) ) {
+ fullscreenMonitors = monitors;
+ fullscreenUseMainMonitor = useMainMonitor;
+ fullscreenUseSpanningMode = false;
+ if( fullScreenAction.init(fullscreen) ) {
if(fullScreenAction.fsOn() && isOffscreenInstance(WindowImpl.this, parentWindow)) {
// enable fullscreen on offscreen instance
if(null != parentWindow) {
@@ -1954,8 +2041,8 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
nfs_parent = null;
}
- if(isVisible()) {
- requestFocus(true /* wait */, this.fullscreen /* skipFocusAction */, true /* force */);
+ if( fullscreen && isVisible() ) { // force focus on fullscreen
+ requestFocus(true /* wait */, true /* skipFocusAction */, true /* force */);
}
}
return this.fullscreen;
@@ -1964,20 +2051,34 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
private class MonitorModeListenerImpl implements MonitorModeListener {
boolean animatorPaused = false;
+ boolean hadFocus = false;
+ boolean fullscreenPaused = false;
+ List<MonitorDevice> _fullscreenMonitors = null;
+ boolean _fullscreenUseMainMonitor = true;
public void monitorModeChangeNotify(MonitorEvent me) {
+ hadFocus = hasFocus();
if(DEBUG_IMPLEMENTATION) {
- System.err.println("Window.monitorModeChangeNotify: "+me);
+ System.err.println("Window.monitorModeChangeNotify: hadFocus "+hadFocus+", "+me+" @ "+Thread.currentThread().getName());
}
if(null!=lifecycleHook) {
animatorPaused = lifecycleHook.pauseRenderingAction();
}
+ if( fullscreen && isReconfigureFlagSupported(FLAG_IS_FULLSCREEN_SPAN) ) {
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Window.monitorModeChangeNotify: FS Pause");
+ }
+ fullscreenPaused = true;
+ _fullscreenMonitors = fullscreenMonitors;
+ _fullscreenUseMainMonitor = fullscreenUseMainMonitor;
+ setFullscreenImpl(false, true, null);
+ }
}
public void monitorModeChanged(MonitorEvent me, boolean success) {
if(DEBUG_IMPLEMENTATION) {
- System.err.println("Window.monitorModeChanged: "+me+", success: "+success);
+ System.err.println("Window.monitorModeChanged: hadFocus "+hadFocus+", "+me+", success: "+success+" @ "+Thread.currentThread().getName());
}
if(success) {
@@ -1985,7 +2086,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
// Didn't pass above notify method. probably detected screen change after it happened.
animatorPaused = lifecycleHook.pauseRenderingAction();
}
- if( !fullscreen ) {
+ if( !fullscreen && !fullscreenPaused ) {
// Simply move/resize window to fit in virtual screen if required
final RectangleImmutable viewport = screen.getViewport();
if( viewport.getWidth() > 0 && viewport.getHeight() > 0 ) { // failsafe
@@ -2001,13 +2102,35 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
setSize(viewport.getWidth(), viewport.getHeight());
}
}
+ } else if( fullscreenPaused ){
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Window.monitorModeChanged: FS Restore");
+ }
+ setFullscreenImpl(true, _fullscreenUseMainMonitor, _fullscreenMonitors);
+ fullscreenPaused = false;
+ _fullscreenMonitors = null;
+ _fullscreenUseMainMonitor = true;
+ } else {
+ // If changed monitor is part of this fullscreen mode, reset size! (Bug 771)
+ final MonitorDevice md = me.getMonitor();
+ if( fullscreenMonitors.contains(md) ) {
+ final RectangleImmutable viewport = MonitorDevice.unionOfViewports(new Rectangle(), fullscreenMonitors);
+ if(DEBUG_IMPLEMENTATION) {
+ final RectangleImmutable rect = new Rectangle(getX(), getY(), getWidth(), getHeight());
+ System.err.println("Window.monitorModeChanged: FS Monitor Match: Fit window "+rect+" into new viewport union "+viewport+", provoked by "+md);
+ }
+ definePosition(viewport.getX(), viewport.getY()); // set pos for setVisible(..) or createNative(..) - reduce EDT roundtrip
+ setFullscreenSize(viewport.getWidth(), viewport.getHeight());
+ }
}
}
-
if(animatorPaused) {
lifecycleHook.resumeRenderingAction();
}
sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); // trigger a resize/relayout and repaint to listener
+ if( hadFocus ) {
+ requestFocus(true);
+ }
}
}
private final MonitorModeListenerImpl monitorModeListenerImpl = new MonitorModeListenerImpl();
@@ -2476,7 +2599,6 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
return keyListeners.toArray(new KeyListener[keyListeners.size()]);
}
- @SuppressWarnings("deprecation")
private final boolean propagateKeyEvent(KeyEvent e, KeyListener l) {
switch(e.getEventType()) {
case KeyEvent.EVENT_KEY_PRESSED:
@@ -2485,58 +2607,29 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
case KeyEvent.EVENT_KEY_RELEASED:
l.keyReleased(e);
break;
- case KeyEvent.EVENT_KEY_TYPED:
- l.keyTyped(e);
- break;
default:
throw new NativeWindowException("Unexpected key event type " + e.getEventType());
}
return e.isConsumed();
}
- @SuppressWarnings("deprecation")
protected void consumeKeyEvent(KeyEvent e) {
- boolean consumedE = false, consumedTyped = false;
- if( KeyEvent.EVENT_KEY_TYPED == e.getEventType() ) {
- throw new InternalError("Deprecated KeyEvent.EVENT_KEY_TYPED is synthesized - don't send/enqueue it!");
- }
-
- // Synthesize deprecated event KeyEvent.EVENT_KEY_TYPED
- final KeyEvent eTyped;
- if( KeyEvent.EVENT_KEY_RELEASED == e.getEventType() && e.isPrintableKey() && !e.isAutoRepeat() ) {
- eTyped = KeyEvent.create(KeyEvent.EVENT_KEY_TYPED, e.getSource(), e.getWhen(), e.getModifiers(), e.getKeyCode(), e.getKeySymbol(), e.getKeyChar());
- } else {
- eTyped = null;
- }
- if(null != keyboardFocusHandler) {
+ boolean consumedE = false;
+ if( null != keyboardFocusHandler && !e.isAutoRepeat() ) {
consumedE = propagateKeyEvent(e, keyboardFocusHandler);
if(DEBUG_KEY_EVENT) {
- System.err.println("consumeKeyEvent: "+e+", keyboardFocusHandler consumed: "+consumedE);
- }
- if( null != eTyped ) {
- consumedTyped = propagateKeyEvent(eTyped, keyboardFocusHandler);
- if(DEBUG_KEY_EVENT) {
- System.err.println("consumeKeyEvent: "+eTyped+", keyboardFocusHandler consumed: "+consumedTyped);
- }
+ if( consumedE ) {
+ System.err.println("consumeKeyEvent(kfh): "+e+", consumed: "+consumedE);
+ }
}
}
- if(DEBUG_KEY_EVENT) {
- if( !consumedE ) {
- System.err.println("consumeKeyEvent: "+e);
+ if( !consumedE ) {
+ for(int i = 0; !consumedE && i < keyListeners.size(); i++ ) {
+ consumedE = propagateKeyEvent(e, keyListeners.get(i));
}
- }
- for(int i = 0; !consumedE && i < keyListeners.size(); i++ ) {
- consumedE = propagateKeyEvent(e, keyListeners.get(i));
- }
- if( null != eTyped ) {
if(DEBUG_KEY_EVENT) {
- if( !consumedTyped ) {
- System.err.println("consumeKeyEvent: "+eTyped);
- }
+ System.err.println("consumeKeyEvent(usr): "+e+", consumed: "+consumedE);
}
- for(int i = 0; !consumedTyped && i < keyListeners.size(); i++ ) {
- consumedTyped = propagateKeyEvent(eTyped, keyListeners.get(i));
- }
}
}
diff --git a/src/newt/classes/jogamp/newt/driver/android/DisplayDriver.java b/src/newt/classes/jogamp/newt/driver/android/DisplayDriver.java
index a367462c4..a2877dba2 100644
--- a/src/newt/classes/jogamp/newt/driver/android/DisplayDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/android/DisplayDriver.java
@@ -55,7 +55,7 @@ public class DisplayDriver extends jogamp.newt.DisplayImpl {
aDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(EGL.EGL_DEFAULT_DISPLAY, AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT);
}
- protected void closeNativeImpl() {
+ protected void closeNativeImpl(AbstractGraphicsDevice aDevice) {
aDevice.close();
}
diff --git a/src/newt/classes/jogamp/newt/driver/android/NewtVersionActivity.java b/src/newt/classes/jogamp/newt/driver/android/NewtVersionActivity.java
index de524d54c..9f6210269 100644
--- a/src/newt/classes/jogamp/newt/driver/android/NewtVersionActivity.java
+++ b/src/newt/classes/jogamp/newt/driver/android/NewtVersionActivity.java
@@ -78,7 +78,7 @@ public class NewtVersionActivity extends NewtBaseActivity {
glWindow.addGLEventListener(new GLEventListener() {
public void init(GLAutoDrawable drawable) {
GL gl = drawable.getGL();
- final StringBuffer sb = new StringBuffer();
+ final StringBuilder sb = new StringBuilder();
sb.append(JoglVersion.getGLInfo(gl, null, true)).append(Platform.NEWLINE);
sb.append("Requested: ").append(Platform.NEWLINE);
sb.append(drawable.getNativeSurface().getGraphicsConfiguration().getRequestedCapabilities()).append(Platform.NEWLINE).append(Platform.NEWLINE);
diff --git a/src/newt/classes/jogamp/newt/driver/awt/AWTEDTUtil.java b/src/newt/classes/jogamp/newt/driver/awt/AWTEDTUtil.java
index fc9bbb848..80c72c008 100644
--- a/src/newt/classes/jogamp/newt/driver/awt/AWTEDTUtil.java
+++ b/src/newt/classes/jogamp/newt/driver/awt/AWTEDTUtil.java
@@ -45,7 +45,7 @@ public class AWTEDTUtil implements EDTUtil {
private final ThreadGroup threadGroup;
private final String name;
private final Runnable dispatchMessages;
- private NewtEventDispatchThread nedt = null;
+ private NEDT nedt = null;
private int start_iter=0;
private static long pollPeriod = EDTUtil.defaultEDTPollPeriod;
@@ -53,7 +53,7 @@ public class AWTEDTUtil implements EDTUtil {
this.threadGroup = tg;
this.name=Thread.currentThread().getName()+"-"+name+"-EDT-";
this.dispatchMessages=dispatchMessages;
- this.nedt = new NewtEventDispatchThread(threadGroup, name);
+ this.nedt = new NEDT(threadGroup, name);
this.nedt.setDaemon(true); // don't stop JVM from shutdown ..
}
@@ -68,24 +68,29 @@ public class AWTEDTUtil implements EDTUtil {
}
@Override
- final public void reset() {
- synchronized(edtLock) {
- waitUntilStopped();
+ public final boolean restart() throws IllegalStateException {
+ synchronized(edtLock) {
+ if( nedt.isRunning() ) {
+ throw new IllegalStateException("EDT still running and not subject to stop. Curr "+Thread.currentThread().getName()+", NEDT "+nedt.getName()+", isRunning "+nedt.isRunning+", shouldStop "+nedt.shouldStop+", on AWT-EDT "+EventQueue.isDispatchThread());
+ }
if(DEBUG) {
System.err.println(Thread.currentThread()+": AWT-EDT reset - edt: "+nedt);
}
- this.nedt = new NewtEventDispatchThread(threadGroup, name);
- this.nedt.setDaemon(true); // don't stop JVM from shutdown ..
+ if( nedt.getState() != Thread.State.NEW ) {
+ nedt = new NEDT(threadGroup, name);
+ nedt.setDaemon(true); // don't stop JVM from shutdown ..
+ }
+ startImpl();
}
+ return invoke(true, nullTask);
}
private final void startImpl() {
if(nedt.isAlive()) {
- throw new RuntimeException("AWT-EDT Thread.isAlive(): true, isRunning: "+nedt.isRunning()+", edt: "+nedt);
+ throw new RuntimeException("AWT-EDT Thread.isAlive(): true, isRunning: "+nedt.isRunning+", shouldStop "+nedt.shouldStop+", edt: "+nedt);
}
start_iter++;
nedt.setName(name+start_iter);
- nedt.shouldStop = false;
if(DEBUG) {
System.err.println(Thread.currentThread()+": AWT-EDT START - edt: "+nedt);
// Thread.dumpStack();
@@ -110,59 +115,76 @@ public class AWTEDTUtil implements EDTUtil {
@Override
final public boolean isRunning() {
- return nedt.isRunning() ; // AWT is always running
+ return nedt.isRunning() ;
}
@Override
- public final void invokeStop(Runnable task) {
- invokeImpl(true, task, true);
+ public final boolean invokeStop(boolean wait, Runnable task) {
+ return invokeImpl(wait, task, true);
}
@Override
- public final void invoke(boolean wait, Runnable task) {
- invokeImpl(wait, task, false);
+ public final boolean invoke(boolean wait, Runnable task) {
+ return invokeImpl(wait, task, false);
}
- private void invokeImpl(boolean wait, Runnable task, boolean stop) {
+ private static Runnable nullTask = new Runnable() {
+ @Override
+ public void run() { }
+ };
+
+ private final boolean invokeImpl(boolean wait, Runnable task, boolean stop) {
Throwable throwable = null;
RunnableTask rTask = null;
- Object rTaskLock = new Object();
+ final Object rTaskLock = new Object();
synchronized(rTaskLock) { // lock the optional task execution
synchronized(edtLock) { // lock the EDT status
if( nedt.shouldStop ) {
// drop task ..
+ System.err.println(Thread.currentThread()+": Warning: AWT-EDT about (1) to stop, won't enqueue new task: "+nedt);
if(DEBUG) {
- System.err.println(Thread.currentThread()+": Warning: AWT-EDT about (1) to stop, won't enqueue new task: "+nedt);
Thread.dumpStack();
}
- return;
+ return false;
}
- // System.err.println(Thread.currentThread()+" XXX stop: "+stop+", tasks: "+edt.tasks.size()+", task: "+task);
- // Thread.dumpStack();
- if(stop) {
- synchronized(nedt.sync) {
+ if( isCurrentThreadEDT() ) {
+ if(null != task) {
+ task.run();
+ }
+ wait = false; // running in same thread (EDT) -> no wait
+ if(stop) {
nedt.shouldStop = true;
- nedt.sync.notifyAll(); // stop immediate if waiting (poll freq)
}
- if(DEBUG) {
- System.err.println(Thread.currentThread()+": AWT-EDT signal STOP (on edt: "+isCurrentThreadEDT()+") - "+nedt);
- // Thread.dumpStack();
+ } else {
+ if( !nedt.isRunning ) {
+ if( null != task ) {
+ if( stop ) {
+ System.err.println(Thread.currentThread()+": Warning: AWT-EDT is about (3) to stop and stopped already, dropping task. NEDT "+nedt);
+ } else {
+ System.err.println(Thread.currentThread()+": Warning: AWT-EDT is not running, dropping task. NEDT "+nedt);
+ }
+ if(DEBUG) {
+ Thread.dumpStack();
+ }
+ }
+ return false;
+ } else if( stop ) {
+ if(DEBUG) {
+ System.err.println(Thread.currentThread()+": AWT-EDT signal STOP (on edt: "+isCurrentThreadEDT()+") - "+nedt+", isRunning "+nedt.isRunning+", shouldStop "+nedt.shouldStop);
+ }
+ synchronized(nedt.sync) {
+ nedt.shouldStop = true;
+ nedt.sync.notifyAll(); // stop immediate if waiting (poll freq)
+ }
+ }
+
+ if(null != task) {
+ rTask = new RunnableTask(task,
+ wait ? rTaskLock : null,
+ true /* always catch and report Exceptions, don't disturb EDT */,
+ wait ? null : System.err);
+ AWTEDTExecutor.singleton.invoke(false, rTask);
}
- } else if( !nedt.isRunning() ) {
- // start if should not stop && not started yet
- startImpl();
- }
- if( null == task ) {
- wait = false;
- } else if( isCurrentThreadEDT() ) {
- task.run();
- wait = false; // running in same thread (EDT) -> no wait
- } else {
- rTask = new RunnableTask(task,
- wait ? rTaskLock : null,
- true /* always catch and report Exceptions, don't disturb EDT */,
- wait ? null : System.err);
- AWTEDTExecutor.singleton.invoke(false, rTask);
}
}
if( wait ) {
@@ -181,51 +203,56 @@ public class AWTEDTUtil implements EDTUtil {
throw new RuntimeException(throwable);
}
}
+ return true;
}
}
@Override
- final public void waitUntilIdle() {
- final NewtEventDispatchThread _edt;
+ final public boolean waitUntilIdle() {
+ final NEDT _edt;
synchronized(edtLock) {
_edt = nedt;
}
- if(!_edt.isRunning() || _edt == Thread.currentThread() || EventQueue.isDispatchThread()) {
- return;
+ if(!_edt.isRunning || _edt == Thread.currentThread() || EventQueue.isDispatchThread()) {
+ return false;
}
try {
AWTEDTExecutor.singleton.invoke(true, new Runnable() {
public void run() { }
});
} catch (Exception e) { }
+ return true;
}
@Override
- final public void waitUntilStopped() {
+ final public boolean waitUntilStopped() {
synchronized(edtLock) {
- if(nedt.isRunning() && nedt != Thread.currentThread() && !EventQueue.isDispatchThread()) {
- while(nedt.isRunning()) {
+ if( nedt.isRunning && nedt != Thread.currentThread() && !EventQueue.isDispatchThread() ) {
+ while( nedt.isRunning ) {
try {
edtLock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
+ return true;
+ } else {
+ return false;
}
}
}
- class NewtEventDispatchThread extends Thread {
+ class NEDT extends Thread {
volatile boolean shouldStop = false;
volatile boolean isRunning = false;
Object sync = new Object();
- public NewtEventDispatchThread(ThreadGroup tg, String name) {
+ public NEDT(ThreadGroup tg, String name) {
super(tg, name);
}
final public boolean isRunning() {
- return isRunning;
+ return isRunning && !shouldStop;
}
@Override
@@ -278,10 +305,8 @@ public class AWTEDTUtil implements EDTUtil {
System.err.println(getName()+": AWT-EDT run() END "+ getName()+", "+error);
}
synchronized(edtLock) {
- isRunning = !shouldStop;
- if(!isRunning) {
- edtLock.notifyAll();
- }
+ isRunning = false;
+ edtLock.notifyAll();
}
if(DEBUG) {
System.err.println(getName()+": AWT-EDT run() EXIT "+ getName()+", exception: "+error);
diff --git a/src/newt/classes/jogamp/newt/driver/awt/DisplayDriver.java b/src/newt/classes/jogamp/newt/driver/awt/DisplayDriver.java
index 4139951aa..30449f9bc 100644
--- a/src/newt/classes/jogamp/newt/driver/awt/DisplayDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/awt/DisplayDriver.java
@@ -34,6 +34,8 @@
package jogamp.newt.driver.awt;
+import javax.media.nativewindow.AbstractGraphicsDevice;
+
import com.jogamp.nativewindow.awt.AWTGraphicsDevice;
import com.jogamp.newt.NewtFactory;
import com.jogamp.newt.util.EDTUtil;
@@ -65,7 +67,7 @@ public class DisplayDriver extends DisplayImpl {
return def;
}
- protected void closeNativeImpl() {
+ protected void closeNativeImpl(AbstractGraphicsDevice aDevice) {
aDevice.close();
}
diff --git a/src/newt/classes/jogamp/newt/driver/bcm/egl/DisplayDriver.java b/src/newt/classes/jogamp/newt/driver/bcm/egl/DisplayDriver.java
index cc55c336e..112be2b04 100644
--- a/src/newt/classes/jogamp/newt/driver/bcm/egl/DisplayDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/bcm/egl/DisplayDriver.java
@@ -69,7 +69,7 @@ public class DisplayDriver extends jogamp.newt.DisplayImpl {
aDevice = new EGLGraphicsDevice(EGL.EGL_DEFAULT_DISPLAY, handle, AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT, null);
}
- protected void closeNativeImpl() {
+ protected void closeNativeImpl(AbstractGraphicsDevice aDevice) {
if (aDevice.getHandle() != EGL.EGL_NO_DISPLAY) {
DestroyDisplay(aDevice.getHandle());
}
diff --git a/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/DisplayDriver.java b/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/DisplayDriver.java
index 08c5c573c..4872a9071 100644
--- a/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/DisplayDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/DisplayDriver.java
@@ -64,7 +64,7 @@ public class DisplayDriver extends DisplayImpl {
aDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(EGL.EGL_DEFAULT_DISPLAY, AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT);
}
- protected void closeNativeImpl() {
+ protected void closeNativeImpl(AbstractGraphicsDevice aDevice) {
aDevice.close();
}
diff --git a/src/newt/classes/jogamp/newt/driver/intel/gdl/DisplayDriver.java b/src/newt/classes/jogamp/newt/driver/intel/gdl/DisplayDriver.java
index e370038d9..ee93eb932 100644
--- a/src/newt/classes/jogamp/newt/driver/intel/gdl/DisplayDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/intel/gdl/DisplayDriver.java
@@ -72,7 +72,7 @@ public class DisplayDriver extends jogamp.newt.DisplayImpl {
aDevice = new DefaultGraphicsDevice(NativeWindowFactory.TYPE_DEFAULT, AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT, displayHandle);
}
- protected void closeNativeImpl() {
+ protected void closeNativeImpl(AbstractGraphicsDevice aDevice) {
if(0==displayHandle) {
throw new NativeWindowException("displayHandle null; initCnt "+initCounter);
}
diff --git a/src/newt/classes/jogamp/newt/driver/kd/DisplayDriver.java b/src/newt/classes/jogamp/newt/driver/kd/DisplayDriver.java
index 745be5dae..3cd72e971 100644
--- a/src/newt/classes/jogamp/newt/driver/kd/DisplayDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/kd/DisplayDriver.java
@@ -64,7 +64,7 @@ public class DisplayDriver extends DisplayImpl {
aDevice = EGLDisplayUtil.eglCreateEGLGraphicsDevice(EGL.EGL_DEFAULT_DISPLAY, AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT);
}
- protected void closeNativeImpl() {
+ protected void closeNativeImpl(AbstractGraphicsDevice aDevice) {
aDevice.close();
}
diff --git a/src/newt/classes/jogamp/newt/driver/macosx/DisplayDriver.java b/src/newt/classes/jogamp/newt/driver/macosx/DisplayDriver.java
index b49c6b6e0..a99bc4f23 100644
--- a/src/newt/classes/jogamp/newt/driver/macosx/DisplayDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/macosx/DisplayDriver.java
@@ -72,7 +72,7 @@ public class DisplayDriver extends DisplayImpl {
aDevice = new MacOSXGraphicsDevice(AbstractGraphicsDevice.DEFAULT_UNIT);
}
- protected void closeNativeImpl() {
+ protected void closeNativeImpl(AbstractGraphicsDevice aDevice) {
aDevice.close();
}
diff --git a/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java
index 6370782df..6aebf0410 100644
--- a/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java
@@ -423,8 +423,8 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl
", was: pressed "+isKeyPressed(keyCode)+", isModifierKeyCode "+isModifierKeyCode);
} */
- // 1:1 Order: OSX and NEWT delivery order is PRESSED, RELEASED and TYPED
- // Auto-Repeat: OSX delivers only PRESSED, inject auto-repeat RELEASE and TYPED keys _before_ PRESSED
+ // OSX delivery order is PRESSED (t0), RELEASED (t1) and TYPED (t2) -> NEWT order: PRESSED (t0) and RELEASED (t1)
+ // Auto-Repeat: OSX delivers only PRESSED, inject auto-repeat RELEASE key _before_ PRESSED
switch(eventType) {
case KeyEvent.EVENT_KEY_RELEASED:
if( isKeyCodeTracked(keyCode) ) {
diff --git a/src/newt/classes/jogamp/newt/driver/windows/DisplayDriver.java b/src/newt/classes/jogamp/newt/driver/windows/DisplayDriver.java
index 1b9ec0f25..595d5e952 100644
--- a/src/newt/classes/jogamp/newt/driver/windows/DisplayDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/windows/DisplayDriver.java
@@ -76,7 +76,7 @@ public class DisplayDriver extends DisplayImpl {
aDevice = new WindowsGraphicsDevice(AbstractGraphicsDevice.DEFAULT_UNIT);
}
- protected void closeNativeImpl() {
+ protected void closeNativeImpl(AbstractGraphicsDevice aDevice) {
sharedClassFactory.releaseSharedClass();
aDevice.close();
}
diff --git a/src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java
index ad7e1e8f3..393445db0 100644
--- a/src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java
@@ -79,6 +79,11 @@ public class WindowDriver extends WindowImpl {
}
hmon = MonitorFromWindow0(hWnd);
+ // Let's not trigger on HDC change, GLDrawableImpl.'s destroy/create is a nop here anyways.
+ // FIXME: Validate against EGL surface creation: ANGLE uses HWND -> fine!
+ return LOCK_SUCCESS;
+
+ /**
if( hdc_old == hdc ) {
return LOCK_SUCCESS;
}
@@ -86,7 +91,7 @@ public class WindowDriver extends WindowImpl {
System.err.println("WindowsWindow: surface change "+toHexString(hdc_old)+" -> "+toHexString(hdc));
// Thread.dumpStack();
}
- return LOCK_SURFACE_CHANGED;
+ return LOCK_SURFACE_CHANGED; */
}
@Override
@@ -286,9 +291,9 @@ public class WindowDriver extends WindowImpl {
public final void sendKeyEvent(short eventType, int modifiers, short keyCode, short keySym, char keyChar) {
final boolean isModifierKey = KeyEvent.isModifierKey(keySym);
// System.err.println("*** sendKeyEvent: event "+KeyEvent.getEventTypeString(eventType)+", keyCode "+toHexString(keyCode)+", keyChar <"+keyChar+">, mods "+toHexString(modifiers)+
- // ", isKeyCodeTracked "+isKeyCodeTracked(keyCode)+", was: pressed "+isKeyPressed(keyCode)+", repeat "+isKeyInAutoRepeat(keyCode)+", printableKey "+KeyEvent.isPrintableKey(keyCode)+" [modifierKey "+isModifierKey+"] - "+System.currentTimeMillis());
+ // ", isKeyCodeTracked "+isKeyCodeTracked(keyCode)+", was: pressed "+isKeyPressed(keyCode)+", printableKey "+KeyEvent.isPrintableKey(keyCode, false)+" [modifierKey "+isModifierKey+"] - "+System.currentTimeMillis());
- // Reorder: WINDOWS delivery order is PRESSED (t0), TYPED (t0) and RELEASED (t1) -> NEWT order: PRESSED (t0), RELEASED (t1) and TYPED (t1)
+ // Reorder: WINDOWS delivery order is PRESSED (t0), TYPED (t0) and RELEASED (t1) -> NEWT order: PRESSED (t0) and RELEASED (t1)
// Auto-Repeat: WINDOWS delivers only PRESSED (t0) and TYPED (t0).
switch(eventType) {
case KeyEvent.EVENT_KEY_RELEASED:
@@ -307,8 +312,6 @@ public class WindowDriver extends WindowImpl {
super.sendKeyEvent(KeyEvent.EVENT_KEY_PRESSED, modifiers, keyCode, keySym, keyChar);
}
break;
- // case KeyEvent.EVENT_KEY_TYPED:
- // break;
}
}
diff --git a/src/newt/classes/jogamp/newt/driver/x11/DisplayDriver.java b/src/newt/classes/jogamp/newt/driver/x11/DisplayDriver.java
index 4fe025ec4..d911483b0 100644
--- a/src/newt/classes/jogamp/newt/driver/x11/DisplayDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/x11/DisplayDriver.java
@@ -57,10 +57,8 @@ public class DisplayDriver extends DisplayImpl {
}
}
- public static void initSingleton() {
- // just exist to ensure static init has been run
- }
-
+ /** Ensure static init has been run. */
+ /* pp */static void initSingleton() { }
public DisplayDriver() {
}
@@ -84,13 +82,13 @@ public class DisplayDriver extends DisplayImpl {
try {
CompleteDisplay0(aDevice.getHandle());
} catch(RuntimeException e) {
- closeNativeImpl();
+ closeNativeImpl(aDevice);
throw e;
}
}
@Override
- protected void closeNativeImpl() {
+ protected void closeNativeImpl(AbstractGraphicsDevice aDevice) {
DisplayRelease0(aDevice.getHandle(), javaObjectAtom, windowDeleteAtom /*, kbdHandle */); // XKB disabled for now
javaObjectAtom = 0;
windowDeleteAtom = 0;
diff --git a/src/newt/classes/jogamp/newt/driver/x11/RandR.java b/src/newt/classes/jogamp/newt/driver/x11/RandR.java
index c569e5fd8..e39a6c63a 100644
--- a/src/newt/classes/jogamp/newt/driver/x11/RandR.java
+++ b/src/newt/classes/jogamp/newt/driver/x11/RandR.java
@@ -29,13 +29,21 @@ package jogamp.newt.driver.x11;
import java.util.List;
+import javax.media.nativewindow.util.RectangleImmutable;
+
import jogamp.newt.MonitorModeProps;
+import com.jogamp.common.util.VersionNumber;
import com.jogamp.newt.MonitorDevice;
import com.jogamp.newt.MonitorMode;
public interface RandR {
+ public static final VersionNumber version110 = new VersionNumber(1, 1, 0);
+ public static final VersionNumber version130 = new VersionNumber(1, 3, 0);
+ public static final VersionNumber version140 = new VersionNumber(1, 4, 0);
+ VersionNumber getVersion();
+
void dumpInfo(final long dpy, final int screen_idx);
/**
@@ -72,5 +80,7 @@ public interface RandR {
int[] getMonitorDeviceProps(final long dpy, final ScreenDriver screen, MonitorModeProps.Cache cache, final int crt_idx);
int[] getMonitorDeviceViewport(final long dpy, final ScreenDriver screen, final int crt_idx);
int[] getCurrentMonitorModeProps(final long dpy, final ScreenDriver screen, final int crt_idx);
- boolean setCurrentMonitorMode(final long dpy, final ScreenDriver screen, MonitorDevice monitor, final MonitorMode mode);
+ boolean setCurrentMonitorMode(final long dpy, final ScreenDriver screen, MonitorDevice monitor, final MonitorMode mode);
+
+ public void updateScreenViewport(final long dpy, final ScreenDriver screen, RectangleImmutable viewport);
}
diff --git a/src/newt/classes/jogamp/newt/driver/x11/RandR11.java b/src/newt/classes/jogamp/newt/driver/x11/RandR11.java
index a938b4064..877607f72 100644
--- a/src/newt/classes/jogamp/newt/driver/x11/RandR11.java
+++ b/src/newt/classes/jogamp/newt/driver/x11/RandR11.java
@@ -27,6 +27,8 @@
*/
package jogamp.newt.driver.x11;
+import javax.media.nativewindow.util.RectangleImmutable;
+
import jogamp.newt.MonitorModeProps;
import jogamp.newt.ScreenImpl;
@@ -34,20 +36,17 @@ import com.jogamp.common.util.VersionNumber;
import com.jogamp.newt.MonitorDevice;
import com.jogamp.newt.MonitorMode;
-public class RandR11 implements RandR {
+class RandR11 implements RandR {
private static final boolean DEBUG = ScreenDriver.DEBUG;
- public static VersionNumber version = new VersionNumber(1, 1, 0);
-
- public static RandR11 createInstance(VersionNumber rAndRVersion) {
- if( rAndRVersion.compareTo(version) >= 0 ) {
- return new RandR11();
- }
- return null;
- }
- private RandR11() {
+ RandR11() {
}
-
+
+ @Override
+ public final VersionNumber getVersion() {
+ return version110;
+ }
+
@Override
public void dumpInfo(final long dpy, final int screen_idx) {
// NOP
@@ -336,6 +335,11 @@ public class RandR11 implements RandR {
}
return done;
}
+
+ @Override
+ public final void updateScreenViewport(final long dpy, final ScreenDriver screen, RectangleImmutable viewport) {
+ // nop
+ }
/** @return int[] { rot1, .. } */
private static native int[] getAvailableScreenRotations0(long display, int screen_index);
diff --git a/src/newt/classes/jogamp/newt/driver/x11/RandR13.java b/src/newt/classes/jogamp/newt/driver/x11/RandR13.java
index d10591381..ac83fc5f2 100644
--- a/src/newt/classes/jogamp/newt/driver/x11/RandR13.java
+++ b/src/newt/classes/jogamp/newt/driver/x11/RandR13.java
@@ -29,6 +29,8 @@ package jogamp.newt.driver.x11;
import java.util.Iterator;
+import javax.media.nativewindow.util.RectangleImmutable;
+
import jogamp.newt.MonitorModeProps;
import com.jogamp.common.util.IntLongHashMap;
@@ -43,18 +45,15 @@ import com.jogamp.newt.MonitorMode;
* MonitorDevice.id == XRR monitor-idx (not id)
* </pre>
*/
-public class RandR13 implements RandR {
+class RandR13 implements RandR {
private static final boolean DEBUG = ScreenDriver.DEBUG;
- public static VersionNumber version = new VersionNumber(1, 3, 0);
-
- public static RandR13 createInstance(VersionNumber rAndRVersion) {
- if( rAndRVersion.compareTo(version) >= 0 ) {
- return new RandR13();
- }
- return null;
- }
- private RandR13() {
+ RandR13() {
+ }
+
+ @Override
+ public final VersionNumber getVersion() {
+ return version130;
}
@Override
@@ -238,54 +237,20 @@ public class RandR13 implements RandR {
} finally {
releaseScreenResourceHandle(screenResources);
}
- /***
- * TODO: Would need a complete re-layout of crt positions,
- * which is _not_ implicit by XRandR .. sadly.
- *
- if( res ) {
- updateScreenViewport(dpy, screen, monitor);
- } */
return res;
}
- /** See above ..
- private final void updateScreenViewport(final long dpy, final ScreenDriver screen, MonitorDevice monitor) {
+ @Override
+ public final void updateScreenViewport(final long dpy, final ScreenDriver screen, final RectangleImmutable viewport) {
final int screen_idx = screen.getIndex();
final long screenResources = getScreenResourceHandle(dpy, screen_idx);
try {
- RectangleImmutable newViewp = null;
- final long monitorInfo = getMonitorInfoHandle(dpy, screen_idx, screenResources, monitor.getId());
- try {
- final int[] vprops = getMonitorViewport0(monitorInfo);
- if( null != vprops ) {
- newViewp = new Rectangle(vprops[0], vprops[1], vprops[2], vprops[3]);
- }
- System.err.println("XXX setScreenViewport: newVp "+newViewp);
- } finally {
- releaseMonitorInfoHandle(monitorInfo);
- }
- if( null != newViewp ) {
- final List<MonitorDevice> monitors = screen.getMonitorDevices();
- final ArrayList<RectangleImmutable> viewports = new ArrayList<RectangleImmutable>();
- for(int i=0; i<monitors.size(); i++) {
- final MonitorDevice crt = monitors.get(i);
- if( crt.getId() != monitor.getId() ) {
- System.err.println("XXX setScreenViewport: add.pre["+i+"]: "+crt.getViewport());
- viewports.add( crt.getViewport() ) ;
- } else {
- System.err.println("XXX setScreenViewport: add.new["+i+"]: "+newViewp);
- viewports.add( newViewp );
- }
- }
- final RectangleImmutable newScrnViewp = new Rectangle().union(viewports);
- System.err.println("XXX setScreenViewport: "+screen.getViewport()+" -> "+newScrnViewp);
- setScreenViewport0(dpy, screen_idx, screenResources, newScrnViewp.getX(), newScrnViewp.getY(), newScrnViewp.getWidth(), newScrnViewp.getHeight());
- }
+ setScreenViewport0(dpy, screen_idx, screenResources, viewport.getX(), viewport.getY(), viewport.getWidth(), viewport.getHeight());
} finally {
dumpInfo0(dpy, screen_idx, screenResources);
releaseScreenResourceHandle(screenResources);
- }
- } */
+ }
+ }
private static native long getScreenResources0(long display, int screen_index);
private static native void freeScreenResources0(long screenResources);
diff --git a/src/newt/classes/jogamp/newt/driver/x11/ScreenDriver.java b/src/newt/classes/jogamp/newt/driver/x11/ScreenDriver.java
index b8b13939b..f37556dd7 100644
--- a/src/newt/classes/jogamp/newt/driver/x11/ScreenDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/x11/ScreenDriver.java
@@ -38,6 +38,7 @@ import java.util.List;
import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.util.Rectangle;
+import javax.media.nativewindow.util.RectangleImmutable;
import jogamp.nativewindow.x11.X11Util;
import jogamp.newt.Debug;
@@ -54,12 +55,18 @@ import com.jogamp.newt.MonitorDevice;
import com.jogamp.newt.MonitorMode;
public class ScreenDriver extends ScreenImpl {
- protected static final boolean DEBUG_TEST_RANDR13_DISABLED = Debug.isPropertyDefined("newt.test.Screen.disableRandR13", true);
+ protected static final boolean DEBUG_TEST_RANDR13_DISABLED;
static {
+ Debug.initSingleton();
+ DEBUG_TEST_RANDR13_DISABLED = Debug.isPropertyDefined("newt.test.Screen.disableRandR13", true);
+
DisplayDriver.initSingleton();
}
+ /** Ensure static init has been run. */
+ /* pp */static void initSingleton() { }
+
public ScreenDriver() {
}
@@ -81,11 +88,12 @@ public class ScreenDriver extends ScreenImpl {
randrVersion = new VersionNumber(v[0], v[1], 0);
}
{
- final RandR13 rAndR13 = DEBUG_TEST_RANDR13_DISABLED ? null : RandR13.createInstance(randrVersion);
- if( null != rAndR13 ) {
- rAndR = rAndR13;
+ if( !DEBUG_TEST_RANDR13_DISABLED && randrVersion.compareTo(RandR.version130) >= 0 ) {
+ rAndR = new RandR13();
+ } else if( randrVersion.compareTo(RandR.version110) >= 0 ) {
+ rAndR = new RandR11();
} else {
- rAndR = RandR11.createInstance(randrVersion);
+ rAndR = null;
}
}
if( DEBUG ) {
@@ -183,7 +191,7 @@ public class ScreenDriver extends ScreenImpl {
if( null == rAndR ) { return false; }
final long t0 = System.currentTimeMillis();
- boolean done = runWithTempDisplayHandle( new DisplayImpl.DisplayRunnable<Boolean>() {
+ boolean done = runWithOptTempDisplayHandle( new DisplayImpl.DisplayRunnable<Boolean>() {
public Boolean run(long dpy) {
return Boolean.valueOf( rAndR.setCurrentMonitorMode(dpy, ScreenDriver.this, monitor, mode) );
}
@@ -214,14 +222,31 @@ public class ScreenDriver extends ScreenImpl {
@Override
protected void calcVirtualScreenOriginAndSize(final Rectangle vOriginSize) {
- runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable<Object>() {
- public Object run(long dpy) {
- vOriginSize.setX(0);
- vOriginSize.setY(0);
- vOriginSize.setWidth(getWidth0(dpy, screen_idx));
- vOriginSize.setHeight(getHeight0(dpy, screen_idx));
- return null;
- } } );
+ final RectangleImmutable ov = (RectangleImmutable) getViewport().cloneMutable();
+ /**
+ if( null != rAndR && rAndR.getVersion().compareTo(RandR.version130) >= 0 && getMonitorDevices().size()>0 ) {
+ super.calcVirtualScreenOriginAndSize(vOriginSize);
+ if( DEBUG ) {
+ System.err.println("X11Screen.calcVirtualScreenOriginAndSize: UpdatingViewport "+ov+" -> "+vOriginSize);
+ }
+ runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable<Object>() {
+ public Object run(long dpy) {
+ rAndR.updateScreenViewport(dpy, ScreenDriver.this, vOriginSize);
+ return null;
+ } } );
+ } else */ {
+ runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable<Object>() {
+ public Object run(long dpy) {
+ vOriginSize.setX(0);
+ vOriginSize.setY(0);
+ vOriginSize.setWidth(getWidth0(dpy, screen_idx));
+ vOriginSize.setHeight(getHeight0(dpy, screen_idx));
+ return null;
+ } } );
+ if( DEBUG ) {
+ System.err.println("X11Screen.calcVirtualScreenOriginAndSize: Querying X11: "+ov+" -> "+vOriginSize);
+ }
+ }
}
//----------------------------------------------------------------------
@@ -245,6 +270,14 @@ public class ScreenDriver extends ScreenImpl {
return res;
}
+ private final <T> T runWithOptTempDisplayHandle(DisplayRunnable<T> action) {
+ if( null != rAndR && rAndR.getVersion().compareTo(RandR.version130) >= 0 ) {
+ return display.runWithLockedDisplayDevice(action);
+ } else {
+ return runWithTempDisplayHandle(action);
+ }
+ }
+
private static native long GetScreen0(long dpy, int scrn_idx);
private static native int getWidth0(long display, int scrn_idx);
diff --git a/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java
index 69a09c1f9..4786ea04f 100644
--- a/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java
@@ -59,12 +59,13 @@ public class WindowDriver extends WindowImpl {
private static final int X11_WHEEL_TWO_DOWN_BUTTON = 7;
static {
- DisplayDriver.initSingleton();
+ ScreenDriver.initSingleton();
}
public WindowDriver() {
}
+ @Override
protected void createNativeImpl() {
final ScreenDriver screen = (ScreenDriver) getScreen();
final DisplayDriver display = (DisplayDriver) screen.getDisplay();
@@ -109,6 +110,7 @@ public class WindowDriver extends WindowImpl {
}
}
+ @Override
protected void closeNativeImpl() {
if(0!=windowHandleClose && null!=getScreen() ) {
DisplayDriver display = (DisplayDriver) getScreen().getDisplay();
@@ -133,7 +135,19 @@ public class WindowDriver extends WindowImpl {
}
}
- protected boolean reconfigureWindowImpl(final int x, final int y, final int width, final int height, final int flags) {
+ /**
+ * <p>
+ * X11 Window supports {@link #FLAG_IS_FULLSCREEN_SPAN}
+ * </p>
+ * {@inheritDoc}
+ */
+ @Override
+ protected boolean isReconfigureFlagSupported(int changeFlags) {
+ return true; // all flags!
+ }
+
+ @Override
+ protected boolean reconfigureWindowImpl(final int x, final int y, final int width, final int height, int flags) {
if(DEBUG_IMPLEMENTATION) {
System.err.println("X11Window reconfig: "+x+"/"+y+" "+width+"x"+height+", "+ getReconfigureFlagsAsString(null, flags));
}
@@ -148,18 +162,57 @@ public class WindowDriver extends WindowImpl {
_x = x;
_y = y;
}
+ if( 0 != ( FLAG_CHANGE_FULLSCREEN & flags ) ) {
+ if( 0 != ( FLAG_IS_FULLSCREEN & flags) && 0 != ( FLAG_IS_FULLSCREEN_SPAN & flags) && 0 == ( FLAG_IS_ALWAYSONTOP & flags) ) {
+ tempFSAlwaysOnTop = true;
+ flags |= FLAG_IS_ALWAYSONTOP;
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("X11Window reconfig.2: temporary "+getReconfigureFlagsAsString(null, flags));
+ }
+ } else {
+ tempFSAlwaysOnTop = false;
+ }
+ }
+ final int fflags = flags;
final DisplayDriver display = (DisplayDriver) getScreen().getDisplay();
runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable<Object>() {
public Object run(long dpy) {
reconfigureWindow0( dpy, getScreenIndex(),
getParentWindowHandle(), getWindowHandle(), display.getWindowDeleteAtom(),
- _x, _y, width, height, flags);
+ _x, _y, width, height, fflags);
return null;
}
});
return true;
}
+ volatile boolean tempFSAlwaysOnTop = false;
+ /**
+ * <p>
+ * Deal w/ tempAlwaysOnTop.
+ * </p>
+ * {@inheritDoc}
+ */
+ @Override
+ protected void focusChanged(boolean defer, boolean focusGained) {
+ if( tempFSAlwaysOnTop && hasFocus() != focusGained && isNativeValid() ) {
+ final int flags = getReconfigureFlags(FLAG_CHANGE_ALWAYSONTOP, isVisible()) | ( focusGained ? FLAG_IS_ALWAYSONTOP : 0 );
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("X11Window reconfig.3 (focus): temporary "+getReconfigureFlagsAsString(null, flags));
+ }
+ final DisplayDriver display = (DisplayDriver) getScreen().getDisplay();
+ runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable<Object>() {
+ public Object run(long dpy) {
+ reconfigureWindow0( dpy, getScreenIndex(),
+ getParentWindowHandle(), getWindowHandle(), display.getWindowDeleteAtom(),
+ getX(), getY(), getWidth(), getHeight(), flags);
+ return null;
+ }
+ });
+ }
+ super.focusChanged(defer, focusGained);
+ }
+
protected void reparentNotify(long newParentWindowHandle) {
if(DEBUG_IMPLEMENTATION) {
final long p0 = getParentWindowHandle();
@@ -167,6 +220,7 @@ public class WindowDriver extends WindowImpl {
}
}
+ @Override
protected void requestFocusImpl(final boolean force) {
runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable<Object>() {
public Object run(long dpy) {
@@ -214,6 +268,7 @@ public class WindowDriver extends WindowImpl {
});
}
+ @Override
protected Point getLocationOnScreenImpl(final int x, final int y) {
return runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable<Point>() {
public Point run(long dpy) {
@@ -222,6 +277,7 @@ public class WindowDriver extends WindowImpl {
} );
}
+ @Override
protected void updateInsetsImpl(Insets insets) {
// nop - using event driven insetsChange(..)
}
@@ -241,16 +297,17 @@ public class WindowDriver extends WindowImpl {
}
break;
case MouseEvent.EVENT_MOUSE_RELEASED:
+ final boolean shiftPressed = 0 != ( modifiers & InputEvent.SHIFT_MASK );
switch(button) {
case X11_WHEEL_ONE_UP_BUTTON: // vertical scroll up
eventType = MouseEvent.EVENT_MOUSE_WHEEL_MOVED;
button = 1;
- rotationXYZ[1] = 1;
+ rotationXYZ[shiftPressed ? 0 : 1] = 1;
break;
case X11_WHEEL_ONE_DOWN_BUTTON: // vertical scroll down
eventType = MouseEvent.EVENT_MOUSE_WHEEL_MOVED;
button = 1;
- rotationXYZ[1] = -1;
+ rotationXYZ[shiftPressed ? 0 : 1] = -1;
break;
case X11_WHEEL_TWO_UP_BUTTON: // horizontal scroll left
eventType = MouseEvent.EVENT_MOUSE_WHEEL_MOVED;
@@ -269,7 +326,8 @@ public class WindowDriver extends WindowImpl {
}
super.doMouseEvent(enqueue, wait, eventType, modifiers, x, y, button, rotationXYZ, rotationScale);
}
-
+
+ /** Called by native TK */
protected final void sendKeyEvent(short eventType, int modifiers, short keyCode, short keySym, char keyChar0, String keyString) {
// handleKeyEvent(true, false, eventType, modifiers, keyCode, keyChar);
final boolean isModifierKey = KeyEvent.isModifierKey(keyCode);
@@ -287,9 +345,6 @@ public class WindowDriver extends WindowImpl {
case KeyEvent.EVENT_KEY_RELEASED:
super.sendKeyEvent(KeyEvent.EVENT_KEY_RELEASED, modifiers, keyCode, keySym, keyChar);
break;
-
- // case KeyEvent.EVENT_KEY_TYPED:
- // break;
}
}
}
diff --git a/src/newt/classes/jogamp/newt/swt/SWTEDTUtil.java b/src/newt/classes/jogamp/newt/swt/SWTEDTUtil.java
index 2008b5ea4..d46562050 100644
--- a/src/newt/classes/jogamp/newt/swt/SWTEDTUtil.java
+++ b/src/newt/classes/jogamp/newt/swt/SWTEDTUtil.java
@@ -46,7 +46,7 @@ public class SWTEDTUtil implements EDTUtil {
private final String name;
private final Runnable dispatchMessages;
private final org.eclipse.swt.widgets.Display swtDisplay;
- private NewtEventDispatchThread nedt = null;
+ private NEDT nedt = null;
private int start_iter=0;
private static long pollPeriod = EDTUtil.defaultEDTPollPeriod;
@@ -58,7 +58,7 @@ public class SWTEDTUtil implements EDTUtil {
((jogamp.newt.DisplayImpl) newtDisplay).dispatchMessages();
} };
this.swtDisplay = swtDisplay;
- this.nedt = new NewtEventDispatchThread(threadGroup, name);
+ this.nedt = new NEDT(threadGroup, name);
this.nedt.setDaemon(true); // don't stop JVM from shutdown ..
}
@@ -77,24 +77,39 @@ public class SWTEDTUtil implements EDTUtil {
}
@Override
- public void reset() {
- synchronized(edtLock) {
- waitUntilStopped();
+ public final boolean restart() throws IllegalStateException {
+ final boolean swtDisposed = swtDisplay.isDisposed();
+ synchronized(edtLock) {
+ if( nedt.isRunning() ) {
+ final Thread curT = Thread.currentThread();
+ final Thread swtT = !swtDisposed ? swtDisplay.getThread() : null;
+ final boolean onSWTEDT = swtT == curT;
+ throw new IllegalStateException("EDT still running and not subject to stop. Curr "+curT.getName()+", NEDT "+nedt.getName()+", isRunning "+nedt.isRunning+", shouldStop "+nedt.shouldStop+", SWT-EDT "+swtT.getName()+", on SWT-EDT "+onSWTEDT);
+ }
if(DEBUG) {
- System.err.println(Thread.currentThread()+": SWT-EDT reset - edt: "+nedt);
+ System.err.println(Thread.currentThread()+": SWT-EDT reset - edt: "+nedt+", swtDisposed (skipping) "+swtDisposed);
+ }
+ if( !swtDisposed ) {
+ if( nedt.getState() != Thread.State.NEW ) {
+ nedt = new NEDT(threadGroup, name);
+ nedt.setDaemon(true); // don't stop JVM from shutdown ..
+ }
+ startImpl();
}
- this.nedt = new NewtEventDispatchThread(threadGroup, name);
- this.nedt.setDaemon(true); // don't stop JVM from shutdown ..
+ }
+ if( !swtDisposed ) {
+ return invoke(true, nullTask);
+ } else {
+ return false;
}
}
private final void startImpl() {
if(nedt.isAlive()) {
- throw new RuntimeException("SWT-EDT Thread.isAlive(): true, isRunning: "+nedt.isRunning()+", edt: "+nedt);
+ throw new RuntimeException("SWT-EDT Thread.isAlive(): true, isRunning: "+nedt.isRunning+", shouldStop "+nedt.shouldStop+", edt: "+nedt);
}
start_iter++;
nedt.setName(name+start_iter);
- nedt.shouldStop = false;
if(DEBUG) {
System.err.println(Thread.currentThread()+": SWT-EDT START - edt: "+nedt);
// Thread.dumpStack();
@@ -104,7 +119,7 @@ public class SWTEDTUtil implements EDTUtil {
@Override
public boolean isCurrentThreadEDT() {
- return swtDisplay.getThread() == Thread.currentThread();
+ return !swtDisplay.isDisposed() && swtDisplay.getThread() == Thread.currentThread();
}
@Override
@@ -115,66 +130,94 @@ public class SWTEDTUtil implements EDTUtil {
@Override
public final boolean isCurrentThreadEDTorNEDT() {
final Thread ct = Thread.currentThread();
- return ct == swtDisplay.getThread() || ct == nedt ;
+ return ( !swtDisplay.isDisposed() && ct == swtDisplay.getThread() ) || ct == nedt ;
}
@Override
public boolean isRunning() {
- return nedt.isRunning() ; // SWT is always running
+ return nedt.isRunning();
}
@Override
- public final void invokeStop(Runnable task) {
- invokeImpl(true, task, true);
+ public final boolean invokeStop(boolean wait, Runnable task) {
+ return invokeImpl(wait, task, true);
}
@Override
- public final void invoke(boolean wait, Runnable task) {
- invokeImpl(wait, task, false);
+ public final boolean invoke(boolean wait, Runnable task) {
+ return invokeImpl(wait, task, false);
}
- private void invokeImpl(boolean wait, Runnable task, boolean stop) {
+ private static Runnable nullTask = new Runnable() {
+ @Override
+ public void run() { }
+ };
+
+ private final boolean invokeImpl(boolean wait, Runnable task, boolean stop) {
Throwable throwable = null;
RunnableTask rTask = null;
- Object rTaskLock = new Object();
+ final Object rTaskLock = new Object();
synchronized(rTaskLock) { // lock the optional task execution
synchronized(edtLock) { // lock the EDT status
if( nedt.shouldStop ) {
// drop task ..
if(DEBUG) {
- System.err.println(Thread.currentThread()+": Warning: SWT-EDT about (1) to stop, won't enqueue new task: "+nedt);
+ System.err.println(Thread.currentThread()+": Warning: SWT-EDT about (1) to stop, won't enqueue new task: "+nedt+", isRunning "+nedt.isRunning+", shouldStop "+nedt.shouldStop);
Thread.dumpStack();
}
- return;
+ return false;
+ }
+ if( swtDisplay.isDisposed() ) {
+ stop = true;
}
- // System.err.println(Thread.currentThread()+" XXX stop: "+stop+", tasks: "+edt.tasks.size()+", task: "+task);
- // Thread.dumpStack();
- if(stop) {
- synchronized(nedt.sync) {
+
+ if( isCurrentThreadEDT() ) {
+ if(null != task) {
+ task.run();
+ }
+ wait = false; // running in same thread (EDT) -> no wait
+ if( stop ) {
nedt.shouldStop = true;
- nedt.sync.notifyAll(); // stop immediate if waiting (poll freq)
}
- if(DEBUG) {
- System.err.println(Thread.currentThread()+": SWT-EDT signal STOP (on edt: "+isCurrentThreadEDT()+") - "+nedt);
- // Thread.dumpStack();
+ } else {
+ if( !nedt.isRunning && !swtDisplay.isDisposed() ) {
+ if( null != task ) {
+ if( stop ) {
+ System.err.println(Thread.currentThread()+": Warning: SWT-EDT is about (3) to stop and stopped already, dropping task. NEDT "+nedt);
+ } else {
+ System.err.println(Thread.currentThread()+": Warning: SWT-EDT is not running, dropping task. NEDT "+nedt);
+ }
+ if(DEBUG) {
+ Thread.dumpStack();
+ }
+ }
+ return false;
+ } else if( stop ) {
+ if( nedt.isRunning ) {
+ if(DEBUG) {
+ System.err.println(Thread.currentThread()+": SWT-EDT signal STOP (on edt: "+isCurrentThreadEDT()+") - "+nedt+", isRunning "+nedt.isRunning+", shouldStop "+nedt.shouldStop);
+ }
+ synchronized(nedt.sync) {
+ nedt.shouldStop = true;
+ nedt.sync.notifyAll(); // stop immediate if waiting (poll freq)
+ }
+ }
+ if( swtDisplay.isDisposed() ) {
+ System.err.println(Thread.currentThread()+": Warning: SWT-EDT is about (3) to stop and stopped already, dropping task. "+nedt);
+ if(DEBUG) {
+ Thread.dumpStack();
+ }
+ return false;
+ }
+ }
+
+ if( null != task ) {
+ rTask = new RunnableTask(task,
+ wait ? rTaskLock : null,
+ true /* always catch and report Exceptions, don't disturb EDT */,
+ wait ? null : System.err);
+ swtDisplay.asyncExec(rTask);
}
- } else if( !nedt.isRunning() ) {
- // start if should not stop && not started yet
- startImpl();
- }
- if( null == task ) {
- wait = false;
- } else if( isCurrentThreadEDT() ) {
- task.run();
- wait = false; // running in same thread (EDT) -> no wait
- } else if( swtDisplay.isDisposed() ) {
- wait = false; // drop task, SWT disposed
- } else {
- rTask = new RunnableTask(task,
- wait ? rTaskLock : null,
- true /* always catch and report Exceptions, don't disturb EDT */,
- wait ? null : System.err);
- swtDisplay.asyncExec(rTask);
}
}
if( wait ) {
@@ -193,53 +236,60 @@ public class SWTEDTUtil implements EDTUtil {
throw new RuntimeException(throwable);
}
}
+ return true;
}
}
@Override
- final public void waitUntilIdle() {
- final NewtEventDispatchThread _nedt;
+ final public boolean waitUntilIdle() {
+ final NEDT _nedt;
synchronized(edtLock) {
_nedt = nedt;
}
final Thread ct = Thread.currentThread();
- if(!_nedt.isRunning() || _nedt == ct || swtDisplay.getThread() == ct) {
- return;
+ if( !_nedt.isRunning || _nedt == ct || swtDisplay.isDisposed() || swtDisplay.getThread() == ct ) {
+ return false;
}
try {
swtDisplay.syncExec(new Runnable() {
public void run() { }
});
} catch (Exception e) { }
+ return true;
}
@Override
- final public void waitUntilStopped() {
+ final public boolean waitUntilStopped() {
synchronized(edtLock) {
- final Thread ct = Thread.currentThread();
- if(nedt.isRunning() && nedt != ct && swtDisplay.getThread() != ct) {
- while(nedt.isRunning()) {
+ final Thread curT = Thread.currentThread();
+ final Thread swtT = !swtDisplay.isDisposed() ? swtDisplay.getThread() : null;
+ final boolean onSWTEDT = swtT == curT;
+ if( nedt.isRunning && nedt != curT && !onSWTEDT ) {
+ while( nedt.isRunning ) {
try {
edtLock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
+ return true;
+ } else {
+ return false;
}
}
}
- class NewtEventDispatchThread extends Thread {
+ class NEDT extends Thread {
volatile boolean shouldStop = false;
volatile boolean isRunning = false;
Object sync = new Object();
- public NewtEventDispatchThread(ThreadGroup tg, String name) {
+ public NEDT(ThreadGroup tg, String name) {
super(tg, name);
}
final public boolean isRunning() {
- return isRunning;
+ return isRunning && !shouldStop;
}
@Override
@@ -296,10 +346,8 @@ public class SWTEDTUtil implements EDTUtil {
System.err.println(getName()+": SWT-EDT run() END "+ getName()+", "+error);
}
synchronized(edtLock) {
- isRunning = !shouldStop;
- if(!isRunning) {
- edtLock.notifyAll();
- }
+ isRunning = false;
+ edtLock.notifyAll();
}
if(DEBUG) {
System.err.println(getName()+": SWT-EDT run() EXIT "+ getName()+", exception: "+error);
diff --git a/src/newt/classes/jogamp/newt/swt/event/SWTNewtEventFactory.java b/src/newt/classes/jogamp/newt/swt/event/SWTNewtEventFactory.java
index 1e99d1ef7..3782a1186 100644
--- a/src/newt/classes/jogamp/newt/swt/event/SWTNewtEventFactory.java
+++ b/src/newt/classes/jogamp/newt/swt/event/SWTNewtEventFactory.java
@@ -56,7 +56,6 @@ public class SWTNewtEventFactory {
case SWT.KeyDown: return com.jogamp.newt.event.KeyEvent.EVENT_KEY_PRESSED;
case SWT.KeyUp: return com.jogamp.newt.event.KeyEvent.EVENT_KEY_RELEASED;
- // case SWT.KeyXXX: return com.jogamp.newt.event.KeyEvent.EVENT_KEY_TYPED;
}
return (short)0;
}