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.java47
-rw-r--r--src/newt/classes/com/jogamp/newt/Screen.java131
-rw-r--r--src/newt/classes/com/jogamp/newt/ScreenMode.java249
-rw-r--r--src/newt/classes/com/jogamp/newt/Window.java3
-rw-r--r--src/newt/classes/com/jogamp/newt/event/ScreenModeListener.java39
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/DefaultEDTUtil.java47
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/DisplayImpl.java8
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/ScreenImpl.java668
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/ScreenModeStatus.java286
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/ScreensModeState.java21
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/WindowImpl.java136
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/awt/AWTScreen.java1
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/intel/gdl/Screen.java4
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/macosx/MacScreen.java4
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/opengl/broadcom/egl/Screen.java2
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/opengl/kd/KDScreen.java2
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/windows/WindowsScreen.java194
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/x11/X11Screen.java339
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/x11/X11Window.java1
-rw-r--r--src/newt/classes/com/jogamp/newt/opengl/GLWindow.java8
-rw-r--r--src/newt/classes/com/jogamp/newt/util/MonitorMode.java105
-rw-r--r--src/newt/classes/com/jogamp/newt/util/ScreenModeUtil.java367
-rw-r--r--src/newt/native/NewtCommon.c29
-rw-r--r--src/newt/native/NewtCommon.h4
-rw-r--r--src/newt/native/ScreenMode.h16
-rw-r--r--src/newt/native/WindowsWindow.c416
-rw-r--r--src/newt/native/X11Window.c472
27 files changed, 2371 insertions, 1228 deletions
diff --git a/src/newt/classes/com/jogamp/newt/Display.java b/src/newt/classes/com/jogamp/newt/Display.java
index b09f63962..7ce20e4bb 100644
--- a/src/newt/classes/com/jogamp/newt/Display.java
+++ b/src/newt/classes/com/jogamp/newt/Display.java
@@ -54,24 +54,69 @@ public abstract class Display {
public abstract void destroy();
+ /**
+ * @return the value set by {@link #setDestroyWhenUnused(boolean)}
+ * or the default <code>false</code>.
+ *
+ * @see #addReference()
+ * @see #removeReference()
+ */
public abstract boolean getDestroyWhenUnused();
/**
+ * Handles the lifecycle of the native Display instance.<br>
+ * If set to <code>true</code>, the last {@link #removeReference()} call
+ * will destroy this instance, otherwise it will stay alive.<br>
+ * Default is <code>false</code>.
*
- * @param v
+ * @see #addReference()
+ * @see #removeReference()
*/
public abstract void setDestroyWhenUnused(boolean v);
+ /**
+ * The 1st call will initiate native creation,
+ * since we follow the lazy creation pattern.
+ *
+ * @return number of references after adding one
+ * @see #removeReference()
+ */
+ public abstract int addReference();
+
+ /**
+ * The last call may destroy this instance,
+ * if {@link #getDestroyWhenUnused()} returns <code>true</code>.
+ *
+ * @return number of references after removing one
+ * @see #addReference()
+ * @see #getDestroyWhenUnused()
+ * @see #setDestroyWhenUnused(boolean)
+ */
+ public abstract int removeReference();
+
public abstract AbstractGraphicsDevice getGraphicsDevice();
+ /**
+ * @return the fully qualified Display name,
+ * which is a key of {@link #getType()} + {@link #getName()} + {@link #getId()}
+ */
public abstract String getFQName();
public abstract long getHandle();
+ /**
+ * @return this display internal serial id
+ */
public abstract int getId();
+ /**
+ * @return this display instance name as defined at creation time
+ */
public abstract String getName();
+ /**
+ * @return the native display type, ie {@link javax.media.nativewindow.NativeWindowFactory#getNativeWindowType(boolean)}
+ */
public abstract String getType();
public abstract EDTUtil getEDTUtil();
diff --git a/src/newt/classes/com/jogamp/newt/Screen.java b/src/newt/classes/com/jogamp/newt/Screen.java
index b57e34091..2cea88d19 100644
--- a/src/newt/classes/com/jogamp/newt/Screen.java
+++ b/src/newt/classes/com/jogamp/newt/Screen.java
@@ -25,13 +25,21 @@
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of JogAmp Community.
*/
-
package com.jogamp.newt;
+import com.jogamp.newt.event.ScreenModeListener;
import com.jogamp.newt.impl.Debug;
+import java.util.List;
import javax.media.nativewindow.AbstractGraphicsScreen;
public interface Screen {
+
+ /**
+ * A 10s timeout for screen mode change. It is observed, that some platforms
+ * need a notable amount of time for this task, especially in case of rotation change.
+ */
+ public static final int SCREEN_MODE_CHANGE_TIMEOUT = 10000;
+
public static final boolean DEBUG = Debug.debug("Screen");
boolean isNativeValid();
@@ -44,69 +52,106 @@ public interface Screen {
void destroy();
+ /**
+ * @return {@link Display#getDestroyWhenUnused()}
+ *
+ * @see #addReference()
+ * @see #removeReference()
+ * @see Display#setDestroyWhenUnused(boolean)
+ */
boolean getDestroyWhenUnused();
+ /**
+ * calls {@link Display#setDestroyWhenUnused(boolean)}.
+ *
+ * @see #addReference()
+ * @see #removeReference()
+ * @see Display#setDestroyWhenUnused(boolean)
+ */
void setDestroyWhenUnused(boolean v);
+ /**
+ * See {@link Display#addReference()}
+ *
+ * @see #removeReference()
+ * @see #setDestroyWhenUnused(boolean)
+ * @see #getDestroyWhenUnused()
+ */
+ int addReference();
+
+ /**
+ * See {@link Display#removeReference()}
+ *
+ * @see #addReference()
+ * @see #setDestroyWhenUnused(boolean)
+ * @see #getDestroyWhenUnused()
+ */
+ int removeReference();
+
AbstractGraphicsScreen getGraphicsScreen();
+ /**
+ * @return this Screen index of all Screens of {@link #getDisplay()}.
+ */
int getIndex();
/**
- * The actual implementation shall return the detected display value,
- * if not we return 800.
- * This can be overwritten with the user property 'newt.ws.swidth',
+ * @return the current screen width
*/
int getWidth();
/**
- * The actual implementation shall return the detected display value,
- * if not we return 480.
- * This can be overwritten with the user property 'newt.ws.sheight',
+ * @return the current screen height
*/
int getHeight();
+ /**
+ * @return the associated Display
+ */
Display getDisplay();
-
- /** Get the screen fully qualified name
- * which can be used to get the screen controller
- * associated with this screen
+
+ /**
+ * @return the screen fully qualified Screen name,
+ * which is a key of {@link com.jogamp.newt.Display#getFQName()} + {@link #getIndex()}.
*/
- String getScreenFQN();
-
+ String getFQName();
+
/**
- * Get the Current Desktop Screen mode index
- * returns -1 if functionality not implemented
- * for screen platform
+ * @param sml ScreenModeListener to be added for ScreenMode change events
*/
- int getDesktopScreenModeIndex();
-
- /** Get the current screen rate
- * returns -1 if not natively implemented
+ public void addScreenModeListener(ScreenModeListener sml);
+
+ /**
+ * @param sml ScreenModeListener to be removed from ScreenMode change events
*/
- short getCurrentScreenRate();
-
+ public void removeScreenModeListener(ScreenModeListener sml);
+
/**
- * Get list of available screen modes
- * null if not implemented for screen platform
+ * Return a list of available {@link com.jogamp.newt.ScreenMode}s.
+ * @return a shallow copy of the internal immutable {@link com.jogamp.newt.ScreenMode}s,
+ * or null if not implemented for this native type {@link com.jogamp.newt.Display#getType()}.
*/
- ScreenMode[] getScreenModes();
-
- /**
- * change the screen mode
- * @param modeIndex mode index from the list of available screen modes
- * @param rate the desired rate should be one of the available rates.
- */
- void setScreenMode(int modeIndex, short rate);
-
- /** Change the Screen Rotation to
- * one of the rotations defined in ScreenMode
- * @param rot rotation id, example ScreenMode.ROTATE_0
- */
- public void setScreenRotation(int rot);
-
- /** Get the Current screen rotation
- * returns -1 if not implemented natively
- */
- public int getCurrentScreenRotation();
+ List/*<ScreenMode>*/ getScreenModes();
+
+ /**
+ * Return the original {@link com.jogamp.newt.ScreenMode}, as used at NEWT initialization.
+ * @return null if functionality not implemented,
+ * otherwise the original ScreenMode which is element of the list {@link #getScreenModes()}.
+ *
+ */
+ ScreenMode getOriginalScreenMode();
+
+ /**
+ * Return the current {@link com.jogamp.newt.ScreenMode}.
+ * @return null if functionality not implemented,
+ * otherwise the current ScreenMode which is element of the list {@link #getScreenModes()}.
+ */
+ ScreenMode getCurrentScreenMode();
+
+ /**
+ * Set the current {@link com.jogamp.newt.ScreenMode}.
+ * @param screenMode to be made current, must be element of the list {@link #getScreenModes()}.
+ * @return true if successful, otherwise false
+ */
+ boolean setCurrentScreenMode(ScreenMode screenMode);
}
diff --git a/src/newt/classes/com/jogamp/newt/ScreenMode.java b/src/newt/classes/com/jogamp/newt/ScreenMode.java
index f37652a23..8fb5aabb8 100644
--- a/src/newt/classes/com/jogamp/newt/ScreenMode.java
+++ b/src/newt/classes/com/jogamp/newt/ScreenMode.java
@@ -1,76 +1,179 @@
+/**
+ * Copyright 2010 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
package com.jogamp.newt;
-public class ScreenMode {
- public static final int ROTATE_0 = 0;
- public static final int ROTATE_90 = 90;
- public static final int ROTATE_180 = 180;
- public static final int ROTATE_270 = 270;
-
- private int index;
- private int width;
- private int height;
- private int bitsPerPixel = -1;
-
- private short[] rates = null;
-
- public ScreenMode(int index, int width, int height) {
- this.index = index;
- this.width = width;
- this.height = height;
- }
- /** Not safe to use this on platforms
- * other than windows. Since the mode ids
- * on X11 match the native ids. unlike windows
- * where the ids are generated .
- * @param index
- */
- public void setIndex(int index) {
- this.index = index;
- }
- public int getIndex() {
- return index;
- }
- public int getWidth() {
- return width;
- }
- public void setWidth(int width) {
- this.width = width;
- }
- public int getHeight() {
- return height;
- }
- public void setHeight(int height) {
- this.height = height;
- }
- public short[] getRates() {
- return rates;
- }
- public void setRates(short[] rates) {
- this.rates = rates;
- }
-
- public int getBitsPerPixel() {
- return bitsPerPixel;
- }
-
- public void setBitsPerPixel(int bitsPerPixel) {
- this.bitsPerPixel = bitsPerPixel;
- }
-
- public short getHighestAvailableRate(){
- short highest = rates[0];
- if(rates.length > 1){
- for (int i = 1; i < rates.length; i++) {
- if(rates[i] > highest){
- highest = rates[i];
- }
- }
- }
- return highest;
- }
-
- public String toString() {
- return "ScreenMode: " + this.index + " - " + this.width + " x "
- + this.height + " " + getHighestAvailableRate() + " Hz";
- }
+import com.jogamp.newt.util.MonitorMode;
+
+/** Immutable ScreenMode Class, consisting of it's read only components:<br>
+ * <ul>
+ * <li>{@link com.jogamp.newt.util.MonitorMode}</li>
+ * <li><code>rotation</code></li>
+ * </ul>
+ *
+ * <i>Aquire and filter ScreenModes</i><br>
+ * <ul>
+ * <li>A List of read only ScreenMode's is being returned by {@link com.jogamp.newt.Screen#getScreenModes()}.</li>
+ * <li>You may utilize {@link com.jogamp.newt.util.ScreenModeUtil} to filter and select a desired ScreenMode.</li>
+ * <li>The current ScreenMode can be obtained via {@link com.jogamp.newt.Screen#getCurrentScreenMode()}.</li>
+ * <li>The initial original ScreenMode (at startup) can be obtained via {@link com.jogamp.newt.Screen#getOriginalScreenMode()}.</li>
+ * </ul>
+ * <br>
+ *
+ * <i>Changing ScreenModes</i><br>
+ * <ul>
+ * <li> Use {@link com.jogamp.newt.Screen#setCurrentScreenMode(com.jogamp.newt.ScreenMode)}</li>
+ * to change the current ScreenMode of all Screen's referenced via the full qualified name (FQN)
+ * {@link com.jogamp.newt.Screen#getFQName()}.</li>
+ * <li> When the last FQN referenced Screen closes, the original ScreenMode ({@link com.jogamp.newt.Screen#getOriginalScreenMode()})
+ * is restored.</li>
+ * </ul>
+ * <br>
+ * Example for changing the ScreenMode:
+ * <pre>
+ // determine target refresh rate
+ ScreenMode orig = screen.getOriginalScreenMode();
+ int freq = orig.getMonitorMode().getRefreshRate();
+
+ // target resolution
+ Dimension res = new Dimension(800, 600);
+
+ // target rotation
+ int rot = 0;
+
+ // filter available ScreenModes
+ List screenModes = screen.getScreenModes();
+ screenModes = ScreenModeUtil.filterByRate(screenModes, freq); // get the nearest ones
+ screenModes = ScreenModeUtil.filterByRotation(screenModes, rot);
+ screenModes = ScreenModeUtil.filterByResolution(screenModes, res); // get the nearest ones
+ screenModes = ScreenModeUtil.getHighestAvailableBpp(screenModes);
+
+ // pick 1st one ..
+ screen.setCurrentScreenMode((ScreenMode) screenModes.get(0));
+ * </pre>
+ *
+ * X11 / AMD just works<br>
+ * <br>
+ * X11 / NVidia difficulties
+ * <pre>
+ NVidia RANDR RefreshRate Bug
+ If NVidia's 'DynamicTwinView' is enabled, all refresh rates are
+ unique, ie consequent numbers starting with the default refresh, ie 50, 51, ..
+ The only way to workaround it is to disable 'DynamicTwinView'.
+ Read: http://us.download.nvidia.com/XFree86/Linux-x86/260.19.12/README/configtwinview.html
+
+ Check to see if 'DynamicTwinView' is enable:
+ nvidia-settings -q :0/DynamicTwinview
+
+ To disable it (workaround), add the following option to your xorg.conf device section:
+ Option "DynamicTwinView" "False"
+
+ NVidia RANDR Rotation:
+ To enable it, add the following option to your xorg.conf device section:
+ Option "RandRRotation" "on"
+ * </pre>
+ *
+ */
+public class ScreenMode implements Cloneable {
+ public static final int ROTATE_0 = 0;
+ public static final int ROTATE_90 = 90;
+ public static final int ROTATE_180 = 180;
+ public static final int ROTATE_270 = 270;
+
+ MonitorMode monitorMode;
+ int rotation;
+
+ public static boolean isRotationValid(int rotation) {
+ return rotation == ScreenMode.ROTATE_0 || rotation == ScreenMode.ROTATE_90 ||
+ rotation == ScreenMode.ROTATE_180 || rotation == ScreenMode.ROTATE_270 ;
+ }
+
+ /**
+ * @param monitorMode the monitor mode
+ * @param rotation the screen rotation
+ */
+ public ScreenMode(MonitorMode monitorMode, int rotation) {
+ if ( !isRotationValid(rotation) ) {
+ throw new RuntimeException("invalid rotation: "+rotation);
+ }
+ this.monitorMode = monitorMode;
+ this.rotation = rotation;
+ }
+
+ public Object clone() {
+ try {
+ return super.clone();
+ } catch (CloneNotSupportedException ex) {
+ throw new InternalError();
+ }
+ }
+
+ public final MonitorMode getMonitorMode() {
+ return monitorMode;
+ }
+
+ public final int getRotation() {
+ return rotation;
+ }
+
+ public final String toString() {
+ return "ScreenMode[" + getMonitorMode() + ", " + rotation + " degr]";
+ }
+
+ /**
+ * Tests equality of two <code>ScreenMode</code> objects
+ * by evaluating equality of it's components:<br>
+ * <ul>
+ * <li><code>monitorMode</code></li>
+ * <li><code>rotation</code></li>
+ * </ul>
+ * <br>
+ */
+ public final boolean equals(Object obj) {
+ if (obj instanceof ScreenMode) {
+ ScreenMode sm = (ScreenMode)obj;
+ return sm.getMonitorMode().equals(getMonitorMode()) &&
+ sm.getRotation() == this.getRotation() ;
+ }
+ return false;
+ }
+
+ /**
+ * Returns a combined hash code of it's elements:<br>
+ * <ul>
+ * <li><code>monitorMode</code></li>
+ * <li><code>rotation</code></li>
+ * </ul>
+ */
+ public final int hashCode() {
+ // 31 * x == (x << 5) - x
+ int hash = 31 + getMonitorMode().hashCode();
+ hash = ((hash << 5) - hash) + getRotation();
+ return hash;
+ }
}
diff --git a/src/newt/classes/com/jogamp/newt/Window.java b/src/newt/classes/com/jogamp/newt/Window.java
index 7e1a55b21..1be5949fe 100644
--- a/src/newt/classes/com/jogamp/newt/Window.java
+++ b/src/newt/classes/com/jogamp/newt/Window.java
@@ -31,6 +31,7 @@ package com.jogamp.newt;
import com.jogamp.newt.event.WindowListener;
import com.jogamp.newt.event.KeyListener;
import com.jogamp.newt.event.MouseListener;
+import com.jogamp.newt.event.ScreenModeListener;
import com.jogamp.newt.impl.Debug;
import javax.media.nativewindow.Capabilities;
import javax.media.nativewindow.NativeWindow;
@@ -42,7 +43,7 @@ import javax.media.nativewindow.util.Point;
* Specifying the public Window functionality for the
* using a Window and for shadowing one like {@link com.jogamp.newt.opengl.GLWindow}.
*/
-public interface Window extends NativeWindow {
+public interface Window extends NativeWindow, ScreenModeListener {
public static final boolean DEBUG_MOUSE_EVENT = Debug.debug("Window.MouseEvent");
public static final boolean DEBUG_KEY_EVENT = Debug.debug("Window.KeyEvent");
public static final boolean DEBUG_WINDOW_EVENT = Debug.debug("Window.WindowEvent");
diff --git a/src/newt/classes/com/jogamp/newt/event/ScreenModeListener.java b/src/newt/classes/com/jogamp/newt/event/ScreenModeListener.java
new file mode 100644
index 000000000..7bca23cfe
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/event/ScreenModeListener.java
@@ -0,0 +1,39 @@
+/**
+ * Copyright 2010 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package com.jogamp.newt.event;
+
+import com.jogamp.newt.ScreenMode;
+
+public interface ScreenModeListener {
+ /** called before the screen mode will be changed */
+ void screenModeChangeNotify(ScreenMode sm);
+
+ /** called after the screen mode has been changed */
+ void screenModeChanged(ScreenMode sm, boolean success);
+}
diff --git a/src/newt/classes/com/jogamp/newt/impl/DefaultEDTUtil.java b/src/newt/classes/com/jogamp/newt/impl/DefaultEDTUtil.java
index ce204cd25..0fdfd44fe 100644
--- a/src/newt/classes/com/jogamp/newt/impl/DefaultEDTUtil.java
+++ b/src/newt/classes/com/jogamp/newt/impl/DefaultEDTUtil.java
@@ -64,8 +64,10 @@ public class DefaultEDTUtil implements EDTUtil {
waitUntilStopped();
if(DEBUG) {
if(edt.tasks.size()>0) {
- Throwable t = new Throwable("Warning: EDT reset, remaining tasks: "+edt.tasks.size()+" - "+edt);
- t.printStackTrace();
+ String msg = Thread.currentThread()+": EDT reset, remaining tasks: "+edt.tasks.size()+" - "+edt;
+ System.err.println(msg);
+ // Throwable t = new Throwable(msg);
+ // t.printStackTrace();
}
System.err.println(Thread.currentThread()+": EDT reset - edt: "+edt);
}
@@ -75,7 +77,7 @@ public class DefaultEDTUtil implements EDTUtil {
public final void start() {
synchronized(edtLock) {
- if(!edt.isRunning()) {
+ if(!edt.isRunning() && !edt.shouldStop) {
if(edt.isAlive()) {
throw new RuntimeException("EDT Thread.isAlive(): true, isRunning: "+edt.isRunning()+", edt: "+edt+", tasks: "+edt.tasks.size());
}
@@ -83,7 +85,10 @@ public class DefaultEDTUtil implements EDTUtil {
edt.setName(name+start_iter);
edt.shouldStop = false;
if(DEBUG) {
- System.err.println(Thread.currentThread()+": EDT START - edt: "+edt);
+ String msg = Thread.currentThread()+": EDT START - edt: "+edt;
+ System.err.println(msg);
+ // Throwable t = new Throwable(msg);
+ // t.printStackTrace();
}
edt.start();
}
@@ -128,8 +133,10 @@ public class DefaultEDTUtil implements EDTUtil {
if(stop) {
edt.shouldStop = true;
if(DEBUG) {
- System.err.println(Thread.currentThread()+
- ": EDT signal STOP (on edt: "+isCurrentThreadEDT()+") - edt: "+edt);
+ String msg = Thread.currentThread()+": EDT signal STOP (on edt: "+isCurrentThreadEDT()+") - edt: "+edt;
+ System.err.println(msg);
+ // Throwable t = new Throwable(msg);
+ // t.printStackTrace();
}
}
if( isCurrentThreadEDT() ) {
@@ -140,14 +147,15 @@ public class DefaultEDTUtil implements EDTUtil {
t.printStackTrace();
}
} else {
- start(); // start if not started yet
- rTask = new RunnableTask(task,
- wait ? rTaskLock : null,
- wait /* catch Exceptions if waiting for result */);
- if(stop) {
- rTask.setAttachment(new Boolean(true)); // mark final task
- }
synchronized(edt.tasks) {
+ start(); // start if not started yet and !shouldStop
+ wait = wait && edt.isRunning();
+ rTask = new RunnableTask(task,
+ wait ? rTaskLock : null,
+ wait /* catch Exceptions if waiting for result */);
+ if(stop) {
+ rTask.setAttachment(new Boolean(true)); // mark final task
+ }
// append task ..
edt.tasks.add(rTask);
edt.tasks.notifyAll();
@@ -178,6 +186,7 @@ public class DefaultEDTUtil implements EDTUtil {
synchronized(edt.tasks) {
while(edt.isRunning() && edt.tasks.size()>0) {
try {
+ edt.tasks.notifyAll();
edt.tasks.wait();
} catch (InterruptedException e) {
e.printStackTrace();
@@ -190,11 +199,13 @@ public class DefaultEDTUtil implements EDTUtil {
public void waitUntilStopped() {
if(edt.isRunning() && edt != Thread.currentThread() ) {
synchronized(edtLock) {
- while(edt.isRunning()) {
- try {
- edtLock.wait();
- } catch (InterruptedException e) {
- e.printStackTrace();
+ if(edt.isRunning() && edt != Thread.currentThread() ) {
+ while(edt.isRunning()) {
+ try {
+ edtLock.wait();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
}
}
}
diff --git a/src/newt/classes/com/jogamp/newt/impl/DisplayImpl.java b/src/newt/classes/com/jogamp/newt/impl/DisplayImpl.java
index 840411984..30b3cc409 100644
--- a/src/newt/classes/com/jogamp/newt/impl/DisplayImpl.java
+++ b/src/newt/classes/com/jogamp/newt/impl/DisplayImpl.java
@@ -81,7 +81,7 @@ public abstract class DisplayImpl extends Display {
display.refCount=0;
synchronized(displayList) {
display.id = serialno++;
- display.fqname = getFQName(display.id, display.type, display.name);
+ display.fqname = getFQName(display.type, display.name, display.id);
displayList.add(display);
}
display.createEDTUtil();
@@ -191,7 +191,7 @@ public abstract class DisplayImpl extends Display {
}
}
- protected synchronized final int addReference() {
+ public synchronized final int addReference() {
if(DEBUG) {
System.err.println("Display.addReference() ("+DisplayImpl.getThreadName()+"): "+refCount+" -> "+(refCount+1));
}
@@ -205,7 +205,7 @@ public abstract class DisplayImpl extends Display {
}
- protected synchronized final int removeReference() {
+ public synchronized final int removeReference() {
if(DEBUG) {
System.err.println("Display.removeReference() ("+DisplayImpl.getThreadName()+"): "+refCount+" -> "+(refCount-1));
}
@@ -251,7 +251,7 @@ public abstract class DisplayImpl extends Display {
return ( null == name ) ? nilString : name ;
}
- public static final String getFQName(int id, String type, String name) {
+ protected static final String getFQName(String type, String name, int id) {
if(null==type) type=nilString;
if(null==name) name=nilString;
StringBuffer sb = new StringBuffer();
diff --git a/src/newt/classes/com/jogamp/newt/impl/ScreenImpl.java b/src/newt/classes/com/jogamp/newt/impl/ScreenImpl.java
index 37a751fe1..9dc1c1bcc 100644
--- a/src/newt/classes/com/jogamp/newt/impl/ScreenImpl.java
+++ b/src/newt/classes/com/jogamp/newt/impl/ScreenImpl.java
@@ -34,259 +34,429 @@
package com.jogamp.newt.impl;
+import com.jogamp.common.util.ArrayHashSet;
+import com.jogamp.common.util.IntIntHashMap;
+import com.jogamp.newt.Display;
+import com.jogamp.newt.NewtFactory;
+import com.jogamp.newt.Screen;
import com.jogamp.newt.ScreenMode;
-import com.jogamp.newt.*;
+import com.jogamp.newt.Window;
+import com.jogamp.newt.event.ScreenModeListener;
+import com.jogamp.newt.util.ScreenModeUtil;
import javax.media.nativewindow.*;
import java.security.*;
-
-public abstract class ScreenImpl implements Screen {
- protected DisplayImpl display;
- protected int idx;
- protected AbstractGraphicsScreen aScreen;
- protected int refCount; // number of Screen references by Window
- protected int width=-1, height=-1; // detected values: set using setScreenSize
- protected static int usrWidth=-1, usrHeight=-1; // property values: newt.ws.swidth and newt.ws.sheight
- private static AccessControlContext localACC = AccessController.getContext();
-
-
- protected static ScreensModeState screensModeState = new ScreensModeState(); // hold all screen mode controllers
- private String screenFQN = null; // string fully qualified name
-
- private static Class getScreenClass(String type)
- throws ClassNotFoundException
- {
- Class screenClass = NewtFactory.getCustomClass(type, "Screen");
- if(null==screenClass) {
- if (NativeWindowFactory.TYPE_EGL.equals(type)) {
- screenClass = Class.forName("com.jogamp.newt.impl.opengl.kd.KDScreen");
- } else if (NativeWindowFactory.TYPE_WINDOWS.equals(type)) {
- screenClass = Class.forName("com.jogamp.newt.impl.windows.WindowsScreen");
- } else if (NativeWindowFactory.TYPE_MACOSX.equals(type)) {
- screenClass = Class.forName("com.jogamp.newt.impl.macosx.MacScreen");
- } else if (NativeWindowFactory.TYPE_X11.equals(type)) {
- screenClass = Class.forName("com.jogamp.newt.impl.x11.X11Screen");
- } else if (NativeWindowFactory.TYPE_AWT.equals(type)) {
- screenClass = Class.forName("com.jogamp.newt.impl.awt.AWTScreen");
- } else {
- throw new RuntimeException("Unknown window type \"" + type + "\"");
- }
- }
- return screenClass;
- }
-
- public static ScreenImpl create(String type, Display display, final int idx) {
- try {
- if(usrWidth<0 || usrHeight<0) {
- usrWidth = Debug.getIntProperty("newt.ws.swidth", true, localACC);
- usrHeight = Debug.getIntProperty("newt.ws.sheight", true, localACC);
- if(usrWidth>0 || usrHeight>0) {
- System.err.println("User screen size "+usrWidth+"x"+usrHeight);
- }
- }
- Class screenClass = getScreenClass(type);
- ScreenImpl screen = (ScreenImpl) screenClass.newInstance();
- screen.display = (DisplayImpl) display;
- screen.idx = idx;
-
- return screen;
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
-
- protected synchronized final void createNative() {
- if(null == aScreen) {
- if(DEBUG) {
- System.err.println("Screen.createNative() START ("+DisplayImpl.getThreadName()+", "+this+")");
- }
- display.addReference();
- createNativeImpl();
- if(null == aScreen) {
- throw new RuntimeException("Screen.createNative() failed to instanciate an AbstractGraphicsScreen");
- }
- if(DEBUG) {
- System.err.println("Screen.createNative() END ("+DisplayImpl.getThreadName()+", "+this+")");
- }
- }
-
- initScreenModes();
- }
-
- /** Retrieve screen modes
- * and screen rate initializing the status
- * of the screen mode
- */
- private void initScreenModes(){
- ScreenMode[] screenModes = getScreenModes();
- String screenFQN = display.getFQName()+idx;
- setScreenFQN(screenFQN);
- ScreenModeStatus screenModeStatus = new ScreenModeStatus(screenFQN ,
- getDesktopScreenModeIndex(), getCurrentScreenRate(),getCurrentScreenRotation());
- screenModeStatus.setScreenModes(screenModes);
-
- screensModeState.setScreenModeController(screenModeStatus);
- }
-
- private void resetScreenMode() {
- ScreenModeStatus sms = screensModeState.getScreenModeController(getScreenFQN());
-
- /**Revert the screen mode and rate
- * to original state of creation
- */
- if(!sms.isOriginalMode()) {
- setScreenMode(sms.getOriginalScreenMode(),
- sms.getOriginalScreenRate());
- }
- /**Revert Screen Rotation
- * to original value
- */
- if(!sms.isOriginalRotation()) {
- setScreenRotation(sms.getOriginalScreenRotation());
- }
- }
-
- public synchronized final void destroy() {
- resetScreenMode();
-
- if ( null != aScreen ) {
- closeNativeImpl();
- aScreen = null;
- }
- refCount = 0;
- display.removeReference();
- }
-
- protected synchronized final int addReference() {
- if(DEBUG) {
- System.err.println("Screen.addReference() ("+DisplayImpl.getThreadName()+"): "+refCount+" -> "+(refCount+1));
- }
- if ( 0 == refCount ) {
- createNative();
- }
- if(null == aScreen) {
- throw new RuntimeException("Screen.addReference() (refCount "+refCount+") null AbstractGraphicsScreen");
- }
- return ++refCount;
- }
-
- protected synchronized final int removeReference() {
- if(DEBUG) {
- System.err.println("Screen.removeReference() ("+DisplayImpl.getThreadName()+"): "+refCount+" -> "+(refCount-1));
- }
- refCount--; // could become < 0, in case of forced destruction without actual creation/addReference
- if(0>=refCount && getDestroyWhenUnused()) {
- destroy();
- }
- return refCount;
- }
-
- public synchronized final int getReferenceCount() {
- return refCount;
- }
-
- public final boolean getDestroyWhenUnused() {
- return display.getDestroyWhenUnused();
- }
- public final void setDestroyWhenUnused(boolean v) {
- display.setDestroyWhenUnused(v);
- }
-
- protected abstract void createNativeImpl();
- protected abstract void closeNativeImpl();
-
- public int getDesktopScreenModeIndex() {
- ScreenModeStatus sms = screensModeState.getScreenModeController(getScreenFQN());
- if(sms != null){
- return sms.getCurrentScreenMode();
- }
- return -1;
- }
-
- /**
- * Get list of available screen modes
- * null if not implemented for screen platform
- */
- public ScreenMode[] getScreenModes(){
- ScreenModeStatus sms = screensModeState.getScreenModeController(getScreenFQN());
- if(sms != null) {
- return sms.getScreenModes();
- }
- return null;
- }
-
- public void setScreenMode(int modeIndex, short rate) {
- }
-
- public short getCurrentScreenRate() {
- ScreenModeStatus sms = screensModeState.getScreenModeController(getScreenFQN());
- if(sms != null){
- return sms.getCurrentScreenRate();
- }
- return -1;
- }
-
-
- public void setScreenRotation(int rot) {
-
- }
-
- public int getCurrentScreenRotation() {
- ScreenModeStatus sms = screensModeState.getScreenModeController(getScreenFQN());
- if(sms != null) {
- return sms.getCurrentScreenRotation();
- }
- return -1;
- }
-
- /** get the screens mode state handler
- * which contain the screen mode controller of each screen
- * @return the ScreensModeState static object
- */
- protected ScreensModeState getScreensModeState() {
- return screensModeState;
- }
-
- public String getScreenFQN() {
- return screenFQN;
- }
-
- private void setScreenFQN(String screenFQN) {
- this.screenFQN = screenFQN;
- }
-
- protected void setScreenSize(int w, int h) {
- System.err.println("Detected screen size "+w+"x"+h);
- width=w; height=h;
- }
-
- public final Display getDisplay() {
- return display;
- }
-
- public final int getIndex() {
- return idx;
- }
-
- public final AbstractGraphicsScreen getGraphicsScreen() {
- return aScreen;
- }
-
- public final boolean isNativeValid() {
- return null != aScreen;
- }
-
- public final int getWidth() {
- return (usrWidth>0) ? usrWidth : (width>0) ? width : 480;
- }
-
- public final int getHeight() {
- return (usrHeight>0) ? usrHeight : (height>0) ? height : 480;
- }
-
- public String toString() {
- return "NEWT-Screen[idx "+idx+", refCount "+refCount+", "+getWidth()+"x"+getHeight()+", "+aScreen+", "+display+"]";
- }
+import java.util.ArrayList;
+import java.util.List;
+
+public abstract class ScreenImpl implements Screen, ScreenModeListener {
+ protected DisplayImpl display;
+ protected int screen_idx;
+ protected String fqname;
+ protected AbstractGraphicsScreen aScreen;
+ protected int refCount; // number of Screen references by Window
+ protected int width=-1, height=-1; // detected values: set using setScreenSize
+ protected static int usrWidth=-1, usrHeight=-1; // property values: newt.ws.swidth and newt.ws.sheight
+ private static AccessControlContext localACC = AccessController.getContext();
+ private List/*<ScreenModeListener>*/ referencedScreenModeListener = new ArrayList();
+ long t0; // creationTime
+
+ private static Class getScreenClass(String type)
+ throws ClassNotFoundException
+ {
+ Class screenClass = NewtFactory.getCustomClass(type, "Screen");
+ if(null==screenClass) {
+ if (NativeWindowFactory.TYPE_EGL.equals(type)) {
+ screenClass = Class.forName("com.jogamp.newt.impl.opengl.kd.KDScreen");
+ } else if (NativeWindowFactory.TYPE_WINDOWS.equals(type)) {
+ screenClass = Class.forName("com.jogamp.newt.impl.windows.WindowsScreen");
+ } else if (NativeWindowFactory.TYPE_MACOSX.equals(type)) {
+ screenClass = Class.forName("com.jogamp.newt.impl.macosx.MacScreen");
+ } else if (NativeWindowFactory.TYPE_X11.equals(type)) {
+ screenClass = Class.forName("com.jogamp.newt.impl.x11.X11Screen");
+ } else if (NativeWindowFactory.TYPE_AWT.equals(type)) {
+ screenClass = Class.forName("com.jogamp.newt.impl.awt.AWTScreen");
+ } else {
+ throw new RuntimeException("Unknown window type \"" + type + "\"");
+ }
+ }
+ return screenClass;
+ }
+
+ public static ScreenImpl create(String type, Display display, final int idx) {
+ try {
+ if(usrWidth<0 || usrHeight<0) {
+ usrWidth = Debug.getIntProperty("newt.ws.swidth", true, localACC);
+ usrHeight = Debug.getIntProperty("newt.ws.sheight", true, localACC);
+ if(usrWidth>0 || usrHeight>0) {
+ System.err.println("User screen size "+usrWidth+"x"+usrHeight);
+ }
+ }
+ Class screenClass = getScreenClass(type);
+ ScreenImpl screen = (ScreenImpl) screenClass.newInstance();
+ screen.display = (DisplayImpl) display;
+ screen.screen_idx = idx;
+ screen.fqname = display.getFQName()+idx;
+ return screen;
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ protected synchronized final void createNative() {
+ if(null == aScreen) {
+ if(DEBUG) {
+ System.err.println("Screen.createNative() START ("+DisplayImpl.getThreadName()+", "+this+")");
+ }
+ t0 = System.currentTimeMillis();
+ display.addReference();
+ createNativeImpl();
+ if(null == aScreen) {
+ throw new RuntimeException("Screen.createNative() failed to instanciate an AbstractGraphicsScreen");
+ }
+ if(DEBUG) {
+ System.err.println("Screen.createNative() END ("+DisplayImpl.getThreadName()+", "+this+")");
+ }
+ }
+ initScreenModeStatus();
+ }
+
+ public synchronized final void destroy() {
+ releaseScreenModeStatus();
+
+ if ( null != aScreen ) {
+ closeNativeImpl();
+ aScreen = null;
+ }
+ refCount = 0;
+ display.removeReference();
+ }
+
+ public synchronized final int addReference() {
+ if(DEBUG) {
+ System.err.println("Screen.addReference() ("+DisplayImpl.getThreadName()+"): "+refCount+" -> "+(refCount+1));
+ }
+ if ( 0 == refCount ) {
+ createNative();
+ }
+ if(null == aScreen) {
+ throw new RuntimeException("Screen.addReference() (refCount "+refCount+") null AbstractGraphicsScreen");
+ }
+ return ++refCount;
+ }
+
+ public synchronized final int removeReference() {
+ if(DEBUG) {
+ System.err.println("Screen.removeReference() ("+DisplayImpl.getThreadName()+"): "+refCount+" -> "+(refCount-1));
+ }
+ refCount--; // could become < 0, in case of forced destruction without actual creation/addReference
+ if(0>=refCount && getDestroyWhenUnused()) {
+ destroy();
+ }
+ return refCount;
+ }
+
+ public synchronized final int getReferenceCount() {
+ return refCount;
+ }
+
+ public final boolean getDestroyWhenUnused() {
+ return display.getDestroyWhenUnused();
+ }
+ public final void setDestroyWhenUnused(boolean v) {
+ display.setDestroyWhenUnused(v);
+ }
+
+ protected abstract void createNativeImpl();
+ protected abstract void closeNativeImpl();
+
+ public final String getFQName() {
+ return fqname;
+ }
+
+ protected void setScreenSize(int w, int h) {
+ System.err.println("Detected screen size "+w+"x"+h);
+ width=w; height=h;
+ }
+
+ public final Display getDisplay() {
+ return display;
+ }
+
+ public final int getIndex() {
+ return screen_idx;
+ }
+
+ public final AbstractGraphicsScreen getGraphicsScreen() {
+ return aScreen;
+ }
+
+ public final boolean isNativeValid() {
+ return null != aScreen;
+ }
+
+ public final int getWidth() {
+ return (usrWidth>0) ? usrWidth : (width>0) ? width : 480;
+ }
+
+ public final int getHeight() {
+ return (usrHeight>0) ? usrHeight : (height>0) ? height : 480;
+ }
+
+ public String toString() {
+ return "NEWT-Screen["+getFQName()+", idx "+screen_idx+", refCount "+refCount+", "+getWidth()+"x"+getHeight()+", "+aScreen+", "+display+"]";
+ }
+
+ public final List/*<ScreenMode>*/ getScreenModes() {
+ ArrayHashSet screenModes = getScreenModesOrig();
+ if(null != screenModes) {
+ return screenModes.toArrayList();
+ }
+ return null;
+ }
+
+ public ScreenMode getOriginalScreenMode() {
+ ScreenModeStatus sms = ScreenModeStatus.getScreenModeStatus(this.getFQName());
+ return ( null != sms ) ? sms.getOriginalScreenMode() : null ;
+ }
+
+ public ScreenMode getCurrentScreenMode() {
+ ScreenMode smU = null;
+ ScreenModeStatus sms = ScreenModeStatus.getScreenModeStatus(this.getFQName());
+ if(null != sms) {
+ ScreenMode sm0 = getCurrentScreenModeImpl();
+ if(null == sm0) {
+ return null;
+ }
+ sms.lock();
+ try {
+ smU = (ScreenMode) sms.getScreenModes().get(sm0); // unify via value hash
+ if(null == smU) {
+ throw new RuntimeException(sm0+" could not be hashed from ScreenMode list");
+ }
+
+ // if mode has changed somehow, update it ..
+ if( sms.getCurrentScreenMode().hashCode() != smU.hashCode() ) {
+ sms.fireScreenModeChanged(smU, true);
+ }
+ } finally {
+ sms.unlock();
+ }
+ }
+ return smU;
+ }
+
+ public boolean setCurrentScreenMode(ScreenMode screenMode) {
+ ScreenMode smU = (ScreenMode) getScreenModesOrig().get(screenMode); // unify via value hash
+ ScreenModeStatus sms = ScreenModeStatus.getScreenModeStatus(this.getFQName());
+ if(null!=sms) {
+ sms.lock();
+ try {
+ if(DEBUG) {
+ System.err.println("Screen.setCurrentScreenMode ("+(System.currentTimeMillis()-t0)+"): 0.0 "+screenMode);
+ }
+
+ sms.fireScreenModeChangeNotify(smU);
+
+ if(DEBUG) {
+ System.err.println("Screen.setCurrentScreenMode ("+(System.currentTimeMillis()-t0)+"): 0.1 "+screenMode);
+ }
+
+ boolean success = setCurrentScreenModeImpl(smU);
+ if(success) {
+ setScreenSize(screenMode.getMonitorMode().getSurfaceSize().getResolution().getWidth(),
+ screenMode.getMonitorMode().getSurfaceSize().getResolution().getHeight());
+ }
+
+ if(DEBUG) {
+ System.err.println("Screen.setCurrentScreenMode ("+(System.currentTimeMillis()-t0)+"): X.0 "+screenMode+", success: "+success);
+ }
+
+ sms.fireScreenModeChanged(smU, success);
+
+ if(DEBUG) {
+ System.err.println("Screen.setCurrentScreenMode ("+(System.currentTimeMillis()-t0)+"): X.X "+screenMode+", success: "+success);
+ }
+
+ return success;
+ } finally {
+ sms.unlock();
+ }
+ }
+ return false;
+ }
+
+ public void screenModeChangeNotify(ScreenMode sm) {
+ for(int i=0; i<referencedScreenModeListener.size(); i++) {
+ ((ScreenModeListener)referencedScreenModeListener.get(i)).screenModeChangeNotify(sm);
+ }
+ }
+
+ public void screenModeChanged(ScreenMode sm, boolean success) {
+ for(int i=0; i<referencedScreenModeListener.size(); i++) {
+ ((ScreenModeListener)referencedScreenModeListener.get(i)).screenModeChanged(sm, success);
+ }
+ }
+
+ public synchronized final void addScreenModeListener(ScreenModeListener sml) {
+ referencedScreenModeListener.add(sml);
+ }
+
+ public synchronized final void removeScreenModeListener(ScreenModeListener sml) {
+ referencedScreenModeListener.remove(sml);
+ }
+
+ /** ScreenModeStatus bridge to native implementation */
+ protected final ArrayHashSet getScreenModesOrig() {
+ ScreenModeStatus sms = ScreenModeStatus.getScreenModeStatus(this.getFQName());
+ if(null!=sms) {
+ return sms.getScreenModes();
+ }
+ return null;
+ }
+
+ /** ScreenModeStatus bridge to native implementation */
+ protected final IntIntHashMap getScreenModesIdx2NativeIdx() {
+ ScreenModeStatus sms = ScreenModeStatus.getScreenModeStatus(this.getFQName());
+ if(null!=sms) {
+ return sms.getScreenModesIdx2NativeIdx();
+ }
+ return null;
+ }
+
+ /**
+ * To be implemented by the native specification.<br>
+ * Is called within a thread safe environment.<br>
+ * Is called only to collect the ScreenModes, usually at startup setting up modes.<br>
+ * <br>
+ * <b>WARNING</b>: must be synchronized with {@link com.jogamp.newt.util.ScreenModeUtil#NUM_SCREEN_MODE_PROPERTIES},
+ * ie {@link com.jogamp.newt.util.ScreenModeUtil#streamIn(com.jogamp.common.util.ArrayHashSet, com.jogamp.common.util.ArrayHashSet, com.jogamp.common.util.ArrayHashSet, com.jogamp.common.util.ArrayHashSet, int[], int)}<br>
+ * <br>
+ * <b>Note</b>: Additional 1st element is native mode id.
+ */
+ protected int[] getScreenModeFirstImpl() {
+ return null;
+ }
+
+ /**
+ * To be implemented by the native specification.<br>
+ * Is called within a thread safe environment.<br>
+ * Is called only to collect the ScreenModes, usually at startup setting up modes.<br>
+ * <br>
+ * <b>WARNING</b>: must be synchronized with {@link com.jogamp.newt.util.ScreenModeUtil#NUM_SCREEN_MODE_PROPERTIES},
+ * ie {@link com.jogamp.newt.util.ScreenModeUtil#streamIn(com.jogamp.common.util.ArrayHashSet, com.jogamp.common.util.ArrayHashSet, com.jogamp.common.util.ArrayHashSet, com.jogamp.common.util.ArrayHashSet, int[], int)}<br>
+ * <br>
+ * <b>Note</b>: Additional 1st element is native mode id.
+ */
+ protected int[] getScreenModeNextImpl() {
+ return null;
+ }
+
+ /**
+ * To be implemented by the native specification.<br>
+ * Is called within a thread safe environment.<br>
+ * Is called only to collect the ScreenModes, usually at startup setting up modes.<br>
+ */
+ protected ScreenMode getCurrentScreenModeImpl() {
+ return null;
+ }
+
+ /**
+ * To be implemented by the native specification.<br>
+ * Is called within a thread safe environment.<br>
+ */
+ protected boolean setCurrentScreenModeImpl(ScreenMode screenMode) {
+ return false;
+ }
+
+ private void initScreenModeStatus() {
+ ScreenModeStatus sms;
+ ScreenModeStatus.lockScreenModeStatus();
+ try {
+ sms = ScreenModeStatus.getScreenModeStatus(this.getFQName());
+ if(null==sms) {
+ IntIntHashMap screenModesIdx2NativeIdx = new IntIntHashMap();
+
+ ArrayHashSet screenModes = collectNativeScreenModes(screenModesIdx2NativeIdx);
+ sms = new ScreenModeStatus(screenModes, screenModesIdx2NativeIdx);
+ if(null!=screenModes && screenModes.size()>0) {
+ ScreenMode originalScreenMode = getCurrentScreenModeImpl();
+ if(null == originalScreenMode) {
+ throw new RuntimeException("Couldn't fetch current ScreenMode (null), but ScreenMode list size is: "+screenModes.size());
+ }
+ sms.setOriginalScreenMode(originalScreenMode);
+ }
+ ScreenModeStatus.mapScreenModeStatus(this.getFQName(), sms);
+ }
+ sms.addListener(this);
+ } finally {
+ ScreenModeStatus.unlockScreenModeStatus();
+ }
+ }
+
+ private ArrayHashSet collectNativeScreenModes(IntIntHashMap screenModesIdx2NativeId) {
+ ArrayHashSet resolutionPool = new ArrayHashSet();
+ ArrayHashSet surfaceSizePool = new ArrayHashSet();
+ ArrayHashSet screenSizeMMPool = new ArrayHashSet();
+ ArrayHashSet monitorModePool = new ArrayHashSet();
+ ArrayHashSet screenModePool = null;
+
+ screenModePool = new ArrayHashSet();
+
+ int[] smProps = null;
+ int num = 0;
+ do {
+ if(0 == num) {
+ smProps = getScreenModeFirstImpl();
+ } else {
+ smProps = getScreenModeNextImpl();
+ }
+ if(null != smProps) {
+ int nativeId = smProps[0];
+ int screenModeIdx = ScreenModeUtil.streamIn(resolutionPool, surfaceSizePool, screenSizeMMPool,
+ monitorModePool, screenModePool, smProps, 1);
+ if(screenModeIdx >= 0) {
+ screenModesIdx2NativeId.put(screenModeIdx, nativeId);
+ }
+ }
+ num++;
+ } while ( null != smProps );
+
+ ScreenModeUtil.validate(screenModePool, true);
+
+ if(DEBUG) {
+ System.err.println("ScreenImpl.collectNativeScreenModes: ScreenMode number : "+screenModePool.size());
+ System.err.println("ScreenImpl.collectNativeScreenModes: MonitorMode number : "+monitorModePool.size());
+ System.err.println("ScreenImpl.collectNativeScreenModes: ScreenSizeMM number: "+screenSizeMMPool.size());
+ System.err.println("ScreenImpl.collectNativeScreenModes: SurfaceSize number : "+surfaceSizePool.size());
+ System.err.println("ScreenImpl.collectNativeScreenModes: Resolution number : "+resolutionPool.size());
+ }
+
+ return screenModePool;
+ }
+
+ private void releaseScreenModeStatus() {
+ ScreenModeStatus sms;
+ ScreenModeStatus.lockScreenModeStatus();
+ try {
+ sms = ScreenModeStatus.getScreenModeStatus(this.getFQName());
+ if(null != sms) {
+ sms.lock();
+ try {
+ if(0 == sms.removeListener(this)) {
+ if(!sms.isOriginalMode()) {
+ setCurrentScreenMode(sms.getOriginalScreenMode());
+ }
+ ScreenModeStatus.unmapScreenModeStatus(this.getFQName());
+ }
+ } finally {
+ sms.unlock();
+ }
+ }
+ } finally {
+ ScreenModeStatus.unlockScreenModeStatus();
+ }
+ }
}
diff --git a/src/newt/classes/com/jogamp/newt/impl/ScreenModeStatus.java b/src/newt/classes/com/jogamp/newt/impl/ScreenModeStatus.java
index 94d3eb4e6..3ca9b638b 100644
--- a/src/newt/classes/com/jogamp/newt/impl/ScreenModeStatus.java
+++ b/src/newt/classes/com/jogamp/newt/impl/ScreenModeStatus.java
@@ -1,91 +1,207 @@
+/**
+ * Copyright 2010 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
package com.jogamp.newt.impl;
+import com.jogamp.common.util.ArrayHashSet;
+import com.jogamp.common.util.IntIntHashMap;
+import com.jogamp.common.util.locks.RecursiveLock;
+import com.jogamp.newt.Screen;
import com.jogamp.newt.ScreenMode;
+import com.jogamp.newt.event.ScreenModeListener;
+import java.util.ArrayList;
+import java.util.HashMap;
public class ScreenModeStatus {
- private String screenFQN = null;
- private ScreenMode[] screenModes = null;
-
- private int currentScreenMode = -1;
- private short currentScreenRate = -1;
- private int currentScreenRotation = -1;
-
- private int originalScreenMode = -1;
- private short originalScreenRate = -1;
- private int originalScreenRotation = -1;
-
- public ScreenModeStatus(String screenFQN, int originalScreenMode,
- short originalScreenRate, int originalScreenRotation) {
- this.screenFQN = screenFQN;
- this.originalScreenMode = originalScreenMode;
- this.originalScreenRate = originalScreenRate;
- this.originalScreenRotation = originalScreenRotation;
-
- this.currentScreenMode = originalScreenMode;
- this.currentScreenRate = originalScreenRate;
- this.currentScreenRotation = originalScreenRotation;
- }
-
- public void setCurrentScreenRotation(int currentScreenRotation) {
- this.currentScreenRotation = currentScreenRotation;
- }
-
- public int getCurrentScreenRotation() {
- return currentScreenRotation;
- }
-
- public int getOriginalScreenRotation() {
- return originalScreenRotation;
- }
-
- public int getCurrentScreenMode() {
- return currentScreenMode;
- }
-
- public void setCurrentScreenMode(int currentScreenMode) {
- this.currentScreenMode = currentScreenMode;
- }
-
- public short getCurrentScreenRate() {
- return currentScreenRate;
- }
-
- public void setCurrentScreenRate(short currentRate) {
- this.currentScreenRate = currentRate;
- }
-
- public String getScreenFQN() {
- return screenFQN;
- }
-
- public void setScreenFQN(String screenFQN) {
- this.screenFQN = screenFQN;
- }
-
- public ScreenMode[] getScreenModes() {
- return screenModes;
- }
-
- public void setScreenModes(ScreenMode[] screenModes) {
- this.screenModes = screenModes;
- }
- public boolean isOriginalMode(){
- if(currentScreenMode == originalScreenMode
- && currentScreenRate == originalScreenRate)
- return true;
- return false;
- }
- public boolean isOriginalRotation(){
- if(currentScreenRotation == originalScreenRotation)
- return true;
- return false;
- }
-
- public int getOriginalScreenMode() {
- return originalScreenMode;
- }
-
- public short getOriginalScreenRate() {
- return originalScreenRate;
- }
+ private static boolean DEBUG = Screen.DEBUG;
+
+ private RecursiveLock lock = new RecursiveLock();
+ private ArrayHashSet/*<ScreenMode>*/ screenModes;
+ private IntIntHashMap screenModesIdx2NativeIdx;
+ private ScreenMode currentScreenMode;
+ private ScreenMode originalScreenMode;
+ private ArrayList/*<ScreenModeChangeListener>*/ listener = new ArrayList();
+
+ private static HashMap screenFQN2ScreenModeStatus = new HashMap();
+ private static RecursiveLock screen2ScreenModeStatusLock = new RecursiveLock();
+
+ protected static void mapScreenModeStatus(String screenFQN, ScreenModeStatus sms) {
+ screen2ScreenModeStatusLock.lock();
+ try {
+ ScreenModeStatus _sms = (ScreenModeStatus) screenFQN2ScreenModeStatus.get(screenFQN);
+ if( null != _sms ) {
+ throw new RuntimeException("ScreenModeStatus "+_sms+" already mapped to "+screenFQN);
+ }
+ screenFQN2ScreenModeStatus.put(screenFQN, sms);
+ if(DEBUG) {
+ System.err.println("ScreenModeStatus.map "+screenFQN+" -> "+sms);
+ }
+ } finally {
+ screen2ScreenModeStatusLock.unlock();
+ }
+ }
+
+ /**
+ * @param screen the prev user
+ * @return true if mapping is empty, ie no more usage of the mapped ScreenModeStatus
+ */
+ protected static void unmapScreenModeStatus(String screenFQN) {
+ screen2ScreenModeStatusLock.lock();
+ try {
+ ScreenModeStatus sms = (ScreenModeStatus) screenFQN2ScreenModeStatus.remove(screenFQN);
+ if(DEBUG) {
+ System.err.println("ScreenModeStatus.unmap "+screenFQN+" -> "+sms);
+ }
+ } finally {
+ screen2ScreenModeStatusLock.unlock();
+ }
+ }
+
+ protected static ScreenModeStatus getScreenModeStatus(String screenFQN) {
+ screen2ScreenModeStatusLock.lock();
+ try {
+ return (ScreenModeStatus) screenFQN2ScreenModeStatus.get(screenFQN);
+ } finally {
+ screen2ScreenModeStatusLock.unlock();
+ }
+ }
+
+ protected static void lockScreenModeStatus() {
+ screen2ScreenModeStatusLock.lock();
+ }
+
+ protected static void unlockScreenModeStatus() {
+ screen2ScreenModeStatusLock.unlock();
+ }
+
+ public ScreenModeStatus(ArrayHashSet/*<ScreenMode>*/ screenModes,
+ IntIntHashMap screenModesIdx2NativeIdx) {
+ this.screenModes = screenModes;
+ this.screenModesIdx2NativeIdx = screenModesIdx2NativeIdx;
+ }
+
+ protected final void setOriginalScreenMode(ScreenMode originalScreenMode) {
+ this.originalScreenMode = originalScreenMode;
+ this.currentScreenMode = originalScreenMode;
+ }
+
+ public final ScreenMode getOriginalScreenMode() {
+ return originalScreenMode;
+ }
+
+ public final ScreenMode getCurrentScreenMode() {
+ lock();
+ try {
+ return currentScreenMode;
+ } finally {
+ unlock();
+ }
+ }
+
+ public final boolean isOriginalMode() {
+ lock();
+ try {
+ if(null != currentScreenMode && null != originalScreenMode) {
+ return currentScreenMode.hashCode() == originalScreenMode.hashCode();
+ }
+ return true;
+ } finally {
+ unlock();
+ }
+ }
+
+ protected final ArrayHashSet/*<ScreenMode>*/ getScreenModes() {
+ return screenModes;
+ }
+
+ protected final IntIntHashMap getScreenModesIdx2NativeIdx() {
+ return screenModesIdx2NativeIdx;
+ }
+
+ protected final int addListener(ScreenModeListener l) {
+ lock();
+ try {
+ listener.add(l);
+ if(DEBUG) {
+ System.err.println("ScreenModeStatus.addListener (size: "+listener.size()+"): "+l);
+ }
+ return listener.size();
+ } finally {
+ unlock();
+ }
+ }
+
+ protected final int removeListener(ScreenModeListener l) {
+ lock();
+ try {
+ if(!listener.remove(l)) {
+ throw new RuntimeException("ScreenModeListener "+l+" not contained");
+ }
+ if(DEBUG) {
+ System.err.println("ScreenModeStatus.removeListener (size: "+listener.size()+"): "+l);
+ }
+ return listener.size();
+ } finally {
+ unlock();
+ }
+ }
+
+ protected final void fireScreenModeChangeNotify(ScreenMode desiredScreenMode) {
+ lock();
+ try {
+ for(int i=0; i<listener.size(); i++) {
+ ((ScreenModeListener)listener.get(i)).screenModeChangeNotify(desiredScreenMode);
+ }
+ } finally {
+ unlock();
+ }
+ }
+
+ protected void fireScreenModeChanged(ScreenMode currentScreenMode, boolean success) {
+ lock();
+ try {
+ if(success) {
+ this.currentScreenMode = currentScreenMode;
+ }
+ for(int i=0; i<listener.size(); i++) {
+ ((ScreenModeListener)listener.get(i)).screenModeChanged(currentScreenMode, success);
+ }
+ } finally {
+ unlock();
+ }
+ }
+
+ protected final void lock() throws RuntimeException {
+ lock.lock();
+ }
+
+ protected final void unlock() throws RuntimeException {
+ lock.unlock();
+ }
+
}
diff --git a/src/newt/classes/com/jogamp/newt/impl/ScreensModeState.java b/src/newt/classes/com/jogamp/newt/impl/ScreensModeState.java
deleted file mode 100644
index e4291496d..000000000
--- a/src/newt/classes/com/jogamp/newt/impl/ScreensModeState.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package com.jogamp.newt.impl;
-
-import java.util.HashMap;
-
-public class ScreensModeState {
- private static HashMap screenModes = new HashMap();
- private static Object lock = new Object();
-
- public ScreensModeState(){
-
- }
- public synchronized void setScreenModeController(ScreenModeStatus screenModeStatus){
- synchronized (lock) {
- screenModes.put(screenModeStatus.getScreenFQN(), screenModeStatus);
- }
- }
-
- public synchronized ScreenModeStatus getScreenModeController(String screenFQN){
- return (ScreenModeStatus) screenModes.get(screenFQN);
- }
-}
diff --git a/src/newt/classes/com/jogamp/newt/impl/WindowImpl.java b/src/newt/classes/com/jogamp/newt/impl/WindowImpl.java
index 631c1b1c0..f9383ea38 100644
--- a/src/newt/classes/com/jogamp/newt/impl/WindowImpl.java
+++ b/src/newt/classes/com/jogamp/newt/impl/WindowImpl.java
@@ -43,14 +43,16 @@ import com.jogamp.newt.event.*;
import com.jogamp.common.util.*;
import javax.media.nativewindow.*;
import com.jogamp.common.util.locks.RecursiveLock;
+import com.jogamp.newt.ScreenMode;
import java.util.ArrayList;
import java.lang.reflect.Method;
+import javax.media.nativewindow.util.DimensionReadOnly;
import javax.media.nativewindow.util.Insets;
import javax.media.nativewindow.util.Point;
import javax.media.nativewindow.util.Rectangle;
-public abstract class WindowImpl implements Window, NEWTEventConsumer
+public abstract class WindowImpl implements Window, NEWTEventConsumer, ScreenModeListener
{
public static final boolean DEBUG_TEST_REPARENT_INCOMPATIBLE = Debug.isPropertyDefined("newt.test.Window.reparent.incompatible", true);
@@ -178,9 +180,11 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
private boolean handleDestroyNotify = true;
private final void destroyScreen() {
- screenReferenced = false;
if(null!=screen) {
- screen.removeReference();
+ if(screenReferenced) {
+ screen.removeReference();
+ screenReferenced = false;
+ }
screen = null;
}
}
@@ -208,6 +212,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
createNativeImpl();
setVisibleImpl(true, x, y, width, height);
+ screen.addScreenModeListener(this);
}
} finally {
if(null!=parentWindow) {
@@ -461,11 +466,13 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
class VisibleAction implements Runnable {
boolean visible;
+ long timeOut;
boolean nativeWindowCreated;
boolean madeVisible;
- public VisibleAction (boolean visible) {
+ public VisibleAction (boolean visible, long timeOut) {
this.visible = visible;
+ this.timeOut = timeOut;
this.nativeWindowCreated = false;
this.madeVisible = false;
}
@@ -494,13 +501,13 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
if(0==windowHandle && visible) {
if( 0<width*height ) {
nativeWindowCreated = createNative();
- WindowImpl.this.waitForVisible(visible, true);
+ WindowImpl.this.waitForVisible(visible, true, timeOut);
madeVisible = visible;
}
} else if(WindowImpl.this.visible != visible) {
if(0 != windowHandle) {
setVisibleImpl(visible, x, y, width, height);
- WindowImpl.this.waitForVisible(visible, true);
+ WindowImpl.this.waitForVisible(visible, true, timeOut);
madeVisible = visible;
}
}
@@ -529,12 +536,17 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
public void setVisible(boolean visible) {
+ setVisible(visible, TIMEOUT_NATIVEWINDOW);
+
+ }
+
+ protected final void setVisible(boolean visible, long timeOut) {
if(isValid()) {
if( 0==windowHandle && visible && 0>=width*height ) {
// fast-path: not realized yet, make visible, but zero size
return;
}
- VisibleAction visibleAction = new VisibleAction(visible);
+ VisibleAction visibleAction = new VisibleAction(visible, timeOut);
runOnEDTIfAvail(true, visibleAction);
if( visibleAction.getChanged() ) {
sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); // trigger a resize/relayout and repaint to listener
@@ -647,6 +659,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
keyListeners = new ArrayList();
}
if( null != screen && 0 != windowHandle ) {
+ screen.removeScreenModeListener(WindowImpl.this);
closeNativeImpl();
}
invalidate(unrecoverable);
@@ -666,7 +679,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
System.err.println(msg);
//Exception ee = new Exception(msg);
//ee.printStackTrace();
- }
+ }
DestroyAction destroyAction = new DestroyAction(unrecoverable);
runOnEDTIfAvail(true, destroyAction);
}
@@ -932,11 +945,15 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
setVisibleImpl(true, x, y, width, height);
ok = WindowImpl.this.waitForVisible(true, false);
display.dispatchMessagesNative(); // status up2date
- if( WindowImpl.this.x != x ||
- WindowImpl.this.y != y ||
- WindowImpl.this.width != width ||
- WindowImpl.this.height != height )
+ if( ok &&
+ ( WindowImpl.this.x != x ||
+ WindowImpl.this.y != y ||
+ WindowImpl.this.width != width ||
+ WindowImpl.this.height != height ) )
{
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Window.reparent (reconfig)");
+ }
// reset pos/size .. due to some native impl flakyness
reconfigureWindowImpl(x, y, width, height, false, 0, 0);
display.dispatchMessagesNative(); // status up2date
@@ -1343,23 +1360,46 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
h = nfs_height;
}
if(DEBUG_IMPLEMENTATION || DEBUG_WINDOW_EVENT) {
- System.err.println("X11Window fs: "+fullscreen+" "+x+"/"+y+" "+w+"x"+h+", "+isUndecorated()+", "+screen);
+ System.err.println("Window fs: "+fullscreen+" "+x+"/"+y+" "+w+"x"+h+", "+isUndecorated()+", "+screen);
}
DisplayImpl display = (DisplayImpl) screen.getDisplay();
display.dispatchMessagesNative(); // status up2date
boolean wasVisible = isVisible();
setVisibleImpl(false, x, y, width, height);
- WindowImpl.this.waitForVisible(false, true);
+ WindowImpl.this.waitForVisible(false, true, Screen.SCREEN_MODE_CHANGE_TIMEOUT);
display.dispatchMessagesNative(); // status up2date
+
+ // write back mirrored values, to be able to detect satisfaction
+ WindowImpl.this.x = x;
+ WindowImpl.this.y = y;
+ WindowImpl.this.width = w;
+ WindowImpl.this.height = h;
reconfigureWindowImpl(x, y, w, h, getParentWindowHandle()!=0, fullscreen?1:-1, isUndecorated()?-1:1);
display.dispatchMessagesNative(); // status up2date
+
if(wasVisible) {
setVisibleImpl(true, x, y, width, height);
- WindowImpl.this.waitForVisible(true, true);
+ boolean ok = WindowImpl.this.waitForVisible(true, true, Screen.SCREEN_MODE_CHANGE_TIMEOUT);
display.dispatchMessagesNative(); // status up2date
+ if( ok &&
+ ( WindowImpl.this.x != x ||
+ WindowImpl.this.y != y ||
+ WindowImpl.this.width != w ||
+ WindowImpl.this.height != h ) )
+ {
+ if(DEBUG_IMPLEMENTATION || DEBUG_WINDOW_EVENT) {
+ System.err.println("Window fs (reconfig): "+x+"/"+y+" "+w+"x"+h+", "+screen);
+ }
+ // reset pos/size .. due to some native impl flakyness
+ reconfigureWindowImpl(x, y, width, height, false, 0, 0);
+ display.dispatchMessagesNative(); // status up2date
+ }
requestFocusImpl(true);
display.dispatchMessagesNative(); // status up2date
+ if(DEBUG_IMPLEMENTATION || DEBUG_WINDOW_EVENT) {
+ System.err.println("Window fs done");
+ }
}
}
} finally {
@@ -1377,6 +1417,45 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
return this.fullscreen;
}
+ boolean screenModeChangeVisible;
+ boolean screenModeChangeFullscreen;
+
+ public void screenModeChangeNotify(ScreenMode sm) {
+ if(DEBUG_IMPLEMENTATION || DEBUG_WINDOW_EVENT) {
+ System.err.println("Window.screenModeChangeNotify: "+sm);
+ }
+ screenModeChangeFullscreen = isFullscreen();
+ if(screenModeChangeFullscreen) {
+ setFullscreen(false);
+ }
+ screenModeChangeVisible = isVisible();
+ if(screenModeChangeVisible) {
+ setVisible(false);
+ }
+ windowLock.lock();
+ }
+
+ public void screenModeChanged(ScreenMode sm, boolean success) {
+ if(DEBUG_IMPLEMENTATION || DEBUG_WINDOW_EVENT) {
+ System.err.println("Window.screenModeChanged: "+sm+", success: "+success);
+ }
+ windowLock.unlock();
+
+ if(success) {
+ DimensionReadOnly screenSize = sm.getMonitorMode().getSurfaceSize().getResolution();
+ if ( getHeight() > screenSize.getHeight() ||
+ getWidth() > screenSize.getWidth() ) {
+ setSize(screenSize.getWidth(), screenSize.getHeight());
+ }
+ }
+ if(screenModeChangeFullscreen) {
+ setFullscreen(true);
+ }
+ if(screenModeChangeVisible) {
+ setVisible(true, Screen.SCREEN_MODE_CHANGE_TIMEOUT);
+ }
+ }
+
//----------------------------------------------------------------------
// Child Window Management
//
@@ -1866,8 +1945,12 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
private boolean waitForVisible(boolean visible, boolean failFast) {
+ return waitForVisible(visible, failFast, TIMEOUT_NATIVEWINDOW);
+ }
+
+ private boolean waitForVisible(boolean visible, boolean failFast, long timeOut) {
DisplayImpl display = (DisplayImpl) screen.getDisplay();
- for(long sleep = TIMEOUT_NATIVEWINDOW; 0<sleep && this.visible != visible; sleep-=10 ) {
+ for(long sleep = timeOut; 0<sleep && this.visible != visible; sleep-=10 ) {
display.dispatchMessagesNative(); // status up2date
try {
Thread.sleep(10);
@@ -1876,9 +1959,9 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
if(this.visible != visible) {
if(failFast) {
- throw new NativeWindowException("Visibility not reached as requested within "+TIMEOUT_NATIVEWINDOW+"ms : requested "+visible+", is "+this.visible);
+ throw new NativeWindowException("Visibility not reached as requested within "+timeOut+"ms : requested "+visible+", is "+this.visible);
} else if (DEBUG_IMPLEMENTATION) {
- System.err.println("******* Visibility not reached as requested within "+TIMEOUT_NATIVEWINDOW+"ms : requested "+visible+", is "+this.visible);
+ System.err.println("******* Visibility not reached as requested within "+timeOut+"ms : requested "+visible+", is "+this.visible);
}
}
return this.visible == visible;
@@ -1937,16 +2020,17 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
// Exception ee = new Exception("Window.windowRepaint: "+" - "+x+"/"+y+" "+width+"x"+height);
// ee.printStackTrace();
}
- if(0>width) {
- width=this.width;
- }
- if(0>height) {
- height=this.height;
- }
- NEWTEvent e = new WindowUpdateEvent(WindowEvent.EVENT_WINDOW_REPAINT, this, System.currentTimeMillis(),
- new Rectangle(x, y, width, height));
if(isNativeValid()) {
+ if(0>width) {
+ width=this.width;
+ }
+ if(0>height) {
+ height=this.height;
+ }
+
+ NEWTEvent e = new WindowUpdateEvent(WindowEvent.EVENT_WINDOW_REPAINT, this, System.currentTimeMillis(),
+ new Rectangle(x, y, width, height));
doEvent(false, false, e);
}
}
diff --git a/src/newt/classes/com/jogamp/newt/impl/awt/AWTScreen.java b/src/newt/classes/com/jogamp/newt/impl/awt/AWTScreen.java
index eaf758b2d..5e097fdc3 100644
--- a/src/newt/classes/com/jogamp/newt/impl/awt/AWTScreen.java
+++ b/src/newt/classes/com/jogamp/newt/impl/awt/AWTScreen.java
@@ -62,5 +62,4 @@ public class AWTScreen extends ScreenImpl {
}
protected void closeNativeImpl() { }
-
}
diff --git a/src/newt/classes/com/jogamp/newt/impl/intel/gdl/Screen.java b/src/newt/classes/com/jogamp/newt/impl/intel/gdl/Screen.java
index c5253e142..4abee350f 100644
--- a/src/newt/classes/com/jogamp/newt/impl/intel/gdl/Screen.java
+++ b/src/newt/classes/com/jogamp/newt/impl/intel/gdl/Screen.java
@@ -47,8 +47,8 @@ public class Screen extends com.jogamp.newt.impl.ScreenImpl {
protected void createNativeImpl() {
AbstractGraphicsDevice adevice = getDisplay().getGraphicsDevice();
- GetScreenInfo(adevice.getHandle(), idx);
- aScreen = new DefaultGraphicsScreen(adevice, idx);
+ GetScreenInfo(adevice.getHandle(), screen_idx);
+ aScreen = new DefaultGraphicsScreen(adevice, screen_idx);
}
protected void closeNativeImpl() { }
diff --git a/src/newt/classes/com/jogamp/newt/impl/macosx/MacScreen.java b/src/newt/classes/com/jogamp/newt/impl/macosx/MacScreen.java
index 21018b2be..f0c388366 100644
--- a/src/newt/classes/com/jogamp/newt/impl/macosx/MacScreen.java
+++ b/src/newt/classes/com/jogamp/newt/impl/macosx/MacScreen.java
@@ -46,8 +46,8 @@ public class MacScreen extends ScreenImpl {
}
protected void createNativeImpl() {
- aScreen = new DefaultGraphicsScreen(getDisplay().getGraphicsDevice(), idx);
- setScreenSize(getWidthImpl0(idx), getHeightImpl0(idx));
+ aScreen = new DefaultGraphicsScreen(getDisplay().getGraphicsDevice(), screen_idx);
+ setScreenSize(getWidthImpl0(screen_idx), getHeightImpl0(screen_idx));
}
protected void closeNativeImpl() { }
diff --git a/src/newt/classes/com/jogamp/newt/impl/opengl/broadcom/egl/Screen.java b/src/newt/classes/com/jogamp/newt/impl/opengl/broadcom/egl/Screen.java
index 50fdf92e5..144fe5e83 100644
--- a/src/newt/classes/com/jogamp/newt/impl/opengl/broadcom/egl/Screen.java
+++ b/src/newt/classes/com/jogamp/newt/impl/opengl/broadcom/egl/Screen.java
@@ -46,7 +46,7 @@ public class Screen extends com.jogamp.newt.impl.ScreenImpl {
}
protected void createNativeImpl() {
- aScreen = new DefaultGraphicsScreen(getDisplay().getGraphicsDevice(), idx);
+ aScreen = new DefaultGraphicsScreen(getDisplay().getGraphicsDevice(), screen_idx);
setScreenSize(fixedWidth, fixedHeight);
}
diff --git a/src/newt/classes/com/jogamp/newt/impl/opengl/kd/KDScreen.java b/src/newt/classes/com/jogamp/newt/impl/opengl/kd/KDScreen.java
index a814f15b5..1a73d0e5d 100644
--- a/src/newt/classes/com/jogamp/newt/impl/opengl/kd/KDScreen.java
+++ b/src/newt/classes/com/jogamp/newt/impl/opengl/kd/KDScreen.java
@@ -46,7 +46,7 @@ public class KDScreen extends ScreenImpl {
}
protected void createNativeImpl() {
- aScreen = new DefaultGraphicsScreen(getDisplay().getGraphicsDevice(), idx);
+ aScreen = new DefaultGraphicsScreen(getDisplay().getGraphicsDevice(), screen_idx);
}
protected void closeNativeImpl() { }
diff --git a/src/newt/classes/com/jogamp/newt/impl/windows/WindowsScreen.java b/src/newt/classes/com/jogamp/newt/impl/windows/WindowsScreen.java
index 04ffbe11d..d35021605 100644
--- a/src/newt/classes/com/jogamp/newt/impl/windows/WindowsScreen.java
+++ b/src/newt/classes/com/jogamp/newt/impl/windows/WindowsScreen.java
@@ -30,182 +30,80 @@
* SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*
*/
-
package com.jogamp.newt.impl.windows;
+import com.jogamp.common.util.ArrayHashSet;
import java.util.ArrayList;
import com.jogamp.newt.*;
import com.jogamp.newt.impl.ScreenImpl;
import com.jogamp.newt.ScreenMode;
import com.jogamp.newt.impl.ScreenModeStatus;
+import com.jogamp.newt.util.ScreenModeUtil;
import javax.media.nativewindow.*;
public class WindowsScreen extends ScreenImpl {
+
static {
WindowsDisplay.initSingleton();
}
-
public WindowsScreen() {
}
protected void createNativeImpl() {
- aScreen = new DefaultGraphicsScreen(getDisplay().getGraphicsDevice(), idx);
- setScreenSize(getWidthImpl0(idx), getHeightImpl0(idx));
+ aScreen = new DefaultGraphicsScreen(getDisplay().getGraphicsDevice(), screen_idx);
+ setScreenSize(getWidthImpl0(screen_idx), getHeightImpl0(screen_idx));
}
- protected void closeNativeImpl() { }
-
- public int getDesktopScreenModeIndex() {
- int index = super.getDesktopScreenModeIndex();
- if(index == -1) {
- /** Set the current screen mode to refering to index zero
- * dependent on the impl of getScreenModes which saves the
- * current screen mode at index 0 which is the original screen mode
- */
- ScreenMode[] screenModes = getScreenModes();
- if(screenModes != null) {
- if(screenModes[0] != null) {
- index = screenModes[0].getIndex();
- }
- }
- }
- return index;
+ protected void closeNativeImpl() {
}
-
- public void setScreenMode(int modeIndex, short rate) {
- ScreenModeStatus sms = screensModeState.getScreenModeController(getScreenFQN());
- ScreenMode[] screenModes = sms.getScreenModes();
-
- short selectedRate = rate;
- int selectedMode = modeIndex;
-
- if(modeIndex < 0 || (modeIndex > screenModes.length)){
- selectedMode = sms.getOriginalScreenMode();
- }
- ScreenMode sm = screenModes[selectedMode];
-
- if(selectedRate == -1){
- selectedRate = sms.getOriginalScreenRate();
- }
-
- boolean rateAvailable = false;
- short[] rates = sm.getRates();
- for(int i=0;i<rates.length;i++){
- if(rates[i] == selectedRate){
- rateAvailable = true;
- break;
- }
- }
- if(!rateAvailable){
- selectedRate = rates[0];
- }
-
- if(0 == setScreenMode0(idx, sm.getWidth(), sm.getHeight(), sm.getBitsPerPixel(), selectedRate)){
- sms.setCurrentScreenMode(selectedMode);
- sms.setCurrentScreenRate(selectedRate);
- }
+
+ private int[] getScreenModeIdx(int idx) {
+ int[] modeProps = getScreenMode0(screen_idx, idx);
+ if (null == modeProps) {
+ return null;
+ }
+ if(modeProps.length != ScreenModeUtil.NUM_SCREEN_MODE_PROPERTIES_ALL + 1) {
+ throw new RuntimeException("properties array too short, should be >= "+ScreenModeUtil.NUM_SCREEN_MODE_PROPERTIES_ALL+", is "+modeProps.length);
+ }
+ return modeProps;
}
-
- public short getCurrentScreenRate() {
- short rate = super.getCurrentScreenRate();
- if(rate == -1){
- rate = (short)getCurrentScreenRate0(idx);
- }
- return rate;
- }
-
- public ScreenMode[] getScreenModes() {
- ScreenMode[] screenModes = super.getScreenModes();
- if(screenModes == null) {
- ArrayList smTemp = new ArrayList();
-
- int modeID = -1;
- ScreenMode mySM = getScreenMode(modeID++);
- int currentBitsPerPixel = mySM.getBitsPerPixel();
- while(mySM != null){
- //filter out modes with diff bits per pixel
- if(mySM.getBitsPerPixel() == currentBitsPerPixel) {
- smTemp.add(mySM);
- }
- mySM = getScreenMode(modeID++);
- }
- int numModes = smTemp.size();
- if(numModes > 0) {
- screenModes = new ScreenMode[numModes];
- for(int i=0;i<numModes;i++) {
- ScreenMode sm = (ScreenMode)smTemp.get(i);
- sm.setIndex(i);
- screenModes[i] = sm;
- }
- }
- }
- return screenModes;
+
+ private int nativeModeIdx;
+
+ protected int[] getScreenModeFirstImpl() {
+ nativeModeIdx = 0;
+ return getScreenModeNextImpl();
}
- private ScreenMode getScreenMode(int modeIndex) {
- int[] modeProp = getScreenMode0(idx, modeIndex);
- if(modeProp == null){
- return null;
- }
- int propIndex = 0;
- int width = modeProp[propIndex++];
- int height = modeProp[propIndex++];
- int bits = modeProp[propIndex++];
- short rate = (short)modeProp[propIndex++];
-
- ScreenMode screenMode = new ScreenMode(modeIndex+1, width, height);
- screenMode.setRates(new short[]{rate});
- screenMode.setBitsPerPixel(bits);
- return screenMode;
+
+ protected int[] getScreenModeNextImpl() {
+ int[] modeProps = getScreenModeIdx(nativeModeIdx);
+ if (null != modeProps) {
+ nativeModeIdx++;
+ }
+ return modeProps;
}
-
- public void setScreenRotation(int rot) {
- if(!isRotationValid(rot)){
- return;
- }
- ScreenModeStatus sms = screensModeState.getScreenModeController(getScreenFQN());
- if(0 == setScreenRotation0(idx, rot)) {
- sms.setCurrentScreenRotation(rot);
- }
- }
-
- /** Check if this rotation is valid for platform
- * @param rot user requested rotation angle
- * @return true if is valid
- */
- private boolean isRotationValid(int rot){
- if((rot == ScreenMode.ROTATE_0) || (rot == ScreenMode.ROTATE_90) ||
- (rot == ScreenMode.ROTATE_180) || (rot == ScreenMode.ROTATE_270)) {
- return true;
- }
- return false;
- }
-
- public int getCurrentScreenRotation() {
- int rot = super.getCurrentScreenRotation();
- if(rot == -1){
- return getCurrentScreenRotation0(idx);
- }
- return rot;
- }
-
- // Native calls
+ protected ScreenMode getCurrentScreenModeImpl() {
+ return ScreenModeUtil.streamIn(getScreenModeIdx(-1), 0);
+ }
+
+ protected boolean setCurrentScreenModeImpl(ScreenMode sm) {
+ return setScreenMode0(screen_idx,
+ sm.getMonitorMode().getSurfaceSize().getResolution().getWidth(),
+ sm.getMonitorMode().getSurfaceSize().getResolution().getHeight(),
+ sm.getMonitorMode().getSurfaceSize().getBitsPerPixel(),
+ sm.getMonitorMode().getRefreshRate(),
+ sm.getRotation());
+ }
+
+ // Native calls
private native int getWidthImpl0(int scrn_idx);
+
private native int getHeightImpl0(int scrn_idx);
-
- private native int getCurrentScreenRate0(int scrn_idx);
+
private native int[] getScreenMode0(int screen_index, int mode_index);
-
- /** Change screen mode and return zero if successful
- */
- private native int setScreenMode0(int screen_index, int width, int height, int bits, short freq);
-
- private native int getCurrentScreenRotation0(int screen_index);
-
- /** Change screen mode and return zero if successful
- */
- private native int setScreenRotation0(int screen_index, int rot);
+ private native boolean setScreenMode0(int screen_index, int width, int height, int bits, int freq, int rot);
}
diff --git a/src/newt/classes/com/jogamp/newt/impl/x11/X11Screen.java b/src/newt/classes/com/jogamp/newt/impl/x11/X11Screen.java
index 52c80bbe9..a04ce4242 100644
--- a/src/newt/classes/com/jogamp/newt/impl/x11/X11Screen.java
+++ b/src/newt/classes/com/jogamp/newt/impl/x11/X11Screen.java
@@ -30,12 +30,13 @@
* SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*
*/
-
package com.jogamp.newt.impl.x11;
+import com.jogamp.nativewindow.impl.x11.X11Util;
import com.jogamp.newt.impl.ScreenImpl;
import com.jogamp.newt.ScreenMode;
-import com.jogamp.newt.impl.ScreenModeStatus;
+import com.jogamp.newt.util.ScreenModeUtil;
+import java.util.List;
import javax.media.nativewindow.x11.*;
@@ -45,153 +46,221 @@ public class X11Screen extends ScreenImpl {
X11Display.initSingleton();
}
-
public X11Screen() {
}
protected void createNativeImpl() {
- long handle = GetScreen0(display.getHandle(), idx);
- if (handle == 0 ) {
- throw new RuntimeException("Error creating screen: "+idx);
+ long handle = GetScreen0(display.getHandle(), screen_idx);
+ if (handle == 0) {
+ throw new RuntimeException("Error creating screen: " + screen_idx);
+ }
+ aScreen = new X11GraphicsScreen((X11GraphicsDevice) getDisplay().getGraphicsDevice(), screen_idx);
+ setScreenSize(getWidth0(display.getHandle(), screen_idx),
+ getHeight0(display.getHandle(), screen_idx));
+ }
+
+ protected void closeNativeImpl() {
+ }
+
+ private int[] nrotations;
+ private int nrotation_index;
+ private int nres_number;
+ private int nres_index;
+ private int[] nrates;
+ private int nrate_index;
+ private int nmode_number;
+
+ protected int[] getScreenModeFirstImpl() {
+ // initialize iterators and static data
+ nrotations = getAvailableScreenModeRotations0(display.getHandle(), screen_idx);
+ if(null==nrotations) {
+ nrotations = new int[1];
+ nrotations[0]=0;
}
- aScreen = new X11GraphicsScreen((X11GraphicsDevice)getDisplay().getGraphicsDevice(), idx);
- setScreenSize(getWidth0(display.getHandle(), idx),
- getHeight0(display.getHandle(), idx));
+ nrotation_index = 0;
+
+ nres_number = getNumScreenModeResolutions0(display.getHandle(), screen_idx);
+ nres_index = 0;
+
+ nrates = getScreenModeRates0(display.getHandle(), screen_idx, nres_index);
+ nrate_index = 0;
+
+ nmode_number = 0;
+
+ return getScreenModeNextImpl();
}
- protected void closeNativeImpl() { }
-
- public int getDesktopScreenModeIndex() {
- int index = super.getDesktopScreenModeIndex();
- if(index == -1){
- return getDesktopScreenModeIndex0(display.getHandle(), idx);
- }
- return index;
+ protected int[] getScreenModeNextImpl() {
+ // assemble: w x h x bpp x f x r
+
+ /**
+ System.err.println("******** mode: "+nmode_number);
+ System.err.println("rot "+nrotation_index);
+ System.err.println("rate "+nrate_index);
+ System.err.println("res "+nres_index); */
+
+ int[] res = getScreenModeResolution0(display.getHandle(), screen_idx, nres_index);
+ if(null == res) {
+ throw new InternalError("null resolution received for res idx "+nres_index+"/"+nres_number);
+ }
+ if(0>=res[0] || 0>=res[1]) {
+ throw new InternalError("invalid resolution: "+res[0]+"x"+res[1]+" for res idx "+nres_index+"/"+nres_number);
+ }
+ int bpp = 32; // FIXME
+ int rate = nrates[nrate_index];
+ if(0>=rate) {
+ throw new InternalError("invalid rate: "+rate+" at index "+nrate_index+"/"+nrates.length);
+ }
+ int rotation = nrotations[nrotation_index];
+
+ int[] props = new int[ 1 + ScreenModeUtil.NUM_SCREEN_MODE_PROPERTIES_ALL ];
+ int i = 0;
+ props[i++] = nres_index; // use resolution index, not unique for native -> ScreenMode
+ props[i++] = 0; // set later for verification of iterator
+ props[i++] = res[0]; // width
+ props[i++] = res[1]; // height
+ props[i++] = bpp; // bpp
+ props[i++] = res[2]; // widthmm
+ props[i++] = res[3]; // heightmm
+ props[i++] = rate; // rate
+ props[i++] = rotation;
+ props[i - ScreenModeUtil.NUM_SCREEN_MODE_PROPERTIES_ALL] = i - 1; // count without extra element
+
+ nmode_number++;
+
+ // iteration: r -> f -> bpp -> [w x h]
+ nrotation_index++;
+ if(nrotation_index == nrotations.length) {
+ nrotation_index=0;
+ nrate_index++;
+ if(null == nrates || nrate_index == nrates.length){
+ nres_index++;
+ if(nres_index == nres_number) {
+ // done
+ nrates=null;
+ nrotations=null;
+ return null;
+ }
+
+ nrates = getScreenModeRates0(display.getHandle(), screen_idx, nres_index);
+ nrate_index = 0;
+ }
+ }
+
+ return props;
}
-
- public void setScreenMode(int modeIndex, short rate) {
- ScreenModeStatus sms = screensModeState.getScreenModeController(getScreenFQN());
- ScreenMode[] screenModes = sms.getScreenModes();
-
- short selectedRate = rate;
- int selectedMode = modeIndex;
-
- if(modeIndex < 0 || (modeIndex > screenModes.length)){
- selectedMode = sms.getOriginalScreenMode();
- }
- ScreenMode screenMode = screenModes[selectedMode];
-
- if(selectedRate == -1){
- selectedRate = sms.getOriginalScreenRate();
- }
-
- boolean rateAvailable = false;
- short[] rates = screenMode.getRates();
- for(int i=0;i<rates.length;i++){
- if(rates[i] == selectedRate){
- rateAvailable = true;
- break;
- }
- }
- if(!rateAvailable){
- selectedRate = rates[0];
- }
-
-
- setScreenMode0(display.getHandle(), idx, selectedMode, selectedRate, getCurrentScreenRotation());
- sms.setCurrentScreenMode(selectedMode);
- sms.setCurrentScreenRate(selectedRate);
+
+ protected ScreenMode getCurrentScreenModeImpl() {
+ int resNumber = getNumScreenModeResolutions0(display.getHandle(), screen_idx);
+ int resIdx = getCurrentScreenResolutionIndex0(display.getHandle(), screen_idx);
+ if(0>resIdx || resIdx>=resNumber) {
+ throw new RuntimeException("Invalid resolution index: ! 0 < "+resIdx+" < "+resNumber);
+ }
+ int[] res = getScreenModeResolution0(display.getHandle(), screen_idx, resIdx);
+ if(null == res) {
+ throw new InternalError("null resolution received for res idx "+resIdx+"/"+resNumber);
+ }
+ if(0>=res[0] || 0>=res[1]) {
+ throw new InternalError("invalid resolution: "+res[0]+"x"+res[1]+" for res idx "+resIdx+"/"+resNumber);
+ }
+ int rate = getCurrentScreenRate0(display.getHandle(), screen_idx);
+ int rot = getCurrentScreenRotation0(display.getHandle(), screen_idx);
+
+ int[] props = new int[ScreenModeUtil.NUM_SCREEN_MODE_PROPERTIES_ALL];
+ int i = 0;
+ props[i++] = 0; // set later for verification of iterator
+ props[i++] = res[0]; // width
+ props[i++] = res[1]; // height
+ props[i++] = 32; // FIXME: bpp
+ props[i++] = res[2]; // widthmm
+ props[i++] = res[3]; // heightmm
+ props[i++] = rate; // rate
+ props[i++] = rot;
+ props[i - ScreenModeUtil.NUM_SCREEN_MODE_PROPERTIES_ALL] = i; // count
+ return ScreenModeUtil.streamIn(props, 0);
}
-
- public short getCurrentScreenRate() {
- short rate = super.getCurrentScreenRate();
- if(rate == -1){
- return getCurrentScreenRate0(display.getHandle(), idx);
- }
- return rate;
- }
-
- public ScreenMode[] getScreenModes() {
- ScreenMode[] screenModes = super.getScreenModes();
- if(screenModes == null){
- int numModes = getNumScreenModes0(display.getHandle(), idx);
- screenModes = new ScreenMode[numModes];
- for(int i=0; i< numModes; i++){
- screenModes[i] = getScreenMode(i);
- }
- }
- return screenModes;
+
+ protected boolean setCurrentScreenModeImpl(ScreenMode screenMode) {
+ List screenModes = this.getScreenModesOrig();
+ int screenModeIdx = screenModes.indexOf(screenMode);
+ if(0>screenModeIdx) {
+ throw new RuntimeException("ScreenMode not element of ScreenMode list: "+screenMode);
+ }
+ int resNumber = getNumScreenModeResolutions0(display.getHandle(), screen_idx);
+ int resIdx = getScreenModesIdx2NativeIdx().get(screenModeIdx);
+ if(0>resIdx || resIdx>=resNumber) {
+ throw new RuntimeException("Invalid resolution index: ! 0 < "+resIdx+" < "+resNumber+", screenMode["+screenModeIdx+"] "+screenMode);
+ }
+ String tname = Thread.currentThread()+"-X11Screen.setCurrentScreenModeImpl()";
+ SetScreenModeAction setScreenModeAction = new SetScreenModeAction(screenMode, resIdx);
+ Thread randrTask = new Thread(setScreenModeAction, tname);
+ randrTask.start();
+ int to = SCREEN_MODE_CHANGE_TIMEOUT / 100 ;
+ while(to>0 && randrTask.isAlive()) {
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException ex) { }
+ to--;
+ }
+ if(0==to && DEBUG) {
+ System.err.println("X11Screen.setCurrentScreenModeImpl: TO ("+SCREEN_MODE_CHANGE_TIMEOUT+") reached: "+
+ randrTask+", alive "+randrTask.isAlive());
+ }
+ return setScreenModeAction.getResult();
}
-
- private ScreenMode getScreenMode(int modeIndex){
- int[] modeProp = getScreenMode0(display.getHandle(), idx, modeIndex);
-
- if(modeProp == null){
- return null;
- }
- int propIndex = 0;
- int index = modeProp[propIndex++];
- int width = modeProp[propIndex++];
- int height = modeProp[propIndex++];
-
- ScreenMode screenMode = new ScreenMode(index, width, height);
-
- short[] rates = new short[modeProp.length - propIndex];
- for(int i= propIndex; i < modeProp.length; i++)
- {
- rates[i-propIndex] = (short) modeProp[i];
- }
- screenMode.setRates(rates);
- return screenMode;
+
+ class SetScreenModeAction implements Runnable {
+ boolean res;
+ ScreenMode screenMode;
+ int resIdx;
+
+ public SetScreenModeAction(ScreenMode screenMode, int resIdx) {
+ this.screenMode = screenMode;
+ this.resIdx = resIdx;
+ this.res = false;
+ }
+
+ public boolean getResult() {
+ return res;
+ }
+
+ public void run() {
+ long dpy = X11Util.createDisplay(display.getName());
+ if( 0 == dpy ) {
+ throw new RuntimeException("Error creating display: "+display.getName());
+ }
+ try {
+ res = setCurrentScreenMode0(dpy, screen_idx, resIdx,
+ screenMode.getMonitorMode().getRefreshRate(), screenMode.getRotation());
+ } finally {
+ X11Util.closeDisplay(dpy);
+ }
+ }
}
-
- public void setScreenRotation(int rot) {
- if(!isRotationValid(rot)){
- return;
- }
- ScreenModeStatus sms = screensModeState.getScreenModeController(getScreenFQN());
- setScreenRotation0(display.getHandle(), idx, rot);
- sms.setCurrentScreenRotation(rot);
- }
-
- /** Check if this rotation is valid for platform
- * @param rot user requested rotation angle
- * @return true if is valid
- */
- private boolean isRotationValid(int rot){
- if((rot == ScreenMode.ROTATE_0) || (rot == ScreenMode.ROTATE_90) ||
- (rot == ScreenMode.ROTATE_180) || (rot == ScreenMode.ROTATE_270)) {
- return true;
- }
- return false;
- }
-
- public int getCurrentScreenRotation() {
- int rotation = super.getCurrentScreenRotation();
- if(rotation == -1){
- rotation = getCurrentScreenRotation0(display.getHandle(), idx);
- }
- return rotation;
- }
-
+
//----------------------------------------------------------------------
// Internals only
//
+ private static native long GetScreen0(long dpy, int scrn_idx);
- private native long GetScreen0(long dpy, int scrn_idx);
- private native int getWidth0(long display, int scrn_idx);
- private native int getHeight0(long display, int scrn_idx);
-
- private native int getDesktopScreenModeIndex0(long display, int screen_index);
- private native short getCurrentScreenRate0(long display, int screen_index);
-
- private native int getCurrentScreenRotation0(long display, int screen_index);
- private native void setScreenRotation0(long display, int screen_index, int rot);
-
- private native void setScreenMode0(long display, int screen_index, int mode_index, short freq, int rot);
-
- private native int[] getScreenMode0(long display, int screen_index, int mode_index);
- private native int getNumScreenModes0(long display, int screen_index);
+ private static native int getWidth0(long display, int scrn_idx);
-}
+ private static native int getHeight0(long display, int scrn_idx);
+ /** @return int[] { rot1, .. } */
+ private static native int[] getAvailableScreenModeRotations0(long display, int screen_index);
+
+ private static native int getNumScreenModeResolutions0(long display, int screen_index);
+
+ /** @return int[] { width, height, widthmm, heightmm } */
+ private static native int[] getScreenModeResolution0(long display, int screen_index, int mode_index);
+
+ private static native int[] getScreenModeRates0(long display, int screen_index, int mode_index);
+
+ private static native int getCurrentScreenResolutionIndex0(long display, int screen_index);
+ private static native int getCurrentScreenRate0(long display, int screen_index);
+ private static native int getCurrentScreenRotation0(long display, int screen_index);
+
+ /** needs own Display connection for XRANDR event handling */
+ private static native boolean setCurrentScreenMode0(long display, int screen_index, int mode_index, int freq, int rot);
+}
diff --git a/src/newt/classes/com/jogamp/newt/impl/x11/X11Window.java b/src/newt/classes/com/jogamp/newt/impl/x11/X11Window.java
index 06c7dfa99..60af9b9af 100644
--- a/src/newt/classes/com/jogamp/newt/impl/x11/X11Window.java
+++ b/src/newt/classes/com/jogamp/newt/impl/x11/X11Window.java
@@ -33,6 +33,7 @@
package com.jogamp.newt.impl.x11;
+import com.jogamp.newt.ScreenMode;
import com.jogamp.newt.impl.WindowImpl;
import javax.media.nativewindow.*;
import javax.media.nativewindow.x11.*;
diff --git a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
index 50fe3f63a..aef4de92a 100644
--- a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
+++ b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
@@ -230,6 +230,14 @@ public class GLWindow implements GLAutoDrawable, Window {
window.addChild(win);
}
+ public void screenModeChangeNotify(ScreenMode sm) {
+ window.screenModeChangeNotify(sm);
+ }
+
+ public void screenModeChanged(ScreenMode sm, boolean success) {
+ window.screenModeChanged(sm, success);
+ }
+
//----------------------------------------------------------------------
// Window.LifecycleHook Implementation
//
diff --git a/src/newt/classes/com/jogamp/newt/util/MonitorMode.java b/src/newt/classes/com/jogamp/newt/util/MonitorMode.java
new file mode 100644
index 000000000..f24416469
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/util/MonitorMode.java
@@ -0,0 +1,105 @@
+/**
+ * Copyright 2010 JogAmp Community. All rights reserved.
+ * Copyright (c) 2010 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package com.jogamp.newt.util;
+
+import javax.media.nativewindow.util.*;
+
+/** Immutable MonitorMode Class, consisting of it's read only components:<br>
+ * <ul>
+ * <li>{@link javax.media.nativewindow.util.SurfaceSize} surface memory size</li>
+ * <li>{@link javax.media.nativewindow.util.DimensionReadOnly} size in [mm]</li>
+ * <li><code>refresh rate</code></li>
+ * </ul>
+ */
+public class MonitorMode implements Cloneable {
+ SurfaceSize surfaceSize;
+ DimensionReadOnly screenSizeMM; // in [mm]
+ int refreshRate;
+
+ public MonitorMode(SurfaceSize surfaceSize, DimensionReadOnly screenSizeMM, int refreshRate) {
+ if(null==surfaceSize || refreshRate<=0) {
+ throw new IllegalArgumentException("surfaceSize must be set and refreshRate greater 0");
+ }
+ this.surfaceSize=surfaceSize;
+ this.screenSizeMM=screenSizeMM;
+ this.refreshRate=refreshRate;
+ }
+
+ public Object clone() {
+ try {
+ return super.clone();
+ } catch (CloneNotSupportedException ex) {
+ throw new InternalError();
+ }
+ }
+
+ public final SurfaceSize getSurfaceSize() {
+ return surfaceSize;
+ }
+
+ public final DimensionReadOnly getScreenSizeMM() {
+ return screenSizeMM;
+ }
+
+ public final int getRefreshRate() {
+ return refreshRate;
+ }
+
+ public final String toString() {
+ return new String("MonitorMode["+surfaceSize+" x "+refreshRate+" Hz, "+screenSizeMM+" [mm]x[mm]]");
+ }
+
+ /**
+ * Checks whether two size objects are equal. Two instances
+ * of <code>MonitorMode</code> are equal if the three components
+ * <code>surfaceSize</code>, <code>screenSizeMM</code> and <code>refreshRate</code>
+ * are equal.
+ * @return <code>true</code> if the two dimensions are equal;
+ * otherwise <code>false</code>.
+ */
+ public final boolean equals(Object obj) {
+ if (obj instanceof MonitorMode) {
+ MonitorMode p = (MonitorMode)obj;
+ return getSurfaceSize().equals(p.getSurfaceSize()) &&
+ getScreenSizeMM().equals(p.getScreenSizeMM()) &&
+ getRefreshRate() == p.getRefreshRate() ;
+ }
+ return false;
+ }
+
+ public final int hashCode() {
+ // 31 * x == (x << 5) - x
+ int hash = 31 + getSurfaceSize().hashCode();
+ hash = ((hash << 5) - hash) + getScreenSizeMM().hashCode();
+ hash = ((hash << 5) - hash) + getRefreshRate();
+ return hash;
+ }
+}
+
diff --git a/src/newt/classes/com/jogamp/newt/util/ScreenModeUtil.java b/src/newt/classes/com/jogamp/newt/util/ScreenModeUtil.java
new file mode 100644
index 000000000..9cb04c2a1
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/util/ScreenModeUtil.java
@@ -0,0 +1,367 @@
+/**
+ * Copyright 2010 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package com.jogamp.newt.util;
+
+import com.jogamp.common.util.ArrayHashSet;
+import com.jogamp.newt.ScreenMode;
+import java.util.ArrayList;
+import java.util.List;
+import javax.media.nativewindow.util.Dimension;
+import javax.media.nativewindow.util.DimensionReadOnly;
+import javax.media.nativewindow.util.SurfaceSize;
+
+/**
+ * Convenient {@link com.jogamp.newt.ScreenMode} utility methods,
+ * filters etc.
+ */
+public class ScreenModeUtil {
+ /** WARNING: must be synchronized with ScreenMode.h, native implementation
+ * 2: width and height
+ */
+ public static final int NUM_RESOLUTION_PROPERTIES = 2;
+
+ /** WARNING: must be synchronized with ScreenMode.h, native implementation
+ * 1: bpp
+ */
+ public static final int NUM_SURFACE_SIZE_PROPERTIES = 1;
+
+ /** WARNING: must be synchronized with ScreenMode.h, native implementation
+ * 3: ScreenSizeMM[width, height], refresh-rate
+ */
+ public static final int NUM_MONITOR_MODE_PROPERTIES = 3;
+
+ /** WARNING: must be synchronized with ScreenMode.h, native implementation
+ * 1: rotation, native_mode_id
+ */
+ public static final int NUM_SCREEN_MODE_PROPERTIES = 1;
+
+ /** WARNING: must be synchronized with ScreenMode.h, native implementation
+ * count + all the above
+ */
+ public static final int NUM_SCREEN_MODE_PROPERTIES_ALL = 8;
+
+ public static int getIndex(List/*<ScreenMode>*/ screenModes, ScreenMode search) {
+ return screenModes.indexOf(search);
+ }
+
+ public static int getIndexByHashCode(List/*<ScreenMode>*/ screenModes, ScreenMode search) {
+ for (int i=0; null!=screenModes && i<screenModes.size(); i++) {
+ if ( search.hashCode() == ((ScreenMode)screenModes.get(i)).hashCode() ) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * Validate the given list of {@link com.jogamp.newt.ScreenMode}s, testing on:<br>
+ * <ul>
+ * <li> unique {@link com.jogamp.newt.ScreenMode}s by equality and hash code
+ * </ul>
+ * This
+ * @param screenModes list of {@link com.jogamp.newt.ScreenMode}s
+ * @param throwException if true and invalid throw IllegalArgumentException
+ * @return true if valid, otherwise false or throw IllegalArgumentException
+ * @throws IllegalArgumentException if invalid
+ */
+ public static boolean validate(List/*<ScreenMode>*/ screenModes, boolean throwException) {
+ for (int j=0; null!=screenModes && j<screenModes.size(); j++) {
+ ScreenMode sm = (ScreenMode)screenModes.get(j);
+ List dups = new ArrayList();
+
+ /*** don't check slow-path 'equals' for now, hash is working
+ for (int i=0; i<screenModes.size(); i++) {
+ ScreenMode sm2 = (ScreenMode)screenModes.get(i);
+ if( i!=j && sm.equals(sm2) ) {
+ dups.add(new Integer(i));
+ }
+ }
+ if(dups.size()>0) {
+ if(throwException) {
+ throw new IllegalArgumentException("Element "+sm+" at index "+j+" is not unique (equality), duplicates: "+dups);
+ } else {
+ return false;
+ }
+ } */
+
+ for (int i=0; null!=screenModes && i<screenModes.size(); i++) {
+ ScreenMode sm2 = (ScreenMode)screenModes.get(i);
+ if ( i!=j && sm.hashCode() == sm2.hashCode() ) {
+ dups.add(new Integer(i));
+ }
+ }
+ if(dups.size()>0) {
+ if(throwException) {
+ throw new IllegalArgumentException("Element "+sm+" at index "+j+" is not unique (hash), duplicates: "+dups);
+ } else {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ /**
+ * @param screenModes
+ * @param resolution
+ * @return modes with nearest resolution, or matching ones
+ */
+ public static List/*<ScreenMode>*/ filterByResolution(List/*<ScreenMode>*/ screenModes, DimensionReadOnly resolution) {
+ List out = new ArrayList();
+ int resolution_sq = resolution.getHeight()*resolution.getWidth();
+ int sm_dsq=resolution_sq, sm_dsq_idx=0;
+
+ for (int i=0; null!=screenModes && i<screenModes.size(); i++) {
+ ScreenMode sm = (ScreenMode)screenModes.get(i);
+ DimensionReadOnly res = sm.getMonitorMode().getSurfaceSize().getResolution();
+ int dsq = Math.abs(resolution_sq - res.getHeight()*res.getWidth());
+ if(dsq<sm_dsq) {
+ sm_dsq = dsq;
+ sm_dsq_idx = i;
+ }
+ if(res.equals(resolution)) {
+ out.add(sm);
+ }
+ }
+ if(out.size()>0) {
+ return out;
+ }
+ // nearest ..
+ resolution = ((ScreenMode)screenModes.get(sm_dsq_idx)).getMonitorMode().getSurfaceSize().getResolution();
+ return filterByResolution(screenModes, resolution);
+ }
+
+ public static List/*<ScreenMode>*/ filterBySurfaceSize(List/*<ScreenMode>*/ screenModes, SurfaceSize surfaceSize) {
+ List out = new ArrayList();
+ for (int i=0; null!=screenModes && i<screenModes.size(); i++) {
+ ScreenMode sm = (ScreenMode)screenModes.get(i);
+ if(sm.getMonitorMode().getSurfaceSize().equals(surfaceSize)) {
+ out.add(sm);
+ }
+ }
+ return out;
+ }
+
+ public static List/*<ScreenMode>*/ filterByRotation(List/*<ScreenMode>*/ screenModes, int rotation) {
+ List out = new ArrayList();
+ for (int i=0; null!=screenModes && i<screenModes.size(); i++) {
+ ScreenMode sm = (ScreenMode)screenModes.get(i);
+ if(sm.getRotation() == rotation) {
+ out.add(sm);
+ }
+ }
+ return out;
+ }
+
+ public static List/*<ScreenMode>*/ filterByBpp(List/*<ScreenMode>*/ screenModes, int bitsPerPixel) {
+ List out = new ArrayList();
+ for (int i=0; null!=screenModes && i<screenModes.size(); i++) {
+ ScreenMode sm = (ScreenMode)screenModes.get(i);
+ if(sm.getMonitorMode().getSurfaceSize().getBitsPerPixel() == bitsPerPixel) {
+ out.add(sm);
+ }
+ }
+ return out;
+ }
+
+ /**
+ *
+ * @param screenModes
+ * @param refreshRate
+ * @return modes with nearest refreshRate, or matching ones
+ */
+ public static List/*<ScreenMode>*/ filterByRate(List/*<ScreenMode>*/ screenModes, int refreshRate) {
+ int sm_dr = refreshRate;
+ int sm_dr_idx = -1;
+ List out = new ArrayList();
+ for (int i=0; null!=screenModes && i<screenModes.size(); i++) {
+ ScreenMode sm = (ScreenMode)screenModes.get(i);
+ int dr = Math.abs(refreshRate - sm.getMonitorMode().getRefreshRate());
+ if(dr<sm_dr) {
+ sm_dr = dr;
+ sm_dr_idx = i;
+ }
+ if(0 == dr) {
+ out.add(sm);
+ }
+ }
+ if(out.size()>0) {
+ return out;
+ }
+ refreshRate = ((ScreenMode)screenModes.get(sm_dr_idx)).getMonitorMode().getRefreshRate();
+ return filterByRate(screenModes, refreshRate);
+ }
+
+ public static List/*<ScreenMode>*/ getHighestAvailableBpp(List/*<ScreenMode>*/ screenModes) {
+ int highest = -1;
+ for (int i=0; null!=screenModes && i < screenModes.size(); i++) {
+ ScreenMode sm = (ScreenMode)screenModes.get(i);
+ int bpp = sm.getMonitorMode().getSurfaceSize().getBitsPerPixel();
+ if (bpp > highest) {
+ highest = bpp;
+ }
+ }
+ return filterByBpp(screenModes, highest);
+ }
+
+ public static List/*<ScreenMode>*/ getHighestAvailableRate(List/*<ScreenMode>*/ screenModes) {
+ int highest = -1;
+ for (int i=0; null!=screenModes && i < screenModes.size(); i++) {
+ ScreenMode sm = (ScreenMode)screenModes.get(i);
+ int rate = sm.getMonitorMode().getRefreshRate();
+ if (rate > highest) {
+ highest = rate;
+ }
+ }
+ return filterByRate(screenModes, highest);
+ }
+
+ /** WARNING: must be synchronized with ScreenMode.h, native implementation */
+ public static DimensionReadOnly streamInResolution(int[] resolutionProperties, int offset) {
+ Dimension resolution = new Dimension(resolutionProperties[offset++], resolutionProperties[offset++]);
+ return resolution;
+ }
+
+ /** WARNING: must be synchronized with ScreenMode.h, native implementation */
+ public static SurfaceSize streamInSurfaceSize(DimensionReadOnly resolution, int[] sizeProperties, int offset) {
+ SurfaceSize surfaceSize = new SurfaceSize(resolution, sizeProperties[offset++]);
+ return surfaceSize;
+ }
+
+ /** WARNING: must be synchronized with ScreenMode.h, native implementation */
+ public static MonitorMode streamInMonitorMode(SurfaceSize surfaceSize, DimensionReadOnly screenSizeMM, int[] monitorProperties, int offset) {
+ int refreshRate = monitorProperties[offset++];
+ return new MonitorMode(surfaceSize, screenSizeMM, refreshRate);
+ }
+
+ /** WARNING: must be synchronized with ScreenMode.h, native implementation */
+ public static ScreenMode streamInScreenMode(MonitorMode monitorMode, int[] modeProperties, int offset) {
+ int rotation = modeProperties[offset++];
+ return new ScreenMode(monitorMode, rotation);
+ }
+
+ /**
+ * WARNING: must be synchronized with ScreenMode.h, native implementation
+ *
+ * @param modeProperties the input data
+ * @param offset the offset to the input data
+ * @return index of the identical (old or new) ScreenMode element in <code>screenModePool</code>,
+ * matching the input <code>modeProperties</code>, or -1 if input could not be processed.
+ */
+ public static ScreenMode streamIn(int[] modeProperties, int offset) {
+ return streamInImpl(null, null, null, null, null, modeProperties, offset);
+ }
+
+ /**
+ * WARNING: must be synchronized with ScreenMode.h, native implementation
+ *
+ * @param resolutionPool hash array of unique DimensionReadOnly resolutions, no duplicates
+ * @param surfaceSizePool hash array of unique SurfaceSize, no duplicates
+ * @param monitorModePool hash array of unique MonitorMode, no duplicates
+ * @param screenModePool hash array of unique ScreenMode, no duplicates
+ * @param modeProperties the input data
+ * @param offset the offset to the input data
+ * @return index of the identical (old or new) ScreenMode element in <code>screenModePool</code>,
+ * matching the input <code>modeProperties</code>, or -1 if input could not be processed.
+ */
+ public static int streamIn(ArrayHashSet resolutionPool,
+ ArrayHashSet surfaceSizePool,
+ ArrayHashSet screenSizeMMPool,
+ ArrayHashSet monitorModePool,
+ ArrayHashSet screenModePool,
+ int[] modeProperties, int offset) {
+ ScreenMode screenMode = streamInImpl(resolutionPool, surfaceSizePool, screenSizeMMPool, monitorModePool, screenModePool,
+ modeProperties, offset);
+ return screenModePool.indexOf(screenMode);
+ }
+
+ private static ScreenMode streamInImpl(ArrayHashSet resolutionPool,
+ ArrayHashSet surfaceSizePool,
+ ArrayHashSet screenSizeMMPool,
+ ArrayHashSet monitorModePool,
+ ArrayHashSet screenModePool,
+ int[] modeProperties, int offset) {
+ int count = modeProperties[offset];
+ if(NUM_SCREEN_MODE_PROPERTIES_ALL != count) {
+ throw new RuntimeException("NUM_SCREEN_MODE_PROPERTIES should be "+NUM_SCREEN_MODE_PROPERTIES_ALL+", is "+count+", len "+(modeProperties.length-offset));
+ }
+ if(NUM_SCREEN_MODE_PROPERTIES_ALL > modeProperties.length-offset) {
+ throw new RuntimeException("properties array too short, should be >= "+NUM_SCREEN_MODE_PROPERTIES_ALL+", is "+(modeProperties.length-offset));
+ }
+ offset++;
+ DimensionReadOnly resolution = ScreenModeUtil.streamInResolution(modeProperties, offset);
+ offset += ScreenModeUtil.NUM_RESOLUTION_PROPERTIES;
+ if(null!=resolutionPool) {
+ resolution = (DimensionReadOnly) resolutionPool.getOrAdd(resolution);
+ }
+
+ SurfaceSize surfaceSize = ScreenModeUtil.streamInSurfaceSize(resolution, modeProperties, offset);
+ offset += ScreenModeUtil.NUM_SURFACE_SIZE_PROPERTIES;
+ if(null!=surfaceSizePool) {
+ surfaceSize = (SurfaceSize) surfaceSizePool.getOrAdd(surfaceSize);
+ }
+
+ DimensionReadOnly screenSizeMM = ScreenModeUtil.streamInResolution(modeProperties, offset);
+ offset += ScreenModeUtil.NUM_RESOLUTION_PROPERTIES;
+ if(null!=screenSizeMMPool) {
+ screenSizeMM = (DimensionReadOnly) screenSizeMMPool.getOrAdd(screenSizeMM);
+ }
+
+ MonitorMode monitorMode = ScreenModeUtil.streamInMonitorMode(surfaceSize, screenSizeMM, modeProperties, offset);
+ offset += ScreenModeUtil.NUM_MONITOR_MODE_PROPERTIES - ScreenModeUtil.NUM_RESOLUTION_PROPERTIES;
+ if(null!=monitorModePool) {
+ monitorMode = (MonitorMode) monitorModePool.getOrAdd(monitorMode);
+ }
+
+ ScreenMode screenMode = ScreenModeUtil.streamInScreenMode(monitorMode, modeProperties, offset);
+ if(null!=screenModePool) {
+ screenMode = (ScreenMode) screenModePool.getOrAdd(screenMode);
+ }
+ return screenMode;
+ }
+
+ /** WARNING: must be synchronized with ScreenMode.h, native implementation */
+ public static int[] streamOut (ScreenMode screenMode) {
+ int[] data = new int[NUM_SCREEN_MODE_PROPERTIES_ALL];
+ int idx=0;
+ data[idx++] = NUM_SCREEN_MODE_PROPERTIES_ALL;
+ data[idx++] = screenMode.getMonitorMode().getSurfaceSize().getResolution().getWidth();
+ data[idx++] = screenMode.getMonitorMode().getSurfaceSize().getResolution().getHeight();
+ data[idx++] = screenMode.getMonitorMode().getSurfaceSize().getBitsPerPixel();
+ data[idx++] = screenMode.getMonitorMode().getScreenSizeMM().getWidth();
+ data[idx++] = screenMode.getMonitorMode().getScreenSizeMM().getHeight();
+ data[idx++] = screenMode.getMonitorMode().getRefreshRate();
+ data[idx++] = screenMode.getRotation();
+ if(NUM_SCREEN_MODE_PROPERTIES_ALL != idx) {
+ throw new InternalError("wrong number of attributes: got "+idx+" != should "+NUM_SCREEN_MODE_PROPERTIES_ALL);
+ }
+ return data;
+ }
+
+}
diff --git a/src/newt/native/NewtCommon.c b/src/newt/native/NewtCommon.c
index 8b64ec37f..353dcb46f 100644
--- a/src/newt/native/NewtCommon.c
+++ b/src/newt/native/NewtCommon.c
@@ -1,6 +1,23 @@
#include "NewtCommon.h"
+static const char * const ClazzNameRuntimeException = "java/lang/RuntimeException";
+static jclass runtimeExceptionClz=NULL;
+
+void NewtCommon_init(JNIEnv *env) {
+ if(NULL==runtimeExceptionClz) {
+ jclass c = (*env)->FindClass(env, ClazzNameRuntimeException);
+ if(NULL==c) {
+ _FatalError(env, "NEWT X11Window: can't find %s", ClazzNameRuntimeException);
+ }
+ runtimeExceptionClz = (jclass)(*env)->NewGlobalRef(env, c);
+ (*env)->DeleteLocalRef(env, c);
+ if(NULL==runtimeExceptionClz) {
+ _FatalError(env, "NEWT X11Window: can't use %s", ClazzNameRuntimeException);
+ }
+ }
+}
+
jchar* NewtCommon_GetNullTerminatedStringChars(JNIEnv* env, jstring str)
{
jchar* strChars = NULL;
@@ -11,3 +28,15 @@ jchar* NewtCommon_GetNullTerminatedStringChars(JNIEnv* env, jstring str)
return strChars;
}
+void NewtCommon_throwNewRuntimeException(JNIEnv *env, const char* msg, ...)
+{
+ char buffer[512];
+ va_list ap;
+
+ va_start(ap, msg);
+ vsnprintf(buffer, sizeof(buffer), msg, ap);
+ va_end(ap);
+
+ (*env)->ThrowNew(env, runtimeExceptionClz, buffer);
+}
+
diff --git a/src/newt/native/NewtCommon.h b/src/newt/native/NewtCommon.h
index 46a0d57cf..00ce0b643 100644
--- a/src/newt/native/NewtCommon.h
+++ b/src/newt/native/NewtCommon.h
@@ -5,6 +5,10 @@
#include <jni.h>
#include <stdlib.h>
+void NewtCommon_init(JNIEnv *env);
+
jchar* NewtCommon_GetNullTerminatedStringChars(JNIEnv* env, jstring str);
+void NewtCommon_throwNewRuntimeException(JNIEnv *env, const char* msg, ...);
+
#endif
diff --git a/src/newt/native/ScreenMode.h b/src/newt/native/ScreenMode.h
new file mode 100644
index 000000000..0a760d54a
--- /dev/null
+++ b/src/newt/native/ScreenMode.h
@@ -0,0 +1,16 @@
+/**
+ * WARNING: must be synced with com.jogamp.newt.util.ScreenModeUtil#streamIn*(int[])
+ */
+
+#ifndef _SCREEN_MODE_H
+#define _SCREEN_MODE_H
+
+#define NUM_RESOLUTION_PROPERTIES 2 /* width, height */
+#define NUM_SURFACE_SIZE_PROPERTIES 1 /* bpp */
+#define NUM_MONITOR_MODE_PROPERTIES 3 /* ScreenSizeMM[width, height], refresh-rate */
+#define NUM_SCREEN_MODE_PROPERTIES 1 /* rotation */
+
+#define NUM_SCREEN_MODE_PROPERTIES_ALL 8 /* count + the above */
+
+#endif
+
diff --git a/src/newt/native/WindowsWindow.c b/src/newt/native/WindowsWindow.c
index 9aac8720c..de501bfbc 100644
--- a/src/newt/native/WindowsWindow.c
+++ b/src/newt/native/WindowsWindow.c
@@ -413,7 +413,7 @@ static void BuildDynamicKeyMapTable()
LCID idLocale = MAKELCID(idLang, SORT_DEFAULT);
// get the ANSI code page associated with this locale
if (GetLocaleInfo(idLocale, LOCALE_IDEFAULTANSICODEPAGE,
- strCodePage, sizeof(strCodePage)/sizeof(TCHAR)) > 0 )
+ strCodePage, sizeof(strCodePage)/sizeof(TCHAR)) > 0 )
{
codePage = _ttoi(strCodePage);
} else {
@@ -1001,7 +1001,7 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message,
RECT r;
useDefWindowProc = 0;
if (GetUpdateRect(wnd, &r, TRUE /* erase background */)) {
- /*
+ /*
jint width = r.right-r.left;
jint height = r.bottom-r.top;
if (width > 0 && height > 0) {
@@ -1146,26 +1146,44 @@ JNIEXPORT jint JNICALL Java_com_jogamp_newt_impl_windows_WindowsScreen_getHeight
return (jint)GetSystemMetrics(SM_CYSCREEN);
}
-/*
- * Class: com_jogamp_newt_impl_windows_WindowsScreen
- * Method: getCurrentScreenRate0
- * Signature: (I)S
- */
-JNIEXPORT jint JNICALL Java_com_jogamp_newt_impl_windows_WindowsScreen_getCurrentScreenRate0
- (JNIEnv *env, jobject object, jint scrn_idx)
-{
- DEVMODE dm;
- // initialize the DEVMODE structure
- ZeroMemory(&dm, sizeof(dm));
- dm.dmSize = sizeof(dm);
-
- int rate = -1;
- if (0 != EnumDisplaySettings(NULL /*current display device*/, ENUM_CURRENT_SETTINGS, &dm))
- {
- rate = dm.dmDisplayFrequency;
- }
-
- return rate;
+static int NewtScreen_RotationNative2Newt(int native) {
+ int rot;
+ switch (native) {
+ case DMDO_DEFAULT:
+ rot = 0;
+ break;
+ case DMDO_270:
+ rot = 270;
+ break;
+ case DMDO_180:
+ rot = 180;
+ break;
+ case DMDO_90:
+ rot = 90;
+ break;
+ default:
+ NewtCommon_throwNewRuntimeException(env, "invalid native rotation: %d", native);
+ break;
+ }
+ return rot;
+}
+
+static LPCTSTR NewtScreen_getDisplayDeviceName(int scrn_idx) {
+ DISPLAY_DEVICE device;
+
+ if( FALSE == EnumDisplayDevices(NULL, scrn_idx, &device, 0) ) {
+ return NULL;
+ }
+
+ if( 0 == ( device.StateFlags & DISPLAY_DEVICE_ACTIVE ) ) {
+ return NULL;
+ }
+
+ return device.DeviceName;
+}
+
+static HDC NewtScreen_createDisplayDC(LPCTSTR displayDeviceName) {
+ return CreateDC("DISPLAY", displayDeviceName, NULL, NULL);
}
/*
@@ -1176,188 +1194,144 @@ JNIEXPORT jint JNICALL Java_com_jogamp_newt_impl_windows_WindowsScreen_getCurren
JNIEXPORT jintArray JNICALL Java_com_jogamp_newt_impl_windows_WindowsScreen_getScreenMode0
(JNIEnv *env, jobject obj, jint scrn_idx, jint mode_idx)
{
- int propIndex = 0;
- int prop_size = 4; //wxhxbxf
-
- DEVMODE dm;
- // initialize the DEVMODE structure
- ZeroMemory(&dm, sizeof(dm));
- dm.dmSize = sizeof(dm);
-
- int devModeID = (int)mode_idx;
-
- if(devModeID == -1)
- {
- devModeID = ENUM_CURRENT_SETTINGS;
- }
-
- jintArray properties = (*env)->NewIntArray(env, prop_size);
-
- //Fill the properties in temp jint array
- jint prop[prop_size];
- if (0 == EnumDisplaySettings(NULL /*current display device*/, devModeID, &dm))
- {
- return NULL;
- }
- prop[propIndex++] = dm.dmPelsWidth;
- prop[propIndex++] = dm.dmPelsHeight;
- prop[propIndex++] = dm.dmBitsPerPel;
- prop[propIndex++] = dm.dmDisplayFrequency;
-
- (*env)->SetIntArrayRegion(env, properties, 0, prop_size, prop);
-
- return properties;
-}
+ int prop_num = NUM_SCREEN_MODE_PROPERTIES_ALL;
+ LPCTSTR deviceName = NewtScreen_getDisplayDeviceName(scrn_idx);
+ if(NULL == deviceName) {
+ return null;
+ }
-#define SCREEN_MODE_NOERROR 0
-#define SCREEN_MODE_ERROR 1
-/*
- * Class: com_jogamp_newt_impl_windows_WindowsScreen
- * Method: setScreenMode0
- * Signature: (IIIIS)I
- */
-JNIEXPORT jint JNICALL Java_com_jogamp_newt_impl_windows_WindowsScreen_setScreenMode0
- (JNIEnv *env, jobject object, jint scrn_idx, jint width, jint height, jint bits, jshort rate)
-{
- DEVMODE dm;
- // initialize the DEVMODE structure
+ int widthmm, heightmm;
+ {
+ HDC hdc = NewtScreen_createDisplayDC(deviceName);
+ widthmm = GetDeviceCaps(hdc, HORZSIZE);
+ heightmm = GetDeviceCaps(hdc, VERTSIZE);
+ DeleteDC(hdc);
+ }
+
+ DEVMODE dm;
ZeroMemory(&dm, sizeof(dm));
dm.dmSize = sizeof(dm);
+
+ int devModeID = (int)mode_idx;
+
+ if(devModeID == -1) {
+ devModeID = ENUM_CURRENT_SETTINGS;
+ prop_num++; // add 1st extra prop, mode_idx
+ }
- if (0 == EnumDisplaySettings(NULL /*current display device*/, ENUM_CURRENT_SETTINGS, &dm))
- {
- return SCREEN_MODE_ERROR;
- }
-
- dm.dmPelsWidth = (int)width;
- dm.dmPelsHeight = (int)height;
- dm.dmBitsPerPel = (int)bits;
- dm.dmDisplayFrequency = (int)rate;
- dm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL | DM_DISPLAYFREQUENCY;
-
- long result = ChangeDisplaySettings(&dm, 0);
- if(result == DISP_CHANGE_SUCCESSFUL)
- {
- return SCREEN_MODE_NOERROR;
- }
- return SCREEN_MODE_ERROR;
-}
+ if (0 == EnumDisplaySettings(deviceName, devModeID, &dm))
+ {
+ return NULL;
+ }
-#define SCREEN_ROT_ERROR -1
-/*
- * Class: com_jogamp_newt_impl_windows_WindowsScreen
- * Method: getCurrentScreenRotation0
- * Signature: (I)I
- */
-JNIEXPORT jint JNICALL Java_com_jogamp_newt_impl_windows_WindowsScreen_getCurrentScreenRotation0
- (JNIEnv *env, jobject object, jint scrn_idx)
-{
- DEVMODE dm;
- // initialize the DEVMODE structure
- ZeroMemory(&dm, sizeof(dm));
- dm.dmSize = sizeof(dm);
+
+ jint prop[ prop_num ];
+ int propIndex = 0;
- if (0 == EnumDisplaySettings(NULL /*current display device*/, ENUM_CURRENT_SETTINGS, &dm))
- {
- return SCREEN_ROT_ERROR;
- }
-
- int currentRotation = -1;
- switch (dm.dmDisplayOrientation)
- {
- case DMDO_DEFAULT:
- currentRotation = 0;
- break;
- case DMDO_270:
- currentRotation = 270;
- break;
- case DMDO_180:
- currentRotation = 180;
- break;
- case DMDO_90:
- currentRotation = 90;
- break;
- default:
- break;
- }
- return currentRotation;
+ if(devModeID == -1) {
+ prop[propIndex++] = mode_idx;
+ }
+ prop[propIndex++] = 0; // set later for verification of iterator
+ prop[propIndex++] = dm.dmPelsWidth;
+ prop[propIndex++] = dm.dmPelsHeight;
+ prop[propIndex++] = dm.dmBitsPerPel;
+ prop[propIndex++] = widthmm;
+ prop[propIndex++] = heightmm;
+ prop[propIndex++] = dm.dmDisplayFrequency;
+ prop[propIndex++] = NewtScreen_RotationNative2Newt(dm.dmDisplayOrientation);
+ props[propIndex - NUM_SCREEN_MODE_PROPERTIES_ALL] = propIndex ; // count
+
+ jintArray properties = (*env)->NewIntArray(env, prop_num);
+ if (properties == NULL) {
+ NewtCommon_throwNewRuntimeException(env, "Could not allocate int array of size %d", prop_num);
+ }
+ (*env)->SetIntArrayRegion(env, properties, 0, prop_num, prop);
+
+ return properties;
}
+
/*
* Class: com_jogamp_newt_impl_windows_WindowsScreen
- * Method: setScreenRotation0
- * Signature: (II)I
+ * Method: setScreenMode0
+ * Signature: (IIIIII)Z
*/
-JNIEXPORT jint JNICALL Java_com_jogamp_newt_impl_windows_WindowsScreen_setScreenRotation0
- (JNIEnv *env, jobject object, jint scrn_idx, jint rot)
+JNIEXPORT jboolean JNICALL Java_com_jogamp_newt_impl_windows_WindowsScreen_setScreenMode0
+ (JNIEnv *env, jobject object, jint scrn_idx, jint width, jint height, jint bits, jint rate, jint rot)
{
- DEVMODE dm;
+ LPCTSTR deviceName = NewtScreen_getDisplayDeviceName(scrn_idx);
+ if(NULL == deviceName) {
+ return null;
+ }
+
+ DEVMODE dm;
// initialize the DEVMODE structure
ZeroMemory(&dm, sizeof(dm));
dm.dmSize = sizeof(dm);
- if (0 == EnumDisplaySettings(NULL /*current display device*/, ENUM_CURRENT_SETTINGS, &dm))
- {
- return SCREEN_MODE_ERROR;
- }
- int requestedRotation = dm.dmDisplayOrientation;
- int currentRotation = dm.dmDisplayOrientation;
-
- int shouldFlipDims = 0;
-
- int rotation = (int)rot;
- switch (rotation)
- {
- case 0:
- requestedRotation = DMDO_DEFAULT;
- if (currentRotation == DMDO_90 || currentRotation == DMDO_270)
- {
- shouldFlipDims = 1;
- }
- break;
- case 270:
- requestedRotation = DMDO_270;
- if (currentRotation == DMDO_DEFAULT || currentRotation == DMDO_180)
- {
- shouldFlipDims = 1;
- }
- break;
- case 180:
- requestedRotation = DMDO_180;
- if (currentRotation == DMDO_90 || currentRotation == DMDO_270)
- {
- shouldFlipDims = 1;
- }
- break;
- case 90:
- requestedRotation = DMDO_90;
- if (currentRotation == DMDO_DEFAULT || currentRotation == DMDO_180)
- {
- shouldFlipDims = 1;
- }
- break;
- default:
- //requested rotation not available
- return SCREEN_MODE_ERROR;
- break;
- }
- /** swap width and height if changing from vertical to horizantal
- * or horizantal to vertical
- */
- if (shouldFlipDims)
- {
- int tempWidth = dm.dmPelsWidth;
- dm.dmPelsWidth = dm.dmPelsHeight;
- dm.dmPelsHeight = tempWidth;
- }
- dm.dmDisplayOrientation = requestedRotation;
- dm.dmFields = DM_DISPLAYORIENTATION | DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL | DM_DISPLAYFREQUENCY;
-
- long result = ChangeDisplaySettings(&dm, 0);
- if(result == DISP_CHANGE_SUCCESSFUL)
- {
- return SCREEN_MODE_NOERROR;
- }
- return SCREEN_MODE_ERROR;
+ if (0 == EnumDisplaySettings(deviceName, ENUM_CURRENT_SETTINGS, &dm)) {
+ return JNI_FALSE;
+ }
+
+ dm.dmPelsWidth = (int)width;
+ dm.dmPelsHeight = (int)height;
+ dm.dmBitsPerPel = (int)bits;
+ dm.dmDisplayFrequency = (int)rate;
+ dm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL | DM_DISPLAYFREQUENCY;
+
+ int requestedRotation = dm.dmDisplayOrientation;
+ int currentRotation = dm.dmDisplayOrientation;
+
+ int shouldFlipDims = 0;
+
+ int rotation = (int)rot;
+ switch (rotation)
+ {
+ case 0:
+ requestedRotation = DMDO_DEFAULT;
+ if (currentRotation == DMDO_90 || currentRotation == DMDO_270)
+ {
+ shouldFlipDims = 1;
+ }
+ break;
+ case 270:
+ requestedRotation = DMDO_270;
+ if (currentRotation == DMDO_DEFAULT || currentRotation == DMDO_180)
+ {
+ shouldFlipDims = 1;
+ }
+ break;
+ case 180:
+ requestedRotation = DMDO_180;
+ if (currentRotation == DMDO_90 || currentRotation == DMDO_270)
+ {
+ shouldFlipDims = 1;
+ }
+ break;
+ case 90:
+ requestedRotation = DMDO_90;
+ if (currentRotation == DMDO_DEFAULT || currentRotation == DMDO_180)
+ {
+ shouldFlipDims = 1;
+ }
+ break;
+ default:
+ //requested rotation not available
+ return SCREEN_MODE_ERROR;
+ break;
+ }
+ /** swap width and height if changing from vertical to horizantal
+ * or horizantal to vertical
+ */
+ if (shouldFlipDims)
+ {
+ int tempWidth = dm.dmPelsWidth;
+ dm.dmPelsWidth = dm.dmPelsHeight;
+ dm.dmPelsHeight = tempWidth;
+ }
+ dm.dmDisplayOrientation = requestedRotation;
+ dm.dmFields = DM_DISPLAYORIENTATION | DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL | DM_DISPLAYFREQUENCY;
+
+ return ( DISP_CHANGE_SUCCESSFUL == ChangeDisplaySettings(&dm, 0) ) ? JNI_TRUE : JNI_FALSE ;
}
/*
@@ -1368,6 +1342,8 @@ JNIEXPORT jint JNICALL Java_com_jogamp_newt_impl_windows_WindowsScreen_setScreen
JNIEXPORT jboolean JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_initIDs0
(JNIEnv *env, jclass clazz)
{
+ NewtCommon_init(env);
+
if(NULL==pointClz) {
jclass c = (*env)->FindClass(env, ClazzNamePoint);
if(NULL==c) {
@@ -1628,31 +1604,31 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_setVisibl
static int NewtWindows_setFullScreen(jboolean fullscreen)
{
- int flags = 0;
- DEVMODE dm;
+ int flags = 0;
+ DEVMODE dm;
// initialize the DEVMODE structure
ZeroMemory(&dm, sizeof(dm));
dm.dmSize = sizeof(dm);
- if (0 == EnumDisplaySettings(NULL /*current display device*/, ENUM_CURRENT_SETTINGS, &dm))
- {
- return FULLSCREEN_ERROR;
- }
-
- if(fullscreen == JNI_TRUE)
- {
- flags = CDS_FULLSCREEN; //set fullscreen temporary
- }
- else
- {
- flags = CDS_RESET; // reset to registery values
- }
- long result = ChangeDisplaySettings(&dm, flags);
- if(result == DISP_CHANGE_SUCCESSFUL)
- {
- return FULLSCREEN_NOERROR;
- }
- return FULLSCREEN_ERROR;
+ if (0 == EnumDisplaySettings(NULL /*current display device*/, ENUM_CURRENT_SETTINGS, &dm))
+ {
+ return FULLSCREEN_ERROR;
+ }
+
+ if(fullscreen == JNI_TRUE)
+ {
+ flags = CDS_FULLSCREEN; //set fullscreen temporary
+ }
+ else
+ {
+ flags = CDS_RESET; // reset to registery values
+ }
+ long result = ChangeDisplaySettings(&dm, flags);
+ if(result == DISP_CHANGE_SUCCESSFUL)
+ {
+ return FULLSCREEN_NOERROR;
+ }
+ return FULLSCREEN_ERROR;
}
/*
@@ -1687,11 +1663,11 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_reconfigu
if(JNI_TRUE == visible) {
windowStyle |= WS_VISIBLE ;
}
-
- if(fullScreenChange < 0)
- {
- NewtWindows_setFullScreen(JNI_FALSE);
- }
+
+ if(fullScreenChange < 0)
+ {
+ NewtWindows_setFullScreen(JNI_FALSE);
+ }
// order of call sequence: (MS documentation)
// TOP: SetParent(.., NULL); Clear WS_CHILD [, Set WS_POPUP]
@@ -1700,11 +1676,11 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_reconfigu
if ( JNI_TRUE == parentChange && NULL == hwndP ) {
SetParent(hwnd, NULL);
}
-
- if(fullScreenChange > 0)
- {
- NewtWindows_setFullScreen(JNI_TRUE);
- }
+
+ if(fullScreenChange > 0)
+ {
+ NewtWindows_setFullScreen(JNI_TRUE);
+ }
if ( styleChange ) {
if(NULL!=hwndP) {
diff --git a/src/newt/native/X11Window.c b/src/newt/native/X11Window.c
index 6c6aff478..bced039b9 100644
--- a/src/newt/native/X11Window.c
+++ b/src/newt/native/X11Window.c
@@ -48,7 +48,7 @@
#include <X11/keysym.h>
#include <X11/Xatom.h>
-#include<X11/extensions/Xrandr.h>
+#include <X11/extensions/Xrandr.h>
#include "com_jogamp_newt_impl_x11_X11Screen.h"
#include "com_jogamp_newt_impl_x11_X11Display.h"
@@ -57,6 +57,7 @@
#include "MouseEvent.h"
#include "KeyEvent.h"
#include "WindowEvent.h"
+#include "ScreenMode.h"
#include "NewtCommon.h"
@@ -149,16 +150,12 @@ static void _FatalError(JNIEnv *env, const char* msg, ...)
(*env)->FatalError(env, buffer);
}
-static const char * const ClazzNameRuntimeException = "java/lang/RuntimeException";
-
static const char * const ClazzNameNewtWindow = "com/jogamp/newt/Window";
static const char * const ClazzNamePoint = "javax/media/nativewindow/util/Point";
static const char * const ClazzAnyCstrName = "<init>";
static const char * const ClazzNamePointCstrSignature = "(II)V";
-static jclass runtimeExceptionClz=NULL;
-
static jclass newtWindowClz=NULL;
static jclass pointClz = NULL;
@@ -182,18 +179,6 @@ static jmethodID enqueueRequestFocusID = NULL;
static jmethodID displayCompletedID = NULL;
-static void _throwNewRuntimeException(Display * unlockDisplay, JNIEnv *env, const char* msg, ...)
-{
- char buffer[512];
- va_list ap;
-
- va_start(ap, msg);
- vsnprintf(buffer, sizeof(buffer), msg, ap);
- va_end(ap);
-
- (*env)->ThrowNew(env, runtimeExceptionClz, buffer);
-}
-
/**
* Display
*/
@@ -212,7 +197,7 @@ static int displayDispatchErrorHandler(Display *dpy, XErrorEvent *e)
{
fprintf(stderr, " BadWindow (%p): Window probably already removed\n", (void*)e->resourceid);
} else {
- _throwNewRuntimeException(NULL, x11ErrorHandlerJNIEnv, "NEWT X11 Error: Display %p, Code 0x%X", dpy, e->error_code);
+ NewtCommon_throwNewRuntimeException(x11ErrorHandlerJNIEnv, "NEWT X11 Error: Display %p, Code 0x%X", dpy, e->error_code);
}
return 0;
@@ -240,6 +225,8 @@ JNIEXPORT jboolean JNICALL Java_com_jogamp_newt_impl_x11_X11Display_initIDs0
{
jclass c;
+ NewtCommon_init(env);
+
displayCompletedID = (*env)->GetMethodID(env, clazz, "displayCompleted", "(JJ)V");
if (displayCompletedID == NULL) {
return JNI_FALSE;
@@ -257,18 +244,6 @@ JNIEXPORT jboolean JNICALL Java_com_jogamp_newt_impl_x11_X11Display_initIDs0
}
}
- if(NULL==runtimeExceptionClz) {
- c = (*env)->FindClass(env, ClazzNameRuntimeException);
- if(NULL==c) {
- _FatalError(env, "NEWT X11Window: can't find %s", ClazzNameRuntimeException);
- }
- runtimeExceptionClz = (jclass)(*env)->NewGlobalRef(env, c);
- (*env)->DeleteLocalRef(env, c);
- if(NULL==runtimeExceptionClz) {
- _FatalError(env, "NEWT X11Window: can't use %s", ClazzNameRuntimeException);
- }
- }
-
if(NULL==pointClz) {
c = (*env)->FindClass(env, ClazzNamePoint);
if(NULL==c) {
@@ -306,13 +281,13 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Display_CompleteDisplay0
javaObjectAtom = (jlong) XInternAtom(dpy, "JOGL_JAVA_OBJECT", False);
if(None==javaObjectAtom) {
- _throwNewRuntimeException(dpy, env, "could not create Atom JOGL_JAVA_OBJECT, bail out!");
+ NewtCommon_throwNewRuntimeException(env, "could not create Atom JOGL_JAVA_OBJECT, bail out!");
return;
}
windowDeleteAtom = (jlong) XInternAtom(dpy, "WM_DELETE_WINDOW", False);
if(None==windowDeleteAtom) {
- _throwNewRuntimeException(dpy, env, "could not create Atom WM_DELETE_WINDOW, bail out!");
+ NewtCommon_throwNewRuntimeException(env, "could not create Atom WM_DELETE_WINDOW, bail out!");
return;
}
@@ -400,7 +375,7 @@ static jobject getJavaWindowProperty(JNIEnv *env, Display *dpy, Window window, j
#ifdef VERBOSE_ON
if(JNI_FALSE == (*env)->IsInstanceOf(env, jwindow, newtWindowClz)) {
- _throwNewRuntimeException(dpy, env, "fetched Atom JOGL_JAVA_OBJECT window is not a NEWT Window: javaWindow 0x%X !", jwindow);
+ NewtCommon_throwNewRuntimeException(env, "fetched Atom JOGL_JAVA_OBJECT window is not a NEWT Window: javaWindow 0x%X !", jwindow);
}
#endif
return jwindow;
@@ -480,8 +455,6 @@ static void NewtWindows_setDecorations (Display *dpy, Window w, Bool decorated)
#define _NET_WM_STATE_REMOVE 0
#define _NET_WM_STATE_ADD 1
-
-
static void NewtWindows_setFullscreen (Display *dpy, Window root, Window w, Bool fullscreen) {
Atom _NET_WM_STATE = XInternAtom( dpy, "_NET_WM_STATE", False );
Atom _NET_WM_STATE_ABOVE = XInternAtom( dpy, "_NET_WM_STATE_ABOVE", False );
@@ -555,12 +528,12 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Display_DispatchMessages
num_events--;
if( 0==evt.xany.window ) {
- _throwNewRuntimeException(dpy, env, "event window NULL, bail out!");
+ NewtCommon_throwNewRuntimeException(env, "event window NULL, bail out!");
return ;
}
if(dpy!=evt.xany.display) {
- _throwNewRuntimeException(dpy, env, "wrong display, bail out!");
+ NewtCommon_throwNewRuntimeException(env, "wrong display, bail out!");
return ;
}
@@ -808,7 +781,7 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Display_DispatchMessages
* Signature: (JI)J
*/
JNIEXPORT jlong JNICALL Java_com_jogamp_newt_impl_x11_X11Screen_GetScreen0
- (JNIEnv *env, jobject obj, jlong display, jint screen_index)
+ (JNIEnv *env, jclass clazz, jlong display, jint screen_index)
{
Display * dpy = (Display *)(intptr_t)display;
Screen * scrn= NULL;
@@ -831,176 +804,224 @@ JNIEXPORT jlong JNICALL Java_com_jogamp_newt_impl_x11_X11Screen_GetScreen0
}
JNIEXPORT jint JNICALL Java_com_jogamp_newt_impl_x11_X11Screen_getWidth0
- (JNIEnv *env, jobject obj, jlong display, jint scrn_idx)
+ (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
{
Display * dpy = (Display *) (intptr_t) display;
return (jint) XDisplayWidth( dpy, scrn_idx);
}
JNIEXPORT jint JNICALL Java_com_jogamp_newt_impl_x11_X11Screen_getHeight0
- (JNIEnv *env, jobject obj, jlong display, jint scrn_idx)
+ (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
{
Display * dpy = (Display *) (intptr_t) display;
return (jint) XDisplayHeight( dpy, scrn_idx);
}
+
+static Bool NewtScreen_getRANDRVersion(Display *dpy, int *major, int *minor) {
+ if( 0 == XRRQueryVersion(dpy, major, minor) ) {
+ return False;
+ }
+ return True;
+}
+
+static Bool NewtScreen_hasRANDR(Display *dpy) {
+ int major, minor;
+ return NewtScreen_getRANDRVersion(dpy, &major, &minor);
+}
+
+static int NewtScreen_XRotation2Degree(JNIEnv *env, int xrotation) {
+ int rot;
+ if(xrotation == RR_Rotate_0) {
+ rot = 0;
+ }
+ else if(xrotation == RR_Rotate_90) {
+ rot = 90;
+ }
+ else if(xrotation == RR_Rotate_180) {
+ rot = 180;
+ }
+ else if(xrotation == RR_Rotate_270) {
+ rot = 270;
+ } else {
+ NewtCommon_throwNewRuntimeException(env, "invalid native rotation: %d", xrotation);
+ }
+ return rot;
+}
+
/*
* Class: com_jogamp_newt_impl_x11_X11Screen
- * Method: getDesktopScreenModeIndex0
+ * Method: getAvailableScreenModeRotations0
* Signature: (JI)I
*/
-JNIEXPORT jint JNICALL Java_com_jogamp_newt_impl_x11_X11Screen_getDesktopScreenModeIndex0
- (JNIEnv *env, jobject object, jlong display, jint scrn_indx)
+JNIEXPORT jintArray JNICALL Java_com_jogamp_newt_impl_x11_X11Screen_getAvailableScreenModeRotations0
+ (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
{
- Display *dpy = (Display *) (intptr_t) display;
- Window root = RootWindow(dpy, (int)scrn_indx);
-
- // get current resolutions and frequency configuration
- XRRScreenConfiguration *conf = XRRGetScreenInfo(dpy, root);
- short original_rate = XRRConfigCurrentRate(conf);
-
- Rotation original_rotation;
- SizeID original_size_id = XRRConfigCurrentConfiguration(conf, &original_rotation);
-
- //free
- XRRFreeScreenConfigInfo(conf);
-
- return (jint)original_size_id;
-}
+ Display *dpy = (Display *) (intptr_t) display;
+ Window root = RootWindow(dpy, (int)scrn_idx);
+ int num_rotations = 0;
+ Rotation cur_rotation, rotations_supported;
+ int rotations[4];
+ int major, minor;
+
+ if(False == NewtScreen_getRANDRVersion(dpy, &major, &minor)) {
+ fprintf(stderr, "RANDR not available\n");
+ } else {
+ fprintf(stderr, "RANDR %d.%d available\n", major, minor);
+ }
-static void X11Screen_changeScreenMode(Display* dpy, Window root, int screen_indx, XRRScreenSize *xrrs, int screenModeIndex, short freq, int rotation)
-{
- int num_rates; //number of available rates for selected mode index
- short *rates = XRRRates(dpy, screen_indx, screenModeIndex, &num_rates);
-
- XRRScreenConfiguration *conf = XRRGetScreenInfo(dpy, root);
-
- int rot = RR_Rotate_0;
-
- if(rotation == 90)
- {
- rot = RR_Rotate_90;
+ rotations_supported = XRRRotations (dpy, (int)scrn_idx, &cur_rotation);
+
+ if(0 != (rotations_supported & RR_Rotate_0)) {
+ rotations[num_rotations++] = 0;
}
- else if(rotation == 180)
- {
- rot = RR_Rotate_180;
+ if(0 != (rotations_supported & RR_Rotate_90)) {
+ rotations[num_rotations++] = 90;
}
- else if(rotation == 270)
- {
- rot = RR_Rotate_270;
+ if(0 != (rotations_supported & RR_Rotate_180)) {
+ rotations[num_rotations++] = 180;
}
- // Change the resolution
- DBG_PRINT("\nCHANGED TO %i x %i PIXELS, %i Hz\n\n", xrrs[screenModeIndex].width, xrrs[screenModeIndex].height, selectedFreq);
- XRRSetScreenConfigAndRate(dpy, conf, root, screenModeIndex, rot, freq, CurrentTime);
-
- //free
- XRRFreeScreenConfigInfo(conf);
+ if(0 != (rotations_supported & RR_Rotate_270)) {
+ rotations[num_rotations++] = 270;
+ }
+
+ jintArray properties = NULL;
+
+ if(num_rotations>0) {
+ properties = (*env)->NewIntArray(env, num_rotations);
+ if (properties == NULL)
+ {
+ NewtCommon_throwNewRuntimeException(env, "Could not allocate int array of size %d", num_rotations);
+ }
+
+ // move from the temp structure to the java structure
+ (*env)->SetIntArrayRegion(env, properties, 0, num_rotations, rotations);
+ }
+
+ return properties;
}
/*
* Class: com_jogamp_newt_impl_x11_X11Screen
- * Method: setScreenMode0
- * Signature: (JIIS)V
+ * Method: getNumScreenModeResolution0
+ * Signature: (JI)I
*/
-JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Screen_setScreenMode0
- (JNIEnv *env, jobject object, jlong display, jint scrn_indx, jint mode_indx, jshort freq, jint rotation)
+JNIEXPORT jint JNICALL Java_com_jogamp_newt_impl_x11_X11Screen_getNumScreenModeResolutions0
+ (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
{
Display *dpy = (Display *) (intptr_t) display;
- Window root = RootWindow(dpy, (int)scrn_indx);
+ Window root = RootWindow(dpy, (int)scrn_idx);
+
+ if(False == NewtScreen_hasRANDR(dpy)) {
+ return 0;
+ }
int num_sizes;
- XRRScreenSize *xrrs = XRRSizes(dpy, (int)scrn_indx, &num_sizes); //get possible screen resolutions
- int screenModeIndex = (int)mode_indx;
+ XRRScreenSize *xrrs = XRRSizes(dpy, (int)scrn_idx, &num_sizes); //get possible screen resolutions
- if((screenModeIndex > num_sizes) || (screenModeIndex < 0))
- {
- DBG_PRINT("\nSelected mode index not available for selected screen, index: %i\n", screenModeIndex);
- return;
- }
-
- X11Screen_changeScreenMode(dpy, root, (int)scrn_indx, xrrs, screenModeIndex, (short)freq, (int)rotation);
+ return num_sizes;
}
-#define NUM_SCREEN_MODE_PROPERTIES 3
-
/*
* Class: com_jogamp_newt_impl_x11_X11Screen
- * Method: getScreenMode0
+ * Method: getScreenModeResolutions0
* Signature: (JII)[I
*/
-JNIEXPORT jintArray JNICALL Java_com_jogamp_newt_impl_x11_X11Screen_getScreenMode0
- (JNIEnv *env, jobject object, jlong display, jint scrn_indx, jint mode_indx)
+JNIEXPORT jintArray JNICALL Java_com_jogamp_newt_impl_x11_X11Screen_getScreenModeResolution0
+ (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx, jint resMode_idx)
{
Display *dpy = (Display *) (intptr_t) display;
- Window root = RootWindow(dpy, (int)scrn_indx);
+ Window root = RootWindow(dpy, (int)scrn_idx);
+ if(False == NewtScreen_hasRANDR(dpy)) {
+ return NULL;
+ }
+
int num_sizes;
- XRRScreenSize *xrrs = XRRSizes(dpy, (int)scrn_indx, &num_sizes); //get possible screen resolutions
+ XRRScreenSize *xrrs = XRRSizes(dpy, (int)scrn_idx, &num_sizes); //get possible screen resolutions
- int num_rates;
- short *rates = XRRRates(dpy, (int)scrn_indx, (int)mode_indx, &num_rates);
-
- int prop_size = NUM_SCREEN_MODE_PROPERTIES +num_rates;
-
- jintArray properties = (*env)->NewIntArray(env, prop_size);
- if (properties == NULL)
- {
- return NULL; /* out of memory error thrown */
+ if( 0 > resMode_idx || resMode_idx >= num_sizes ) {
+ NewtCommon_throwNewRuntimeException(env, "Invalid resolution index: ! 0 < %d < %d", resMode_idx, num_sizes);
}
-
- //Fill the properties in temp jint array
+
+ // Fill the properties in temp jint array
int propIndex = 0;
- jint prop[prop_size];
+ jint prop[4];
- prop[propIndex++] = (int)mode_indx;
- prop[propIndex++] = xrrs[(int)mode_indx].width;
- prop[propIndex++] = xrrs[(int)mode_indx].height;
+ prop[propIndex++] = xrrs[(int)resMode_idx].width;
+ prop[propIndex++] = xrrs[(int)resMode_idx].height;
+ prop[propIndex++] = xrrs[(int)resMode_idx].mwidth;
+ prop[propIndex++] = xrrs[(int)resMode_idx].mheight;
- //loop through all possible resolutions
- //with the selectable display frequencies
- int i= 0;
- while(i < num_rates)
- {
- prop[propIndex++] = rates[i];
- i++;
- }
+ jintArray properties = (*env)->NewIntArray(env, 4);
+ if (properties == NULL) {
+ NewtCommon_throwNewRuntimeException(env, "Could not allocate int array of size %d", 4);
+ }
-
// move from the temp structure to the java structure
- (*env)->SetIntArrayRegion(env, properties, 0, prop_size, prop);
+ (*env)->SetIntArrayRegion(env, properties, 0, 4, prop);
return properties;
}
/*
* Class: com_jogamp_newt_impl_x11_X11Screen
- * Method: getNumScreenModes0
- * Signature: (JI)I
+ * Method: getScreenModeRates0
+ * Signature: (JII)[I
*/
-JNIEXPORT jint JNICALL Java_com_jogamp_newt_impl_x11_X11Screen_getNumScreenModes0
- (JNIEnv *env, jobject object, jlong display, jint scrn_indx)
+JNIEXPORT jintArray JNICALL Java_com_jogamp_newt_impl_x11_X11Screen_getScreenModeRates0
+ (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx, jint resMode_idx)
{
Display *dpy = (Display *) (intptr_t) display;
- Window root = RootWindow(dpy, (int)scrn_indx);
+ Window root = RootWindow(dpy, (int)scrn_idx);
+ if(False == NewtScreen_hasRANDR(dpy)) {
+ return NULL;
+ }
+
int num_sizes;
- XRRScreenSize *xrrs = XRRSizes(dpy, (int)scrn_indx, &num_sizes); //get possible screen resolutions
+ XRRScreenSize *xrrs = XRRSizes(dpy, (int)scrn_idx, &num_sizes); //get possible screen resolutions
+
+ if( 0 > resMode_idx || resMode_idx >= num_sizes ) {
+ NewtCommon_throwNewRuntimeException(env, "Invalid resolution index: ! 0 < %d < %d", resMode_idx, num_sizes);
+ }
+
+ int num_rates;
+ short *rates = XRRRates(dpy, (int)scrn_idx, (int)resMode_idx, &num_rates);
+
+ jint prop[num_rates];
+ int i;
+ for(i=0; i<num_rates; i++) {
+ prop[i] = (int) rates[i];
+ /** fprintf(stderr, "rate[%d, %d, %d/%d]: %d\n", (int)scrn_idx, resMode_idx, i, num_rates, prop[i]); */
+ }
- return num_sizes;
+ jintArray properties = (*env)->NewIntArray(env, num_rates);
+ if (properties == NULL) {
+ NewtCommon_throwNewRuntimeException(env, "Could not allocate int array of size %d", num_rates);
+ }
+
+ // move from the temp structure to the java structure
+ (*env)->SetIntArrayRegion(env, properties, 0, num_rates, prop);
+
+ return properties;
}
-
/*
* Class: com_jogamp_newt_impl_x11_X11Screen
* Method: getCurrentScreenRate0
- * Signature: (JI)S
+ * Signature: (JI)I
*/
-JNIEXPORT jshort JNICALL Java_com_jogamp_newt_impl_x11_X11Screen_getCurrentScreenRate0
- (JNIEnv *env, jobject object, jlong display, jint scrn_indx)
+JNIEXPORT jint JNICALL Java_com_jogamp_newt_impl_x11_X11Screen_getCurrentScreenRate0
+ (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
{
Display *dpy = (Display *) (intptr_t) display;
- Window root = RootWindow(dpy, (int)scrn_indx);
+ Window root = RootWindow(dpy, (int)scrn_idx);
+ if(False == NewtScreen_hasRANDR(dpy)) {
+ return -1;
+ }
+
// get current resolutions and frequencies
XRRScreenConfiguration *conf = XRRGetScreenInfo(dpy, root);
short original_rate = XRRConfigCurrentRate(conf);
@@ -1008,7 +1029,7 @@ JNIEXPORT jshort JNICALL Java_com_jogamp_newt_impl_x11_X11Screen_getCurrentScree
//free
XRRFreeScreenConfigInfo(conf);
- return original_rate;
+ return (jint) original_rate;
}
/*
@@ -1017,11 +1038,15 @@ JNIEXPORT jshort JNICALL Java_com_jogamp_newt_impl_x11_X11Screen_getCurrentScree
* Signature: (JI)I
*/
JNIEXPORT jint JNICALL Java_com_jogamp_newt_impl_x11_X11Screen_getCurrentScreenRotation0
- (JNIEnv *env, jobject object, jlong display, jint scrn_indx)
+ (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
{
Display *dpy = (Display *) (intptr_t) display;
- Window root = RootWindow(dpy, (int)scrn_indx);
+ Window root = RootWindow(dpy, (int)scrn_idx);
+ if(False == NewtScreen_hasRANDR(dpy)) {
+ return -1;
+ }
+
//get current resolutions and frequencies
XRRScreenConfiguration *conf = XRRGetScreenInfo(dpy, root);
@@ -1031,68 +1056,122 @@ JNIEXPORT jint JNICALL Java_com_jogamp_newt_impl_x11_X11Screen_getCurrentScreenR
//free
XRRFreeScreenConfigInfo(conf);
- int rot = -1;
-
- if(rotation == RR_Rotate_0) {
- rot = 0;
- }
- else if(rotation == RR_Rotate_90) {
- rot = 90;
- }
- else if(rotation == RR_Rotate_180) {
- rot = 180;
- }
- else if(rotation == RR_Rotate_270) {
- rot = 270;
- }
-
- return rot;
+ return NewtScreen_XRotation2Degree(env, rotation);
+}
+
+
+/*
+ * Class: com_jogamp_newt_impl_x11_X11Screen
+ * Method: getCurrentScreenResolutionIndex0
+ * Signature: (JI)I
+ */
+JNIEXPORT jint JNICALL Java_com_jogamp_newt_impl_x11_X11Screen_getCurrentScreenResolutionIndex0
+ (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
+{
+ Display *dpy = (Display *) (intptr_t) display;
+ Window root = RootWindow(dpy, (int)scrn_idx);
+
+ if(False == NewtScreen_hasRANDR(dpy)) {
+ return -1;
+ }
+
+ // get current resolutions and frequency configuration
+ XRRScreenConfiguration *conf = XRRGetScreenInfo(dpy, root);
+ short original_rate = XRRConfigCurrentRate(conf);
+
+ Rotation original_rotation;
+ SizeID original_size_id = XRRConfigCurrentConfiguration(conf, &original_rotation);
+
+ //free
+ XRRFreeScreenConfigInfo(conf);
+
+ return (jint)original_size_id;
}
/*
* Class: com_jogamp_newt_impl_x11_X11Screen
- * Method: setScreenRotation0
- * Signature: (JII)V
+ * Method: setScreenMode0
+ * Signature: (JIIII)Z
*/
-JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Screen_setScreenRotation0
- (JNIEnv *env, jobject object, jlong display, jint scrn_indx, jint rotation)
+JNIEXPORT jboolean JNICALL Java_com_jogamp_newt_impl_x11_X11Screen_setCurrentScreenMode0
+ (JNIEnv *env, jclass clazz, jlong display, jint screen_idx, jint resMode_idx, jint freq, jint rotation)
{
+ int randr_event_base, randr_error_base;
Display *dpy = (Display *) (intptr_t) display;
- Window root = RootWindow(dpy, (int)scrn_indx);
-
- int rot = -1;
-
- if(rotation == 0)
- {
- rot = RR_Rotate_0;
- }
- else if(rotation == 90)
- {
- rot = RR_Rotate_90;
- }
- else if(rotation == 180)
- {
- rot = RR_Rotate_180;
+ Window root = RootWindow(dpy, (int)screen_idx);
+
+ if(False == NewtScreen_hasRANDR(dpy)) {
+ return JNI_FALSE;
}
- else if(rotation == 270)
- {
- rot = RR_Rotate_270;
+
+ XRRQueryExtension(dpy, &randr_event_base, &randr_error_base);
+ DBG_PRINT("RANDR: event_base: %d\n", randr_event_base);
+
+ int num_sizes;
+ XRRScreenSize *xrrs = XRRSizes(dpy, (int)screen_idx, &num_sizes); //get possible screen resolutions
+ XRRScreenConfiguration *conf;
+ int rot;
+
+ if( 0 > resMode_idx || resMode_idx >= num_sizes ) {
+ NewtCommon_throwNewRuntimeException(env, "Invalid resolution index: ! 0 < %d < %d", resMode_idx, num_sizes);
}
- else
- {
- return;
+
+ conf = XRRGetScreenInfo(dpy, root);
+
+ switch(rotation) {
+ case 0:
+ rot = RR_Rotate_0;
+ break;
+ case 90:
+ rot = RR_Rotate_90;
+ break;
+ case 180:
+ rot = RR_Rotate_180;
+ break;
+ case 270:
+ rot = RR_Rotate_270;
+ break;
+ default:
+ NewtCommon_throwNewRuntimeException(env, "Invalid rotation: %d", rotation);
}
- XRRScreenConfiguration *conf = XRRGetScreenInfo(dpy, root);
-
- Rotation current_rotation;
- SizeID current_mode_id = XRRConfigCurrentConfiguration(conf, &current_rotation);
- short current_rate = XRRConfigCurrentRate(conf);
+ DBG_PRINT("X11Screen.setCurrentScreenMode0: CHANGED TO %d: %d x %d PIXELS, %d Hz, %d degree\n",
+ resMode_idx, xrrs[resMode_idx].width, xrrs[resMode_idx].height, (int)freq, rotation);
+
+ XRRSelectInput (dpy, root, RRScreenChangeNotifyMask);
+
+ XSync(dpy, False);
+ XRRSetScreenConfigAndRate(dpy, conf, root, (int)resMode_idx, rot, (short)freq, CurrentTime);
+ XSync(dpy, False);
+
+ XEvent evt;
+ XRRScreenChangeNotifyEvent * scn_event = (XRRScreenChangeNotifyEvent *) &evt;
+ int done = 0;
+ do {
+ // XWindowEvent(dpy, root, randr_event_base + RRScreenChangeNotify, &evt);
+ XNextEvent(dpy, &evt);
+
+ switch (evt.type - randr_event_base) {
+ case RRScreenChangeNotify:
+ rot = NewtScreen_XRotation2Degree(env, (int)scn_event->rotation);
+ DBG_PRINT( "XRANDR: event . RRScreenChangeNotify call %p (root %p) resIdx %d rot %d %dx%d\n",
+ (void*)scn_event->window, (void*)scn_event->root,
+ (int)scn_event->size_index, rot,
+ scn_event->width, scn_event->height);
+ // done = scn_event->size_index == resMode_idx; // not reliable ..
+ done = rot == rotation &&
+ scn_event->width == xrrs[resMode_idx].width &&
+ scn_event->height == xrrs[resMode_idx].height;
+ break;
+ default:
+ DBG_PRINT("RANDR: event . unhandled %d 0x%X call %p\n", (int)evt.type, (int)evt.type, (void*)evt.xany.window);
+ }
+ XRRUpdateConfiguration(&evt);
+ } while(!done);
- XRRSetScreenConfigAndRate(dpy, conf, root, current_mode_id, rot, current_rate, CurrentTime);
-
//free
XRRFreeScreenConfigInfo(conf);
+ XSync(dpy, False);
}
/**
@@ -1175,7 +1254,7 @@ JNIEXPORT jlong JNICALL Java_com_jogamp_newt_impl_x11_X11Window_CreateWindow0
}
if(visualID<0) {
- _throwNewRuntimeException(NULL, env, "invalid VisualID ..");
+ NewtCommon_throwNewRuntimeException(env, "invalid VisualID ..");
return 0;
}
@@ -1209,7 +1288,7 @@ JNIEXPORT jlong JNICALL Java_com_jogamp_newt_impl_x11_X11Window_CreateWindow0
if (visual==NULL)
{
- _throwNewRuntimeException(dpy, env, "could not query Visual by given VisualID, bail out!");
+ NewtCommon_throwNewRuntimeException(env, "could not query Visual by given VisualID, bail out!");
return 0;
}
@@ -1247,7 +1326,7 @@ JNIEXPORT jlong JNICALL Java_com_jogamp_newt_impl_x11_X11Window_CreateWindow0
&xswa);
if(0==window) {
- _throwNewRuntimeException(dpy, env, "could not create Window, bail out!");
+ NewtCommon_throwNewRuntimeException(env, "could not create Window, bail out!");
return 0;
}
@@ -1294,11 +1373,11 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_CloseWindow0
jwindow = getJavaWindowProperty(env, dpy, w, javaObjectAtom, True);
if(NULL==jwindow) {
- _throwNewRuntimeException(dpy, env, "could not fetch Java Window object, bail out!");
+ NewtCommon_throwNewRuntimeException(env, "could not fetch Java Window object, bail out!");
return;
}
if ( JNI_FALSE == (*env)->IsSameObject(env, jwindow, obj) ) {
- _throwNewRuntimeException(dpy, env, "Internal Error .. Window global ref not the same!");
+ NewtCommon_throwNewRuntimeException(env, "Internal Error .. Window global ref not the same!");
return;
}
@@ -1416,7 +1495,6 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_reconfigureWindow
NewtWindows_setPosSize(dpy, w, x, y, width, height);
-
if(0 < fullscreenChange ) { // FS on
NewtWindows_setFullscreen(dpy, root, w, True );
XSync(dpy, False);