aboutsummaryrefslogtreecommitdiffstats
path: root/src/newt
diff options
context:
space:
mode:
Diffstat (limited to 'src/newt')
-rw-r--r--src/newt/classes/com/jogamp/newt/Display.java83
-rw-r--r--src/newt/classes/com/jogamp/newt/MonitorDevice.java4
-rw-r--r--src/newt/classes/com/jogamp/newt/MonitorMode.java119
-rw-r--r--src/newt/classes/com/jogamp/newt/Screen.java62
-rw-r--r--src/newt/classes/com/jogamp/newt/Window.java6
-rw-r--r--src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java8
-rw-r--r--src/newt/classes/com/jogamp/newt/event/KeyEvent.java34
-rw-r--r--src/newt/classes/com/jogamp/newt/event/MouseEvent.java27
-rw-r--r--src/newt/classes/com/jogamp/newt/opengl/GLWindow.java92
-rw-r--r--src/newt/classes/com/jogamp/newt/swt/NewtCanvasSWT.java4
-rw-r--r--src/newt/classes/com/jogamp/newt/util/EDTUtil.java58
-rw-r--r--src/newt/classes/com/jogamp/newt/util/MonitorModeUtil.java11
-rw-r--r--src/newt/classes/jogamp/newt/Debug.java9
-rw-r--r--src/newt/classes/jogamp/newt/DefaultEDTUtil.java115
-rw-r--r--src/newt/classes/jogamp/newt/DisplayImpl.java186
-rw-r--r--src/newt/classes/jogamp/newt/MonitorDeviceImpl.java12
-rw-r--r--src/newt/classes/jogamp/newt/ScreenImpl.java62
-rw-r--r--src/newt/classes/jogamp/newt/WindowImpl.java220
-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/windows/DisplayDriver.java2
-rw-r--r--src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java9
-rw-r--r--src/newt/classes/jogamp/newt/driver/x11/DisplayDriver.java4
-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.java58
-rw-r--r--src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java63
-rw-r--r--src/newt/classes/jogamp/newt/swt/SWTEDTUtil.java170
-rw-r--r--src/newt/native/KeyEvent.h2
-rw-r--r--src/newt/native/WindowsWindow.c3
-rw-r--r--src/newt/native/X11RandR11.c2
-rw-r--r--src/newt/native/X11Window.c159
40 files changed, 1196 insertions, 642 deletions
diff --git a/src/newt/classes/com/jogamp/newt/Display.java b/src/newt/classes/com/jogamp/newt/Display.java
index d6ddd9613..c618405c2 100644
--- a/src/newt/classes/com/jogamp/newt/Display.java
+++ b/src/newt/classes/com/jogamp/newt/Display.java
@@ -31,6 +31,7 @@ package com.jogamp.newt;
import com.jogamp.newt.util.EDTUtil;
import jogamp.newt.Debug;
+import java.lang.ref.WeakReference;
import java.util.*;
import javax.media.nativewindow.AbstractGraphicsDevice;
@@ -153,41 +154,40 @@ public abstract class Display {
/**
* Sets a new {@link EDTUtil} and returns the previous one.
* <p>
- * If <code>newEDTUtil</code> is <code>null</code>,
+ * If <code>usrEDTUtil</code> is <code>null</code>,
* the device's default EDTUtil is created and used.
* </p>
* <p>
- * If a previous one exists and it differs from the new one,
- * it's being stopped, wait-until-idle and reset to allow a restart at a later time.
+ * If a previous one exists and it differs from <code>usrEDTUtil</code>,
+ * it's being stopped, wait-until-idle.
* </p>
* <p>
- * If <code>newEDTUtil</code> is not null and equals the previous one,
+ * If <code>usrEDTUtil</code> is not null and equals the previous one,
* no change is being made.
* </p>
- * <p>
- * Note that <code>newEDTUtil</code> will be started by this method,
- * if it is not running yet.
- * </p>
*/
- public abstract EDTUtil setEDTUtil(EDTUtil newEDTUtil);
+ public abstract EDTUtil setEDTUtil(EDTUtil usrEDTUtil);
public abstract EDTUtil getEDTUtil();
+ /**
+ * @return true if EDT is running and not subject to be stopped, otherwise false.
+ */
public abstract boolean isEDTRunning();
public abstract void dispatchMessages();
// Global Displays
- protected static final ArrayList<Display> displayList = new ArrayList<Display>();
+ protected static final ArrayList<WeakReference<Display>> displayList = new ArrayList<WeakReference<Display>>();
protected static int displaysActive = 0;
public static void dumpDisplayList(String prefix) {
synchronized(displayList) {
- Iterator<Display> i = displayList.iterator();
System.err.println(prefix+" DisplayList[] entries: "+displayList.size()+" - "+getThreadName());
- for(int j=0; i.hasNext(); j++) {
- Display d = i.next();
- System.err.println(" ["+j+"] : "+d);
+ final Iterator<WeakReference<Display>> ri = displayList.iterator();
+ for(int j=0; ri.hasNext(); j++) {
+ final Display d = ri.next().get();
+ System.err.println(" ["+j+"] : "+d+", GC'ed "+(null==d));
}
}
}
@@ -216,29 +216,62 @@ public abstract class Display {
return getDisplayOfImpl(type, name, fromIndex, -1, shared);
}
- private static Display getDisplayOfImpl(String type, String name, int fromIndex, int incr, boolean shared) {
+ private static Display getDisplayOfImpl(String type, String name, final int fromIndex, final int incr, boolean shared) {
synchronized(displayList) {
int i = fromIndex >= 0 ? fromIndex : displayList.size() - 1 ;
while( ( incr > 0 ) ? i < displayList.size() : i >= 0 ) {
- Display display = (Display) displayList.get(i);
- if( display.getType().equals(type) &&
- display.getName().equals(name) &&
- ( !shared || shared && !display.isExclusive() )
- ) {
- return display;
+ final Display display = (Display) displayList.get(i).get();
+ if( null == display ) {
+ // Clear GC'ed dead reference entry!
+ displayList.remove(i);
+ if( incr < 0 ) {
+ // decrease
+ i+=incr;
+ } // else nop - remove shifted subsequent elements to the left
+ } else {
+ if( display.getType().equals(type) &&
+ display.getName().equals(name) &&
+ ( !shared || shared && !display.isExclusive() )
+ ) {
+ return display;
+ }
+ i+=incr;
}
- i+=incr;
}
}
return null;
}
-
+
+ protected static void addDisplay2List(Display display) {
+ synchronized(displayList) {
+ // GC before add
+ int i=0;
+ while( i < displayList.size() ) {
+ if( null == displayList.get(i).get() ) {
+ displayList.remove(i);
+ } else {
+ i++;
+ }
+ }
+ displayList.add(new WeakReference<Display>(display));
+ }
+ }
+
/** Returns the global display collection */
- @SuppressWarnings("unchecked")
public static Collection<Display> getAllDisplays() {
ArrayList<Display> list;
synchronized(displayList) {
- list = (ArrayList<Display>) displayList.clone();
+ list = new ArrayList<Display>();
+ int i = 0;
+ while( i < displayList.size() ) {
+ final Display d = displayList.get(i).get();
+ if( null == d ) {
+ displayList.remove(i);
+ } else {
+ list.add( displayList.get(i).get() );
+ i++;
+ }
+ }
}
return list;
}
diff --git a/src/newt/classes/com/jogamp/newt/MonitorDevice.java b/src/newt/classes/com/jogamp/newt/MonitorDevice.java
index 4b0a760a4..8bc7f40e3 100644
--- a/src/newt/classes/com/jogamp/newt/MonitorDevice.java
+++ b/src/newt/classes/com/jogamp/newt/MonitorDevice.java
@@ -129,6 +129,10 @@ public abstract class MonitorDevice {
/**
* Returns a list of immutable {@link MonitorMode}s supported by this monitor.
* <p>
+ * The list is ordered in descending order,
+ * see {@link MonitorMode#compareTo(MonitorMode)}.
+ * </p>
+ * <p>
* Use w/ care, it's not a copy!
* </p>
*/
diff --git a/src/newt/classes/com/jogamp/newt/MonitorMode.java b/src/newt/classes/com/jogamp/newt/MonitorMode.java
index 914aa880f..218cd8bd5 100644
--- a/src/newt/classes/com/jogamp/newt/MonitorMode.java
+++ b/src/newt/classes/com/jogamp/newt/MonitorMode.java
@@ -28,6 +28,8 @@
package com.jogamp.newt;
+import java.util.Comparator;
+
import javax.media.nativewindow.util.DimensionImmutable;
import javax.media.nativewindow.util.RectangleImmutable;
import javax.media.nativewindow.util.SurfaceSize;
@@ -108,22 +110,36 @@ import com.jogamp.newt.util.MonitorModeUtil;
monitor.setCurrentMode(mm);
* </pre>
*/
-public class MonitorMode {
+public class MonitorMode implements Comparable<MonitorMode> {
+
+ /** Comparator for 2 {@link MonitorMode}s, following comparison order as described in {@link MonitorMode#compareTo(MonitorMode)}, returning the ascending order. */
+ public static final Comparator<MonitorMode> monitorModeComparator = new Comparator<MonitorMode>() {
+ public int compare(MonitorMode mm1, MonitorMode mm2) {
+ return mm1.compareTo(mm2);
+ } };
+
+ /** Comparator for 2 {@link MonitorMode}s, following comparison order as described in {@link MonitorMode#compareTo(MonitorMode)}, returning the descending order. */
+ public static final Comparator<MonitorMode> monitorModeComparatorInv = new Comparator<MonitorMode>() {
+ public int compare(MonitorMode mm1, MonitorMode mm2) {
+ return mm2.compareTo(mm1);
+ } };
+
/**
- * Immutable <i>surfaceSize and refreshRate</i> Class, consisting of it's read only components:<br>
+ * Immutable <i>surfaceSize, flags and refreshRate</i> Class, consisting of it's read only components:<br>
* <ul>
* <li>nativeId</li>
* <li>{@link SurfaceSize} surface memory size</li>
+ * <li><code>flags</code></li>
* <li><code>refresh rate</code></li>
* </ul>
*/
- public static class SizeAndRRate {
+ public static class SizeAndRRate implements Comparable<SizeAndRRate> {
/** Non rotated surface size */
public final SurfaceSize surfaceSize;
- /** Vertical refresh rate */
- public final float refreshRate;
/** Mode bitfield flags, i.e. {@link #FLAG_DOUBLESCAN}, {@link #FLAG_INTERLACE}, .. */
public final int flags;
+ /** Vertical refresh rate */
+ public final float refreshRate;
public final int hashCode;
public SizeAndRRate(SurfaceSize surfaceSize, float refreshRate, int flags) {
@@ -131,8 +147,8 @@ public class MonitorMode {
throw new IllegalArgumentException("surfaceSize must be set ("+surfaceSize+")");
}
this.surfaceSize=surfaceSize;
- this.refreshRate=refreshRate;
this.flags = flags;
+ this.refreshRate=refreshRate;
this.hashCode = getHashCode();
}
@@ -140,8 +156,8 @@ public class MonitorMode {
private final static String STR_DOUBLESCAN = "DoubleScan";
private final static String STR_SEP = ", ";
- public static final StringBuffer flags2String(int flags) {
- final StringBuffer sb = new StringBuffer();
+ public static final StringBuilder flags2String(int flags) {
+ final StringBuilder sb = new StringBuilder();
boolean sp = false;
if( 0 != ( flags & FLAG_INTERLACE ) ) {
sb.append(STR_INTERLACE);
@@ -161,6 +177,49 @@ public class MonitorMode {
}
/**
+ * <p>
+ * Compares {@link SurfaceSize#compareTo(SurfaceSize) surfaceSize} 1st, then {@link #flags}, then {@link #refreshRate}.
+ * </p>
+ * <p>
+ * Flags are compared as follows:
+ * <pre>
+ * NONE > DOUBLESCAN > INTERLACE
+ * </pre>
+ * </p>
+ * <p>
+ * Refresh rate differences of &lt; 0.01 are considered equal (epsilon).
+ * </p>
+ * {@inheritDoc}
+ */
+ @Override
+ public int compareTo(final SizeAndRRate sszr) {
+ final int rssz = surfaceSize.compareTo(sszr.surfaceSize);
+ if( 0 != rssz ) {
+ return rssz;
+ }
+ final int tflags = 0 == flags ? Integer.MAX_VALUE : flags; // normalize NONE
+ final int xflags = 0 == sszr.flags ? Integer.MAX_VALUE : sszr.flags; // normalize NONE
+ if( tflags == xflags ) {
+ final float refreshEpsilon = 0.01f; // reasonable sorting granularity of refresh rate
+ final float drate = refreshRate - sszr.refreshRate;
+ if( Math.abs(drate) < refreshEpsilon ) {
+ return 0;
+ } else if( drate > refreshEpsilon ) {
+ return 1;
+ } else {
+ return -1;
+ }
+ } else {
+ if(tflags > xflags) {
+ return 1;
+ } else if(tflags < xflags) {
+ return -1;
+ }
+ return 0;
+ }
+ }
+
+ /**
* Tests equality of two {@link SizeAndRRate} objects
* by evaluating equality of it's components:<br/>
* <ul>
@@ -174,8 +233,8 @@ public class MonitorMode {
if (obj instanceof SizeAndRRate) {
final SizeAndRRate p = (SizeAndRRate)obj;
return surfaceSize.equals(p.surfaceSize) &&
- refreshRate == p.refreshRate &&
- flags == p.flags ;
+ flags == p.flags &&
+ refreshRate == p.refreshRate ;
}
return false;
}
@@ -184,8 +243,8 @@ public class MonitorMode {
* Returns a combined hash code of it's elements:<br/>
* <ul>
* <li><code>surfaceSize</code></li>
- * <li><code>refreshRate</code></li>
* <li><code>flags</code></li>
+ * <li><code>refreshRate</code></li>
* </ul>
*/
public final int hashCode() {
@@ -194,8 +253,8 @@ public class MonitorMode {
private final int getHashCode() {
// 31 * x == (x << 5) - x
int hash = 31 + surfaceSize.hashCode();
- hash = ((hash << 5) - hash) + (int)(refreshRate*100.0f);
hash = ((hash << 5) - hash) + flags;
+ hash = ((hash << 5) - hash) + (int)(refreshRate*100.0f);
return hash;
}
}
@@ -306,6 +365,42 @@ public class MonitorMode {
}
/**
+ * <p>
+ * Compares {@link SizeAndRRate#compareTo(SizeAndRRate) sizeAndRRate} 1st, then {@link #rotation}.
+ * </p>
+ * <p>
+ * Rotation is compared inverted, i.e. <code>360 - rotation</code>,
+ * so the lowest rotation reflects a higher value.
+ * </p>
+ * <p>
+ * Order of comparing MonitorMode:
+ * <ul>
+ * <li>resolution</li>
+ * <li>bits per pixel</li>
+ * <li>flags</li>
+ * <li>refresh rate</li>
+ * <li>rotation</li>
+ * </ul>
+ * </p>
+ * {@inheritDoc}
+ */
+ @Override
+ public int compareTo(final MonitorMode mm) {
+ final int c = sizeAndRRate.compareTo(mm.sizeAndRRate);
+ if( 0 != c ) {
+ return c;
+ }
+ final int trot = 360 - rotation; // normalize rotation
+ final int xrot = 360 - mm.rotation; // normalize rotation
+ if(trot > xrot) {
+ return 1;
+ } else if(trot < xrot) {
+ return -1;
+ }
+ return 0;
+ }
+
+ /**
* Tests equality of two {@link MonitorMode} objects
* by evaluating equality of it's components:<br/>
* <ul>
diff --git a/src/newt/classes/com/jogamp/newt/Screen.java b/src/newt/classes/com/jogamp/newt/Screen.java
index f56aff964..f56ee344b 100644
--- a/src/newt/classes/com/jogamp/newt/Screen.java
+++ b/src/newt/classes/com/jogamp/newt/Screen.java
@@ -29,6 +29,8 @@ package com.jogamp.newt;
import com.jogamp.newt.event.MonitorModeListener;
import jogamp.newt.Debug;
+
+import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@@ -64,7 +66,7 @@ public abstract class Screen {
}
/**
- * Manual trigger the native creation, if it is not done yet..<br>
+ * Manual trigger the native creation, if not done yet..<br>
* This is useful to be able to request the {@link javax.media.nativewindow.AbstractGraphicsScreen}, via
* {@link #getGraphicsScreen()}.<br>
* Otherwise the abstract device won't be available before the dependent component (Window) is realized.
@@ -164,6 +166,10 @@ public abstract class Screen {
/**
* Return a list of all {@link MonitorMode}s for all {@link MonitorDevice}s.
+ * <p>
+ * The list is ordered in descending order,
+ * see {@link MonitorMode#compareTo(MonitorMode)}.
+ * </p>
*/
public abstract List<MonitorMode> getMonitorModes();
@@ -220,7 +226,7 @@ public abstract class Screen {
public abstract void removeMonitorModeListener(MonitorModeListener sml);
// Global Screens
- protected static ArrayList<Screen> screenList = new ArrayList<Screen>();
+ protected static final ArrayList<WeakReference<Screen>> screenList = new ArrayList<WeakReference<Screen>>();
protected static int screensActive = 0;
/**
@@ -249,26 +255,60 @@ public abstract class Screen {
synchronized(screenList) {
int i = fromIndex >= 0 ? fromIndex : screenList.size() - 1 ;
while( ( incr > 0 ) ? i < screenList.size() : i >= 0 ) {
- Screen screen = (Screen) screenList.get(i);
- if( screen.getDisplay().equals(display) &&
- screen.getIndex() == idx ) {
- return screen;
+ final Screen screen = (Screen) screenList.get(i).get();
+ if( null == screen ) {
+ // Clear GC'ed dead reference entry!
+ screenList.remove(i);
+ if( incr < 0 ) {
+ // decrease
+ i+=incr;
+ } // else nop - remove shifted subsequent elements to the left
+ } else {
+ if( screen.getDisplay().equals(display) &&
+ screen.getIndex() == idx ) {
+ return screen;
+ }
+ i+=incr;
}
- i+=incr;
}
}
return null;
}
- /** Returns the global display collection */
- @SuppressWarnings("unchecked")
+
+ protected static void addScreen2List(Screen screen) {
+ synchronized(screenList) {
+ // GC before add
+ int i=0;
+ while( i < screenList.size() ) {
+ if( null == screenList.get(i).get() ) {
+ screenList.remove(i);
+ } else {
+ i++;
+ }
+ }
+ screenList.add(new WeakReference<Screen>(screen));
+ }
+ }
+
+ /** Returns the global screen collection */
public static Collection<Screen> getAllScreens() {
ArrayList<Screen> list;
synchronized(screenList) {
- list = (ArrayList<Screen>) screenList.clone();
+ list = new ArrayList<Screen>();
+ int i = 0;
+ while( i < screenList.size() ) {
+ final Screen s = screenList.get(i).get();
+ if( null == s ) {
+ screenList.remove(i);
+ } else {
+ list.add( screenList.get(i).get() );
+ i++;
+ }
+ }
}
return list;
}
-
+
public static int getActiveScreenNumber() {
synchronized(screenList) {
return screensActive;
diff --git a/src/newt/classes/com/jogamp/newt/Window.java b/src/newt/classes/com/jogamp/newt/Window.java
index 0bebf330a..f63c03738 100644
--- a/src/newt/classes/com/jogamp/newt/Window.java
+++ b/src/newt/classes/com/jogamp/newt/Window.java
@@ -406,7 +406,11 @@ public interface Window extends NativeWindow, WindowClosingProtocol {
* Sets a {@link KeyListener} allowing focus traversal with a covered window toolkit like AWT.
* <p>
* The {@link KeyListener} methods are invoked prior to all other {@link KeyListener}'s
- * allowing to suppress the {@link KeyEvent} via the {@link InputEvent#consumedTag}.
+ * allowing to suppress the {@link KeyEvent} via the {@link InputEvent#consumedTag}
+ * and to perform focus traversal with a 3rd party toolkit.
+ * </p>
+ * <p>
+ * The {@link KeyListener} methods are not invoked for {@link KeyEvent#isAutoRepeat() auto-repeat} events.
* </p>
* @param l
*/
diff --git a/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java b/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java
index dd8939e43..e4b5a25c4 100644
--- a/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java
+++ b/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java
@@ -223,7 +223,7 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto
final Set<AWTKeyStroke> fwdKeys = keyboardFocusManager.getDefaultFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS);
final Set<AWTKeyStroke> bwdKeys = keyboardFocusManager.getDefaultFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS);
if(fwdKeys.contains(ks)) {
- final Component nextFocus = AWTMisc.getNextFocus(NewtCanvasAWT.this);
+ final Component nextFocus = AWTMisc.getNextFocus(NewtCanvasAWT.this, true /* forward */);
if(DEBUG) {
System.err.println("NewtCanvasAWT.focusKey (fwd): "+ks+", current focusOwner "+keyboardFocusManager.getFocusOwner()+", hasFocus: "+hasFocus()+", nextFocus "+nextFocus);
}
@@ -231,7 +231,7 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto
nextFocus.requestFocus();
suppress = true;
} else if(bwdKeys.contains(ks)) {
- final Component prevFocus = AWTMisc.getPrevFocus(NewtCanvasAWT.this);
+ final Component prevFocus = AWTMisc.getNextFocus(NewtCanvasAWT.this, false /* forward */);
if(DEBUG) {
System.err.println("NewtCanvasAWT.focusKey (bwd): "+ks+", current focusOwner "+keyboardFocusManager.getFocusOwner()+", hasFocus: "+hasFocus()+", prevFocus "+prevFocus);
}
@@ -576,7 +576,9 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto
}
final int w = getWidth();
final int h = getHeight();
- System.err.println("NewtCanvasAWT.attachNewtChild.2: size "+w+"x"+h);
+ if(DEBUG) {
+ System.err.println("NewtCanvasAWT.attachNewtChild.2: size "+w+"x"+h);
+ }
newtChild.setVisible(false);
newtChild.setSize(w, h);
newtChild.reparentWindow(jawtWindow);
diff --git a/src/newt/classes/com/jogamp/newt/event/KeyEvent.java b/src/newt/classes/com/jogamp/newt/event/KeyEvent.java
index ec05a34ad..085f598dc 100644
--- a/src/newt/classes/com/jogamp/newt/event/KeyEvent.java
+++ b/src/newt/classes/com/jogamp/newt/event/KeyEvent.java
@@ -312,13 +312,13 @@ public class KeyEvent extends InputEvent
* @param isKeyChar true if <code>uniChar</code> is a key character, otherwise a virtual key code
*/
public static boolean isPrintableKey(final short uniChar, final boolean isKeyChar) {
- if( VK_UNDEFINED == uniChar ) {
- return false;
+ if ( VK_BACK_SPACE == uniChar || VK_TAB == uniChar || VK_ENTER == uniChar ) {
+ return true;
}
if( !isKeyChar ) {
if( ( nonPrintableKeys[0].min <= uniChar && uniChar <= nonPrintableKeys[0].max ) ||
( nonPrintableKeys[1].min <= uniChar && uniChar <= nonPrintableKeys[1].max ) ||
- ( nonPrintableKeys[2].min <= uniChar && uniChar <= nonPrintableKeys[2].max ) ||
+ ( nonPrintableKeys[2].min <= uniChar && uniChar <= nonPrintableKeys[2].max ) ||
( nonPrintableKeys[3].min <= uniChar && uniChar <= nonPrintableKeys[3].max ) ) {
return false;
}
@@ -330,7 +330,7 @@ public class KeyEvent extends InputEvent
return false;
}
}
- return true;
+ return VK_UNDEFINED != uniChar;
}
/**
@@ -381,9 +381,19 @@ public class KeyEvent extends InputEvent
this.inclKeyChar = inclKeyChar;
}
};
- /** Non printable key ranges, currently fixed to an array of size 4. */
+ /**
+ * Non printable key ranges, currently fixed to an array of size 4.
+ * <p>
+ * Not included, queried upfront:
+ * <ul>
+ * <li>{@link #VK_BACK_SPACE}</li>
+ * <li>{@link #VK_TAB}</li>
+ * <li>{@link #VK_ENTER}</li>
+ * </ul>
+ * </p>
+ */
public final static NonPrintableRange[] nonPrintableKeys = {
- new NonPrintableRange( (short)0x0000, (short)0x001F, true ), // Unicode: Non printable controls: [0x00 - 0x1F]
+ new NonPrintableRange( (short)0x0000, (short)0x001F, true ), // Unicode: Non printable controls: [0x00 - 0x1F], see exclusion above
new NonPrintableRange( (short)0x0061, (short)0x0078, false), // Small 'a' thru 'z' (0x61 - 0x7a) - Not used for keyCode / keySym - Re-used for Fn (collision)
new NonPrintableRange( (short)0x008F, (short)0x009F, true ), // Unicode: Non printable controls: [0x7F - 0x9F], Numpad keys [0x7F - 0x8E] are printable!
new NonPrintableRange( (short)0xE000, (short)0xF8FF, true ) // Unicode: Private 0xE000 - 0xF8FF (Marked Non-Printable)
@@ -415,14 +425,14 @@ public class KeyEvent extends InputEvent
static final short VK_FREE06 = (short) 0x06;
static final short VK_FREE07 = (short) 0x07;
- /** Constant for the BACK SPACE key "\b", matching ASCII. */
+ /** Constant for the BACK SPACE key "\b", matching ASCII. Printable! */
public static final short VK_BACK_SPACE = (short) 0x08;
- /** Constant for the HORIZ TAB key "\t", matching ASCII. */
+ /** Constant for the HORIZ TAB key "\t", matching ASCII. Printable! */
public static final short VK_TAB = (short) 0x09;
- /** Constant for the ENTER key, i.e. LINE FEED "\n", matching ASCII. */
- public static final short VK_ENTER = (short) 0x0A;
+ /** LINE_FEED "\n", matching ASCII, n/a on keyboard. */
+ static final short VK_FREE0A = (short) 0x0A;
/** Constant for the PAGE DOWN function key. ASCII: Vertical Tabulation. */
public static final short VK_PAGE_DOWN = (short) 0x0B;
@@ -430,7 +440,9 @@ public class KeyEvent extends InputEvent
/** Constant for the CLEAR key, i.e. FORM FEED, matching ASCII. */
public static final short VK_CLEAR = (short) 0x0C;
- static final short VK_FREE0D = (short) 0x0D;
+ /** Constant for the ENTER key, i.e. CARRIAGE RETURN, matching ASCII. Printable! */
+ public static final short VK_ENTER = (short) 0x0D;
+
static final short VK_FREE0E = (short) 0x0E;
/** Constant for the CTRL function key. ASCII: shift-in. */
diff --git a/src/newt/classes/com/jogamp/newt/event/MouseEvent.java b/src/newt/classes/com/jogamp/newt/event/MouseEvent.java
index 18c8285f7..93bbcc0b9 100644
--- a/src/newt/classes/com/jogamp/newt/event/MouseEvent.java
+++ b/src/newt/classes/com/jogamp/newt/event/MouseEvent.java
@@ -252,33 +252,6 @@ public class MouseEvent extends InputEvent
}
/**
- * <i>Usually</i> a wheel rotation of <b>&gt; 0.0f is up</b>,
- * and <b>&lt; 0.0f is down</b>.
- * <p>
- * Usually a wheel rotations is considered a vertical scroll.<br/>
- * If {@link #isShiftDown()}, a wheel rotations is
- * considered a horizontal scroll, where <b>shift-up = left = &gt; 0.0f</b>,
- * and <b>shift-down = right = &lt; 0.0f</b>.
- * </p>
- * <p>
- * <i>However</i>, on some OS this might be flipped due to the OS <i>default</i> behavior.
- * The latter is true for OS X 10.7 (Lion) for example.
- * </p>
- * <p>
- * The events will be send usually in steps of one, ie. <i>-1.0f</i> and <i>1.0f</i>.
- * Higher values may result due to fast scrolling.
- * Fractional values may result due to slow scrolling with high resolution devices.
- * </p>
- * <p>
- * The button number refers to the wheel number.
- * </p>
- * @deprecated Use {@link #getRotation()}
- */
- public float getWheelRotation() {
- return isShiftDown() ? rotationXYZ[0] : rotationXYZ[1] ;
- }
-
- /**
* Returns a 3-component float array filled with the values of the rotational axis
* in the following order: horizontal-, vertical- and z-axis.
* <p>
diff --git a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
index 345d92bc1..e85d67dea 100644
--- a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
+++ b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
@@ -34,6 +34,8 @@
package com.jogamp.newt.opengl;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
import java.util.List;
import javax.media.nativewindow.AbstractGraphicsConfiguration;
@@ -47,6 +49,8 @@ import javax.media.nativewindow.util.InsetsImmutable;
import javax.media.nativewindow.util.Point;
import javax.media.opengl.FPSCounter;
import javax.media.opengl.GL;
+import javax.media.opengl.GL3;
+import javax.media.opengl.GL4ES3;
import javax.media.opengl.GLAnimatorControl;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCapabilities;
@@ -54,6 +58,8 @@ import javax.media.opengl.GLCapabilitiesImmutable;
import javax.media.opengl.GLContext;
import javax.media.opengl.GLDrawable;
import javax.media.opengl.GLDrawableFactory;
+import javax.media.opengl.GLES2;
+import javax.media.opengl.GLES3;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.GLException;
import javax.media.opengl.GLProfile;
@@ -529,6 +535,29 @@ public class GLWindow extends GLAutoDrawableBase implements GLAutoDrawable, Wind
savedAnimator.resume();
}
}
+
+ @SuppressWarnings("deprecation")
+ @Override
+ public void shutdownRenderingAction() {
+ final GLAnimatorControl anim = GLWindow.this.getAnimator();
+ if ( null != anim && anim.isAnimating() ) {
+ final Thread animThread = anim.getThread();
+ if( animThread == Thread.currentThread() ) {
+ anim.stop(); // on anim thread, non-blocking
+ } else {
+ AccessController.doPrivileged(new PrivilegedAction<Object>() {
+ public Object run() {
+ if( anim.isAnimating() && null != animThread ) {
+ try {
+ animThread.stop();
+ } catch(Throwable t) {
+ }
+ }
+ return null;
+ } } );
+ }
+ }
+ }
}
//----------------------------------------------------------------------
@@ -805,14 +834,58 @@ public class GLWindow extends GLAutoDrawableBase implements GLAutoDrawable, Wind
* A most simple JOGL AWT test entry
*/
public static void main(String args[]) {
+ final boolean forceES2;
+ final boolean forceES3;
+ final boolean forceGL3;
+ final boolean forceGL4ES3;
+ {
+ boolean _forceES2 = false;
+ boolean _forceES3 = false;
+ boolean _forceGL3 = false;
+ boolean _forceGL4ES3 = false;
+ if( null != args ) {
+ for(int i=0; i<args.length; i++) {
+ if(args[i].equals("-es2")) {
+ _forceES2 = true;
+ } else if(args[i].equals("-es3")) {
+ _forceES3 = true;
+ } else if(args[i].equals("-gl3")) {
+ _forceGL3 = true;
+ } else if(args[i].equals("-gl4es3")) {
+ _forceGL4ES3 = true;
+ }
+ }
+ }
+ forceES2 = _forceES2;
+ forceES3 = _forceES3;
+ forceGL3 = _forceGL3;
+ forceGL4ES3 = _forceGL4ES3;
+ }
+ System.err.println("forceES2 "+forceES2);
+ System.err.println("forceES3 "+forceES3);
+ System.err.println("forceGL3 "+forceGL3);
+ System.err.println("forceGL4ES3 "+forceGL4ES3);
+
System.err.println(VersionUtil.getPlatformInfo());
System.err.println(GlueGenVersion.getInstance());
System.err.println(JoglVersion.getInstance());
System.err.println(JoglVersion.getDefaultOpenGLInfo(null, null, true).toString());
- final GLProfile glp = GLProfile.getDefault();
+ final GLProfile glp;
+ if(forceGL4ES3) {
+ glp = GLProfile.get(GLProfile.GL4ES3);
+ } else if(forceGL3) {
+ glp = GLProfile.get(GLProfile.GL3);
+ } else if(forceES3) {
+ glp = GLProfile.get(GLProfile.GLES3);
+ } else if(forceES2) {
+ glp = GLProfile.get(GLProfile.GLES2);
+ } else {
+ glp = GLProfile.getDefault();
+ }
final GLCapabilitiesImmutable caps = new GLCapabilities( glp );
+ System.err.println("Requesting: "+caps);
GLWindow glWindow = GLWindow.create(caps);
glWindow.setSize(128, 128);
@@ -824,6 +897,23 @@ public class GLWindow extends GLAutoDrawableBase implements GLAutoDrawable, Wind
System.err.println(JoglVersion.getGLInfo(gl, null));
System.err.println("Requested: "+drawable.getNativeSurface().getGraphicsConfiguration().getRequestedCapabilities());
System.err.println("Chosen : "+drawable.getChosenGLCapabilities());
+ System.err.println("GL impl. class "+gl.getClass().getName());
+ if( gl.isGL4ES3() ) {
+ GL4ES3 _gl = gl.getGL4ES3();
+ System.err.println("GL4ES3 retrieved, impl. class "+_gl.getClass().getName());
+ }
+ if( gl.isGL3() ) {
+ GL3 _gl = gl.getGL3();
+ System.err.println("GL3 retrieved, impl. class "+_gl.getClass().getName());
+ }
+ if( gl.isGLES3() ) {
+ GLES3 _gl = gl.getGLES3();
+ System.err.println("GLES3 retrieved, impl. class "+_gl.getClass().getName());
+ }
+ if( gl.isGLES2() ) {
+ GLES2 _gl = gl.getGLES2();
+ System.err.println("GLES2 retrieved, impl. class "+_gl.getClass().getName());
+ }
}
@Override
diff --git a/src/newt/classes/com/jogamp/newt/swt/NewtCanvasSWT.java b/src/newt/classes/com/jogamp/newt/swt/NewtCanvasSWT.java
index dbe7c0d98..47dfca0f3 100644
--- a/src/newt/classes/com/jogamp/newt/swt/NewtCanvasSWT.java
+++ b/src/newt/classes/com/jogamp/newt/swt/NewtCanvasSWT.java
@@ -345,7 +345,9 @@ public class NewtCanvasSWT extends Canvas implements WindowClosingProtocol {
// set SWT EDT and start it
{
final Display newtDisplay = newtChild.getScreen().getDisplay();
- newtDisplay.setEDTUtil( new SWTEDTUtil(newtDisplay, getDisplay()) );
+ final EDTUtil edtUtil = new SWTEDTUtil(newtDisplay, getDisplay());
+ edtUtil.restart();
+ newtDisplay.setEDTUtil( edtUtil );
}
newtChild.setSize(w, h);
diff --git a/src/newt/classes/com/jogamp/newt/util/EDTUtil.java b/src/newt/classes/com/jogamp/newt/util/EDTUtil.java
index 0183da592..e86df2084 100644
--- a/src/newt/classes/com/jogamp/newt/util/EDTUtil.java
+++ b/src/newt/classes/com/jogamp/newt/util/EDTUtil.java
@@ -65,14 +65,19 @@ public interface EDTUtil {
public void setPollPeriod(long ms);
/**
- * Create a new EDT. One should invoke <code>reset()</code><br>
- * after <code>invokeStop(..)</code> in case another start via <code>invoke(..)</code>
- * is expected.
- *
- * @see #invoke(boolean, java.lang.Runnable)
- * @see #invokeStop(java.lang.Runnable)
+ * Starts or restarts the EDT.
+ * <p>
+ * If the EDT is running, it must be stopped first via {@link #invokeStop(boolean, Runnable)}
+ * and the caller should wait until it's stopped via {@link #waitUntilStopped()}.
+ * </p>
+ *
+ * @return true if EDT has been successfully restarted, otherwise false
+ * @throws IllegalStateException if EDT is running and not subject to be stopped, i.e. {@link #isRunning()} returns true
+ *
+ * @see #invokeStop(boolean, java.lang.Runnable)
+ * @see #waitUntilStopped()
*/
- public void reset();
+ public boolean restart() throws IllegalStateException;
/**
* Returns true if the current thread is the event dispatch thread (EDT).
@@ -107,44 +112,57 @@ public interface EDTUtil {
public boolean isCurrentThreadEDTorNEDT();
/**
- * @return True if EDT is running
+ * @return True if EDT is running and not subject to be stopped.
*/
public boolean isRunning();
/**
* Append the final task to the EDT task queue,
- * signals EDT to stop and wait until stopped.<br/>
+ * signals EDT to stop.
+ * <p>
+ * If <code>wait</code> is <code>true</code> methods
+ * blocks until EDT is stopped.
+ * </p>
+ * <p>
* <code>task</code> maybe <code>null</code><br/>
* Due to the nature of this method:
* <ul>
* <li>All previous queued tasks will be finished.</li>
* <li>No new tasks are allowed, an Exception is thrown.</li>
* <li>Can be issued from within EDT, ie from within an enqueued task.</li>
- * <li>{@link #reset()} may follow immediately, ie creating a new EDT</li>
+ * <li>{@link #restart()} may follow immediately, ie creating a new EDT</li>
* </ul>
+ * </p>
+ * @return true if <code>task</code> has been executed or queued for later execution, otherwise false
*/
- public void invokeStop(Runnable finalTask);
+ public boolean invokeStop(boolean wait, Runnable finalTask);
/**
- * Shall start the thread if not running, <code>task</code> maybe null for this purpose.<br>
- * Append task to the EDT task queue.<br>
- * Wait until execution is finished if <code>wait == true</code>.<br>
+ * Appends task to the EDT task queue if current thread is not EDT,
+ * otherwise execute task immediately.
+ * <p>
+ * Wait until execution is finished if <code>wait == true</code>.
+ * </p>
* Can be issued from within EDT, ie from within an enqueued task.<br>
- *
- * @throws RuntimeException in case EDT is stopped and not {@link #reset()}
+ * @return true if <code>task</code> has been executed or queued for later execution, otherwise false
*/
- public void invoke(boolean wait, Runnable task);
+ public boolean invoke(boolean wait, Runnable task);
/**
* Wait until the EDT task queue is empty.<br>
* The last task may still be in execution when this method returns.
+ * @return true if waited for idle, otherwise false, i.e. in case of current thread is EDT or NEDT
*/
- public void waitUntilIdle();
+ public boolean waitUntilIdle();
/**
* Wait until EDT task is stopped.<br>
- * No <code>stop</code> action is performed, {@link #invokeStop(java.lang.Runnable)} should be used before.
+ * No <code>stop</code> action is performed, {@link #invokeStop(boolean, java.lang.Runnable)} should be used before.
+ * <p>
+ * If caller thread is EDT or NEDT, this call will not block.
+ * </p>
+ * @return true if stopped, otherwise false, i.e. in case of current thread is EDT or NEDT
*/
- public void waitUntilStopped();
+ public boolean waitUntilStopped();
}
diff --git a/src/newt/classes/com/jogamp/newt/util/MonitorModeUtil.java b/src/newt/classes/com/jogamp/newt/util/MonitorModeUtil.java
index 16ffe754f..c30b427d6 100644
--- a/src/newt/classes/com/jogamp/newt/util/MonitorModeUtil.java
+++ b/src/newt/classes/com/jogamp/newt/util/MonitorModeUtil.java
@@ -31,7 +31,9 @@ package com.jogamp.newt.util;
import com.jogamp.newt.MonitorMode;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
+
import javax.media.nativewindow.util.DimensionImmutable;
import javax.media.nativewindow.util.SurfaceSize;
@@ -68,6 +70,15 @@ public class MonitorModeUtil {
return null;
}
+ /** Sort the given {@link MonitorMode} collection w/ {@link MonitorMode#compareTo(MonitorMode)} function. */
+ public static void sort(List<MonitorMode> monitorModes, boolean ascendingOrder) {
+ if( ascendingOrder ) {
+ Collections.sort(monitorModes);
+ } else {
+ Collections.sort(monitorModes, MonitorMode.monitorModeComparatorInv);
+ }
+ }
+
/**
*
* @param monitorModes
diff --git a/src/newt/classes/jogamp/newt/Debug.java b/src/newt/classes/jogamp/newt/Debug.java
index 676d9b758..4b0a98216 100644
--- a/src/newt/classes/jogamp/newt/Debug.java
+++ b/src/newt/classes/jogamp/newt/Debug.java
@@ -69,15 +69,18 @@ public class Debug extends PropertyAccess {
}
}
- 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 3edb532db..8f792b23c 100644
--- a/src/newt/classes/jogamp/newt/DisplayImpl.java
+++ b/src/newt/classes/jogamp/newt/DisplayImpl.java
@@ -41,6 +41,7 @@ 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;
@@ -76,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());
@@ -96,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());
@@ -136,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+")");
}
@@ -152,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+")");
+ }
}
}
}
@@ -178,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;
}
@@ -205,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;
}
@@ -238,52 +269,67 @@ 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());
- }
+ if(DEBUG) {
+ System.err.println("Display.destroy(): "+this+", active "+displaysActive+" "+getThreadName());
+ }
+ }
final DisplayImpl f_dpy = this;
- removeEDT( new Runnable() { // blocks!
+ final AbstractGraphicsDevice f_aDevice = aDevice;
+ aDevice = null;
+ refCount=0;
+ stopEDT( edtUtil, new Runnable() { // blocks!
public void run() {
- if ( null != aDevice ) {
- f_dpy.closeNativeImpl();
+ if ( null != f_aDevice ) {
+ f_dpy.closeNativeImpl(f_aDevice);
}
}
} );
- aDevice = null;
- refCount=0;
if(DEBUG) {
dumpDisplayList("Display.destroy("+getFQName()+") END");
}
}
- /** Maybe utilized at a shutdown hook, impl. does not synchronize, however the EDT removal blocks. */
+ /** 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);
- if(0 < displaysActive) {
- displaysActive--;
- }
+ final DisplayImpl d = (DisplayImpl) displayList.remove(0).get();
if(DEBUG) {
- System.err.println("Display.shutdownAll["+(i+1)+"/"+dCount+"]: "+d);
+ System.err.println("Display.shutdownAll["+(i+1)+"/"+dCount+"]: "+d+", GCed "+(null==d));
}
- d.removeEDT( new Runnable() {
- public void run() {
- if ( null != d.getGraphicsDevice() ) {
- d.closeNativeImpl();
+ 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();
}
- } );
- d.aDevice = null;
- d.refCount=0;
+ }
}
}
@@ -318,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() {
@@ -386,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 */
@@ -487,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;
}
@@ -544,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 f63d1499e..5ffa2ebbf 100644
--- a/src/newt/classes/jogamp/newt/ScreenImpl.java
+++ b/src/newt/classes/jogamp/newt/ScreenImpl.java
@@ -52,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;
@@ -124,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());
}
@@ -168,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;
}
@@ -216,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;
@@ -285,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);
}
}
}
@@ -397,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);
@@ -410,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);
@@ -425,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);
@@ -536,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++) {
@@ -550,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);
}
@@ -605,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 {
@@ -663,11 +673,13 @@ public abstract class ScreenImpl extends Screen implements MonitorModeListener {
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);
+ final ScreenImpl s = (ScreenImpl) screenList.remove(0).get();
if(DEBUG) {
- System.err.println("Screen.shutdownAll["+(i+1)+"/"+sCount+"]: "+s);
+ System.err.println("Screen.shutdownAll["+(i+1)+"/"+sCount+"]: "+s+", GCed "+(null==s));
+ }
+ if( null != s ) {
+ s.shutdown();
}
- s.shutdown();
}
}
}
diff --git a/src/newt/classes/jogamp/newt/WindowImpl.java b/src/newt/classes/jogamp/newt/WindowImpl.java
index 1ac97b07c..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,26 +81,50 @@ 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);
-
- protected static final ArrayList<WindowImpl> windowList = new ArrayList<WindowImpl>();
+ 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();
}
-
- /** Maybe utilized at a shutdown hook, impl. does not synchronize, however the Window destruction and EDT removal blocks. */
+
+ 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);
+ 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.shutdownAll["+(i+1)+"/"+wCount+"]: "+toHexString(w.getWindowHandle()));
+ System.err.println("Window.addWindow2List: GCed "+gced+", size "+windowList.size());
}
- w.markInvalid();
}
}
@@ -129,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
@@ -207,9 +233,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
window.screen = (ScreenImpl) screen;
window.capsRequested = (CapabilitiesImmutable) caps.cloneMutable();
window.instantiationFinished();
- synchronized( windowList ) {
- windowList.add(window);
- }
+ addWindow2List(window);
return window;
} catch (Throwable t) {
t.printStackTrace();
@@ -232,9 +256,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
window.screen = (ScreenImpl) screen;
window.capsRequested = (CapabilitiesImmutable) caps.cloneMutable();
window.instantiationFinished();
- synchronized( windowList ) {
- windowList.add(window);
- }
+ addWindow2List(window);
return window;
} catch (Throwable t) {
throw new NativeWindowException(t);
@@ -242,12 +264,16 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
/** Fast invalidation of instance w/o any blocking function call. */
- private final void markInvalid() {
+ 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;
}
@@ -310,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() {
@@ -361,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 {
@@ -551,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 ) |
@@ -881,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);
}
@@ -926,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) {
@@ -1004,6 +1051,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
fullscreen = false;
fullscreenMonitors = null;
fullscreenUseMainMonitor = true;
+ fullscreenUseSpanningMode = false;
hasFocus = false;
parentWindowHandle = 0;
@@ -1035,9 +1083,6 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
@Override
public void destroy() {
- synchronized( windowList ) {
- windowList.remove(this);
- }
visible = false; // Immediately mark synchronized visibility flag, avoiding possible recreation
runOnEDTIfAvail(true, destroyAction);
}
@@ -1839,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;
}
}
@@ -1872,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();
@@ -1894,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;
@@ -1915,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;
@@ -1952,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);
}
@@ -1964,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) {
@@ -1978,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) {
@@ -1997,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;
@@ -2007,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) {
@@ -2028,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
@@ -2044,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();
@@ -2535,19 +2615,21 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
protected void consumeKeyEvent(KeyEvent e) {
boolean consumedE = false;
- if(null != keyboardFocusHandler) {
+ if( null != keyboardFocusHandler && !e.isAutoRepeat() ) {
consumedE = propagateKeyEvent(e, keyboardFocusHandler);
if(DEBUG_KEY_EVENT) {
- System.err.println("consumeKeyEvent: "+e+", keyboardFocusHandler consumed: "+consumedE);
+ 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));
+ }
+ if(DEBUG_KEY_EVENT) {
+ System.err.println("consumeKeyEvent(usr): "+e+", consumed: "+consumedE);
}
- }
- for(int i = 0; !consumedE && i < keyListeners.size(); i++ ) {
- consumedE = propagateKeyEvent(e, 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/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 60fc3ec0f..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,7 +291,7 @@ 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) and RELEASED (t1)
// Auto-Repeat: WINDOWS delivers only PRESSED (t0) and TYPED (t0).
diff --git a/src/newt/classes/jogamp/newt/driver/x11/DisplayDriver.java b/src/newt/classes/jogamp/newt/driver/x11/DisplayDriver.java
index 88d06f69c..d911483b0 100644
--- a/src/newt/classes/jogamp/newt/driver/x11/DisplayDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/x11/DisplayDriver.java
@@ -82,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 e1373bba5..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,9 +55,12 @@ 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();
}
@@ -84,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 ) {
@@ -186,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) );
}
@@ -217,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);
+ }
+ }
}
//----------------------------------------------------------------------
@@ -248,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 786587d65..4786ea04f 100644
--- a/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java
@@ -65,6 +65,7 @@ public class WindowDriver extends WindowImpl {
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(..)
}
@@ -270,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);
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/native/KeyEvent.h b/src/newt/native/KeyEvent.h
index 59977d565..c0a366a17 100644
--- a/src/newt/native/KeyEvent.h
+++ b/src/newt/native/KeyEvent.h
@@ -39,9 +39,9 @@
#define J_VK_PRINTSCREEN ( 0x05U )
#define J_VK_BACK_SPACE ( 0x08U )
#define J_VK_TAB ( 0x09U )
-#define J_VK_ENTER ( 0x0AU )
#define J_VK_PAGE_DOWN ( 0x0BU )
#define J_VK_CLEAR ( 0x0CU )
+#define J_VK_ENTER ( 0x0DU )
#define J_VK_SHIFT ( 0x0FU )
#define J_VK_PAGE_UP ( 0x10U )
#define J_VK_CONTROL ( 0x11U )
diff --git a/src/newt/native/WindowsWindow.c b/src/newt/native/WindowsWindow.c
index ac0ebf07e..4ef2459e8 100644
--- a/src/newt/native/WindowsWindow.c
+++ b/src/newt/native/WindowsWindow.c
@@ -431,6 +431,9 @@ static void ParseWmVKeyAndScanCode(USHORT winVKey, BYTE winScanCode, BYTE flags,
break;
}
}
+ if( J_VK_UNDEFINED == javaVKeyUS ) {
+ javaVKeyUS = javaVKeyXX;
+ }
}
*outJavaVKeyUS = javaVKeyUS;
diff --git a/src/newt/native/X11RandR11.c b/src/newt/native/X11RandR11.c
index 81a6726b5..53d01a6fe 100644
--- a/src/newt/native/X11RandR11.c
+++ b/src/newt/native/X11RandR11.c
@@ -311,7 +311,7 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_RandR11_setCurrentScreenM
/*
* Class: jogamp_newt_driver_x11_RandR11
* Method: setCurrentScreenModePollEnd0
- * Signature: (J)Z
+ * Signature: (JIII)Z
*/
JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_RandR11_setCurrentScreenModePollEnd0
(JNIEnv *env, jclass clazz, jlong display, jint screen_idx, jint resMode_idx, jint freq, jint rotation)
diff --git a/src/newt/native/X11Window.c b/src/newt/native/X11Window.c
index 3f50f27a4..e6e300d2e 100644
--- a/src/newt/native/X11Window.c
+++ b/src/newt/native/X11Window.c
@@ -299,9 +299,8 @@ static void NewtWindows_setNormalWindowEWMH (Display *dpy, Window w) {
#define _NET_WM_STATE_REMOVE 0
#define _NET_WM_STATE_ADD 1
-
-#define _NET_WM_FULLSCREEN ( 1 << 0 )
-#define _NET_WM_ABOVE ( 1 << 1 )
+#define _NET_WM_STATE_FLAG_FULLSCREEN ( 1 << 0 )
+#define _NET_WM_STATE_FLAG_ABOVE ( 1 << 1 )
/**
* Set fullscreen using Extended Window Manager Hints (EWMH)
@@ -314,7 +313,9 @@ static void NewtWindows_setNormalWindowEWMH (Display *dpy, Window w) {
* and resets it when leaving FS.
* The same is assumed for the decoration state.
*/
-static int NewtWindows_isFullscreenEWMHSupported (Display *dpy, Window w) {
+static int NewtWindows_getSupportedStackingEWMHFlags(Display *dpy, Window w) {
+#ifdef VERBOSE_ON
+ // Code doesn't work reliable on KDE4 ...
Atom _NET_WM_ALLOWED_ACTIONS = XInternAtom( dpy, "_NET_WM_ALLOWED_ACTIONS", False );
Atom _NET_WM_ACTION_FULLSCREEN = XInternAtom( dpy, "_NET_WM_ACTION_FULLSCREEN", False );
Atom _NET_WM_ACTION_ABOVE = XInternAtom( dpy, "_NET_WM_ACTION_ABOVE", False );
@@ -329,86 +330,75 @@ static int NewtWindows_isFullscreenEWMHSupported (Display *dpy, Window w) {
for(i=0; i<action_len; i++) {
if(_NET_WM_ACTION_FULLSCREEN == actions[i]) {
DBG_PRINT( "**************** X11: FS EWMH CHECK[%d]: _NET_WM_ACTION_FULLSCREEN (*)\n", i);
- res |= _NET_WM_FULLSCREEN ;
+ res |= _NET_WM_STATE_FLAG_FULLSCREEN ;
} else if(_NET_WM_ACTION_ABOVE == actions[i]) {
DBG_PRINT( "**************** X11: FS EWMH CHECK[%d]: _NET_WM_ACTION_ABOVE (*)\n", i);
- res |= _NET_WM_ABOVE ;
+ res |= _NET_WM_STATE_FLAG_ABOVE ;
}
-#ifdef VERBOSE_ON
else {
char * astr = XGetAtomName(dpy, actions[i]);
DBG_PRINT( "**************** X11: FS EWMH CHECK[%d]: %s (unused)\n", i, astr);
XFree(astr);
}
-#endif
}
DBG_PRINT( "**************** X11: FS EWMH CHECK: 0x%X\n", res);
} else {
DBG_PRINT( "**************** X11: FS EWMH CHECK: XGetWindowProperty failed: %d\n", s);
}
- // above code doesn't work reliable on KDE4 ...
- res = _NET_WM_FULLSCREEN | _NET_WM_ABOVE ;
- return res;
+#endif
+ return _NET_WM_STATE_FLAG_FULLSCREEN | _NET_WM_STATE_FLAG_ABOVE ;
}
-static Bool NewtWindows_setFullscreenEWMH (Display *dpy, Window root, Window w, int ewmhFlags, Bool isVisible, Bool enable) {
+static Bool NewtWindows_setStackingEWMHFlags (Display *dpy, Window root, Window w, int ewmhFlags, Bool isVisible, Bool enable) {
Atom _NET_WM_STATE = XInternAtom( dpy, "_NET_WM_STATE", False );
Atom _NET_WM_STATE_ABOVE = XInternAtom( dpy, "_NET_WM_STATE_ABOVE", False );
Atom _NET_WM_STATE_FULLSCREEN = XInternAtom( dpy, "_NET_WM_STATE_FULLSCREEN", False );
- int ewmhMask = NewtWindows_isFullscreenEWMHSupported(dpy, w);
+ int ewmhMask = NewtWindows_getSupportedStackingEWMHFlags(dpy, w);
+ Bool changeFullscreen = 0 != ( ( _NET_WM_STATE_FLAG_FULLSCREEN & ewmhMask ) & ewmhFlags ) ;
+ Bool changeAbove = 0 != ( ( _NET_WM_STATE_FLAG_ABOVE & ewmhMask ) & ewmhFlags ) ;
Bool res = False;
if(0 == ewmhMask) {
return res;
}
- if(!isVisible && True==enable) {
- Atom types[2]={0};
- int ntypes=0;
-
- if( 0 != ( ( _NET_WM_FULLSCREEN & ewmhMask ) & ewmhFlags ) ) {
- types[ntypes++] = _NET_WM_STATE_FULLSCREEN;
- }
- if( 0 != ( ( _NET_WM_ABOVE & ewmhMask ) & ewmhFlags ) ) {
- types[ntypes++] = _NET_WM_STATE_ABOVE;
- }
- if(ntypes>0) {
- XChangeProperty( dpy, w, _NET_WM_STATE, XA_ATOM, 32, PropModeReplace, (unsigned char *)&types, ntypes);
- XSync(dpy, False);
- res = True;
- }
- } else {
- if(enable) {
- NewtWindows_setCWAbove(dpy, w);
- }
- XEvent xev;
- long mask = SubstructureNotifyMask | SubstructureRedirectMask ;
- int i=0;
-
- memset ( &xev, 0, sizeof(xev) );
-
- xev.type = ClientMessage;
- xev.xclient.window = w;
- xev.xclient.message_type = _NET_WM_STATE;
- xev.xclient.format = 32;
+ // _NET_WM_STATE: fullscreen and/or above
+ if( changeFullscreen || changeAbove ) {
+ {
+ // _NET_WM_STATE as event to root window
+ XEvent xev;
+ long mask = SubstructureNotifyMask | SubstructureRedirectMask ;
+ int i=0;
- xev.xclient.data.l[i++] = ( True == enable ) ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE ;
- if( 0 != ( ( _NET_WM_FULLSCREEN & ewmhMask ) & ewmhFlags ) ) {
- xev.xclient.data.l[i++] = _NET_WM_STATE_FULLSCREEN;
- }
- if( 0 != ( ( _NET_WM_ABOVE & ewmhMask ) & ewmhFlags ) ) {
- xev.xclient.data.l[i++] = _NET_WM_STATE_ABOVE;
- }
- xev.xclient.data.l[3] = 1; //source indication for normal applications
+ memset ( &xev, 0, sizeof(xev) );
+
+ xev.type = ClientMessage;
+ xev.xclient.window = w;
+ xev.xclient.message_type = _NET_WM_STATE;
+ xev.xclient.format = 32;
+
+ xev.xclient.data.l[i++] = enable ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE ;
+ if( changeFullscreen ) {
+ xev.xclient.data.l[i++] = _NET_WM_STATE_FULLSCREEN;
+ }
+ if( changeAbove ) {
+ xev.xclient.data.l[i++] = _NET_WM_STATE_ABOVE;
+ }
+ xev.xclient.data.l[3] = 1; //source indication for normal applications
- if(i>0) {
XSendEvent ( dpy, root, False, mask, &xev );
- res = True;
}
+ // Also change _NET_WM_BYPASS_COMPOSITOR!
+ {
+ Atom _NET_WM_BYPASS_COMPOSITOR = XInternAtom( dpy, "_NET_WM_BYPASS_COMPOSITOR", False );
+ unsigned long value = enable ? 1 : 0;
+ XChangeProperty( dpy, w, _NET_WM_BYPASS_COMPOSITOR, XA_CARDINAL, 32, PropModeReplace, (unsigned char*)&value, 1);
+ }
+ XSync(dpy, False);
+ res = True;
}
- XSync(dpy, False);
- DBG_PRINT( "X11: reconfigureWindow0 FULLSCREEN EWMH ON %d, ewmhMask 0x%X, ewmhFlags 0x%X, visible %d: %d\n",
- enable, ewmhMask, ewmhFlags, isVisible, res);
+ DBG_PRINT( "X11: setStackingEWMHFlags ON %d, changeFullscreen %d, changeAbove %d, visible %d: %d\n",
+ enable, changeFullscreen, changeAbove, isVisible, res);
return res;
}
@@ -657,7 +647,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_WindowDriver_CreateWindow0
NewtWindows_setPosSize(dpy, window, x, y, width, height);
if( TST_FLAG_IS_ALWAYSONTOP(flags) ) {
- NewtWindows_setFullscreenEWMH(dpy, root, window, _NET_WM_ABOVE, True, True);
+ NewtWindows_setStackingEWMHFlags(dpy, root, window, _NET_WM_STATE_FLAG_ABOVE, True, True);
}
}
@@ -720,15 +710,6 @@ static Bool WaitForReparentNotify( Display *dpy, XEvent *event, XPointer arg ) {
}
#endif
-/**
- * KDE cause lost input focus in fullscreen mode.
- * Using 'XGrabKeyboard(..)' would prevent the loss,
- * but also would disable WM task switcher etc.
- *
- * #define FS_GRAB_KEYBOARD 1
- *
- */
-
/*
* Class: jogamp_newt_driver_x11_WindowDriver
* Method: reconfigureWindow0
@@ -747,21 +728,22 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_reconfigureWindo
XEvent event;
Bool isVisible = !TST_FLAG_CHANGE_VISIBILITY(flags) && TST_FLAG_IS_VISIBLE(flags) ;
Bool tempInvisible = ( TST_FLAG_CHANGE_FULLSCREEN(flags) || TST_FLAG_CHANGE_PARENTING(flags) ) && isVisible ;
+ // Bool tempInvisible = TST_FLAG_CHANGE_PARENTING(flags) && isVisible ;
int fsEWMHFlags = 0;
if( TST_FLAG_CHANGE_FULLSCREEN(flags) ) {
- if( !TST_FLAG_IS_FULLSCREEN_SPAN(flags) ) { // doesn't work w/ spanning across monitors
- fsEWMHFlags |= _NET_WM_FULLSCREEN;
+ if( !TST_FLAG_IS_FULLSCREEN_SPAN(flags) ) { // doesn't work w/ spanning across monitors. See also Bug 770 & Bug 771
+ fsEWMHFlags |= _NET_WM_STATE_FLAG_FULLSCREEN;
}
if( TST_FLAG_IS_FULLSCREEN(flags) ) {
if( TST_FLAG_IS_ALWAYSONTOP(flags) ) {
- fsEWMHFlags |= _NET_WM_ABOVE; // fs on, above on
- } // else { } // fs on, above off
+ fsEWMHFlags |= _NET_WM_STATE_FLAG_ABOVE; // fs on, above on
+ } // else { } // fs on, above off
} else if( !TST_FLAG_IS_ALWAYSONTOP(flags) ) {
- fsEWMHFlags |= _NET_WM_ABOVE; // fs off, above off
- } // else { } // fs off, above on
+ fsEWMHFlags |= _NET_WM_STATE_FLAG_ABOVE; // fs off, above off
+ } // else { } // fs off, above on
}
if( TST_FLAG_CHANGE_ALWAYSONTOP(flags) ) {
- fsEWMHFlags |= _NET_WM_ABOVE; // toggle above
+ fsEWMHFlags |= _NET_WM_STATE_FLAG_ABOVE; // toggle above
}
DBG_PRINT( "X11: reconfigureWindow0 dpy %p, scrn %d, parent %p/%p, win %p, %d/%d %dx%d, parentChange %d, hasParent %d, decorationChange %d, undecorated %d, fullscreenChange %d, fullscreen %d (span %d), alwaysOnTopChange %d, alwaysOnTop %d, visibleChange %d, visible %d, tempInvisible %d, fsEWMHFlags %d\n",
@@ -780,21 +762,11 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_reconfigureWindo
!TST_FLAG_IS_FULLSCREEN_SPAN(flags) &&
( TST_FLAG_CHANGE_FULLSCREEN(flags) || TST_FLAG_CHANGE_ALWAYSONTOP(flags) ) ) {
Bool enable = TST_FLAG_CHANGE_FULLSCREEN(flags) ? TST_FLAG_IS_FULLSCREEN(flags) : TST_FLAG_IS_ALWAYSONTOP(flags) ;
- if( NewtWindows_setFullscreenEWMH(dpy, root, w, fsEWMHFlags, isVisible, enable) ) {
+ if( NewtWindows_setStackingEWMHFlags(dpy, root, w, fsEWMHFlags, isVisible, enable) ) {
if ( TST_FLAG_CHANGE_FULLSCREEN(flags) && !TST_FLAG_IS_FULLSCREEN(flags) ) { // FS off - restore decoration
NewtWindows_setDecorations (dpy, w, TST_FLAG_IS_UNDECORATED(flags) ? False : True);
}
- #ifdef FS_GRAB_KEYBOARD
- if(TST_FLAG_CHANGE_FULLSCREEN(flags)) {
- if(TST_FLAG_IS_FULLSCREEN(flags)) {
- XGrabKeyboard(dpy, w, True, GrabModeAsync, GrabModeAsync, CurrentTime);
- } else {
- XUngrabKeyboard(dpy, CurrentTime);
- }
- } else if(TST_FLAG_CHANGE_ALWAYSONTOP(flags) && !TST_FLAG_IS_ALWAYSONTOP(flags)) {
- XUngrabKeyboard(dpy, CurrentTime);
- }
- #endif
+ DBG_PRINT( "X11: reconfigureWindow0 X (fast)\n");
return;
}
}
@@ -808,10 +780,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_reconfigureWindo
if( fsEWMHFlags && ( ( TST_FLAG_CHANGE_FULLSCREEN(flags) && !TST_FLAG_IS_FULLSCREEN(flags) ) ||
( TST_FLAG_CHANGE_ALWAYSONTOP(flags) && !TST_FLAG_IS_ALWAYSONTOP(flags) ) ) ) { // FS off
- NewtWindows_setFullscreenEWMH(dpy, root, w, fsEWMHFlags, isVisible, False);
- #ifdef FS_GRAB_KEYBOARD
- XUngrabKeyboard(dpy, CurrentTime);
- #endif
+ NewtWindows_setStackingEWMHFlags(dpy, root, w, fsEWMHFlags, isVisible, False);
}
if( TST_FLAG_CHANGE_PARENTING(flags) && !TST_FLAG_HAS_PARENT(flags) ) {
@@ -844,9 +813,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_reconfigureWindo
XMapRaised(dpy, w);
XIfEvent( dpy, &event, WaitForMapNotify, (XPointer) w );
// no need to notify the java side .. just temp change
- }
-
- if( TST_FLAG_CHANGE_VISIBILITY(flags) ) {
+ } else if( TST_FLAG_CHANGE_VISIBILITY(flags) ) {
if( TST_FLAG_IS_VISIBLE(flags) ) {
DBG_PRINT( "X11: reconfigureWindow0 VISIBLE ON\n");
XMapRaised(dpy, w);
@@ -859,15 +826,11 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_reconfigureWindo
if( fsEWMHFlags && ( ( TST_FLAG_CHANGE_FULLSCREEN(flags) && TST_FLAG_IS_FULLSCREEN(flags) ) ||
( TST_FLAG_CHANGE_ALWAYSONTOP(flags) && TST_FLAG_IS_ALWAYSONTOP(flags) ) ) ) { // FS on
- NewtWindows_setFullscreenEWMH(dpy, root, w, fsEWMHFlags, isVisible, True);
- #ifdef FS_GRAB_KEYBOARD
- if(TST_FLAG_CHANGE_FULLSCREEN(flags) && TST_FLAG_IS_FULLSCREEN(flags)) {
- XGrabKeyboard(dpy, w, True, GrabModeAsync, GrabModeAsync, CurrentTime);
- }
- #endif
+ NewtWindows_requestFocus (dpy, w, True);
+ NewtWindows_setStackingEWMHFlags(dpy, root, w, fsEWMHFlags, isVisible, True);
}
- DBG_PRINT( "X11: reconfigureWindow0 X\n");
+ DBG_PRINT( "X11: reconfigureWindow0 X (full)\n");
}
/*