From e9890fee4c2aa296aff2af5ff555908c6362fc5f Mon Sep 17 00:00:00 2001
From: Sven Gothel <sgothel@jausoft.com>
Date: Wed, 19 Oct 2011 19:12:08 +0200
Subject: Only revert ScreenMode (destroy/shutdown) if owner (Screen) changed
 it

---
 src/newt/classes/jogamp/newt/ScreenImpl.java       | 18 +++++++++++----
 src/newt/classes/jogamp/newt/ScreenModeStatus.java | 27 ++++++++++++++++++----
 .../classes/jogamp/newt/driver/x11/X11Screen.java  |  2 +-
 3 files changed, 36 insertions(+), 11 deletions(-)

(limited to 'src/newt/classes')

diff --git a/src/newt/classes/jogamp/newt/ScreenImpl.java b/src/newt/classes/jogamp/newt/ScreenImpl.java
index 749bba114..d79a567db 100644
--- a/src/newt/classes/jogamp/newt/ScreenImpl.java
+++ b/src/newt/classes/jogamp/newt/ScreenImpl.java
@@ -68,7 +68,7 @@ public abstract class ScreenImpl extends Screen implements ScreenModeListener {
     long t0; // creationTime
 
     static {
-        AccessController.doPrivileged(new PrivilegedAction() {
+        AccessController.doPrivileged(new PrivilegedAction<Object>() {
             public Object run() {
                 registerShutdownHook();
                 return null;
@@ -76,6 +76,7 @@ public abstract class ScreenImpl extends Screen implements ScreenModeListener {
         });
     }
     
+    @SuppressWarnings("unchecked")
     private static Class<? extends Screen> getScreenClass(String type) throws ClassNotFoundException 
     {
         Class<?> screenClass = NewtFactory.getCustomClass(type, "Screen");
@@ -557,8 +558,14 @@ public abstract class ScreenImpl extends Screen implements ScreenModeListener {
                 sms.lock();
                 try {
                     if(0 == sms.removeListener(this)) {
-                        if(!sms.isOriginalMode()) {
-                            setCurrentScreenMode(sms.getOriginalScreenMode());
+                        if(sms.isOriginalModeChangedByOwner()) {
+                            System.err.println("Screen.destroy(): "+sms.getCurrentScreenMode()+" -> "+sms.getOriginalScreenMode());
+                            try {
+                                setCurrentScreenMode(sms.getOriginalScreenMode());
+                            } catch (Throwable t) {
+                                // be verbose but continue
+                                t.printStackTrace();
+                            }
                         }
                         ScreenModeStatus.unmapScreenModeStatus(getFQName());
                     }
@@ -574,8 +581,9 @@ public abstract class ScreenImpl extends Screen implements ScreenModeListener {
     private final void shutdown() {
         ScreenModeStatus sms = ScreenModeStatus.getScreenModeStatusUnlocked(getFQName());
         if(null != sms) {
-            if(!sms.isOriginalMode()) {
+            if(sms.isOriginalModeChangedByOwner()) {
                 try {
+                    System.err.println("Screen.shutdown(): "+sms.getCurrentScreenMode()+" -> "+sms.getOriginalScreenMode());
                     setCurrentScreenModeImpl(sms.getOriginalScreenMode());
                 } catch (Throwable t) {
                     // be quiet .. shutdown
@@ -596,7 +604,7 @@ public abstract class ScreenImpl extends Screen implements ScreenModeListener {
                 ScreenImpl.shutdownAll();
             }
         });
-        AccessController.doPrivileged(new PrivilegedAction() {
+        AccessController.doPrivileged(new PrivilegedAction<Object>() {
             public Object run() {
                 Runtime.getRuntime().addShutdownHook(shutdownHook);
                 return null;
diff --git a/src/newt/classes/jogamp/newt/ScreenModeStatus.java b/src/newt/classes/jogamp/newt/ScreenModeStatus.java
index be87ce0dd..4075fb131 100644
--- a/src/newt/classes/jogamp/newt/ScreenModeStatus.java
+++ b/src/newt/classes/jogamp/newt/ScreenModeStatus.java
@@ -47,6 +47,7 @@ public class ScreenModeStatus {
     private IntIntHashMap screenModesIdx2NativeIdx;
     private ScreenMode currentScreenMode;
     private ScreenMode originalScreenMode;
+    private boolean screenModeChangedByOwner; 
     private ArrayList<ScreenModeListener> listener = new ArrayList<ScreenModeListener>();
 
     private static HashMap<String, ScreenModeStatus> screenFQN2ScreenModeStatus = new HashMap<String, ScreenModeStatus>();
@@ -111,6 +112,7 @@ public class ScreenModeStatus {
                             IntIntHashMap screenModesIdx2NativeIdx) {
         this.screenModes = screenModes;
         this.screenModesIdx2NativeIdx = screenModesIdx2NativeIdx;
+        this.screenModeChangedByOwner = false;
     }
 
     protected final void setOriginalScreenMode(ScreenMode originalScreenMode) {
@@ -131,18 +133,32 @@ public class ScreenModeStatus {
         }
     }
 
-    public final boolean isOriginalMode() {
+    /**
+     * We cannot guarantee that we won't interfere w/ another running
+     * application's screen mode change.
+     * <p>
+     * At least we only return <code>true</true> if the owner, ie. the Screen,
+     * has changed the screen mode and if the original screen mode 
+     * is not current the current one.
+     * </p>
+     * @return
+     */
+    public final boolean isOriginalModeChangedByOwner() {
         lock();
         try {
-            if(null != currentScreenMode && null != originalScreenMode) {
-                return currentScreenMode.hashCode() == originalScreenMode.hashCode();
-            }
-            return true;
+            return screenModeChangedByOwner && !isCurrentModeOriginalMode();
         } finally {
             unlock();
         }
     }
 
+    protected final boolean isCurrentModeOriginalMode() {
+        if(null != currentScreenMode && null != originalScreenMode) {
+            return currentScreenMode.hashCode() == originalScreenMode.hashCode();
+        }
+        return true;
+    }
+    
     protected final ArrayHashSet<ScreenMode> getScreenModes() {
         return screenModes;
     }
@@ -195,6 +211,7 @@ public class ScreenModeStatus {
         try {
             if(success) {
                 this.currentScreenMode = currentScreenMode;
+                this.screenModeChangedByOwner = !isCurrentModeOriginalMode();
             }
             for(int i=0; i<listener.size(); i++) {
                 listener.get(i).screenModeChanged(currentScreenMode, success);
diff --git a/src/newt/classes/jogamp/newt/driver/x11/X11Screen.java b/src/newt/classes/jogamp/newt/driver/x11/X11Screen.java
index af96dc460..5c9c326d7 100644
--- a/src/newt/classes/jogamp/newt/driver/x11/X11Screen.java
+++ b/src/newt/classes/jogamp/newt/driver/x11/X11Screen.java
@@ -245,7 +245,7 @@ public class X11Screen extends ScreenImpl {
             }            
         }).booleanValue();
         
-        if(done) {
+        if(DEBUG && done) {
             System.err.println("X11Screen.setCurrentScreenModeImpl: TO ("+SCREEN_MODE_CHANGE_TIMEOUT+") reached: "+
                                (System.currentTimeMillis()-t0)+"ms");
         }
-- 
cgit v1.2.3