From 6ebf649d1b87944257fe492e0aef842d1b8debc2 Mon Sep 17 00:00:00 2001
From: Sven Gothel
+ * Coverage is computed by:
+ * 0.0
and 1.0
.
+ *
+ * isect = this.intersection(r);
+ * coverage = area( isect ) / area( this ) ;
+ *
+ *
Rectangle
are equal if the four integer values
diff --git a/src/nativewindow/classes/javax/media/nativewindow/util/SurfaceSize.java b/src/nativewindow/classes/javax/media/nativewindow/util/SurfaceSize.java
index 8f21bc49b..d7e451af8 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/util/SurfaceSize.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/util/SurfaceSize.java
@@ -36,8 +36,8 @@ package javax.media.nativewindow.util;
*
*/
public class SurfaceSize {
- DimensionImmutable resolution;
- int bitsPerPixel;
+ final DimensionImmutable resolution;
+ final int bitsPerPixel;
public SurfaceSize(DimensionImmutable resolution, int bitsPerPixel) {
if(null==resolution || bitsPerPixel<=0) {
diff --git a/src/newt/classes/com/jogamp/newt/MonitorDevice.java b/src/newt/classes/com/jogamp/newt/MonitorDevice.java
new file mode 100644
index 000000000..fbe4d8cf0
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/MonitorDevice.java
@@ -0,0 +1,235 @@
+/**
+ * Copyright 2013 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;
+
+import java.util.List;
+
+import javax.media.nativewindow.util.DimensionImmutable;
+import javax.media.nativewindow.util.Rectangle;
+import javax.media.nativewindow.util.RectangleImmutable;
+
+import com.jogamp.common.util.ArrayHashSet;
+
+/**
+ * Visual output device, i.e. a CRT, LED ..consisting of it's components:List<MonitorMode>
supportedModesMonitorDevice
objects
+ * by evaluating equality of it's components:nativeID
nativeID
true
if given coordinates are contained by this {@link #getViewport() viewport}, otherwise false
. */
+ public final boolean contains(int x, int y) {
+ return x >= viewport.getX() &&
+ x < viewport.getX() + viewport.getWidth() &&
+ y >= viewport.getY() &&
+ y < viewport.getY() + viewport.getHeight() ;
+ }
+
+ /**
+ * Returns the coverage of given rectangle w/ this this {@link #getViewport() viewport}, i.e. between 0.0
and 1.0
.
+ * + * Coverage is computed by: + *
+ * isect = viewport.intersection(r); + * coverage = area( isect ) / area( viewport ) ; + *+ * + */ + public final float coverage(RectangleImmutable r) { + return viewport.coverage(r); + } + + /** + * Returns the union of the given monitor's {@link #getViewport() viewport}. + * @param result storage for result, will be returned + * @param monitors given list of monitors + * @return viewport representing the union of given monitor's viewport. + */ + public static Rectangle unionOfViewports(final Rectangle result, final List
true if the {@link MonitorMode}
+ * has been changed programmatic via this API only, otherwise false
.
+ *
+ * Note: We cannot guarantee that we won't interfere w/ another running
+ * application's screen mode change or vice versa.
+ *
+ */
+ public final boolean isModeChangedByUs() {
+ return modeChanged && !isOriginalMode();
+ }
+
+ /**
+ * Return the current cached {@link MonitorMode} w/o native query.
+ *
+ * If {@link MonitorMode}s are not supported for this
+ * native type {@link com.jogamp.newt.Display#getType()}, it returns one with the current screen size.
+ *
+ * @return current {@link MonitorMode} which is element of the list {@link #getSupportedModes()} and {@link Screen#getMonitorModes()}.
+ */
+ public final MonitorMode getCurrentMode() {
+ return currentMode;
+ }
+
+ /**
+ * Return the current {@link MonitorMode} including a native query.
+ *
+ * If {@link MonitorMode}s are not supported for this
+ * native type {@link com.jogamp.newt.Display#getType()}, it returns one with the current screen size.
+ *
+ * @return current {@link MonitorMode} which is element of the list {@link #getSupportedModes()} and {@link Screen#getMonitorModes()}.
+ */
+ public abstract MonitorMode queryCurrentMode();
+
+ /**
+ * Set the current {@link com.jogamp.newt.MonitorMode}.
+ * @param mode to be made current, must be element of the list {@link #getSupportedModes()} and {@link Screen#getMonitorModes()}.
+ * @return true if successful, otherwise false
+ */
+ public abstract boolean setCurrentMode(MonitorMode mode);
+
+ public String toString() {
+ return "Monitor[Id "+Display.toHexString(nativeId)+", "+sizeMM+" mm, viewport "+viewport+ ", orig "+originalMode+", curr "+currentMode+
+ ", modeChanged "+modeChanged+", modeCount "+supportedModes.size()+"]";
+ }
+}
+
diff --git a/src/newt/classes/com/jogamp/newt/MonitorMode.java b/src/newt/classes/com/jogamp/newt/MonitorMode.java
new file mode 100644
index 000000000..e5b329d47
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/MonitorMode.java
@@ -0,0 +1,346 @@
+/**
+ * Copyright 2013 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;
+
+import javax.media.nativewindow.util.DimensionImmutable;
+import javax.media.nativewindow.util.SurfaceSize;
+
+
+/** Immutable MonitorMode Class, consisting of it's read only components:
+ *
+ * - nativeId
+ * - {@link SizeAndRRate}, non rotated surfaceSize and refreshRate
+ * rotation
, measured counter clockwise (CCW)
+ *
+ *
+ * Aquire and filter MonitorMode
+ *
+ * - A List of read only MonitorModes is being returned by {@link com.jogamp.newt.Screen#getMonitorModes()}.
+ * - You may utilize {@link com.jogamp.newt.util.MonitorModeUtil} to filter and select a desired ScreenMode.
+ * - The current ScreenMode can be obtained via {@link com.jogamp.newt.Screen#getCurrentScreenMode()}.
+ * - The initial original ScreenMode (at startup) can be obtained via {@link com.jogamp.newt.Screen#getOriginalScreenMode()}.
+ *
+ *
+ *
+ * Changing ScreenModes
+ * FIXME!!!!!
+ *
+ * - Use {@link com.jogamp.newt.Screen#setCurrentScreenMode(com.jogamp.newt.MonitorMode)}
+ * to change the current ScreenMode of all Screen's referenced via the full qualified name (FQN)
+ * {@link com.jogamp.newt.Screen#getFQName()}.
+ * - When the last FQN referenced Screen closes, the original ScreenMode ({@link com.jogamp.newt.Screen#getOriginalScreenMode()})
+ * is restored.
+ *
+ *
+ * Example for changing the ScreenMode:
+ *
+ // determine target refresh rate
+ ScreenMode orig = screen.getOriginalScreenMode();
+ int freq = orig.getOutputMode().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));
+ *
+ *
+ * X11 / AMD just works
+ *
+ * X11 / NVidia difficulties
+ *
+ 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"
+ *
+ *
+ */
+public class MonitorMode {
+ /**
+ * Immutable surfaceSize and refreshRate Class, consisting of it's read only components:
+ *
+ * - nativeId
+ * - {@link SurfaceSize} surface memory size
+ * refresh rate
+ *
+ */
+ public static class SizeAndRRate {
+ public final SurfaceSize surfaceSize;
+ public final float refreshRate;
+ public final int flags;
+ public final int hashCode;
+
+ public SizeAndRRate(SurfaceSize surfaceSize, float refreshRate, int flags) {
+ if(null==surfaceSize) {
+ throw new IllegalArgumentException("surfaceSize must be set ("+surfaceSize+")");
+ }
+ this.surfaceSize=surfaceSize;
+ this.refreshRate=refreshRate;
+ this.flags = flags;
+ this.hashCode = getHashCode();
+ }
+
+ private final static String STR_INTERLACE = "Interlace";
+ private final static String STR_DOUBLESCAN = "DoubleScan";
+ private final static String STR_SEP = ", ";
+
+ public static final StringBuffer flags2String(int flags) {
+ final StringBuffer sb = new StringBuffer();
+ boolean sp = false;
+ if( 0 != ( flags & FLAG_INTERLACE ) ) {
+ sb.append(STR_INTERLACE);
+ sp = true;
+ }
+ if( 0 != ( flags & FLAG_DOUBLESCAN ) ) {
+ if( sp ) {
+ sb.append(STR_SEP);
+ }
+ sb.append(STR_DOUBLESCAN);
+ sp = true;
+ }
+ return sb;
+ }
+ public final String toString() {
+ return new String(surfaceSize+" @ "+refreshRate+" Hz, flags ["+flags2String(flags).toString()+"]");
+ }
+
+ /**
+ * Tests equality of two {@link SizeAndRRate} objects
+ * by evaluating equality of it's components:
+ *
+ * surfaceSize
+ * refreshRate
+ * flags
+ *
+ */
+ public final boolean equals(Object obj) {
+ if (this == obj) { return true; }
+ if (obj instanceof SizeAndRRate) {
+ final SizeAndRRate p = (SizeAndRRate)obj;
+ return surfaceSize.equals(p.surfaceSize) &&
+ refreshRate == p.refreshRate &&
+ flags == p.flags ;
+ }
+ return false;
+ }
+
+ /**
+ * Returns a combined hash code of it's elements:
+ *
+ * surfaceSize
+ * refreshRate
+ * flags
+ *
+ */
+ public final int hashCode() {
+ return hashCode;
+ }
+ private final int getHashCode() {
+ // 31 * x == (x << 5) - x
+ int hash = 31 + surfaceSize.hashCode();
+ hash = ((hash << 5) - hash) + (int)(refreshRate*100.0f);
+ hash = ((hash << 5) - hash) + flags;
+ return hash;
+ }
+ }
+
+ /** zero rotation, compared to normal settings */
+ public static final int ROTATE_0 = 0;
+
+ /** 90 degrees CCW rotation */
+ public static final int ROTATE_90 = 90;
+
+ /** 180 degrees CCW rotation */
+ public static final int ROTATE_180 = 180;
+
+ /** 270 degrees CCW rotation */
+ public static final int ROTATE_270 = 270;
+
+ /** Frame is split into two fields. See {@link #getFlags()}. */
+ public static final int FLAG_INTERLACE = 1 << 0;
+
+ /** Lines are doubled. See {@link #getFlags()}. */
+ public static final int FLAG_DOUBLESCAN = 1 << 1;
+
+ /** The immutable native Id of this instance, which may not be unique. */
+ private final int nativeId;
+ private final SizeAndRRate sizeAndRRate;
+ private final int rotation;
+ private final int hashCode;
+
+ public static boolean isRotationValid(int rotation) {
+ return rotation == MonitorMode.ROTATE_0 || rotation == MonitorMode.ROTATE_90 ||
+ rotation == MonitorMode.ROTATE_180 || rotation == MonitorMode.ROTATE_270 ;
+ }
+
+ /**
+ * @param sizeAndRRate the surface size and refresh rate mode
+ * @param rotation the screen rotation, measured counter clockwise (CCW)
+ */
+ public MonitorMode(int nativeId, SizeAndRRate sizeAndRRate, int rotation) {
+ if ( !isRotationValid(rotation) ) {
+ throw new RuntimeException("invalid rotation: "+rotation);
+ }
+ this.nativeId = nativeId;
+ this.sizeAndRRate = sizeAndRRate;
+ this.rotation = rotation;
+ this.hashCode = getHashCode();
+ }
+
+ /**
+ * Creates a user instance w/o {@link #getId() identity} to filter our matching modes w/ identity.
+ *
+ * See {@link com.jogamp.newt.util.MonitorModeUtil} for filter utilities.
+ *
+ * @param surfaceSize
+ * @param refreshRate
+ * @param flags
+ * @param rotation
+ */
+ public MonitorMode(SurfaceSize surfaceSize, float refreshRate, int flags, int rotation) {
+ this(0, new SizeAndRRate(surfaceSize, refreshRate, flags), rotation);
+ }
+
+ /** @return the immutable native Id of this mode, may not be unique, may be 0. */
+ public final int getId() { return nativeId; }
+
+ /** Returns the surfaceSize and refreshRate instance. */
+ public final SizeAndRRate getSizeAndRRate() {
+ return sizeAndRRate;
+ }
+
+ /** Returns the unrotated {@link SurfaceSize} */
+ public final SurfaceSize getSurfaceSize() {
+ return sizeAndRRate.surfaceSize;
+ }
+
+ public final float getRefreshRate() {
+ return sizeAndRRate.refreshRate;
+ }
+
+ /** Returns bitfield w/ flags, i.e. {@link #FLAG_DOUBLESCAN}, {@link #FLAG_INTERLACE}, .. */
+ public final int getFlags() {
+ return sizeAndRRate.flags;
+ }
+
+ /** Returns the CCW rotation of this mode */
+ public final int getRotation() {
+ return rotation;
+ }
+
+ /** Returns the rotated screen width,
+ * derived from getMonitorMode().getSurfaceSize().getResolution()
+ * and getRotation()
+ */
+ public final int getRotatedWidth() {
+ return getRotatedWH(true);
+ }
+
+ /** Returns the rotated screen height,
+ * derived from getMonitorMode().getSurfaceSize().getResolution()
+ * and getRotation()
+ */
+ public final int getRotatedHeight() {
+ return getRotatedWH(false);
+ }
+
+ public final String toString() {
+ return "[Id "+Display.toHexString(nativeId)+", " + sizeAndRRate + ", " + rotation + " degr]";
+ }
+
+ /**
+ * Tests equality of two {@link MonitorMode} objects
+ * by evaluating equality of it's components:
+ *
+ * nativeId
+ * sizeAndRRate
+ * rotation
+ *
+ */
+ public final boolean equals(Object obj) {
+ if (this == obj) { return true; }
+ if (obj instanceof MonitorMode) {
+ MonitorMode sm = (MonitorMode)obj;
+ return sm.nativeId == this.nativeId &&
+ sm.sizeAndRRate.equals(sizeAndRRate) &&
+ sm.rotation == this.rotation ;
+ }
+ return false;
+ }
+
+ /**
+ * Returns a combined hash code of it's elements:
+ *
+ * nativeId
+ * sizeAndRRate
+ * rotation
+ *
+ */
+ public final int hashCode() {
+ return hashCode;
+ }
+ private final int getHashCode() {
+ // 31 * x == (x << 5) - x
+ int hash = 31 + getId();
+ hash = ((hash << 5) - hash) + sizeAndRRate.hashCode();
+ hash = ((hash << 5) - hash) + getRotation();
+ return hash;
+ }
+
+ private final int getRotatedWH(boolean width) {
+ final DimensionImmutable d = sizeAndRRate.surfaceSize.getResolution();
+ final boolean swap = MonitorMode.ROTATE_90 == rotation || MonitorMode.ROTATE_270 == rotation ;
+ if ( ( width && swap ) || ( !width && !swap ) ) {
+ return d.getHeight();
+ }
+ return d.getWidth();
+ }
+}
diff --git a/src/newt/classes/com/jogamp/newt/Screen.java b/src/newt/classes/com/jogamp/newt/Screen.java
index a09748d52..81a62d898 100644
--- a/src/newt/classes/com/jogamp/newt/Screen.java
+++ b/src/newt/classes/com/jogamp/newt/Screen.java
@@ -27,14 +27,19 @@
*/
package com.jogamp.newt;
-import com.jogamp.newt.event.ScreenModeListener;
+import com.jogamp.newt.event.MonitorModeListener;
import jogamp.newt.Debug;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import javax.media.nativewindow.AbstractGraphicsScreen;
import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.util.Rectangle;
+import javax.media.nativewindow.util.RectangleImmutable;
+/**
+ * A screen may span multiple {@link MonitorDevice}s representing their combined virtual size.
+ */
public abstract class Screen {
/**
@@ -122,25 +127,30 @@ public abstract class Screen {
public abstract int getIndex();
/**
- * @return the x position of the virtual top-left origin.
+ * @return the x position of the virtual viewport's top-left origin.
*/
public abstract int getX();
/**
- * @return the y position of the virtual top-left origin.
+ * @return the y position of the virtual viewport's top-left origin.
*/
public abstract int getY();
/**
- * @return the rotated virtual width.
+ * @return the rotated virtual viewport's width.
*/
public abstract int getWidth();
/**
- * @return the rotated virtual height.
+ * @return the rotated virtual viewport's height.
*/
public abstract int getHeight();
+ /**
+ * @return the rotated virtual viewport, i.e. origin and size.
+ */
+ public abstract RectangleImmutable getViewport();
+
/**
* @return the associated Display
*/
@@ -152,48 +162,68 @@ public abstract class Screen {
*/
public abstract String getFQName();
- /**
- * @param sml ScreenModeListener to be added for ScreenMode change events
- */
- public abstract void addScreenModeListener(ScreenModeListener sml);
-
- /**
- * @param sml ScreenModeListener to be removed from ScreenMode change events
+ /**
+ * Return a list of all available {@link MonitorMode}s for all {@link MonitorDevice}s.
+ *
+ * If {@link com.jogamp.newt.MonitorMode ScreenMode}s are not supported for this
+ * native type {@link com.jogamp.newt.Display#getType()}, it returns a list of size one with the current screen size.
*/
- public abstract void removeScreenModeListener(ScreenModeListener sml);
+ public abstract List getMonitorModes();
/**
- * Return a list of available {@link com.jogamp.newt.ScreenMode ScreenMode}s.
+ * Return a list of all available {@link MonitorDevice}s.
*
- * If {@link com.jogamp.newt.ScreenMode ScreenMode}s are not supported for this
+ * If {@link com.jogamp.newt.MonitorMode ScreenMode}s are not supported for this
* native type {@link com.jogamp.newt.Display#getType()}, it returns a list of size one with the current screen size.
- *
- * @return a shallow copy of the internal immutable {@link com.jogamp.newt.ScreenMode ScreenMode}s.
*/
- public abstract List getScreenModes();
+ public abstract List getMonitorDevices();
/**
- * Return the original {@link com.jogamp.newt.ScreenMode}, as used at NEWT initialization.
- * @return original ScreenMode which is element of the list {@link #getScreenModes()}.
+ * Returns the {@link MonitorDevice} which {@link MonitorDevice#getViewport() viewport}
+ * {@link MonitorDevice#coverage(RectangleImmutable) covers} the given rectangle the most.
+ *
+ * If no coverage is detected the first {@link MonitorDevice} is returned.
+ *
*/
- public abstract ScreenMode getOriginalScreenMode();
+ public final MonitorDevice getMainMonitor(RectangleImmutable r) {
+ MonitorDevice res = null;
+ float maxCoverage = Float.MIN_VALUE;
+ final List monitors = getMonitorDevices();
+ for(int i=monitors.size()-1; i>=0; i--) {
+ final MonitorDevice monitor = monitors.get(i);
+ final float coverage = monitor.coverage(r);
+ if( coverage > maxCoverage ) {
+ maxCoverage = coverage;
+ res = monitor;
+ }
+ }
+ if( maxCoverage > 0.0f && null != res ) {
+ return res;
+ }
+ return monitors.get(0);
+ }
/**
- * Return the current {@link com.jogamp.newt.ScreenMode}.
+ * Returns the union of all monitor's {@link MonitorDevice#getViewport() viewport}.
*
- * If {@link com.jogamp.newt.ScreenMode ScreenMode}s are not supported for this
- * native type {@link com.jogamp.newt.Display#getType()}, it returns one with the current screen size.
- *
- * @return current ScreenMode which is element of the list {@link #getScreenModes()}.
+ * Should be equal to {@link #getX()}, {@link #getY()}, {@link #getWidth()} and {@link #getHeight()},
+ * however, some native toolkits may choose a different virtual screen area.
+ *
+ * @param result storage for result, will be returned
+ */
+ public final Rectangle unionOfMonitorViewportSize(final Rectangle result) {
+ return MonitorDevice.unionOfViewports(result, getMonitorDevices());
+ }
+
+ /**
+ * @param sml {@link MonitorModeListener} to be added for {@link MonitorEvent}
*/
- public abstract ScreenMode getCurrentScreenMode();
+ public abstract void addMonitorModeListener(MonitorModeListener sml);
/**
- * 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
+ * @param sml {@link MonitorModeListener} to be removed from {@link MonitorEvent}
*/
- public abstract boolean setCurrentScreenMode(ScreenMode screenMode);
+ public abstract void removeMonitorModeListener(MonitorModeListener sml);
// Global Screens
protected static ArrayList screenList = new ArrayList();
@@ -236,6 +266,7 @@ public abstract class Screen {
return null;
}
/** Returns the global display collection */
+ @SuppressWarnings("unchecked")
public static Collection getAllScreens() {
ArrayList list;
synchronized(screenList) {
diff --git a/src/newt/classes/com/jogamp/newt/ScreenMode.java b/src/newt/classes/com/jogamp/newt/ScreenMode.java
deleted file mode 100644
index 1f12217bb..000000000
--- a/src/newt/classes/com/jogamp/newt/ScreenMode.java
+++ /dev/null
@@ -1,208 +0,0 @@
-/**
- * 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;
-
-import javax.media.nativewindow.util.DimensionImmutable;
-
-import com.jogamp.newt.util.MonitorMode;
-
-/** Immutable ScreenMode Class, consisting of it's read only components:
- *
- * - {@link com.jogamp.newt.util.MonitorMode}, non rotated values
- * rotation
, measured counter clockwise (CCW)
- *
- *
- * Aquire and filter ScreenModes
- *
- * - A List of read only ScreenMode's is being returned by {@link com.jogamp.newt.Screen#getScreenModes()}.
- * - You may utilize {@link com.jogamp.newt.util.ScreenModeUtil} to filter and select a desired ScreenMode.
- * - The current ScreenMode can be obtained via {@link com.jogamp.newt.Screen#getCurrentScreenMode()}.
- * - The initial original ScreenMode (at startup) can be obtained via {@link com.jogamp.newt.Screen#getOriginalScreenMode()}.
- *
- *
- *
- * Changing ScreenModes
- *
- * - Use {@link com.jogamp.newt.Screen#setCurrentScreenMode(com.jogamp.newt.ScreenMode)}
- * to change the current ScreenMode of all Screen's referenced via the full qualified name (FQN)
- * {@link com.jogamp.newt.Screen#getFQName()}.
- * - When the last FQN referenced Screen closes, the original ScreenMode ({@link com.jogamp.newt.Screen#getOriginalScreenMode()})
- * is restored.
- *
- *
- * Example for changing the ScreenMode:
- *
- // 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));
- *
- *
- * X11 / AMD just works
- *
- * X11 / NVidia difficulties
- *
- 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"
- *
- *
- */
-public class ScreenMode {
- /** zero rotation, compared to normal settings */
- public static final int ROTATE_0 = 0;
-
- /** 90 degrees CCW rotation */
- public static final int ROTATE_90 = 90;
-
- /** 180 degrees CCW rotation */
- public static final int ROTATE_180 = 180;
-
- /** 270 degrees CCW rotation */
- 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, measured counter clockwise (CCW)
- */
- public ScreenMode(MonitorMode monitorMode, int rotation) {
- if ( !isRotationValid(rotation) ) {
- throw new RuntimeException("invalid rotation: "+rotation);
- }
- this.monitorMode = monitorMode;
- this.rotation = rotation;
- }
-
- /** Returns the unrotated MonitorMode
*/
- public final MonitorMode getMonitorMode() {
- return monitorMode;
- }
-
- /** Returns the CCW rotation of this mode */
- public final int getRotation() {
- return rotation;
- }
-
- /** Returns the rotated screen width,
- * derived from getMonitorMode().getSurfaceSize().getResolution()
- * and getRotation()
- */
- public final int getRotatedWidth() {
- return getRotatedWH(true);
- }
-
- /** Returns the rotated screen height,
- * derived from getMonitorMode().getSurfaceSize().getResolution()
- * and getRotation()
- */
- public final int getRotatedHeight() {
- return getRotatedWH(false);
- }
-
- public final String toString() {
- return "[ " + getMonitorMode() + ", " + rotation + " degr ]";
- }
-
- /**
- * Tests equality of two ScreenMode
objects
- * by evaluating equality of it's components:
- *
- * monitorMode
- * rotation
- *
- *
- */
- public final boolean equals(Object obj) {
- if (this == obj) { return true; }
- 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:
- *
- * monitorMode
- * rotation
- *
- */
- public final int hashCode() {
- // 31 * x == (x << 5) - x
- int hash = 31 + getMonitorMode().hashCode();
- hash = ((hash << 5) - hash) + getRotation();
- return hash;
- }
-
- private final int getRotatedWH(boolean width) {
- final DimensionImmutable d = getMonitorMode().getSurfaceSize().getResolution();
- final boolean swap = ScreenMode.ROTATE_90 == rotation || ScreenMode.ROTATE_270 == rotation ;
- if ( ( width && swap ) || ( !width && !swap ) ) {
- return d.getHeight();
- }
- return d.getWidth();
- }
-}
diff --git a/src/newt/classes/com/jogamp/newt/Window.java b/src/newt/classes/com/jogamp/newt/Window.java
index ab1eef308..0bebf330a 100644
--- a/src/newt/classes/com/jogamp/newt/Window.java
+++ b/src/newt/classes/com/jogamp/newt/Window.java
@@ -28,6 +28,8 @@
package com.jogamp.newt;
+import java.util.List;
+
import com.jogamp.newt.event.WindowEvent;
import com.jogamp.newt.event.WindowListener;
import com.jogamp.newt.event.KeyListener;
@@ -41,6 +43,7 @@ import javax.media.nativewindow.CapabilitiesChooser;
import javax.media.nativewindow.CapabilitiesImmutable;
import javax.media.nativewindow.NativeWindow;
import javax.media.nativewindow.WindowClosingProtocol;
+import javax.media.nativewindow.util.RectangleImmutable;
/**
* Specifying NEWT's Window functionality:
@@ -80,10 +83,19 @@ public interface Window extends NativeWindow, WindowClosingProtocol {
boolean isNativeValid();
/**
- * @return The associated Screen
+ * @return The associated {@link Screen}
*/
Screen getScreen();
+ /**
+ * Returns the {@link MonitorDevice} which {@link MonitorDevice#getViewport() viewport}
+ * {@link MonitorDevice#coverage(RectangleImmutable) covers} this window the most.
+ *
+ * If no coverage is detected the first {@link MonitorDevice} is returned.
+ *
+ */
+ MonitorDevice getMainMonitor();
+
/**
* Set the CapabilitiesChooser to help determine the native visual type.
*
@@ -344,8 +356,32 @@ public interface Window extends NativeWindow, WindowClosingProtocol {
ReparentOperation reparentWindow(NativeWindow newParent, boolean forceDestroyCreate);
+ /**
+ * Enable or disable fullscreen mode for this window.
+ *
+ * Fullscreen mode is established on the {@link #getMainMonitor() main monitor}.
+ *
+ * @param fullscreen enable or disable fullscreen mode
+ * @return success
+ * @see #setFullscreen(List)
+ * @see #isFullscreen()
+ */
boolean setFullscreen(boolean fullscreen);
+ /**
+ * Enable fullscreen mode for this window spanning across the given {@link MonitorDevice}s
+ * or across all {@link MonitorDevice}s.
+ *
+ * Disable fullscreen via {@link #setFullscreen(boolean)}.
+ *
+ * @param monitors if null
fullscreen will be spanned across all {@link MonitorDevice}s,
+ * otherwise across the given list of {@link MonitorDevice}.
+ * @return success
+ * @see #setFullscreen(boolean)
+ * @see #isFullscreen()
+ */
+ boolean setFullscreen(List monitors);
+
boolean isFullscreen();
static interface FocusRunnable {
diff --git a/src/newt/classes/com/jogamp/newt/event/MonitorEvent.java b/src/newt/classes/com/jogamp/newt/event/MonitorEvent.java
new file mode 100644
index 000000000..c47936a7a
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/event/MonitorEvent.java
@@ -0,0 +1,71 @@
+/**
+ * Copyright 2013 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.MonitorDevice;
+import com.jogamp.newt.MonitorMode;
+
+@SuppressWarnings("serial")
+public class MonitorEvent extends OutputEvent {
+ public static final short EVENT_MONITOR_MODE_CHANGE_NOTIFY = 600;
+ public static final short EVENT_MONITOR_MODE_CHANGED = 601;
+
+ private final MonitorMode mode;
+
+ public MonitorEvent (short eventType, MonitorDevice source, long when, MonitorMode mode) {
+ super(eventType, source, when);
+ this.mode = mode;
+ }
+
+ /** Returns the {@link #getSource() source}, which is a {@link MonitorDevice}. */
+ public final MonitorDevice getMonitor() { return (MonitorDevice)source; }
+
+ public final MonitorMode getMode() { return mode; }
+
+ public static String getEventTypeString(short type) {
+ switch(type) {
+ case EVENT_MONITOR_MODE_CHANGE_NOTIFY: return "EVENT_MONITOR_MODE_CHANGE_NOTIFY";
+ case EVENT_MONITOR_MODE_CHANGED: return "EVENT_MONITOR_MODE_CHANGED";
+ default: return "unknown (" + type + ")";
+ }
+ }
+
+ public final String toString() {
+ return toString(null).toString();
+ }
+
+ public final StringBuilder toString(StringBuilder sb) {
+ if(null == sb) {
+ sb = new StringBuilder();
+ }
+ sb.append("MonitorEvent[").append(getEventTypeString(getEventType())).append(", source ").append(source)
+ .append(", mode ").append(mode).append(", ");
+ return super.toString(sb).append("]");
+ }
+}
diff --git a/src/newt/classes/com/jogamp/newt/event/MonitorModeListener.java b/src/newt/classes/com/jogamp/newt/event/MonitorModeListener.java
new file mode 100644
index 000000000..11e23def1
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/event/MonitorModeListener.java
@@ -0,0 +1,37 @@
+/**
+ * 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;
+
+public interface MonitorModeListener {
+ /** called before the monitor mode will be changed */
+ void monitorModeChangeNotify(MonitorEvent me);
+
+ /** called after the monitor mode has been changed */
+ void monitorModeChanged(MonitorEvent me, boolean success);
+}
diff --git a/src/newt/classes/com/jogamp/newt/event/NEWTEvent.java b/src/newt/classes/com/jogamp/newt/event/NEWTEvent.java
index ea96f634f..c1bc791d8 100644
--- a/src/newt/classes/com/jogamp/newt/event/NEWTEvent.java
+++ b/src/newt/classes/com/jogamp/newt/event/NEWTEvent.java
@@ -41,9 +41,10 @@ package com.jogamp.newt.event;
*
* Event type registry:
*
- * - WindowEvent
100..10x
- * - MouseEvent
200..20x
- * - KeyEvent
300..30x
+ * - WindowEvent
100..10x
+ * - MouseEvent
200..20x
+ * - KeyEvent
300..30x
+ * - MonitorEvent
600..60x
*
*/
@SuppressWarnings("serial")
diff --git a/src/newt/classes/com/jogamp/newt/event/OutputEvent.java b/src/newt/classes/com/jogamp/newt/event/OutputEvent.java
new file mode 100644
index 000000000..86fa95877
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/event/OutputEvent.java
@@ -0,0 +1,51 @@
+/**
+ * Copyright 2013 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;
+
+@SuppressWarnings("serial")
+public abstract class OutputEvent extends NEWTEvent
+{
+ protected OutputEvent(short eventType, Object source, long when) {
+ super(eventType, source, when);
+ }
+
+ /**
+ public String toString() {
+ return toString(null).toString();
+ }
+
+ public StringBuilder toString(StringBuilder sb) {
+ if(null == sb) {
+ sb = new StringBuilder();
+ }
+ sb.append("OutputEvent[");
+ super.toString(sb).append("]");
+ return sb;
+ } */
+}
diff --git a/src/newt/classes/com/jogamp/newt/event/ScreenModeListener.java b/src/newt/classes/com/jogamp/newt/event/ScreenModeListener.java
deleted file mode 100644
index 7bca23cfe..000000000
--- a/src/newt/classes/com/jogamp/newt/event/ScreenModeListener.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/**
- * 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/opengl/GLWindow.java b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
index de62747be..1500d48e6 100644
--- a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
+++ b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
@@ -34,6 +34,8 @@
package com.jogamp.newt.opengl;
+import java.util.List;
+
import javax.media.nativewindow.AbstractGraphicsConfiguration;
import javax.media.nativewindow.CapabilitiesChooser;
import javax.media.nativewindow.CapabilitiesImmutable;
@@ -64,6 +66,7 @@ import jogamp.opengl.GLDrawableImpl;
import com.jogamp.common.GlueGenVersion;
import com.jogamp.common.util.VersionUtil;
import com.jogamp.common.util.locks.RecursiveLock;
+import com.jogamp.newt.MonitorDevice;
import com.jogamp.newt.NewtFactory;
import com.jogamp.newt.Screen;
import com.jogamp.newt.Window;
@@ -224,6 +227,11 @@ public class GLWindow extends GLAutoDrawableBase implements GLAutoDrawable, Wind
return window.getScreen();
}
+ @Override
+ public final MonitorDevice getMainMonitor() {
+ return window.getMainMonitor();
+ }
+
@Override
public final void setTitle(String title) {
window.setTitle(title);
@@ -341,6 +349,11 @@ public class GLWindow extends GLAutoDrawableBase implements GLAutoDrawable, Wind
public final boolean setFullscreen(boolean fullscreen) {
return window.setFullscreen(fullscreen);
}
+
+ @Override
+ public boolean setFullscreen(List monitors) {
+ return window.setFullscreen(monitors);
+ }
@Override
public final boolean isFullscreen() {
diff --git a/src/newt/classes/com/jogamp/newt/util/MonitorMode.java b/src/newt/classes/com/jogamp/newt/util/MonitorMode.java
deleted file mode 100644
index 8104f207a..000000000
--- a/src/newt/classes/com/jogamp/newt/util/MonitorMode.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/**
- * 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 javax.media.nativewindow.util.*;
-
-/** Immutable MonitorMode Class, consisting of it's read only components:
- *
- * - {@link javax.media.nativewindow.util.SurfaceSize} surface memory size
- * - {@link javax.media.nativewindow.util.DimensionImmutable} size in [mm]
- * refresh rate
- *
- */
-public class MonitorMode {
- SurfaceSize surfaceSize;
- DimensionImmutable screenSizeMM; // in [mm]
- int refreshRate;
-
- public MonitorMode(SurfaceSize surfaceSize, DimensionImmutable screenSizeMM, int refreshRate) {
- // Don't validate screenSizeMM and refreshRate, since they may not be supported by the OS
- if(null==surfaceSize) {
- throw new IllegalArgumentException("surfaceSize must be set ("+surfaceSize+")");
- }
- this.surfaceSize=surfaceSize;
- this.screenSizeMM=screenSizeMM;
- this.refreshRate=refreshRate;
- }
-
- public final SurfaceSize getSurfaceSize() {
- return surfaceSize;
- }
-
- public final DimensionImmutable getScreenSizeMM() {
- return screenSizeMM;
- }
-
- public final int getRefreshRate() {
- return refreshRate;
- }
-
- public final String toString() {
- return new String("[ "+surfaceSize+" x "+refreshRate+" Hz, "+screenSizeMM+" mm ]");
- }
-
- /**
- * Checks whether two size objects are equal. Two instances
- * of MonitorMode
are equal if the three components
- * surfaceSize
and refreshRate
- * are equal. screenSizeMM
is kept out intentional to reduce the requirements for finding the current mode.
- * @return true
if the two dimensions are equal;
- * otherwise false
.
- */
- public final boolean equals(Object obj) {
- if (this == obj) { return true; }
- if (obj instanceof MonitorMode) {
- MonitorMode p = (MonitorMode)obj;
- return getSurfaceSize().equals(p.getSurfaceSize()) &&
- /* getScreenSizeMM().equals(p.getScreenSizeMM()) && */
- getRefreshRate() == p.getRefreshRate() ;
- }
- return false;
- }
-
- /**
- * returns a hash code over surfaceSize
and refreshRate
.
- * screenSizeMM
is kept out intentional to reduce the requirements for finding the current mode.
- */
- 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/MonitorModeUtil.java b/src/newt/classes/com/jogamp/newt/util/MonitorModeUtil.java
new file mode 100644
index 000000000..16ffe754f
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/util/MonitorModeUtil.java
@@ -0,0 +1,247 @@
+/**
+ * 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.newt.MonitorMode;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.media.nativewindow.util.DimensionImmutable;
+import javax.media.nativewindow.util.SurfaceSize;
+
+/**
+ * Convenient {@link com.jogamp.newt.MonitorMode} utility methods,
+ * filters etc.
+ */
+public class MonitorModeUtil {
+
+ public static int getIndex(List monitorModes, MonitorMode search) {
+ return monitorModes.indexOf(search);
+ }
+
+ public static int getIndexByHashCode(List monitorModes, MonitorMode search) {
+ if( null!=monitorModes && monitorModes.size()>0 ) {
+ for (int i=0; i monitorModes, MonitorMode.SizeAndRRate sizeAndRate, int modeId, int rotation) {
+ if( null!=monitorModes && monitorModes.size()>0 ) {
+ for (int i=0; i filterBySurfaceSize(List monitorModes, SurfaceSize surfaceSize) {
+ final List out = new ArrayList();
+ if( null!=monitorModes && monitorModes.size()>0 ) {
+ for (int i=0; null!=monitorModes && i filterByRotation(List monitorModes, int rotation) {
+ final List out = new ArrayList();
+ if( null!=monitorModes && monitorModes.size()>0 ) {
+ for (int i=0; null!=monitorModes && i filterByBpp(List monitorModes, int bitsPerPixel) {
+ final List out = new ArrayList();
+ if( null!=monitorModes && monitorModes.size()>0 ) {
+ for (int i=0; null!=monitorModes && i filterByFlags(List monitorModes, int flags) {
+ final List out = new ArrayList();
+ if( null!=monitorModes && monitorModes.size()>0 ) {
+ for (int i=0; null!=monitorModes && i filterByResolution(List monitorModes, DimensionImmutable resolution) {
+ final List out = new ArrayList();
+ if( null!=monitorModes && monitorModes.size()>0 ) {
+ final int resolution_sq = resolution.getHeight()*resolution.getWidth();
+ int mode_dsq=Integer.MAX_VALUE, mode_dsq_idx=0;
+
+ for (int i=0; null!=monitorModes && i filterByRate(List monitorModes, float refreshRate) {
+ final List out = new ArrayList();
+ if( null!=monitorModes && monitorModes.size()>0 ) {
+ float mode_dr = Float.MAX_VALUE;
+ int mode_dr_idx = -1;
+ for (int i=0; null!=monitorModes && i getHighestAvailableBpp(List monitorModes) {
+ if( null!=monitorModes && monitorModes.size()>0 ) {
+ int highest = -1;
+ for (int i=0; null!=monitorModes && i < monitorModes.size(); i++) {
+ final MonitorMode mode = monitorModes.get(i);
+ final int bpp = mode.getSurfaceSize().getBitsPerPixel();
+ if (bpp > highest) {
+ highest = bpp;
+ }
+ }
+ return filterByBpp(monitorModes, highest);
+ }
+ return new ArrayList();
+ }
+
+ /**
+ *
+ * @param monitorModes
+ * @return modes with highest available refresh rate. May return zero sized list for non.
+ */
+ public static List getHighestAvailableRate(List monitorModes) {
+ if( null!=monitorModes && monitorModes.size()>0 ) {
+ float highest = -1;
+ for (int i=0; null!=monitorModes && i < monitorModes.size(); i++) {
+ final MonitorMode mode = monitorModes.get(i);
+ final float rate = mode.getRefreshRate();
+ if (rate > highest) {
+ highest = rate;
+ }
+ }
+ return filterByRate(monitorModes, highest);
+ }
+ return new ArrayList();
+ }
+
+}
diff --git a/src/newt/classes/com/jogamp/newt/util/ScreenModeUtil.java b/src/newt/classes/com/jogamp/newt/util/ScreenModeUtil.java
deleted file mode 100644
index 93797c5fb..000000000
--- a/src/newt/classes/com/jogamp/newt/util/ScreenModeUtil.java
+++ /dev/null
@@ -1,341 +0,0 @@
-/**
- * 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.DimensionImmutable;
-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 screenModes, ScreenMode search) {
- return screenModes.indexOf(search);
- }
-
- public static int getIndexByHashCode(List screenModes, ScreenMode search) {
- for (int i=0; null!=screenModes && i filterByResolution(List screenModes, DimensionImmutable resolution) {
- if(null==screenModes || screenModes.size()==0) {
- return null;
- }
- 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 && i0) {
- return out;
- }
- // nearest ..
- resolution = screenModes.get(sm_dsq_idx).getMonitorMode().getSurfaceSize().getResolution();
- return filterByResolution(screenModes, resolution);
- }
-
- public static List filterBySurfaceSize(List screenModes, SurfaceSize surfaceSize) {
- if(null==screenModes || screenModes.size()==0) {
- return null;
- }
- List out = new ArrayList();
- for (int i=0; null!=screenModes && i0 ? out : null;
- }
-
- public static List filterByRotation(List screenModes, int rotation) {
- if(null==screenModes || screenModes.size()==0) {
- return null;
- }
- List out = new ArrayList();
- for (int i=0; null!=screenModes && i0 ? out : null;
- }
-
- public static List filterByBpp(List screenModes, int bitsPerPixel) {
- if(null==screenModes || screenModes.size()==0) {
- return null;
- }
- List out = new ArrayList();
- for (int i=0; null!=screenModes && i0 ? out : null;
- }
-
- /**
- *
- * @param screenModes
- * @param refreshRate
- * @return modes with nearest refreshRate, or matching ones
- */
- public static List filterByRate(List screenModes, int refreshRate) {
- if(null==screenModes || screenModes.size()==0) {
- return null;
- }
- int sm_dr = refreshRate;
- int sm_dr_idx = -1;
- List out = new ArrayList();
- for (int i=0; null!=screenModes && i0) {
- return out;
- }
- refreshRate = screenModes.get(sm_dr_idx).getMonitorMode().getRefreshRate();
- return filterByRate(screenModes, refreshRate);
- }
-
- public static List getHighestAvailableBpp(List screenModes) {
- if(null==screenModes || screenModes.size()==0) {
- return null;
- }
- int highest = -1;
- for (int i=0; null!=screenModes && i < screenModes.size(); i++) {
- ScreenMode sm = screenModes.get(i);
- int bpp = sm.getMonitorMode().getSurfaceSize().getBitsPerPixel();
- if (bpp > highest) {
- highest = bpp;
- }
- }
- return filterByBpp(screenModes, highest);
- }
-
- public static List getHighestAvailableRate(List screenModes) {
- if(null==screenModes || screenModes.size()==0) {
- return null;
- }
- int highest = -1;
- for (int i=0; null!=screenModes && i < screenModes.size(); i++) {
- ScreenMode sm = 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 DimensionImmutable 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(DimensionImmutable 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, DimensionImmutable 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 ScreenMode element matching the input modeProperties
,
- * or null 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 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 screenModePool
,
- * matching the input modeProperties
, 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++;
- DimensionImmutable resolution = ScreenModeUtil.streamInResolution(modeProperties, offset);
- offset += ScreenModeUtil.NUM_RESOLUTION_PROPERTIES;
- if(null!=resolutionPool) {
- resolution = resolutionPool.getOrAdd(resolution);
- }
-
- SurfaceSize surfaceSize = ScreenModeUtil.streamInSurfaceSize(resolution, modeProperties, offset);
- offset += ScreenModeUtil.NUM_SURFACE_SIZE_PROPERTIES;
- if(null!=surfaceSizePool) {
- surfaceSize = surfaceSizePool.getOrAdd(surfaceSize);
- }
-
- DimensionImmutable screenSizeMM = ScreenModeUtil.streamInResolution(modeProperties, offset);
- offset += ScreenModeUtil.NUM_RESOLUTION_PROPERTIES;
- if(null!=screenSizeMMPool) {
- screenSizeMM = 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 = monitorModePool.getOrAdd(monitorMode);
- }
-
- ScreenMode screenMode = ScreenModeUtil.streamInScreenMode(monitorMode, modeProperties, offset);
- if(null!=screenModePool) {
- 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/classes/jogamp/newt/MonitorDeviceImpl.java b/src/newt/classes/jogamp/newt/MonitorDeviceImpl.java
new file mode 100644
index 000000000..96daed54a
--- /dev/null
+++ b/src/newt/classes/jogamp/newt/MonitorDeviceImpl.java
@@ -0,0 +1,147 @@
+/**
+ * Copyright 2013 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 jogamp.newt;
+
+import javax.media.nativewindow.util.DimensionImmutable;
+import javax.media.nativewindow.util.Rectangle;
+
+import com.jogamp.common.util.ArrayHashSet;
+import com.jogamp.newt.MonitorDevice;
+import com.jogamp.newt.MonitorMode;
+import com.jogamp.newt.Screen;
+
+public class MonitorDeviceImpl extends MonitorDevice {
+
+ public MonitorDeviceImpl(ScreenImpl screen, int nativeId, DimensionImmutable sizeMM, Rectangle viewport, MonitorMode currentMode, ArrayHashSet supportedModes) {
+ super(screen, nativeId, sizeMM, viewport, currentMode, supportedModes);
+ }
+
+ @Override
+ public final MonitorMode queryCurrentMode() {
+ final ScreenImpl screenImpl = (ScreenImpl)screen;
+ final ScreenMonitorState sms = screenImpl.getScreenMonitorStatus(true);
+ sms.lock();
+ try {
+ final MonitorMode mm0 = screenImpl.queryCurrentMonitorModeIntern(this);
+ if(null == mm0) {
+ throw new InternalError("getCurrentMonitorModeIntern() == null");
+ }
+ MonitorMode mmU = supportedModes.get(mm0); // unified instance
+ if( null == mmU ) {
+ // add new mode avoiding exception!
+ mmU = sms.getMonitorModes().getOrAdd(mm0);
+ mmU = supportedModes.getOrAdd(mmU);
+ if( Screen.DEBUG ) {
+ System.err.println("Adding new mode: "+mm0+" -> "+mmU);
+ }
+ }
+ // if mode has changed somehow, update it ..
+ if( getCurrentMode().hashCode() != mmU.hashCode() ) {
+ setCurrentModeValue(mmU);
+ sms.fireScreenModeChanged(this, mmU, true);
+ }
+ return mmU;
+ } finally {
+ sms.unlock();
+ }
+ }
+
+ @Override
+ public final boolean setCurrentMode(MonitorMode mode) {
+ if(Screen.DEBUG) {
+ System.err.println("Screen.setCurrentScreenMode.0: "+this+" -> "+mode);
+ }
+ final ScreenImpl screenImpl = (ScreenImpl)screen;
+ final ScreenMonitorState sms = screenImpl.getScreenMonitorStatus(true);
+ sms.lock();
+ try {
+ final MonitorMode mmC = queryCurrentMode();
+ final MonitorMode mmU = supportedModes.get(mode); // unify via value hash
+ if( null == mmU ) {
+ throw new IllegalArgumentException("Given mode not in set of modes. Current mode "+mode+", "+this);
+ }
+ if( mmU.equals( mmC ) ) {
+ if(Screen.DEBUG) {
+ System.err.println("Screen.setCurrentScreenMode: 0.0 is-current (skip) "+mmU+" == "+mmC);
+ }
+ return true;
+ }
+ final long tStart;
+ if(Screen.DEBUG) {
+ tStart = System.nanoTime();
+ } else {
+ tStart = 0;
+ }
+
+ sms.fireScreenModeChangeNotify(this, mmU);
+ if(Screen.DEBUG) {
+ System.err.println("Screen.setCurrentScreenMode ("+(System.nanoTime()-tStart)/1e6+"ms): fireScreenModeChangeNotify() "+mmU);
+ }
+
+ boolean success = screenImpl.setCurrentMonitorModeImpl(this, mmU);
+ if(success) {
+ if(Screen.DEBUG) {
+ System.err.println("Screen.setCurrentScreenMode ("+(System.nanoTime()-tStart)/1e6+"ms): setCurrentScreenModeImpl() "+mmU+", success(1): "+success);
+ }
+ } else {
+ // 2nd attempt validate!
+ final MonitorMode queriedCurrent = queryCurrentMode(); // may fireScreenModeChanged(..) if successful and differs!
+ success = queriedCurrent.hashCode() == mmU.hashCode() ;
+ if(Screen.DEBUG) {
+ System.err.println("Screen.setCurrentScreenMode.2: queried "+queriedCurrent);
+ System.err.println("Screen.setCurrentScreenMode ("+(System.nanoTime()-tStart)/1e6+"ms): setCurrentScreenModeImpl() "+mmU+", success(2): "+success);
+ }
+ }
+ if( success ) {
+ setCurrentModeValue(mmU);
+ modeChanged = !isOriginalMode();
+ }
+ sms.fireScreenModeChanged(this, mmU, success);
+ if(Screen.DEBUG) {
+ System.err.println("Screen.setCurrentScreenMode ("+(System.nanoTime()-tStart)/1e6+"ms): X.X "+this+", success: "+success);
+ }
+ return success;
+ } finally {
+ sms.unlock();
+ }
+ }
+
+ private final void setCurrentModeValue(MonitorMode currentMode) {
+ this.currentMode = currentMode;
+ }
+
+ /* pp */ final void setViewportValue(Rectangle viewport) {
+ this.viewport = viewport;
+ }
+
+ /* pp */ ArrayHashSet getSupportedModesImpl() {
+ return supportedModes;
+ }
+
+}
\ No newline at end of file
diff --git a/src/newt/classes/jogamp/newt/MonitorModeProps.java b/src/newt/classes/jogamp/newt/MonitorModeProps.java
new file mode 100644
index 000000000..820807e15
--- /dev/null
+++ b/src/newt/classes/jogamp/newt/MonitorModeProps.java
@@ -0,0 +1,355 @@
+/**
+ * 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 jogamp.newt;
+
+import com.jogamp.common.util.ArrayHashSet;
+import com.jogamp.newt.MonitorDevice;
+import com.jogamp.newt.MonitorMode;
+
+import java.util.List;
+import javax.media.nativewindow.util.Dimension;
+import javax.media.nativewindow.util.DimensionImmutable;
+import javax.media.nativewindow.util.Rectangle;
+import javax.media.nativewindow.util.SurfaceSize;
+
+import jogamp.newt.MonitorDeviceImpl;
+import jogamp.newt.ScreenImpl;
+
+/**
+ * Encodes and decodes {@link MonitorMode} and {@link MonitorDevice} properties.
+ */
+public class MonitorModeProps {
+ /** WARNING: must be synchronized with ScreenMode.h, native implementation
+ * 2: width, 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
+ * 2: refresh-rate (Hz*100), flags
+ */
+ public static final int NUM_SIZEANDRATE_PROPERTIES = 2;
+
+ /** WARNING: must be synchronized with ScreenMode.h, native implementation
+ * 2: id, rotation
+ */
+ public static final int NUM_MONITOR_MODE_PROPERTIES = 2;
+
+ /** WARNING: must be synchronized with ScreenMode.h, native implementation
+ * count + all the above
+ */
+ public static final int NUM_MONITOR_MODE_PROPERTIES_ALL = 8;
+
+ public static final int IDX_MONITOR_MODE_BPP = 1 // count
+ + MonitorModeProps.NUM_RESOLUTION_PROPERTIES
+ ;
+ public static final int IDX_MONITOR_MODE_ROT = 1 // count
+ + MonitorModeProps.NUM_RESOLUTION_PROPERTIES
+ + MonitorModeProps.NUM_SURFACE_SIZE_PROPERTIES
+ + MonitorModeProps.NUM_SIZEANDRATE_PROPERTIES
+ + 1 // id of MonitorModeProps.NUM_MONITOR_MODE_PROPERTIES
+ ;
+
+ /** WARNING: must be synchronized with ScreenMode.h, native implementation
+ * 10: count + id, ScreenSizeMM[width, height], rotated Viewport[x, y, width, height], currentMonitorModeId, rotation, supportedModeId+
+ */
+ public static final int MIN_MONITOR_DEVICE_PROPERTIES = 11;
+
+ public static final int IDX_MONITOR_DEVICE_VIEWPORT = 1 // count
+ + 1 // native mode
+ + MonitorModeProps.NUM_RESOLUTION_PROPERTIES // sizeMM
+ ;
+
+ public static class Cache {
+ public final ArrayHashSet resolutions = new ArrayHashSet();
+ public final ArrayHashSet surfaceSizes = new ArrayHashSet();
+ public final ArrayHashSet sizeAndRates = new ArrayHashSet();
+ public final ArrayHashSet monitorModes = new ArrayHashSet();
+ public final ArrayHashSet monitorDevices = new ArrayHashSet();
+ }
+
+ /** WARNING: must be synchronized with ScreenMode.h, native implementation */
+ private static DimensionImmutable streamInResolution(int[] resolutionProperties, int offset) {
+ Dimension resolution = new Dimension(resolutionProperties[offset++], resolutionProperties[offset++]);
+ return resolution;
+ }
+
+ /** WARNING: must be synchronized with ScreenMode.h, native implementation */
+ private static SurfaceSize streamInSurfaceSize(DimensionImmutable resolution, int[] sizeProperties, int offset) {
+ SurfaceSize surfaceSize = new SurfaceSize(resolution, sizeProperties[offset++]);
+ return surfaceSize;
+ }
+
+ /** WARNING: must be synchronized with ScreenMode.h, native implementation */
+ private static MonitorMode.SizeAndRRate streamInSizeAndRRate(SurfaceSize surfaceSize, int[] sizeAndRRateProperties, int offset) {
+ final float refreshRate = sizeAndRRateProperties[offset++]/100.0f;
+ final int flags = sizeAndRRateProperties[offset++];
+ return new MonitorMode.SizeAndRRate(surfaceSize, refreshRate, flags);
+ }
+
+ /** WARNING: must be synchronized with ScreenMode.h, native implementation */
+ private static MonitorMode streamInMonitorMode0(MonitorMode.SizeAndRRate sizeAndRate, int[] modeProperties, int offset) {
+ final int id = modeProperties[offset++];
+ final int rotation = modeProperties[offset++];
+ return new MonitorMode(id, sizeAndRate, rotation);
+ }
+
+ /**
+ * WARNING: must be synchronized with ScreenMode.h, native implementation
+ *
+ * @param mode_idx if not null and cache is given, returns the index of resulting {@link MonitorMode} within {@link Cache#monitorModes}.
+ * @param cache optional hash arrays of unique {@link MonitorMode} components and {@link MonitorDevice}s, allowing to avoid duplicates
+ * @param modeProperties the input data
+ * @param offset the offset to the input data
+ * @return {@link MonitorMode} of the identical (old or new) element in {@link Cache#monitorModes},
+ * matching the input modeProperties
, or null if input could not be processed.
+ */
+ public static MonitorMode streamInMonitorMode(int[] mode_idx, Cache cache,
+ int[] modeProperties, int offset) {
+ final int count = modeProperties[offset];
+ if(NUM_MONITOR_MODE_PROPERTIES_ALL != count) {
+ throw new RuntimeException("property count should be "+NUM_MONITOR_MODE_PROPERTIES_ALL+", but is "+count+", len "+(modeProperties.length-offset));
+ }
+ if(NUM_MONITOR_MODE_PROPERTIES_ALL > modeProperties.length-offset) {
+ throw new RuntimeException("properties array too short, should be >= "+NUM_MONITOR_MODE_PROPERTIES_ALL+", is "+(modeProperties.length-offset));
+ }
+ offset++;
+ DimensionImmutable resolution = MonitorModeProps.streamInResolution(modeProperties, offset);
+ offset += MonitorModeProps.NUM_RESOLUTION_PROPERTIES;
+ if(null!=cache) {
+ resolution = cache.resolutions.getOrAdd(resolution);
+ }
+
+ SurfaceSize surfaceSize = MonitorModeProps.streamInSurfaceSize(resolution, modeProperties, offset);
+ offset += MonitorModeProps.NUM_SURFACE_SIZE_PROPERTIES;
+ if(null!=cache) {
+ surfaceSize = cache.surfaceSizes.getOrAdd(surfaceSize);
+ }
+
+ MonitorMode.SizeAndRRate sizeAndRate = MonitorModeProps.streamInSizeAndRRate(surfaceSize, modeProperties, offset);
+ offset += MonitorModeProps.NUM_SIZEANDRATE_PROPERTIES;
+ if(null!=cache) {
+ sizeAndRate = cache.sizeAndRates.getOrAdd(sizeAndRate);
+ }
+
+ MonitorMode monitorMode = MonitorModeProps.streamInMonitorMode0(sizeAndRate, modeProperties, offset);
+ if(null!=cache) {
+ monitorMode = cache.monitorModes.getOrAdd(monitorMode);
+ }
+ if( null != mode_idx && null!=cache) {
+ int _modeIdx = cache.monitorModes.indexOf(monitorMode);
+ if( 0 > _modeIdx ) {
+ throw new InternalError("Invalid index of current unified mode "+monitorMode);
+ }
+ mode_idx[0] = _modeIdx;
+ }
+ return monitorMode;
+ }
+
+ /** WARNING: must be synchronized with ScreenMode.h, native implementation */
+ public static int[] streamOutMonitorMode (MonitorMode monitorMode) {
+ int[] data = new int[NUM_MONITOR_MODE_PROPERTIES_ALL];
+ int idx=0;
+ data[idx++] = NUM_MONITOR_MODE_PROPERTIES_ALL;
+ data[idx++] = monitorMode.getSurfaceSize().getResolution().getWidth();
+ data[idx++] = monitorMode.getSurfaceSize().getResolution().getHeight();
+ data[idx++] = monitorMode.getSurfaceSize().getBitsPerPixel();
+ data[idx++] = (int)(monitorMode.getRefreshRate()*100.0f); // Hz*100
+ data[idx++] = monitorMode.getFlags();
+ data[idx++] = monitorMode.getId();
+ data[idx++] = monitorMode.getRotation();
+ if(NUM_MONITOR_MODE_PROPERTIES_ALL != idx) {
+ throw new InternalError("wrong number of attributes: got "+idx+" != should "+NUM_MONITOR_MODE_PROPERTIES_ALL);
+ }
+ return data;
+ }
+
+ /**
+ * WARNING: must be synchronized with ScreenMode.h, native implementation
+ *
+ * Note: This variant only works for impl. w/ a unique mode key pair modeId, rotation.
+ *
+ * @param mode_idx if not null, returns the index of resulting {@link MonitorDevice} within {@link Cache#monitorDevices}.
+ * @param cache hash arrays of unique {@link MonitorMode} components and {@link MonitorDevice}s, allowing to avoid duplicates
+ * @param modeProperties the input data
+ * @param offset the offset to the input data
+ * @return {@link MonitorDevice} of the identical (old or new) element in {@link Cache#monitorDevices},
+ * matching the input modeProperties
, or null if input could not be processed.
+ */
+ public static MonitorDevice streamInMonitorDevice(int[] monitor_idx, Cache cache, ScreenImpl screen, int[] monitorProperties, int offset) {
+ // min 11: count, id, ScreenSizeMM[width, height], Viewport[x, y, width, height], currentMonitorModeId, rotation, supportedModeId+
+ final int count = monitorProperties[offset];
+ if(MIN_MONITOR_DEVICE_PROPERTIES > count) {
+ throw new RuntimeException("property count should be >= "+MIN_MONITOR_DEVICE_PROPERTIES+", but is "+count+", len "+(monitorProperties.length-offset));
+ }
+ if(MIN_MONITOR_DEVICE_PROPERTIES > monitorProperties.length-offset) {
+ throw new RuntimeException("properties array too short (min), should be >= "+MIN_MONITOR_DEVICE_PROPERTIES+", is "+(monitorProperties.length-offset));
+ }
+ if(count > monitorProperties.length-offset) {
+ throw new RuntimeException("properties array too short (count), should be >= "+count+", is "+(monitorProperties.length-offset));
+ }
+ final int limit = offset + count;
+ offset++;
+ final List allMonitorModes = cache.monitorModes.getData();
+ final int id = monitorProperties[offset++];
+ final DimensionImmutable sizeMM = streamInResolution(monitorProperties, offset); offset+=NUM_RESOLUTION_PROPERTIES;
+ final Rectangle viewport = new Rectangle(monitorProperties[offset++], monitorProperties[offset++], monitorProperties[offset++], monitorProperties[offset++]);
+ final MonitorMode currentMode;
+ {
+ final int modeId = monitorProperties[offset++];
+ final int rotation = monitorProperties[offset++];
+ currentMode = getByNativeIdAndRotation(allMonitorModes, modeId, rotation);
+ }
+ final ArrayHashSet supportedModes = new ArrayHashSet();
+ while( offset < limit ) {
+ final int modeId = monitorProperties[offset++];
+ for (int i=0; i _monitorIdx ) {
+ throw new InternalError("Invalid index of current unified mode "+monitorDevice);
+ }
+ monitor_idx[0] = _monitorIdx;
+ }
+ return monitorDevice;
+ }
+ private static MonitorMode getByNativeIdAndRotation(List monitorModes, int modeId, int rotation) {
+ if( null!=monitorModes && monitorModes.size()>0 ) {
+ for (int i=0; i
+ * This variant expects count
to be {@link MIN_MONITOR_DEVICE_PROPERTIES} - 1 - {@link NUM_MONITOR_MODE_PROPERTIES}
,
+ * due to lack of supported mode and current mode.
+ *
+ *
+ * @param mode_idx if not null, returns the index of resulting {@link MonitorDevice} within {@link Cache#monitorDevices}.
+ * @param cache hash arrays of unique {@link MonitorMode} components and {@link MonitorDevice}s, allowing to avoid duplicates
+ * @param supportedModes pre-assembled list of supported {@link MonitorMode}s from cache.
+ * @param currentMode pre-fetched current {@link MonitorMode}s from cache.
+ * @param modeProperties the input data minus supported modes!
+ * @param offset the offset to the input data
+ * @return {@link MonitorDevice} of the identical (old or new) element in {@link Cache#monitorDevices},
+ * matching the input modeProperties
, or null if input could not be processed.
+ */
+ public static MonitorDevice streamInMonitorDevice(int[] monitor_idx, Cache cache, ScreenImpl screen, ArrayHashSet supportedModes, MonitorMode currentMode, int[] monitorProperties, int offset) {
+ // min 11: count, id, ScreenSizeMM[width, height], Viewport[x, y, width, height], currentMonitorModeId, rotation, supportedModeId+
+ final int count = monitorProperties[offset];
+ if(MIN_MONITOR_DEVICE_PROPERTIES - 1 - NUM_MONITOR_MODE_PROPERTIES != count) {
+ throw new RuntimeException("property count should be == "+(MIN_MONITOR_DEVICE_PROPERTIES-1-NUM_MONITOR_MODE_PROPERTIES)+", but is "+count+", len "+(monitorProperties.length-offset));
+ }
+ if(MIN_MONITOR_DEVICE_PROPERTIES - 1 - NUM_MONITOR_MODE_PROPERTIES > monitorProperties.length-offset) {
+ throw new RuntimeException("properties array too short (min), should be >= "+(MIN_MONITOR_DEVICE_PROPERTIES-1-NUM_MONITOR_MODE_PROPERTIES)+", is "+(monitorProperties.length-offset));
+ }
+ if(count > monitorProperties.length-offset) {
+ throw new RuntimeException("properties array too short (count), should be >= "+count+", is "+(monitorProperties.length-offset));
+ }
+ offset++;
+ final int id = monitorProperties[offset++];
+ final DimensionImmutable sizeMM = streamInResolution(monitorProperties, offset); offset+=NUM_RESOLUTION_PROPERTIES;
+ final Rectangle viewport = new Rectangle(monitorProperties[offset++], monitorProperties[offset++], monitorProperties[offset++], monitorProperties[offset++]);
+ MonitorDevice monitorDevice = new MonitorDeviceImpl(screen, id, sizeMM, viewport, currentMode, supportedModes);
+ if(null!=cache) {
+ monitorDevice = cache.monitorDevices.getOrAdd(monitorDevice);
+ }
+ if( null != monitor_idx ) {
+ int _monitorIdx = cache.monitorDevices.indexOf(monitorDevice);
+ if( 0 > _monitorIdx ) {
+ throw new InternalError("Invalid index of current unified mode "+monitorDevice);
+ }
+ monitor_idx[0] = _monitorIdx;
+ }
+ return monitorDevice;
+ }
+
+ /** WARNING: must be synchronized with ScreenMode.h, native implementation */
+ public static int[] streamOutMonitorDevice (MonitorDevice monitorDevice) {
+ // min 11: count, id, ScreenSizeMM[width, height], Viewport[x, y, width, height], currentMonitorModeId, rotation, supportedModeId+
+ int supportedModeCount = monitorDevice.getSupportedModes().size();
+ if( 0 == supportedModeCount ) {
+ throw new RuntimeException("no supported modes: "+monitorDevice);
+ }
+ int[] data = new int[MIN_MONITOR_DEVICE_PROPERTIES + supportedModeCount - 1];
+ int idx=0;
+ data[idx++] = data.length;
+ data[idx++] = monitorDevice.getId();
+ data[idx++] = monitorDevice.getSizeMM().getWidth();
+ data[idx++] = monitorDevice.getSizeMM().getHeight();
+ data[idx++] = monitorDevice.getViewport().getX();
+ data[idx++] = monitorDevice.getViewport().getY();
+ data[idx++] = monitorDevice.getViewport().getWidth();
+ data[idx++] = monitorDevice.getViewport().getHeight();
+ data[idx++] = monitorDevice.getCurrentMode().getId();
+ data[idx++] = monitorDevice.getCurrentMode().getRotation();
+ final List supportedModes = monitorDevice.getSupportedModes();
+ for(int i=0; i monitors) {
+ return false; // nop
+ }
+
+
protected boolean reconfigureWindowImpl(int x, int y, int width, int height, int flags) {
sizeChanged(false, width, height, false);
if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) ) {
diff --git a/src/newt/classes/jogamp/newt/ScreenImpl.java b/src/newt/classes/jogamp/newt/ScreenImpl.java
index 1282e5dc5..4d20fdb83 100644
--- a/src/newt/classes/jogamp/newt/ScreenImpl.java
+++ b/src/newt/classes/jogamp/newt/ScreenImpl.java
@@ -43,22 +43,19 @@ import java.util.List;
import javax.media.nativewindow.AbstractGraphicsScreen;
import javax.media.nativewindow.NativeWindowException;
import javax.media.nativewindow.util.Dimension;
-import javax.media.nativewindow.util.DimensionImmutable;
-import javax.media.nativewindow.util.Point;
-import javax.media.nativewindow.util.SurfaceSize;
-
+import javax.media.nativewindow.util.Rectangle;
+import javax.media.nativewindow.util.RectangleImmutable;
import com.jogamp.common.util.ArrayHashSet;
-import com.jogamp.common.util.IntIntHashMap;
import com.jogamp.newt.Display;
+import com.jogamp.newt.MonitorDevice;
+import com.jogamp.newt.MonitorMode;
import com.jogamp.newt.NewtFactory;
import com.jogamp.newt.Screen;
-import com.jogamp.newt.ScreenMode;
-import com.jogamp.newt.event.ScreenModeListener;
-import com.jogamp.newt.util.MonitorMode;
-import com.jogamp.newt.util.ScreenModeUtil;
+import com.jogamp.newt.event.MonitorEvent;
+import com.jogamp.newt.event.MonitorModeListener;
-public abstract class ScreenImpl extends Screen implements ScreenModeListener {
+public abstract class ScreenImpl extends Screen implements MonitorModeListener {
protected static final boolean DEBUG_TEST_SCREENMODE_DISABLED = Debug.isPropertyDefined("newt.test.Screen.disableScreenMode", true);
public static final int default_sm_bpp = 32;
@@ -73,11 +70,11 @@ public abstract class ScreenImpl extends Screen implements ScreenModeListener {
protected int hashCode;
protected AbstractGraphicsScreen aScreen;
protected int refCount; // number of Screen references by Window
- protected Point vOrigin = new Point(0, 0); // virtual top-left origin
- protected Dimension vSize = new Dimension(0, 0); // virtual rotated screen size
+ protected Rectangle vOriginSize = new Rectangle(0, 0, 0, 0); // virtual rotated screen origin and size
protected static Dimension usrSize = null; // property values: newt.ws.swidth and newt.ws.sheight
protected static volatile boolean usrSizeQueried = false;
- private ArrayList referencedScreenModeListener = new ArrayList();
+ private ArrayList referencedScreenModeListener = new ArrayList();
+
private long tCreated; // creationTime
static {
@@ -160,10 +157,12 @@ public abstract class ScreenImpl extends Screen implements ScreenModeListener {
return true;
}
+ @Override
public int hashCode() {
return hashCode;
}
+ @Override
public synchronized final void createNative()
throws NativeWindowException
{
@@ -182,8 +181,7 @@ public abstract class ScreenImpl extends Screen implements ScreenModeListener {
throw new NativeWindowException("Screen.createNative() failed to instanciate an AbstractGraphicsScreen");
}
- initScreenModeStatus();
- updateVirtualScreenOriginAndSize();
+ initScreenMonitorState();
if(DEBUG) {
System.err.println("Screen.createNative() END ("+DisplayImpl.getThreadName()+", "+this+"), total "+ (System.nanoTime()-tCreated)/1e6 +"ms");
}
@@ -191,10 +189,11 @@ public abstract class ScreenImpl extends Screen implements ScreenModeListener {
screensActive++;
}
}
- ScreenModeStatus sms = ScreenModeStatus.getScreenModeStatus(this.getFQName());
+ ScreenMonitorState sms = ScreenMonitorState.getScreenMonitorState(this.getFQName());
sms.addListener(this);
}
+ @Override
public synchronized final void destroy() {
releaseScreenModeStatus();
@@ -213,6 +212,7 @@ public abstract class ScreenImpl extends Screen implements ScreenModeListener {
display.removeReference();
}
+ @Override
public synchronized final int addReference() throws NativeWindowException {
if(DEBUG) {
System.err.println("Screen.addReference() ("+DisplayImpl.getThreadName()+"): "+refCount+" -> "+(refCount+1));
@@ -227,6 +227,7 @@ public abstract class ScreenImpl extends Screen implements ScreenModeListener {
return ++refCount;
}
+ @Override
public synchronized final int removeReference() {
if(DEBUG) {
System.err.println("Screen.removeReference() ("+DisplayImpl.getThreadName()+"): "+refCount+" -> "+(refCount-1));
@@ -240,6 +241,7 @@ public abstract class ScreenImpl extends Screen implements ScreenModeListener {
return refCount;
}
+ @Override
public synchronized final int getReferenceCount() {
return refCount;
}
@@ -259,14 +261,20 @@ public abstract class ScreenImpl extends Screen implements ScreenModeListener {
/**
* Stores the virtual origin and virtual rotated screen size.
*
- * This method is called after the ScreenMode has been set,
+ * This method is called after the ScreenMode has been set or changed,
* hence you may utilize it.
- *
- * @param virtualOrigin the store for the virtual origin
- * @param virtualSize the store for the virtual rotated size
+ *
+ *
+ * Default implementation uses the union of all monitor's viewport,
+ * calculated via {@link #unionOfMonitorViewportSize()}.
+ *
+ * @param vOriginSize storage for result
*/
- protected abstract void getVirtualScreenOriginAndSize(Point virtualOrigin, Dimension virtualSize);
+ protected void calcVirtualScreenOriginAndSize(final Rectangle vOriginSize) {
+ unionOfMonitorViewportSize(vOriginSize);
+ }
+ @Override
public final String getFQName() {
return fqname;
}
@@ -275,258 +283,227 @@ public abstract class ScreenImpl extends Screen implements ScreenModeListener {
* Updates the rotated virtual ScreenSize using the native impl.
*/
protected void updateVirtualScreenOriginAndSize() {
- getVirtualScreenOriginAndSize(vOrigin, vSize);
- if(DEBUG) {
- System.err.println("Detected virtual screen origin "+vOrigin+", size "+vSize);
+ if(null != usrSize ) {
+ vOriginSize.setX(0);
+ vOriginSize.setY(0);
+ vOriginSize.setWidth(usrSize.getWidth());
+ vOriginSize.setHeight(usrSize.getHeight());
+ if(DEBUG) {
+ System.err.println("User virtual screen viewport "+vOriginSize);
+ }
+ } else {
+ calcVirtualScreenOriginAndSize(vOriginSize);
+ if(DEBUG) {
+ System.err.println("Detected virtual screen viewport "+vOriginSize);
+ }
}
}
+ @Override
public final Display getDisplay() {
return display;
}
+ @Override
public final int getIndex() {
return screen_idx;
}
+ @Override
public final AbstractGraphicsScreen getGraphicsScreen() {
return aScreen;
}
+ @Override
public synchronized final boolean isNativeValid() {
return null != aScreen;
}
- public int getX() { return vOrigin.getX(); }
- public int getY() { return vOrigin.getY(); }
-
- public final int getWidth() {
- return (null != usrSize) ? usrSize.getWidth() : vSize.getWidth();
- }
-
- public final int getHeight() {
- return (null != usrSize) ? usrSize.getHeight() : vSize.getHeight();
- }
+ @Override
+ public final int getX() { return vOriginSize.getX(); }
+ @Override
+ public final int getY() { return vOriginSize.getY(); }
+ @Override
+ public final int getWidth() { return vOriginSize.getWidth(); }
+ @Override
+ public final int getHeight() { return vOriginSize.getHeight(); }
+ @Override
+ public final RectangleImmutable getViewport() { return vOriginSize; }
@Override
public String toString() {
- return "NEWT-Screen["+getFQName()+", idx "+screen_idx+", refCount "+refCount+", "+getWidth()+"x"+getHeight()+", "+aScreen+", "+display+"]";
+ return "NEWT-Screen["+getFQName()+", idx "+screen_idx+", refCount "+refCount+", vsize "+vOriginSize+", "+aScreen+", "+display+
+ ", monitors: "+getMonitorDevices()+"]";
}
- public final List getScreenModes() {
- ArrayHashSet screenModes = getScreenModesOrig();
- if(null != screenModes && 0 < screenModes.size()) {
- return screenModes.toArrayList();
- }
- return null;
+ //
+ // MonitorDevice and MonitorMode
+ //
+
+ /**
+ * To be implemented by the native specification.
+ * Is called within a thread safe environment.
+ * Is called only to collect the {@link MonitorMode}s and {@link MonitorDevice}s, usually at startup setting up modes.
+ *
+ * WARNING: must be synchronized with
+ *
+ * - {@link MonitorModeProps#NUM_SCREEN_MODE_PROPERTIES} and
+ * - {@link MonitorModeProps#MIN_MONITOR_DEVICE_PROPERTIES}
+ *
, i.e.
+ *
+ * - {@link MonitorModeProps#streamInMonitorDevice(int[], jogamp.newt.MonitorModeProps.Cache, ScreenImpl, int[], int)}
+ * - {@link MonitorModeProps#streamInMonitorDevice(int[], jogamp.newt.MonitorModeProps.Cache, ScreenImpl, ArrayHashSet, int[], int)}
+ * - {@link MonitorModeProps#streamInMonitorMode(int[], jogamp.newt.MonitorModeProps.Cache, int[], int)}
+ *
+ * @param cache memory pool caching the result
+ */
+ protected abstract void collectNativeMonitorModesAndDevicesImpl(MonitorModeProps.Cache cache);
+
+ protected Rectangle getNativeMonitorDeviceViewportImpl(MonitorDevice monitor) { return null; }
+
+ /**
+ * To be implemented by the native specification.
+ * Is called within a thread safe environment.
+ *
+ * Implementation shall not unify the result w/ monitor's supported modes or a locally
+ * saved {@link MonitorModeProps.Cache}, since caller will perform such tasks.
+ *
+ */
+ protected abstract MonitorMode queryCurrentMonitorModeImpl(MonitorDevice monitor);
+
+ /**
+ * To be implemented by the native specification.
+ * Is called within a thread safe environment.
+ */
+ protected abstract boolean setCurrentMonitorModeImpl(MonitorDevice monitor, MonitorMode mode);
+
+ @Override
+ public final List getMonitorModes() {
+ final ScreenMonitorState sms = getScreenMonitorStatus(false);
+ return null != sms ? sms.getMonitorModes().getData() : null;
+ }
+
+ @Override
+ public final List getMonitorDevices() {
+ final ScreenMonitorState sms = getScreenMonitorStatus(false);
+ return null != sms ? sms.getMonitorDevices().getData() : null;
}
- private final ScreenModeStatus getScreenModeStatus(boolean throwException) {
+ final ScreenMonitorState getScreenMonitorStatus(boolean throwException) {
final String key = this.getFQName();
- final ScreenModeStatus res = ScreenModeStatus.getScreenModeStatus(key);
+ final ScreenMonitorState res = ScreenMonitorState.getScreenMonitorState(key);
if(null == res & throwException) {
- throw new InternalError("ScreenModeStatus.getScreenModeStatus("+key+") == null");
+ throw new InternalError("ScreenMonitorStatus.getScreenModeStatus("+key+") == null");
}
return res;
}
- public ScreenMode getOriginalScreenMode() {
- final ScreenModeStatus sms = getScreenModeStatus(false);
- return ( null != sms ) ? sms.getOriginalScreenMode() : null ;
- }
-
- public ScreenMode getCurrentScreenMode() {
- ScreenMode smU = null;
- final ScreenModeStatus sms = getScreenModeStatus(true);
- final ScreenMode sm0 = getCurrentScreenModeIntern();
- if(null == sm0) {
- throw new InternalError("getCurrentScreenModeImpl() == null");
+ @Override
+ public void monitorModeChangeNotify(MonitorEvent me) {
+ if(DEBUG) {
+ System.err.println("monitorModeChangeNotify: "+me);
}
- sms.lock();
- try {
- smU = sms.getScreenModes().getOrAdd(sm0); // unified instance, maybe new
-
- // if mode has changed somehow, update it ..
- if( sms.getCurrentScreenMode().hashCode() != smU.hashCode() ) {
- sms.fireScreenModeChanged(smU, true);
- }
- } finally {
- sms.unlock();
+ for(int i=0; i monitors = getMonitorDevices();
+ for(int i=monitors.size()-1; i>=0; i--) {
+ final MonitorDeviceImpl monitor = (MonitorDeviceImpl) monitors.get(i);
+ final Rectangle newViewport = getNativeMonitorDeviceViewportImpl(monitor);
+ if( DEBUG ) {
+ System.err.println("Screen.updateMonitorViewport["+i+"]: "+monitor.getViewport()+" -> "+newViewport);
}
-
- sms.fireScreenModeChangeNotify(smU);
- if(DEBUG) {
- System.err.println("Screen.setCurrentScreenMode ("+(System.nanoTime()-tStart)/1e6+"ms): fireScreenModeChangeNotify() "+smU);
+ if( null != newViewport ) {
+ monitor.setViewportValue(newViewport);
}
-
- success = setCurrentScreenModeImpl(smU);
- if(success) {
- if(DEBUG) {
- System.err.println("Screen.setCurrentScreenMode ("+(System.nanoTime()-tStart)/1e6+"ms): setCurrentScreenModeImpl() "+smU+", success(1): "+success);
- }
- } else {
- // 2nd attempt validate!
- final ScreenMode queriedCurrent = getCurrentScreenMode(); // may fireScreenModeChanged(..) if successful and differs!
- final ScreenMode smsCurrent = sms.getCurrentScreenMode();
- success = smsCurrent.hashCode() == smU.hashCode() && queriedCurrent.hashCode() == smU.hashCode() ;
- if(DEBUG) {
- System.err.println("Screen.setCurrentScreenMode.2: queried "+queriedCurrent);
- System.err.println("Screen.setCurrentScreenMode.2: SMS "+smsCurrent);
- System.err.println("Screen.setCurrentScreenMode ("+(System.nanoTime()-tStart)/1e6+"ms): setCurrentScreenModeImpl() "+smU+", success(2): "+success);
- }
- }
- sms.fireScreenModeChanged(smU, success);
- if(DEBUG) {
- System.err.println("Screen.setCurrentScreenMode ("+(System.nanoTime()-tStart)/1e6+"ms): X.X "+smU+", success: "+success);
- }
- } finally {
- sms.unlock();
- }
- return success;
+ }
}
-
- public void screenModeChangeNotify(ScreenMode sm) {
- for(int i=0; i 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.
- * Is called within a thread safe environment.
- * Is called only to collect the ScreenModes, usually at startup setting up modes.
- *
- * WARNING: 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)}
- *
- * Note: Additional 1st element is native mode id.
- */
- protected int[] getScreenModeFirstImpl() {
- return null;
- }
-
- /**
- * To be implemented by the native specification.
- * Is called within a thread safe environment.
- * Is called only to collect the ScreenModes, usually at startup setting up modes.
- *
- * WARNING: 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)}
- *
- * Note: Additional 1st element is native mode id.
- */
- protected int[] getScreenModeNextImpl() {
- return null;
+
+ private final MonitorMode getVirtualMonitorMode(int modeId) {
+ final int[] props = new int[MonitorModeProps.NUM_MONITOR_MODE_PROPERTIES_ALL];
+ int i = 0;
+ props[i++] = MonitorModeProps.NUM_MONITOR_MODE_PROPERTIES_ALL;
+ props[i++] = getWidth(); // width
+ props[i++] = getHeight(); // height
+ props[i++] = default_sm_bpp;
+ props[i++] = default_sm_rate * 100;
+ props[i++] = 0; // flags
+ props[i++] = modeId;
+ props[i++] = default_sm_rotation;
+ if( MonitorModeProps.NUM_MONITOR_MODE_PROPERTIES_ALL != i ) {
+ throw new InternalError("XX");
+ }
+ return MonitorModeProps.streamInMonitorMode(null, null, props, 0);
}
-
- /**
- * To be implemented by the native specification.
- * Is called within a thread safe environment.
- */
- protected ScreenMode getCurrentScreenModeImpl() {
- return null;
+
+ private final MonitorDevice getVirtualMonitorDevice(int monitorId, MonitorMode currentMode) {
+ int[] props = new int[MonitorModeProps.MIN_MONITOR_DEVICE_PROPERTIES];
+ int i = 0;
+ props[i++] = MonitorModeProps.MIN_MONITOR_DEVICE_PROPERTIES;
+ props[i++] = monitorId;
+ props[i++] = default_sm_widthmm;
+ props[i++] = default_sm_heightmm;
+ props[i++] = 0; // rotated viewport x
+ props[i++] = 0; // rotated viewport y
+ props[i++] = currentMode.getRotatedWidth(); // rotated viewport width
+ props[i++] = currentMode.getRotatedHeight(); // rotated viewport height
+ props[i++] = currentMode.getId(); // current mode id
+ props[i++] = currentMode.getRotation();
+ props[i++] = currentMode.getId(); // supported mode id #1
+ if( MonitorModeProps.MIN_MONITOR_DEVICE_PROPERTIES != i ) {
+ throw new InternalError("XX");
+ }
+ return MonitorModeProps.streamInMonitorDevice(null, null, this, props, 0);
}
/**
- * Utilizes {@link #getCurrentScreenModeImpl()}, if the latter returns null it uses
+ * Utilizes {@link #getCurrentMonitorModeImpl()}, if the latter returns null it uses
* the current screen size and dummy values.
*/
- protected ScreenMode getCurrentScreenModeIntern() {
- ScreenMode res;
+ protected final MonitorMode queryCurrentMonitorModeIntern(MonitorDevice monitor) {
+ MonitorMode res;
if(DEBUG_TEST_SCREENMODE_DISABLED) {
res = null;
} else {
- res = getCurrentScreenModeImpl();
+ res = queryCurrentMonitorModeImpl(monitor);
}
if(null == res) {
if( 0>=getWidth() || 0>=getHeight() ) {
updateVirtualScreenOriginAndSize();
}
- int[] props = new int[ScreenModeUtil.NUM_SCREEN_MODE_PROPERTIES_ALL];
- int i = 0;
- props[i++] = 0; // set later for verification of iterator
- props[i++] = getWidth(); // width
- props[i++] = getHeight(); // height
- props[i++] = default_sm_bpp;
- props[i++] = default_sm_widthmm;
- props[i++] = default_sm_heightmm;
- props[i++] = default_sm_rate;
- props[i++] = default_sm_rotation;
- props[i - ScreenModeUtil.NUM_SCREEN_MODE_PROPERTIES_ALL] = i; // count
- res = ScreenModeUtil.streamIn(props, 0);
+ res = getVirtualMonitorMode(monitor.getCurrentMode().getId());
}
return res;
}
- /**
- * To be implemented by the native specification.
- * Is called within a thread safe environment.
- */
- protected boolean setCurrentScreenModeImpl(ScreenMode screenMode) {
- return false;
- }
-
- private ScreenModeStatus initScreenModeStatus() {
+ private final ScreenMonitorState initScreenMonitorState() {
long t0;
if(DEBUG) {
t0 = System.nanoTime();
@@ -535,138 +512,139 @@ public abstract class ScreenImpl extends Screen implements ScreenModeListener {
t0 = 0;
}
- ScreenModeStatus sms;
- ScreenModeStatus.lockScreenModeStatus();
+ boolean vScrnSizeUpdated = false;
+ ScreenMonitorState sms;
+ ScreenMonitorState.lockScreenMonitorState();
try {
- sms = ScreenModeStatus.getScreenModeStatus(this.getFQName());
- if(null==sms) {
- IntIntHashMap screenModesIdx2NativeIdx = new IntIntHashMap();
- final ScreenMode currentSM = getCurrentScreenModeIntern();
- if(null == currentSM) {
- throw new InternalError("getCurrentScreenModeImpl() == null");
+ sms = ScreenMonitorState.getScreenMonitorState(this.getFQName());
+ if(null==sms) {
+ final MonitorModeProps.Cache cache = new MonitorModeProps.Cache();
+ if( 0 >= collectNativeMonitorModes(cache) ) {
+ updateVirtualScreenOriginAndSize();
+ vScrnSizeUpdated = true;
+ final MonitorMode mode = getVirtualMonitorMode(0);
+ cache.monitorModes.getOrAdd(mode);
+ final MonitorDevice monitor = getVirtualMonitorDevice(0, mode);
+ cache.monitorDevices.getOrAdd(monitor);
}
-
- ArrayHashSet screenModes = collectNativeScreenModes(screenModesIdx2NativeIdx);
- screenModes.getOrAdd(currentSM);
if(DEBUG) {
int i=0;
- for(Iterator iter=screenModes.iterator(); iter.hasNext(); i++) {
- System.err.println(i+": "+iter.next());
+ for(Iterator iMode=cache.monitorModes.iterator(); iMode.hasNext(); i++) {
+ System.err.println("All["+i+"]: "+iMode.next());
+ }
+ i=0;
+ for(Iterator iMonitor=cache.monitorDevices.iterator(); iMonitor.hasNext(); i++) {
+ final MonitorDevice crt = iMonitor.next();
+ System.err.println("["+i+"]: "+crt);
+ int j=0;
+ for(Iterator iMode=crt.getSupportedModes().iterator(); iMode.hasNext(); j++) {
+ System.err.println("["+i+"]["+j+"]: "+iMode.next());
+ }
}
}
-
- sms = new ScreenModeStatus(screenModes, screenModesIdx2NativeIdx);
- ScreenMode originalScreenMode0 = screenModes.get(currentSM); // unify via value hash
- if(null == originalScreenMode0) {
- throw new RuntimeException(currentSM+" could not be hashed from ScreenMode list");
- }
- sms.setOriginalScreenMode(originalScreenMode0);
- ScreenModeStatus.mapScreenModeStatus(this.getFQName(), sms);
+ sms = new ScreenMonitorState(cache.monitorDevices, cache.monitorModes);
+ ScreenMonitorState.mapScreenMonitorState(this.getFQName(), sms);
}
} finally {
- ScreenModeStatus.unlockScreenModeStatus();
+ ScreenMonitorState.unlockScreenMonitorState();
}
if(DEBUG) {
System.err.println("Screen.initScreenModeStatus() END dt "+ (System.nanoTime()-t0)/1e6 +"ms");
}
+ if( !vScrnSizeUpdated ) {
+ updateVirtualScreenOriginAndSize();
+ }
+
return sms;
}
- /** ignores bpp < 15 */
- private ArrayHashSet collectNativeScreenModes(IntIntHashMap screenModesIdx2NativeId) {
- ArrayHashSet resolutionPool = new ArrayHashSet();
- ArrayHashSet surfaceSizePool = new ArrayHashSet();
- ArrayHashSet screenSizeMMPool = new ArrayHashSet();
- ArrayHashSet monitorModePool = new ArrayHashSet();
- ArrayHashSet screenModePool = new ArrayHashSet();
-
- int[] smProps = null;
- int num = 0;
- final int idxBpp = 1 // native mode
- + 1 // count
- + ScreenModeUtil.NUM_RESOLUTION_PROPERTIES
- + ScreenModeUtil.NUM_SURFACE_SIZE_PROPERTIES
- - 1 ; // index 0 based
- do {
- if(DEBUG_TEST_SCREENMODE_DISABLED) {
- smProps = null;
- } else if(0 == num) {
- smProps = getScreenModeFirstImpl();
- } else {
- smProps = getScreenModeNextImpl();
- }
- if(null != smProps && 0 < smProps.length && smProps[idxBpp] >= 15) {
- int nativeId = smProps[0];
- int screenModeIdx = ScreenModeUtil.streamIn(resolutionPool, surfaceSizePool, screenSizeMMPool,
- monitorModePool, screenModePool, smProps, 1);
- if(DEBUG) {
- System.err.println("ScreenImpl.collectNativeScreenModes: #"+num+": idx: "+nativeId+" native -> "+screenModeIdx+" newt");
+ /**
+ * Returns the number of successful collected {@link MonitorDevice}s.
+ *
+ * Collects {@link MonitorDevice}s and {@link MonitorMode}s within the given cache.
+ *
+ */
+ private final int collectNativeMonitorModes(MonitorModeProps.Cache cache) {
+ if(!DEBUG_TEST_SCREENMODE_DISABLED) {
+ collectNativeMonitorModesAndDevicesImpl(cache);
+ }
+ // filter out insufficient modes
+ for(int i=cache.monitorModes.size()-1; i>=0; i--) {
+ final MonitorMode mode = cache.monitorModes.get(i);
+ if( 16 > mode.getSurfaceSize().getBitsPerPixel() ) {
+ boolean keep = false;
+ for(int j=cache.monitorDevices.size()-1; !keep && j>=0; j--) {
+ final MonitorDevice monitor = cache.monitorDevices.get(j);
+ keep = monitor.getCurrentMode().equals(mode);
}
-
- if(screenModeIdx >= 0) {
- screenModesIdx2NativeId.put(screenModeIdx, nativeId);
+ if(!keep) {
+ cache.monitorModes.remove(i);
+ for(int j=cache.monitorDevices.size()-1; j>=0; j--) {
+ final MonitorDeviceImpl monitor = (MonitorDeviceImpl) cache.monitorDevices.get(j);
+ monitor.getSupportedModesImpl().remove(mode);
+ }
}
- } else if(DEBUG) {
- System.err.println("ScreenImpl.collectNativeScreenModes: #"+num+": smProps: "+(null!=smProps)+
- ", len: "+(null != smProps ? smProps.length : 0)+
- ", bpp: "+(null != smProps && 0 < smProps.length ? smProps[idxBpp] : 0)+
- " - DROPPING");
}
- num++;
- } while ( null != smProps && 0 < smProps.length );
-
- 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;
+ if( DEBUG ) {
+ System.err.println("ScreenImpl.collectNativeMonitorModes: MonitorDevice number : "+cache.monitorDevices.size());
+ System.err.println("ScreenImpl.collectNativeMonitorModes: MonitorMode number : "+cache.monitorModes.size());
+ System.err.println("ScreenImpl.collectNativeMonitorModes: SizeAndRate number : "+cache.sizeAndRates.size());
+ System.err.println("ScreenImpl.collectNativeMonitorModes: SurfaceSize number : "+cache.surfaceSizes.size());
+ System.err.println("ScreenImpl.collectNativeMonitorModes: Resolution number : "+cache.resolutions.size());
+ }
+ return cache.monitorDevices.size();
}
private void releaseScreenModeStatus() {
- ScreenModeStatus sms;
- ScreenModeStatus.lockScreenModeStatus();
+ ScreenMonitorState sms;
+ ScreenMonitorState.lockScreenMonitorState();
try {
- sms = ScreenModeStatus.getScreenModeStatus(getFQName());
+ sms = ScreenMonitorState.getScreenMonitorState(getFQName());
if(null != sms) {
sms.lock();
try {
if(0 == sms.removeListener(this)) {
- if(sms.isOriginalModeChangedByOwner()) {
- System.err.println("Screen.destroy(): "+sms.getCurrentScreenMode()+" -> "+sms.getOriginalScreenMode());
- try {
- setCurrentScreenMode(sms.getOriginalScreenMode());
- } catch (Throwable t) {
- // be verbose but continue
- t.printStackTrace();
+ final ArrayList monitorDevices = sms.getMonitorDevices().getData();
+ for(int i=0; i "+sms.getOriginalScreenMode());
- setCurrentScreenModeImpl(sms.getOriginalScreenMode());
- } catch (Throwable t) {
- // be quiet .. shutdown
+ final ArrayList monitorDevices = sms.getMonitorDevices().getData();
+ for(int i=0; i screenModes;
- private IntIntHashMap screenModesIdx2NativeIdx;
- private ScreenMode currentScreenMode;
- private ScreenMode originalScreenMode;
- private boolean screenModeChangedByOwner;
- private ArrayList listener = new ArrayList();
-
- private static HashMap screenFQN2ScreenModeStatus = new HashMap();
- private static RecursiveLock screen2ScreenModeStatusLock = LockFactory.createRecursiveLock();
-
- protected static void mapScreenModeStatus(String screenFQN, ScreenModeStatus sms) {
- screen2ScreenModeStatusLock.lock();
- try {
- ScreenModeStatus _sms = 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 {
- unmapScreenModeStatusUnlocked(screenFQN);
- } finally {
- screen2ScreenModeStatusLock.unlock();
- }
- }
- protected static void unmapScreenModeStatusUnlocked(String screenFQN) {
- ScreenModeStatus sms = screenFQN2ScreenModeStatus.remove(screenFQN);
- if(DEBUG) {
- System.err.println("ScreenModeStatus.unmap "+screenFQN+" -> "+sms);
- }
- }
-
- protected static ScreenModeStatus getScreenModeStatus(String screenFQN) {
- screen2ScreenModeStatusLock.lock();
- try {
- return getScreenModeStatusUnlocked(screenFQN);
- } finally {
- screen2ScreenModeStatusLock.unlock();
- }
- }
- protected static ScreenModeStatus getScreenModeStatusUnlocked(String screenFQN) {
- return screenFQN2ScreenModeStatus.get(screenFQN);
- }
-
- protected static void lockScreenModeStatus() {
- screen2ScreenModeStatusLock.lock();
- }
-
- protected static void unlockScreenModeStatus() {
- screen2ScreenModeStatusLock.unlock();
- }
-
- public ScreenModeStatus(ArrayHashSet screenModes,
- IntIntHashMap screenModesIdx2NativeIdx) {
- this.screenModes = screenModes;
- this.screenModesIdx2NativeIdx = screenModesIdx2NativeIdx;
- this.screenModeChangedByOwner = false;
- }
-
- 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();
- }
- }
-
- /**
- * We cannot guarantee that we won't interfere w/ another running
- * application's screen mode change.
- *
- * At least we only return true if the owner, ie. the Screen,
- * has changed the screen mode and if the original screen mode
- * is not current the current one.
- *
- * @return
- */
- public final boolean isOriginalModeChangedByOwner() {
- lock();
- try {
- return screenModeChangedByOwner && !isCurrentModeOriginalMode();
- } finally {
- unlock();
- }
- }
-
- protected final boolean isCurrentModeOriginalMode() {
- if(null != currentScreenMode && null != originalScreenMode) {
- return currentScreenMode.hashCode() == originalScreenMode.hashCode();
- }
- return true;
- }
-
- protected final ArrayHashSet 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 allMonitors;
+ private final ArrayHashSet allMonitorModes;
+ private ArrayList listener = new ArrayList();
+
+ private static HashMap screenFQN2ScreenMonitorState = new HashMap();
+ private static RecursiveLock screen2ScreenMonitorState = LockFactory.createRecursiveLock();
+
+ protected static void mapScreenMonitorState(String screenFQN, ScreenMonitorState sms) {
+ screen2ScreenMonitorState.lock();
+ try {
+ ScreenMonitorState _sms = screenFQN2ScreenMonitorState.get(screenFQN);
+ if( null != _sms ) {
+ throw new RuntimeException("ScreenMonitorState "+_sms+" already mapped to "+screenFQN);
+ }
+ screenFQN2ScreenMonitorState.put(screenFQN, sms);
+ if(DEBUG) {
+ System.err.println("ScreenMonitorState.map "+screenFQN+" -> "+sms);
+ }
+ } finally {
+ screen2ScreenMonitorState.unlock();
+ }
+ }
+
+ /**
+ * @param screen the prev user
+ * @return true if mapping is empty, ie no more usage of the mapped ScreenMonitorState
+ */
+ protected static void unmapScreenMonitorState(String screenFQN) {
+ screen2ScreenMonitorState.lock();
+ try {
+ unmapScreenMonitorStateUnlocked(screenFQN);
+ } finally {
+ screen2ScreenMonitorState.unlock();
+ }
+ }
+ protected static void unmapScreenMonitorStateUnlocked(String screenFQN) {
+ ScreenMonitorState sms = screenFQN2ScreenMonitorState.remove(screenFQN);
+ if(DEBUG) {
+ System.err.println("ScreenMonitorState.unmap "+screenFQN+" -> "+sms);
+ }
+ }
+
+ protected static ScreenMonitorState getScreenMonitorState(String screenFQN) {
+ screen2ScreenMonitorState.lock();
+ try {
+ return getScreenMonitorStateUnlocked(screenFQN);
+ } finally {
+ screen2ScreenMonitorState.unlock();
+ }
+ }
+ protected static ScreenMonitorState getScreenMonitorStateUnlocked(String screenFQN) {
+ return screenFQN2ScreenMonitorState.get(screenFQN);
+ }
+
+ protected static void lockScreenMonitorState() {
+ screen2ScreenMonitorState.lock();
+ }
+
+ protected static void unlockScreenMonitorState() {
+ screen2ScreenMonitorState.unlock();
+ }
+
+ public ScreenMonitorState(ArrayHashSet allMonitors,
+ ArrayHashSet allMonitorModes) {
+ this.allMonitors = allMonitors;
+ this.allMonitorModes = allMonitorModes;
+ }
+
+ protected ArrayHashSet getMonitorDevices() {
+ return allMonitors;
+ }
+
+ protected ArrayHashSet getMonitorModes() {
+ return allMonitorModes;
+ }
+
+ protected final int addListener(MonitorModeListener l) {
+ lock();
+ try {
+ listener.add(l);
+ if(DEBUG) {
+ System.err.println("ScreenMonitorState.addListener (size: "+listener.size()+"): "+l);
+ }
+ return listener.size();
+ } finally {
+ unlock();
+ }
+ }
+
+ protected final int removeListener(MonitorModeListener l) {
+ lock();
+ try {
+ if(!listener.remove(l)) {
+ throw new RuntimeException("ScreenModeListener "+l+" not contained");
+ }
+ if(DEBUG) {
+ System.err.println("ScreenMonitorState.removeListener (size: "+listener.size()+"): "+l);
+ }
+ return listener.size();
+ } finally {
+ unlock();
+ }
+ }
+
+ protected final MonitorDevice getMonitor(MonitorDevice monitor) {
+ return allMonitors.get(monitor);
+ }
+
+ protected final void validateMonitor(MonitorDevice monitor) {
+ final MonitorDevice md = allMonitors.get(monitor);
+ if( null == md ) {
+ throw new InternalError("Monitor unknown: "+monitor);
+ }
+ }
+
+ protected final void fireScreenModeChangeNotify(MonitorDevice monitor, MonitorMode desiredMode) {
+ lock();
+ try {
+ validateMonitor(monitor);
+ final MonitorEvent me = new MonitorEvent(MonitorEvent.EVENT_MONITOR_MODE_CHANGE_NOTIFY, monitor, System.currentTimeMillis(), desiredMode);
+ for(int i=0; i default
- private boolean fullscreen = false, brokenFocusChange = false;
+ private boolean fullscreen = false, brokenFocusChange = false;
+ private List fullscreenMonitors = null;
+ private boolean fullscreenUseMainMonitor = true;
private boolean autoPosition = true; // default: true (allow WM to choose top-level position, if not set by user)
private int nfs_width, nfs_height, nfs_x, nfs_y; // non fullscreen client-area size/pos w/o insets
@@ -294,19 +298,40 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
screenReferenceAdded = true;
}
if(canCreateNativeImpl()) {
+ final int wX, wY;
+ final boolean usePosition;
+ if( autoPosition ) {
+ wX = 0;
+ wY = 0;
+ usePosition = false;
+ } else {
+ wX = getX();
+ wY = getY();
+ usePosition = true;
+ }
+ final long t0 = System.currentTimeMillis();
createNativeImpl();
- screen.addScreenModeListener(screenModeListenerImpl);
+ screen.addMonitorModeListener(screenModeListenerImpl);
setTitleImpl(title);
setPointerVisibleImpl(pointerVisible);
confinePointerImpl(pointerConfined);
setKeyboardVisible(keyboardVisible);
- if(waitForVisible(true, false)) {
+ final long remainingV = waitForVisible(true, false);
+ if( 0 <= remainingV ) {
if(isFullscreen()) {
synchronized(fullScreenAction) {
fullscreen = false; // trigger a state change
- fullScreenAction.init(true);
+ fullScreenAction.init(true, fullscreenUseMainMonitor, fullscreenMonitors);
+ fullscreenMonitors = null; // release references ASAP
+ fullscreenUseMainMonitor = true;
fullScreenAction.run();
}
+ } else {
+ // Wait until position is reached within tolerances, either auto-position or custom position.
+ waitForPosition(usePosition, wX, wY, Window.TIMEOUT_NATIVEWINDOW);
+ }
+ if (DEBUG_IMPLEMENTATION) {
+ System.err.println("Window.createNative(): elapsed "+(System.currentTimeMillis()-t0)+" ms");
}
postParentlockFocus = true;
}
@@ -463,8 +488,9 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
public static final int FLAG_HAS_PARENT = 1 << 8;
public static final int FLAG_IS_UNDECORATED = 1 << 9;
public static final int FLAG_IS_FULLSCREEN = 1 << 10;
- public static final int FLAG_IS_ALWAYSONTOP = 1 << 11;
- public static final int FLAG_IS_VISIBLE = 1 << 12;
+ public static final int FLAG_IS_FULLSCREEN_SPAN = 1 << 11;
+ public static final int FLAG_IS_ALWAYSONTOP = 1 << 12;
+ public static final int FLAG_IS_VISIBLE = 1 << 13;
/**
* The native implementation should invoke the referenced java state callbacks
@@ -509,6 +535,8 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
sb.append("FS_");
sb.append(0 != ( FLAG_IS_FULLSCREEN & flags));
+ sb.append("_span_");
+ sb.append(0 != ( FLAG_IS_FULLSCREEN_SPAN & flags));
sb.append(", ");
if( 0 != ( FLAG_CHANGE_DECORATION & flags) ) {
@@ -718,6 +746,11 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
return screen;
}
+ @Override
+ public final MonitorDevice getMainMonitor() {
+ return screen.getMainMonitor(new Rectangle(getX(), getY(), getWidth(), getHeight()));
+ }
+
protected final void setVisibleImpl(boolean visible, int x, int y, int width, int height) {
reconfigureWindowImpl(x, y, width, height, getReconfigureFlags(FLAG_CHANGE_VISIBILITY, visible));
}
@@ -904,7 +937,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
if( isNativeValid() ) {
- screen.removeScreenModeListener(screenModeListenerImpl);
+ screen.removeMonitorModeListener(screenModeListenerImpl);
closeNativeImpl();
final AbstractGraphicsDevice cfgADevice = config.getScreen().getDevice();
if( cfgADevice != screen.getDisplay().getGraphicsDevice() ) { // don't pull display's device
@@ -929,6 +962,8 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
setWindowHandle(0);
visible = false;
fullscreen = false;
+ fullscreenMonitors = null;
+ fullscreenUseMainMonitor = true;
hasFocus = false;
parentWindowHandle = 0;
@@ -1212,7 +1247,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
display.dispatchMessagesNative(); // status up2date
if(wasVisible) {
setVisibleImpl(true, x, y, width, height);
- ok = WindowImpl.this.waitForVisible(true, false);
+ ok = 0 <= WindowImpl.this.waitForVisible(true, false);
if(ok) {
ok = WindowImpl.this.waitForSize(width, height, false, TIMEOUT_NATIVEWINDOW);
}
@@ -1735,6 +1770,9 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
if(isNativeValid()) {
// this.x/this.y will be set by sizeChanged, triggered by windowing event system
reconfigureWindowImpl(x, y, getWidth(), getHeight(), getReconfigureFlags(0, isVisible()));
+
+ // Wait until custom position is reached within tolerances
+ waitForPosition(true, x, y, Window.TIMEOUT_NATIVEWINDOW);
} else {
definePosition(x, y); // set pos for createNative(..)
}
@@ -1758,13 +1796,25 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
private class FullScreenAction implements Runnable {
boolean fullscreen;
+ List monitors;
+ boolean useMainMonitor;
- private boolean init(boolean fullscreen) {
+ private boolean init(boolean fullscreen, boolean useMainMonitor, List monitors) {
if(isNativeValid()) {
this.fullscreen = fullscreen;
- return isFullscreen() != fullscreen;
+ if( isFullscreen() != fullscreen ) {
+ this.monitors = monitors;
+ this.useMainMonitor = useMainMonitor;
+ return true;
+ } else {
+ this.monitors = null;
+ this.useMainMonitor = true;
+ return false;
+ }
} else {
WindowImpl.this.fullscreen = fullscreen; // set current state for createNative(..)
+ WindowImpl.this.fullscreenMonitors = monitors;
+ WindowImpl.this.fullscreenUseMainMonitor = useMainMonitor;
return false;
}
}
@@ -1777,19 +1827,32 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
// set current state
WindowImpl.this.fullscreen = fullscreen;
- final ScreenMode sm = screen.getCurrentScreenMode();
int x,y,w,h;
+ final RectangleImmutable viewport;
+ final int fs_span_flag;
if(fullscreen) {
+ if( null == monitors ) {
+ if( useMainMonitor ) {
+ monitors = new ArrayList();
+ monitors.add( getMainMonitor() );
+ } else {
+ monitors = getScreen().getMonitorDevices();
+ }
+ }
+ fs_span_flag = monitors.size() > 1 ? FLAG_IS_FULLSCREEN_SPAN : 0 ;
+ viewport = MonitorDevice.unionOfViewports(new Rectangle(), monitors);
nfs_x = getX();
nfs_y = getY();
nfs_width = getWidth();
nfs_height = getHeight();
- x = screen.getX();
- y = screen.getY();
- w = sm.getRotatedWidth();
- h = sm.getRotatedHeight();
+ x = viewport.getX();
+ y = viewport.getY();
+ w = viewport.getWidth();
+ h = viewport.getHeight();
} else {
+ fs_span_flag = 0;
+ viewport = null;
x = nfs_x;
y = nfs_y;
w = nfs_width;
@@ -1809,9 +1872,11 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
}
}
+ monitors = null; // clear references ASAP
+ useMainMonitor = true;
if(DEBUG_IMPLEMENTATION) {
System.err.println("Window fs: "+fullscreen+" "+x+"/"+y+" "+w+"x"+h+", "+isUndecorated()+
- ", virtl-size: "+screen.getWidth()+"x"+screen.getHeight()+", SM "+sm.getRotatedWidth()+"x"+sm.getRotatedHeight());
+ ", virtl-size: "+screen.getWidth()+"x"+screen.getHeight()+", monitorsViewport "+viewport);
}
DisplayImpl display = (DisplayImpl) screen.getDisplay();
@@ -1831,7 +1896,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
try {
reconfigureWindowImpl(x, y, w, h,
getReconfigureFlags( ( ( null != parentWindowLocked ) ? FLAG_CHANGE_PARENTING : 0 ) |
- FLAG_CHANGE_FULLSCREEN | FLAG_CHANGE_DECORATION, wasVisible) );
+ fs_span_flag | FLAG_CHANGE_FULLSCREEN | FLAG_CHANGE_DECORATION, wasVisible) );
} finally {
if(null!=parentWindowLocked) {
parentWindowLocked.unlockSurface();
@@ -1860,8 +1925,17 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
@Override
public boolean setFullscreen(boolean fullscreen) {
+ return setFullscreenImpl(fullscreen, true, null);
+ }
+
+ @Override
+ public boolean setFullscreen(List monitors) {
+ return setFullscreenImpl(true, false, monitors);
+ }
+
+ private boolean setFullscreenImpl(boolean fullscreen, boolean useMainMonitor, List monitors) {
synchronized(fullScreenAction) {
- if( fullScreenAction.init(fullscreen) ) {
+ if( fullScreenAction.init(fullscreen, useMainMonitor, monitors) ) {
if(fullScreenAction.fsOn() && isOffscreenInstance(WindowImpl.this, parentWindow)) {
// enable fullscreen on offscreen instance
if(null != parentWindow) {
@@ -1887,13 +1961,13 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
return this.fullscreen;
}
}
-
- private class ScreenModeListenerImpl implements ScreenModeListener {
+
+ private class ScreenModeListenerImpl implements MonitorModeListener {
boolean animatorPaused = false;
- public void screenModeChangeNotify(ScreenMode sm) {
+ public void monitorModeChangeNotify(MonitorEvent me) {
if(DEBUG_IMPLEMENTATION) {
- System.err.println("Window.screenModeChangeNotify: "+sm);
+ System.err.println("Window.screenModeChangeNotify: "+me);
}
if(null!=lifecycleHook) {
@@ -1901,9 +1975,9 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
}
- public void screenModeChanged(ScreenMode sm, boolean success) {
+ public void monitorModeChanged(MonitorEvent me, boolean success) {
if(DEBUG_IMPLEMENTATION) {
- System.err.println("Window.screenModeChanged: "+sm+", success: "+success);
+ System.err.println("Window.screenModeChanged: "+me+", success: "+success);
}
if(success) {
@@ -1911,10 +1985,19 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
// Didn't pass above notify method. probably detected screen change after it happened.
animatorPaused = lifecycleHook.pauseRenderingAction();
}
- DimensionImmutable screenSize = sm.getMonitorMode().getSurfaceSize().getResolution();
- if ( getHeight() > screenSize.getHeight() ||
- getWidth() > screenSize.getWidth() ) {
- setSize(screenSize.getWidth(), screenSize.getHeight());
+ if( !fullscreen ) {
+ // FIXME: Need to take all covered monitors into account
+ final MonitorDevice mainMonitor = getMainMonitor();
+ final MonitorDevice eventMonitor = me.getMonitor();
+ if( mainMonitor == eventMonitor ) {
+ final RectangleImmutable rect = new Rectangle(getX(), getY(), getWidth(), getHeight());
+ final RectangleImmutable viewport = mainMonitor.getViewport();
+ final RectangleImmutable isect = viewport.intersection(rect);
+ if ( getHeight() > isect.getHeight() ||
+ getWidth() > isect.getWidth() ) {
+ setSize(isect.getWidth(), isect.getHeight());
+ }
+ }
}
}
@@ -2563,14 +2646,17 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
}
- private boolean waitForVisible(boolean visible, boolean failFast) {
+ /** Returns -1 if failed, otherwise remaining time until {@link #TIMEOUT_NATIVEWINDOW}, maybe zero. */
+ private long waitForVisible(boolean visible, boolean failFast) {
return waitForVisible(visible, failFast, TIMEOUT_NATIVEWINDOW);
}
- private boolean waitForVisible(boolean visible, boolean failFast, long timeOut) {
+ /** Returns -1 if failed, otherwise remaining time until timeOut
, maybe zero. */
+ private long waitForVisible(boolean visible, boolean failFast, long timeOut) {
final DisplayImpl display = (DisplayImpl) screen.getDisplay();
display.dispatchMessagesNative(); // status up2date
- for(long sleep = timeOut; 0
+ * Since WM may not obey our positional request exactly, we allow a tolerance of 2 times insets[left/top], or 64 pixels, whatever is greater.
+ *
+ */
+ private boolean waitForPosition(boolean useCustomPosition, int x, int y, long timeOut) {
+ final DisplayImpl display = (DisplayImpl) screen.getDisplay();
+ final int maxDX, maxDY;
+ {
+ final InsetsImmutable insets = getInsets();
+ maxDX = Math.max(64, insets.getLeftWidth() * 2);
+ maxDY = Math.max(64, insets.getTopHeight() * 2);
+ }
+ long remaining = timeOut;
+ boolean ok;
+ do {
+ if( useCustomPosition ) {
+ ok = Math.abs(x - getX()) <= maxDX && Math.abs(y - getY()) <= maxDY ;
+ } else {
+ ok = !autoPosition;
+ }
+ if( !ok ) {
+ try { Thread.sleep(10); } catch (InterruptedException ie) {}
+ display.dispatchMessagesNative(); // status up2date
+ remaining-=10;
+ }
+ } while ( 0getX() || 0>getY()) {
diff --git a/src/newt/classes/jogamp/newt/driver/awt/ScreenDriver.java b/src/newt/classes/jogamp/newt/driver/awt/ScreenDriver.java
index 6b1283a00..8e584fc58 100644
--- a/src/newt/classes/jogamp/newt/driver/awt/ScreenDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/awt/ScreenDriver.java
@@ -35,12 +35,15 @@ package jogamp.newt.driver.awt;
import java.awt.DisplayMode;
+import jogamp.newt.MonitorModeProps.Cache;
import jogamp.newt.ScreenImpl;
import javax.media.nativewindow.util.Dimension;
import javax.media.nativewindow.util.Point;
import com.jogamp.nativewindow.awt.AWTGraphicsDevice;
import com.jogamp.nativewindow.awt.AWTGraphicsScreen;
+import com.jogamp.newt.MonitorDevice;
+import com.jogamp.newt.MonitorMode;
public class ScreenDriver extends ScreenImpl {
public ScreenDriver() {
@@ -68,14 +71,19 @@ public class ScreenDriver extends ScreenImpl {
return idx; // pass through ...
}
- protected void getVirtualScreenOriginAndSize(Point virtualOrigin, Dimension virtualSize) {
- final DisplayMode mode = ((AWTGraphicsDevice)getDisplay().getGraphicsDevice()).getGraphicsDevice().getDisplayMode();
- if(null != mode) {
- virtualOrigin.setX(0);
- virtualOrigin.setY(0);
- virtualSize.setWidth(mode.getWidth());
- virtualSize.setHeight(mode.getHeight());
- }
+ @Override
+ protected void collectNativeMonitorModesAndDevicesImpl(Cache cache) {
+ final DisplayMode mode = ((AWTGraphicsDevice)getDisplay().getGraphicsDevice()).getGraphicsDevice().getDisplayMode();
+ }
+
+ @Override
+ protected MonitorMode queryCurrentMonitorModeImpl(MonitorDevice monitor) {
+ return null;
+ }
+
+ @Override
+ protected boolean setCurrentMonitorModeImpl(MonitorDevice monitor, MonitorMode mode) {
+ return false;
}
}
diff --git a/src/newt/classes/jogamp/newt/driver/bcm/egl/ScreenDriver.java b/src/newt/classes/jogamp/newt/driver/bcm/egl/ScreenDriver.java
index deb2a534b..afaedffe3 100644
--- a/src/newt/classes/jogamp/newt/driver/bcm/egl/ScreenDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/bcm/egl/ScreenDriver.java
@@ -35,8 +35,13 @@
package jogamp.newt.driver.bcm.egl;
import javax.media.nativewindow.DefaultGraphicsScreen;
-import javax.media.nativewindow.util.Dimension;
-import javax.media.nativewindow.util.Point;
+import javax.media.nativewindow.util.Rectangle;
+
+import jogamp.newt.MonitorModeProps;
+import jogamp.newt.ScreenImpl;
+
+import com.jogamp.newt.MonitorDevice;
+import com.jogamp.newt.MonitorMode;
public class ScreenDriver extends jogamp.newt.ScreenImpl {
@@ -58,11 +63,48 @@ public class ScreenDriver extends jogamp.newt.ScreenImpl {
return 0; // only one screen available
}
- protected void getVirtualScreenOriginAndSize(Point virtualOrigin, Dimension virtualSize) {
- virtualOrigin.setX(0);
- virtualOrigin.setY(0);
- virtualSize.setWidth(fixedWidth); // FIXME
- virtualSize.setHeight(fixedHeight); // FIXME
+ @Override
+ protected final void collectNativeMonitorModesAndDevicesImpl(MonitorModeProps.Cache cache) {
+ int[] props = new int[ MonitorModeProps.NUM_MONITOR_MODE_PROPERTIES_ALL ];
+ int i = 0;
+ props[i++] = MonitorModeProps.NUM_MONITOR_MODE_PROPERTIES_ALL;
+ props[i++] = fixedWidth; // FIXME
+ props[i++] = fixedHeight; // FIXME
+ props[i++] = ScreenImpl.default_sm_bpp; // FIXME
+ props[i++] = ScreenImpl.default_sm_rate * 100; // FIXME
+ props[i++] = 0; // flags
+ props[i++] = 0; // mode_idx
+ props[i++] = 0; // rotation
+ final MonitorMode currentMode = MonitorModeProps.streamInMonitorMode(null, cache, props, 0);
+
+ props = new int[MonitorModeProps.MIN_MONITOR_DEVICE_PROPERTIES - 1 - MonitorModeProps.NUM_MONITOR_MODE_PROPERTIES];
+ i = 0;
+ props[i++] = props.length;
+ props[i++] = 0; // crt_idx
+ props[i++] = ScreenImpl.default_sm_widthmm; // FIXME
+ props[i++] = ScreenImpl.default_sm_heightmm; // FIXME
+ props[i++] = 0; // rotated viewport x
+ props[i++] = 0; // rotated viewport y
+ props[i++] = fixedWidth; // FIXME rotated viewport width
+ props[i++] = fixedHeight; // FIXME rotated viewport height
+ MonitorModeProps.streamInMonitorDevice(null, cache, this, cache.monitorModes, currentMode, props, 0);
+ }
+
+ @Override
+ protected MonitorMode queryCurrentMonitorModeImpl(final MonitorDevice monitor) {
+ return monitor.getSupportedModes().get(0);
+ }
+
+ @Override
+ protected boolean setCurrentMonitorModeImpl(final MonitorDevice monitor, final MonitorMode mode) {
+ return false;
+ }
+
+ protected void calcVirtualScreenOriginAndSize(Rectangle vOriginSize) {
+ vOriginSize.setX(0);
+ vOriginSize.setY(0);
+ vOriginSize.setWidth(fixedWidth); // FIXME
+ vOriginSize.setHeight(fixedHeight); // FIXME
}
//----------------------------------------------------------------------
diff --git a/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/ScreenDriver.java b/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/ScreenDriver.java
index 787d1a1b4..f7973def8 100644
--- a/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/ScreenDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/ScreenDriver.java
@@ -29,9 +29,12 @@
package jogamp.newt.driver.bcm.vc.iv;
import javax.media.nativewindow.DefaultGraphicsScreen;
-import javax.media.nativewindow.util.Dimension;
-import javax.media.nativewindow.util.Point;
+import javax.media.nativewindow.util.Rectangle;
+import com.jogamp.newt.MonitorDevice;
+import com.jogamp.newt.MonitorMode;
+
+import jogamp.newt.MonitorModeProps;
import jogamp.newt.ScreenImpl;
public class ScreenDriver extends ScreenImpl {
@@ -53,13 +56,52 @@ public class ScreenDriver extends ScreenImpl {
return 0; // only one screen available
}
- protected void getVirtualScreenOriginAndSize(Point virtualOrigin, Dimension virtualSize) {
- virtualOrigin.setX(0);
- virtualOrigin.setY(0);
- virtualSize.setWidth(cachedWidth);
- virtualSize.setHeight(cachedHeight);
+ @Override
+ protected final void collectNativeMonitorModesAndDevicesImpl(MonitorModeProps.Cache cache) {
+ int[] props = new int[ MonitorModeProps.NUM_MONITOR_MODE_PROPERTIES_ALL ];
+ int i = 0;
+ props[i++] = MonitorModeProps.NUM_MONITOR_MODE_PROPERTIES_ALL;
+ props[i++] = cachedWidth; // width
+ props[i++] = cachedHeight; // height
+ props[i++] = ScreenImpl.default_sm_bpp; // FIXME
+ props[i++] = ScreenImpl.default_sm_rate * 100; // FIXME
+ props[i++] = 0; // flags
+ props[i++] = 0; // mode_idx
+ props[i++] = 0; // rotation
+ final MonitorMode currentMode = MonitorModeProps.streamInMonitorMode(null, cache, props, 0);
+
+ props = new int[MonitorModeProps.MIN_MONITOR_DEVICE_PROPERTIES - 1 - MonitorModeProps.NUM_MONITOR_MODE_PROPERTIES];
+ i = 0;
+ props[i++] = props.length;
+ props[i++] = 0; // crt_idx
+ props[i++] = ScreenImpl.default_sm_widthmm; // FIXME
+ props[i++] = ScreenImpl.default_sm_heightmm; // FIXME
+ props[i++] = 0; // rotated viewport x
+ props[i++] = 0; // rotated viewport y
+ props[i++] = cachedWidth; // rotated viewport width
+ props[i++] = cachedWidth; // rotated viewport height
+ MonitorModeProps.streamInMonitorDevice(null, cache, this, cache.monitorModes, currentMode, props, 0);
+ }
+
+ @Override
+ protected MonitorMode queryCurrentMonitorModeImpl(final MonitorDevice monitor) {
+ return monitor.getSupportedModes().get(0);
+ }
+
+ @Override
+ protected boolean setCurrentMonitorModeImpl(final MonitorDevice monitor, final MonitorMode mode) {
+ return false;
+ }
+
+ @Override
+ protected void calcVirtualScreenOriginAndSize(Rectangle vOriginSize) {
+ vOriginSize.setX(0);
+ vOriginSize.setY(0);
+ vOriginSize.setWidth(cachedWidth);
+ vOriginSize.setHeight(cachedHeight);
}
+ /** Called from {@link #initNative()}. */
protected void setScreenSize(int width, int height) {
cachedWidth = width;
cachedHeight = height;
diff --git a/src/newt/classes/jogamp/newt/driver/intel/gdl/ScreenDriver.java b/src/newt/classes/jogamp/newt/driver/intel/gdl/ScreenDriver.java
index 8eed14dde..4c47eb0d8 100644
--- a/src/newt/classes/jogamp/newt/driver/intel/gdl/ScreenDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/intel/gdl/ScreenDriver.java
@@ -36,8 +36,13 @@ package jogamp.newt.driver.intel.gdl;
import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.DefaultGraphicsScreen;
-import javax.media.nativewindow.util.Dimension;
-import javax.media.nativewindow.util.Point;
+import javax.media.nativewindow.util.Rectangle;
+
+import jogamp.newt.MonitorModeProps;
+import jogamp.newt.ScreenImpl;
+
+import com.jogamp.newt.MonitorDevice;
+import com.jogamp.newt.MonitorMode;
public class ScreenDriver extends jogamp.newt.ScreenImpl {
@@ -60,11 +65,48 @@ public class ScreenDriver extends jogamp.newt.ScreenImpl {
return 0; // only one screen available
}
- protected void getVirtualScreenOriginAndSize(Point virtualOrigin, Dimension virtualSize) {
- virtualOrigin.setX(0);
- virtualOrigin.setY(0);
- virtualSize.setWidth(cachedWidth);
- virtualSize.setHeight(cachedHeight);
+ @Override
+ protected final void collectNativeMonitorModesAndDevicesImpl(MonitorModeProps.Cache cache) {
+ int[] props = new int[ MonitorModeProps.NUM_MONITOR_MODE_PROPERTIES_ALL ];
+ int i = 0;
+ props[i++] = MonitorModeProps.NUM_MONITOR_MODE_PROPERTIES_ALL;
+ props[i++] = cachedWidth; // width
+ props[i++] = cachedHeight; // height
+ props[i++] = ScreenImpl.default_sm_bpp; // FIXME
+ props[i++] = ScreenImpl.default_sm_rate * 100; // FIXME
+ props[i++] = 0; // flags
+ props[i++] = 0; // mode_idx
+ props[i++] = 0; // rotation
+ final MonitorMode currentMode = MonitorModeProps.streamInMonitorMode(null, cache, props, 0);
+
+ props = new int[MonitorModeProps.MIN_MONITOR_DEVICE_PROPERTIES - 1 - MonitorModeProps.NUM_MONITOR_MODE_PROPERTIES];
+ i = 0;
+ props[i++] = props.length;
+ props[i++] = 0; // crt_idx
+ props[i++] = ScreenImpl.default_sm_widthmm; // FIXME
+ props[i++] = ScreenImpl.default_sm_heightmm; // FIXME
+ props[i++] = 0; // rotated viewport x
+ props[i++] = 0; // rotated viewport y
+ props[i++] = cachedWidth; // rotated viewport width
+ props[i++] = cachedWidth; // rotated viewport height
+ MonitorModeProps.streamInMonitorDevice(null, cache, this, cache.monitorModes, currentMode, props, 0);
+ }
+
+ @Override
+ protected MonitorMode queryCurrentMonitorModeImpl(final MonitorDevice monitor) {
+ return monitor.getSupportedModes().get(0);
+ }
+
+ @Override
+ protected boolean setCurrentMonitorModeImpl(final MonitorDevice monitor, final MonitorMode mode) {
+ return false;
+ }
+
+ protected void calcVirtualScreenOriginAndSize(Rectangle vOriginSize) {
+ vOriginSize.setX(0);
+ vOriginSize.setY(0);
+ vOriginSize.setWidth(cachedWidth);
+ vOriginSize.setHeight(cachedHeight);
}
//----------------------------------------------------------------------
diff --git a/src/newt/classes/jogamp/newt/driver/kd/ScreenDriver.java b/src/newt/classes/jogamp/newt/driver/kd/ScreenDriver.java
index 656bcf5c9..dc87c3c08 100644
--- a/src/newt/classes/jogamp/newt/driver/kd/ScreenDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/kd/ScreenDriver.java
@@ -35,9 +35,12 @@
package jogamp.newt.driver.kd;
import javax.media.nativewindow.DefaultGraphicsScreen;
-import javax.media.nativewindow.util.Dimension;
-import javax.media.nativewindow.util.Point;
+import javax.media.nativewindow.util.Rectangle;
+import com.jogamp.newt.MonitorDevice;
+import com.jogamp.newt.MonitorMode;
+
+import jogamp.newt.MonitorModeProps;
import jogamp.newt.ScreenImpl;
public class ScreenDriver extends ScreenImpl {
@@ -58,11 +61,48 @@ public class ScreenDriver extends ScreenImpl {
return 0; // only one screen available
}
- protected void getVirtualScreenOriginAndSize(Point virtualOrigin, Dimension virtualSize) {
- virtualOrigin.setX(0);
- virtualOrigin.setY(0);
- virtualSize.setWidth(cachedWidth);
- virtualSize.setHeight(cachedHeight);
+ @Override
+ protected final void collectNativeMonitorModesAndDevicesImpl(MonitorModeProps.Cache cache) {
+ int[] props = new int[ MonitorModeProps.NUM_MONITOR_MODE_PROPERTIES_ALL ];
+ int i = 0;
+ props[i++] = MonitorModeProps.NUM_MONITOR_MODE_PROPERTIES_ALL;
+ props[i++] = cachedWidth; // width
+ props[i++] = cachedHeight; // height
+ props[i++] = ScreenImpl.default_sm_bpp; // FIXME
+ props[i++] = ScreenImpl.default_sm_rate * 100; // FIXME
+ props[i++] = 0; // flags
+ props[i++] = 0; // mode_idx
+ props[i++] = 0; // rotation
+ final MonitorMode currentMode = MonitorModeProps.streamInMonitorMode(null, cache, props, 0);
+
+ props = new int[MonitorModeProps.MIN_MONITOR_DEVICE_PROPERTIES - 1 - MonitorModeProps.NUM_MONITOR_MODE_PROPERTIES];
+ i = 0;
+ props[i++] = props.length;
+ props[i++] = 0; // crt_idx
+ props[i++] = ScreenImpl.default_sm_widthmm; // FIXME
+ props[i++] = ScreenImpl.default_sm_heightmm; // FIXME
+ props[i++] = 0; // rotated viewport x
+ props[i++] = 0; // rotated viewport y
+ props[i++] = cachedWidth; // rotated viewport width
+ props[i++] = cachedWidth; // rotated viewport height
+ MonitorModeProps.streamInMonitorDevice(null, cache, this, cache.monitorModes, currentMode, props, 0);
+ }
+
+ @Override
+ protected MonitorMode queryCurrentMonitorModeImpl(final MonitorDevice monitor) {
+ return monitor.getSupportedModes().get(0);
+ }
+
+ @Override
+ protected boolean setCurrentMonitorModeImpl(final MonitorDevice monitor, final MonitorMode mode) {
+ return false;
+ }
+
+ protected void calcVirtualScreenOriginAndSize(Rectangle vOriginSize) {
+ vOriginSize.setX(0);
+ vOriginSize.setY(0);
+ vOriginSize.setWidth(cachedWidth);
+ vOriginSize.setHeight(cachedHeight);
}
protected void sizeChanged(int w, int h) {
diff --git a/src/newt/classes/jogamp/newt/driver/macosx/ScreenDriver.java b/src/newt/classes/jogamp/newt/driver/macosx/ScreenDriver.java
index 24e60ba0a..a3bb26731 100644
--- a/src/newt/classes/jogamp/newt/driver/macosx/ScreenDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/macosx/ScreenDriver.java
@@ -34,28 +34,19 @@
package jogamp.newt.driver.macosx;
-import java.util.List;
-
import javax.media.nativewindow.DefaultGraphicsScreen;
-import javax.media.nativewindow.util.Dimension;
-import javax.media.nativewindow.util.DimensionImmutable;
-import javax.media.nativewindow.util.Point;
+import jogamp.newt.MonitorModeProps;
import jogamp.newt.ScreenImpl;
-import com.jogamp.common.util.IntObjectHashMap;
-import com.jogamp.newt.ScreenMode;
-import com.jogamp.newt.util.ScreenModeUtil;
+import com.jogamp.common.util.ArrayHashSet;
+import com.jogamp.newt.MonitorDevice;
+import com.jogamp.newt.MonitorMode;
public class ScreenDriver extends ScreenImpl {
- // caching native CGDisplayScreenSize() results, since it's ridiculous slow (~6 ms each call)
- private static IntObjectHashMap/**/ scrnIdx2Dimension;
-
static {
DisplayDriver.initSingleton();
- scrnIdx2Dimension = new IntObjectHashMap();
- scrnIdx2Dimension.setKeyNotFoundValue(null);
}
public ScreenDriver() {
@@ -67,77 +58,67 @@ public class ScreenDriver extends ScreenImpl {
protected void closeNativeImpl() { }
- private static native int getWidthImpl0(int scrn_idx);
- private static native int getHeightImpl0(int scrn_idx);
-
- private int[] getScreenModeIdx(int idx) {
- // caching native CGDisplayScreenSize() results, since it's ridiculous slow (~6 ms each call)
- DimensionImmutable dim = (DimensionImmutable) scrnIdx2Dimension.get(screen_idx);
- if(null == dim) {
- int[] res = getScreenSizeMM0(screen_idx);
- if(null == res || 0 == res.length) {
- return null;
- }
- dim = new Dimension(res[0], res[1]);
- scrnIdx2Dimension.put(screen_idx, dim);
- }
-
- int[] modeProps = getScreenMode0(screen_idx, idx, dim.getWidth(), dim.getHeight());
- if (null == modeProps || 0 == modeProps.length) {
- return null;
+ private MonitorMode getMonitorModeImpl(MonitorModeProps.Cache cache, int crt_idx, int mode_idx) {
+ final int[] modeProps = getMonitorMode0(crt_idx, mode_idx);
+ final MonitorMode res;
+ if (null == modeProps || 0 >= modeProps.length) {
+ res = null;
+ } else {
+ res = MonitorModeProps.streamInMonitorMode(null, cache, modeProps, 0);
}
- if(modeProps.length < ScreenModeUtil.NUM_SCREEN_MODE_PROPERTIES_ALL) {
- throw new RuntimeException("properties array too short, should be >= "+ScreenModeUtil.NUM_SCREEN_MODE_PROPERTIES_ALL+", is "+modeProps.length);
- }
- return modeProps;
+ return res;
}
-
- private int nativeModeIdx;
- protected int[] getScreenModeFirstImpl() {
- nativeModeIdx = 0;
- return getScreenModeNextImpl();
- }
-
- protected int[] getScreenModeNextImpl() {
- int[] modeProps = getScreenModeIdx(nativeModeIdx);
- if (null != modeProps && 0 < modeProps.length) {
- nativeModeIdx++;
- return modeProps;
- }
- return null;
+ @Override
+ protected final void collectNativeMonitorModesAndDevicesImpl(MonitorModeProps.Cache cache) {
+ int crtIdx = 0;
+ int modeIdx = 0;
+ ArrayHashSet supportedModes = new ArrayHashSet();
+ do {
+ final MonitorMode mode = getMonitorModeImpl(cache, crtIdx, modeIdx);
+ if( null != mode ) {
+ supportedModes.getOrAdd(mode);
+ // next mode on same monitor
+ modeIdx++;
+ } else if( 0 < modeIdx ) {
+ // end of monitor modes - got at least one mode
+ final MonitorMode currentMode = getMonitorModeImpl(cache, crtIdx, -1);
+ if ( null == currentMode ) {
+ throw new InternalError("Could not gather current mode of device "+crtIdx+", but gathered "+modeIdx+" modes");
+ }
+ final int[] monitorProps = getMonitorProps0(crtIdx);
+ if ( null == monitorProps ) {
+ throw new InternalError("Could not gather device "+crtIdx+", but gathered "+modeIdx+" modes");
+ }
+ // merge monitor-props + supported modes
+ MonitorModeProps.streamInMonitorDevice(null, cache, this, supportedModes, currentMode, monitorProps, 0);
+
+ // next monitor, 1st mode
+ supportedModes= new ArrayHashSet();
+ crtIdx++;
+ modeIdx=0;
+ } else {
+ // end of monitor
+ break;
+ }
+ } while ( true );
}
- protected ScreenMode getCurrentScreenModeImpl() {
- int[] modeProps = getScreenModeIdx(-1);
- if (null != modeProps && 0 < modeProps.length) {
- return ScreenModeUtil.streamIn(modeProps, 0);
- }
- return null;
+ @Override
+ protected MonitorMode queryCurrentMonitorModeImpl(MonitorDevice monitor) {
+ return getMonitorModeImpl(null, monitor.getId(), -1);
}
- protected boolean setCurrentScreenModeImpl(final ScreenMode screenMode) {
- final List screenModes = this.getScreenModesOrig();
- final int screenModeIdx = screenModes.indexOf(screenMode);
- if(0>screenModeIdx) {
- throw new RuntimeException("ScreenMode not element of ScreenMode list: "+screenMode);
- }
- final int nativeModeIdx = getScreenModesIdx2NativeIdx().get(screenModeIdx);
- return setScreenMode0(screen_idx, nativeModeIdx);
+ @Override
+ protected boolean setCurrentMonitorModeImpl(MonitorDevice monitor, MonitorMode mode) {
+ return setMonitorMode0(monitor.getId(), mode.getId(), mode.getRotation());
}
protected int validateScreenIndex(int idx) {
- return idx;
+ return 0; // big-desktop w/ multiple monitor attached, only one screen available
}
- protected void getVirtualScreenOriginAndSize(Point virtualOrigin, Dimension virtualSize) {
- virtualOrigin.setX(0);
- virtualOrigin.setY(0);
- virtualSize.setWidth(getWidthImpl0(screen_idx));
- virtualSize.setHeight(getHeightImpl0(screen_idx));
- }
-
- private native int[] getScreenSizeMM0(int screen_idx);
- private native int[] getScreenMode0(int screen_index, int mode_index, int widthMM, int heightMM);
- private native boolean setScreenMode0(int screen_index, int mode_idx);
+ private native int[] getMonitorProps0(int crt_idx);
+ private native int[] getMonitorMode0(int crt_index, int mode_idx);
+ private native boolean setMonitorMode0(int crt_index, int nativeId, int rot);
}
diff --git a/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java
index bb72350e3..6370782df 100644
--- a/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java
@@ -478,7 +478,7 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl
if( 0 != surfaceHandle ) {
throw new NativeWindowException("Internal Error - create w/o window, but has Newt NSView");
}
- surfaceHandle = createView0(pS.getX(), pS.getY(), width, height, fullscreen, getScreen().getIndex());
+ surfaceHandle = createView0(pS.getX(), pS.getY(), width, height, fullscreen);
if( 0 == surfaceHandle ) {
throw new NativeWindowException("Could not create native view "+Thread.currentThread().getName()+" "+this);
}
@@ -487,7 +487,7 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl
final long newWin = createWindow0( pS.getX(), pS.getY(), width, height, fullscreen,
( isUndecorated() || offscreenInstance ) ? NSBorderlessWindowMask :
NSTitledWindowMask|NSClosableWindowMask|NSMiniaturizableWindowMask|NSResizableWindowMask,
- NSBackingStoreBuffered, getScreen().getIndex(), surfaceHandle);
+ NSBackingStoreBuffered, surfaceHandle);
if ( newWin == 0 ) {
throw new NativeWindowException("Could not create native window "+Thread.currentThread().getName()+" "+this);
}
@@ -497,9 +497,8 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl
// Non blocking initialization on main-thread!
OSXUtil.RunOnMainThread(false, new Runnable() {
public void run() {
- initWindow0( parentWin, newWin,
- pS.getX(), pS.getY(), width, height,
- isOpaque, fullscreen, visible && !offscreenInstance, getScreen().getIndex(), surfaceHandle);
+ initWindow0( parentWin, newWin, pS.getX(), pS.getY(), width, height,
+ isOpaque, fullscreen, visible && !offscreenInstance, surfaceHandle);
if( offscreenInstance ) {
orderOut0(0!=parentWin ? parentWin : newWin);
} else {
@@ -514,11 +513,11 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl
}
protected static native boolean initIDs0();
- private native long createView0(int x, int y, int w, int h, boolean fullscreen, int screen_idx);
- private native long createWindow0(int x, int y, int w, int h, boolean fullscreen, int windowStyle, int backingStoreType, int screen_idx, long view);
+ private native long createView0(int x, int y, int w, int h, boolean fullscreen);
+ private native long createWindow0(int x, int y, int w, int h, boolean fullscreen, int windowStyle, int backingStoreType, long view);
/** Must be called on Main-Thread */
private native void initWindow0(long parentWindow, long window, int x, int y, int w, int h,
- boolean opaque, boolean fullscreen, boolean visible, int screen_idx, long view);
+ boolean opaque, boolean fullscreen, boolean visible, long view);
private native boolean lockSurface0(long window, long view);
private native boolean unlockSurface0(long window, long view);
/** Must be called on Main-Thread */
diff --git a/src/newt/classes/jogamp/newt/driver/windows/ScreenDriver.java b/src/newt/classes/jogamp/newt/driver/windows/ScreenDriver.java
index 948b29460..342829691 100644
--- a/src/newt/classes/jogamp/newt/driver/windows/ScreenDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/windows/ScreenDriver.java
@@ -34,91 +34,143 @@
package jogamp.newt.driver.windows;
import javax.media.nativewindow.DefaultGraphicsScreen;
-import javax.media.nativewindow.util.Dimension;
-import javax.media.nativewindow.util.Point;
+import javax.media.nativewindow.util.Rectangle;
+import jogamp.newt.MonitorModeProps;
import jogamp.newt.ScreenImpl;
-import com.jogamp.newt.ScreenMode;
-import com.jogamp.newt.util.ScreenModeUtil;
+import com.jogamp.common.util.ArrayHashSet;
+import com.jogamp.newt.MonitorDevice;
+import com.jogamp.newt.MonitorMode;
+import com.jogamp.newt.Screen;
public class ScreenDriver extends ScreenImpl {
static {
DisplayDriver.initSingleton();
+ if( Screen.DEBUG ) {
+ dumpMonitorInfo0();
+ }
}
public ScreenDriver() {
}
+ @Override
protected void createNativeImpl() {
aScreen = new DefaultGraphicsScreen(getDisplay().getGraphicsDevice(), screen_idx);
}
+ @Override
protected void closeNativeImpl() {
}
- private int[] getScreenModeIdx(int idx) {
- int[] modeProps = getScreenMode0(screen_idx, idx);
- if (null == modeProps || 0 == modeProps.length) {
+ private final String getAdapterName(int crt_idx) {
+ return getAdapterName0(crt_idx);
+ }
+ private final String getActiveMonitorName(String adapterName, int monitor_idx) {
+ return getActiveMonitorName0(adapterName, monitor_idx);
+ }
+
+ private final MonitorMode getMonitorModeImpl(MonitorModeProps.Cache cache, String adapterName, int crtModeIdx) {
+ if( null == adapterName ) {
return null;
}
- if(modeProps.length < ScreenModeUtil.NUM_SCREEN_MODE_PROPERTIES_ALL) {
- throw new RuntimeException("properties array too short, should be >= "+ScreenModeUtil.NUM_SCREEN_MODE_PROPERTIES_ALL+", is "+modeProps.length);
+ final String activeMonitorName = getActiveMonitorName(adapterName, 0);
+ final int[] modeProps = null != activeMonitorName ? getMonitorMode0(adapterName, crtModeIdx) : null;
+ if ( null == modeProps || 0 >= modeProps.length) {
+ return null;
}
- return modeProps;
+ return MonitorModeProps.streamInMonitorMode(null, cache, modeProps, 0);
}
- private int nativeModeIdx;
-
- protected int[] getScreenModeFirstImpl() {
- nativeModeIdx = 0;
- return getScreenModeNextImpl();
- }
-
- protected int[] getScreenModeNextImpl() {
- int[] modeProps = getScreenModeIdx(nativeModeIdx);
- if (null != modeProps && 0 < modeProps.length) {
- nativeModeIdx++;
- return modeProps;
+ @Override
+ protected void collectNativeMonitorModesAndDevicesImpl(MonitorModeProps.Cache cache) {
+ int crtIdx = 0;
+ ArrayHashSet supportedModes = new ArrayHashSet();
+ String adapterName = getAdapterName(crtIdx);
+ while( null != adapterName ) {
+ int crtModeIdx = 0;
+ MonitorMode mode;
+ do {
+ mode = getMonitorModeImpl(cache, adapterName, crtModeIdx);
+ if( null != mode ) {
+ supportedModes.getOrAdd(mode);
+ // next mode on same monitor
+ crtModeIdx++;
+ }
+ } while( null != mode);
+ if( 0 < crtModeIdx ) {
+ // has at least one mode -> add device
+ final MonitorMode currentMode = getMonitorModeImpl(cache, adapterName, -1);
+ if ( null != currentMode ) { // enabled
+ final int[] monitorProps = getMonitorDevice0(adapterName, crtIdx);
+ // merge monitor-props + supported modes
+ MonitorModeProps.streamInMonitorDevice(null, cache, this, supportedModes, currentMode, monitorProps, 0);
+
+ // next monitor, 1st mode
+ supportedModes= new ArrayHashSet();
+ }
+ }
+ crtIdx++;
+ adapterName = getAdapterName(crtIdx);
}
- return null;
}
-
- protected ScreenMode getCurrentScreenModeImpl() {
- int[] modeProps = getScreenModeIdx(-1);
- if (null != modeProps && 0 < modeProps.length) {
- return ScreenModeUtil.streamIn(modeProps, 0);
+
+ @Override
+ protected Rectangle getNativeMonitorDeviceViewportImpl(MonitorDevice monitor) {
+ final String adapterName = getAdapterName(monitor.getId());
+ if( null != adapterName ) {
+ final String activeMonitorName = getActiveMonitorName(adapterName, 0);
+ if( null != activeMonitorName ) {
+ final int[] monitorProps = getMonitorDevice0(adapterName, monitor.getId());
+ int offset = MonitorModeProps.IDX_MONITOR_DEVICE_VIEWPORT;
+ return new Rectangle(monitorProps[offset++], monitorProps[offset++], monitorProps[offset++], monitorProps[offset++]);
+ }
}
return null;
}
- 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());
+ @Override
+ protected MonitorMode queryCurrentMonitorModeImpl(MonitorDevice monitor) {
+ return getMonitorModeImpl(null, getAdapterName(monitor.getId()), -1);
+ }
+
+ @Override
+ protected boolean setCurrentMonitorModeImpl(MonitorDevice monitor, MonitorMode mode) {
+ return setMonitorMode0(monitor.getId(),
+ -1, -1, // no fixed position!
+ mode.getSurfaceSize().getResolution().getWidth(),
+ mode.getSurfaceSize().getResolution().getHeight(),
+ mode.getSurfaceSize().getBitsPerPixel(),
+ (int)mode.getRefreshRate(), // simply cut-off, orig is int
+ mode.getFlags(),
+ mode.getRotation());
}
+ @Override
protected int validateScreenIndex(int idx) {
- return 0; // big-desktop, only one screen available
+ return 0; // big-desktop w/ multiple monitor attached, only one screen available
}
- protected void getVirtualScreenOriginAndSize(Point virtualOrigin, Dimension virtualSize) {
- virtualOrigin.setX(getOriginX0(screen_idx));
- virtualOrigin.setY(getOriginY0(screen_idx));
- virtualSize.setWidth(getWidthImpl0(screen_idx));
- virtualSize.setHeight(getHeightImpl0(screen_idx));
+ @Override
+ protected void calcVirtualScreenOriginAndSize(Rectangle vOriginSize) {
+ vOriginSize.setX(getVirtualOriginX0());
+ vOriginSize.setY(getVirtualOriginY0());
+ vOriginSize.setWidth(getVirtualWidthImpl0());
+ vOriginSize.setHeight(getVirtualHeightImpl0());
}
// Native calls
- private native int getOriginX0(int screen_idx);
- private native int getOriginY0(int screen_idx);
- private native int getWidthImpl0(int scrn_idx);
- private native int getHeightImpl0(int scrn_idx);
+ private native int getVirtualOriginX0();
+ private native int getVirtualOriginY0();
+ private native int getVirtualWidthImpl0();
+ private native int getVirtualHeightImpl0();
- private native int[] getScreenMode0(int screen_index, int mode_index);
- private native boolean setScreenMode0(int screen_index, int width, int height, int bits, int freq, int rot);
+ private static native void dumpMonitorInfo0();
+ private native String getAdapterName0(int crt_index);
+ private native String getActiveMonitorName0(String adapterName, int crtModeIdx);
+ private native int[] getMonitorMode0(String adapterName, int crtModeIdx);
+ private native int[] getMonitorDevice0(String adapterName, int monitor_index);
+ private native boolean setMonitorMode0(int monitor_index, int x, int y, int width, int height, int bits, int freq, int flags, int rot);
}
diff --git a/src/newt/classes/jogamp/newt/driver/x11/RandR.java b/src/newt/classes/jogamp/newt/driver/x11/RandR.java
index 485d976ec..c569e5fd8 100644
--- a/src/newt/classes/jogamp/newt/driver/x11/RandR.java
+++ b/src/newt/classes/jogamp/newt/driver/x11/RandR.java
@@ -27,13 +27,50 @@
*/
package jogamp.newt.driver.x11;
-import com.jogamp.newt.ScreenMode;
+import java.util.List;
+
+import jogamp.newt.MonitorModeProps;
+
+import com.jogamp.newt.MonitorDevice;
+import com.jogamp.newt.MonitorMode;
public interface RandR {
- int[] getScreenModeFirstImpl(final long dpy, final int screen_idx);
- int[] getScreenModeNextImpl(final long dpy, final int screen_idx);
- ScreenMode getCurrentScreenModeImpl(final long dpy, final int screen_idx);
- boolean setCurrentScreenModeImpl(final long dpy, final int screen_idx, final ScreenMode screenMode, final int screenModeIdx, final int resolutionIdx);
+ void dumpInfo(final long dpy, final int screen_idx);
+
+ /**
+ * Encapsulate initial device query allowing caching of internal data structures.
+ * Methods covered:
+ *
+ * - {@link #getMonitorDeviceCount(long, ScreenDriver)}
+ * - {@link #getAvailableRotations(long, ScreenDriver, int)}
+ * - {@link #getMonitorModeProps(long, ScreenDriver, int)}
+ * - {@link #getCurrentMonitorModeProps(long, ScreenDriver, int)
+ * - {@link #getMonitorDeviceProps(long, ScreenDriver, List, int, MonitorMode)}
+ *
+ *
+ * Above methods may be called w/o begin/end, in which case no
+ * internal data structures can be cached:
+ *
+ * @param dpy TODO
+ * @param screen TODO
+ * @return TODO
+ */
+ boolean beginInitialQuery(long dpy, ScreenDriver screen);
+ void endInitialQuery(long dpy, ScreenDriver screen);
+ int getMonitorDeviceCount(final long dpy, final ScreenDriver screen);
+ int[] getAvailableRotations(final long dpy, final ScreenDriver screen, final int crt_idx);
+ /**
+ *
+ * @param dpy
+ * @param screen
+ * @param mode_idx w/o indexing rotation
+ * @return props w/o actual rotation
+ */
+ int[] getMonitorModeProps(final long dpy, final ScreenDriver screen, final int mode_idx);
+ int[] getMonitorDeviceProps(final long dpy, final ScreenDriver screen, MonitorModeProps.Cache cache, final int crt_idx);
+ int[] getMonitorDeviceViewport(final long dpy, final ScreenDriver screen, final int crt_idx);
+ int[] getCurrentMonitorModeProps(final long dpy, final ScreenDriver screen, final int crt_idx);
+ boolean setCurrentMonitorMode(final long dpy, final ScreenDriver screen, MonitorDevice monitor, final MonitorMode mode);
}
diff --git a/src/newt/classes/jogamp/newt/driver/x11/RandR11.java b/src/newt/classes/jogamp/newt/driver/x11/RandR11.java
index ee67bd304..a938b4064 100644
--- a/src/newt/classes/jogamp/newt/driver/x11/RandR11.java
+++ b/src/newt/classes/jogamp/newt/driver/x11/RandR11.java
@@ -27,139 +27,257 @@
*/
package jogamp.newt.driver.x11;
+import jogamp.newt.MonitorModeProps;
import jogamp.newt.ScreenImpl;
-import com.jogamp.newt.ScreenMode;
-import com.jogamp.newt.util.ScreenModeUtil;
+import com.jogamp.common.util.VersionNumber;
+import com.jogamp.newt.MonitorDevice;
+import com.jogamp.newt.MonitorMode;
public class RandR11 implements RandR {
private static final boolean DEBUG = ScreenDriver.DEBUG;
- 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;
+ public static VersionNumber version = new VersionNumber(1, 1, 0);
+
+ public static RandR11 createInstance(VersionNumber rAndRVersion) {
+ if( rAndRVersion.compareTo(version) >= 0 ) {
+ return new RandR11();
+ }
+ return null;
+ }
+ private RandR11() {
+ }
+
+ @Override
+ public void dumpInfo(final long dpy, final int screen_idx) {
+ // NOP
+ }
+
+ private int widthMM=0, heightMM=0;
+ private int modeCount = 0;
+ private int resolutionCount = 0;
+ private int[][] nrates = null; // [nres_number][nrate_number]
+ private int[] idx_rate = null, idx_res = null;
@Override
- public int[] getScreenModeFirstImpl(final long dpy, final int screen_idx) {
+ public boolean beginInitialQuery(long dpy, ScreenDriver screen) {
// initialize iterators and static data
- nrotations = getAvailableScreenModeRotations0(dpy, screen_idx);
- if(null==nrotations || 0==nrotations.length) {
- return null;
+ final int screen_idx = screen.getIndex();
+ resolutionCount = getNumScreenResolutions0(dpy, screen_idx);
+ if(0==resolutionCount) {
+ endInitialQuery(dpy, screen);
+ return false;
}
- nrotation_index = 0;
- nres_number = getNumScreenModeResolutions0(dpy, screen_idx);
- if(0==nres_number) {
- return null;
+ nrates = new int[resolutionCount][];
+ for(int i=0; i= modeCount ) {
+ return null;
+ }
+ final int screen_idx = screen.getIndex();
+
+ final int nres_index = idx_res[mode_idx];
+ final int nrate_index = idx_rate[mode_idx];
+
+ final int[] res = getScreenResolution0(dpy, screen_idx, nres_index);
if(null==res || 0==res.length) {
return null;
}
if(0>=res[0] || 0>=res[1]) {
- throw new InternalError("invalid resolution: "+res[0]+"x"+res[1]+" for res idx "+nres_index+"/"+nres_number);
+ throw new InternalError("invalid resolution: "+res[0]+"x"+res[1]+" for res idx "+nres_index+"/"+resolutionCount);
+ }
+ if( res[2] > widthMM ) {
+ widthMM = res[2];
}
- int rate = nrates[nrate_index];
+ if( res[3] > heightMM ) {
+ heightMM = res[3];
+ }
+
+ int rate = nrates[nres_index][nrate_index];
if(0>=rate) {
rate = ScreenImpl.default_sm_rate;
if(DEBUG) {
System.err.println("Invalid rate: "+rate+" at index "+nrate_index+"/"+nrates.length+", using default: "+ScreenImpl.default_sm_rate);
}
}
- int rotation = nrotations[nrotation_index];
- int[] props = new int[ 1 + ScreenModeUtil.NUM_SCREEN_MODE_PROPERTIES_ALL ];
+ int[] props = new int[ MonitorModeProps.NUM_MONITOR_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++] = MonitorModeProps.NUM_MONITOR_MODE_PROPERTIES_ALL;
props[i++] = res[0]; // width
props[i++] = res[1]; // height
- props[i++] = ScreenImpl.default_sm_bpp; // FIXME
- 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(dpy, screen_idx, nres_index);
- if(null==nrates || 0==nrates.length) {
- return null;
- }
- nrate_index = 0;
- }
+ props[i++] = ScreenImpl.default_sm_bpp; // bpp n/a in RandR11
+ props[i++] = rate*100; // rate (Hz*100)
+ props[i++] = 0; // flags;
+ props[i++] = nres_index;
+ props[i++] = -1; // rotation placeholder;
+ if( MonitorModeProps.NUM_MONITOR_MODE_PROPERTIES_ALL != i ) {
+ throw new InternalError("XX");
+ }
+ return props;
+ }
+
+ @Override
+ public int[] getMonitorDeviceProps(final long dpy, final ScreenDriver screen, final MonitorModeProps.Cache cache, final int crt_idx) {
+ if( 0 < crt_idx ) {
+ // RandR11 only supports 1 CRT
+ return null;
+ }
+ final int[] currentModeProps = getCurrentMonitorModeProps(dpy, screen, crt_idx);
+ if( null == currentModeProps) { // disabled
+ return null;
+ }
+ final MonitorMode currentMode = MonitorModeProps.streamInMonitorMode(null, cache, currentModeProps, 0);
+ final int allModesCount = cache.monitorModes.size();
+ final int[] props = new int[MonitorModeProps.MIN_MONITOR_DEVICE_PROPERTIES - 1 + allModesCount];
+ int i = 0;
+ props[i++] = props.length;
+ props[i++] = crt_idx;
+ props[i++] = widthMM;
+ props[i++] = heightMM;
+ props[i++] = 0; // rotated viewport x
+ props[i++] = 0; // rotated viewport y
+ props[i++] = currentMode.getRotatedWidth(); // rotated viewport width
+ props[i++] = currentMode.getRotatedHeight(); // rotated viewport height
+ props[i++] = currentMode.getId(); // current mode id
+ props[i++] = currentMode.getRotation();
+ for(int j=0; jnres_idx) {
+ return null;
+ }
+ if(nres_idx>=resNumber) {
+ throw new RuntimeException("Invalid resolution index: ! "+nres_idx+" < "+resNumber);
+ }
+ res = getScreenResolution0(dpy, screen_idx, nres_idx);
+ if(null==res || 0==res.length) {
+ return null;
+ }
+ if(0>=res[0] || 0>=res[1]) {
+ throw new InternalError("invalid resolution: "+res[0]+"x"+res[1]+" for res idx "+nres_idx+"/"+resNumber);
+ }
+ } finally {
+ freeScreenConfiguration0(screenConfigHandle);
+ }
+ int[] props = new int[4];
+ int i = 0;
+ props[i++] = 0;
+ props[i++] = 0;
+ props[i++] = res[0]; // width
+ props[i++] = res[1]; // height
+ return props;
+ }
+
@Override
- public ScreenMode getCurrentScreenModeImpl(final long dpy, final int screen_idx) {
+ public int[] getCurrentMonitorModeProps(final long dpy, final ScreenDriver screen, final int crt_idx) {
+ if( 0 < crt_idx ) {
+ // RandR11 only supports 1 CRT
+ return null;
+ }
+ final int screen_idx = screen.getIndex();
long screenConfigHandle = getScreenConfiguration0(dpy, screen_idx);
if(0 == screenConfigHandle) {
return null;
}
int[] res;
int rate, rot;
+ final int nres_idx;
try {
- int resNumber = getNumScreenModeResolutions0(dpy, screen_idx);
+ int resNumber = getNumScreenResolutions0(dpy, screen_idx);
if(0==resNumber) {
return null;
}
- int resIdx = getCurrentScreenResolutionIndex0(screenConfigHandle);
- if(0>resIdx) {
+ nres_idx = getCurrentScreenResolutionIndex0(screenConfigHandle);
+ if(0>nres_idx) {
return null;
}
- if(resIdx>=resNumber) {
- throw new RuntimeException("Invalid resolution index: ! "+resIdx+" < "+resNumber);
+ if(nres_idx>=resNumber) {
+ throw new RuntimeException("Invalid resolution index: ! "+nres_idx+" < "+resNumber);
}
- res = getScreenModeResolution0(dpy, screen_idx, resIdx);
+ res = getScreenResolution0(dpy, screen_idx, nres_idx);
if(null==res || 0==res.length) {
return null;
}
if(0>=res[0] || 0>=res[1]) {
- throw new InternalError("invalid resolution: "+res[0]+"x"+res[1]+" for res idx "+resIdx+"/"+resNumber);
+ throw new InternalError("invalid resolution: "+res[0]+"x"+res[1]+" for res idx "+nres_idx+"/"+resNumber);
}
rate = getCurrentScreenRate0(screenConfigHandle);
if(0>rate) {
@@ -172,40 +290,42 @@ public class RandR11 implements RandR {
} finally {
freeScreenConfiguration0(screenConfigHandle);
}
- int[] props = new int[ScreenModeUtil.NUM_SCREEN_MODE_PROPERTIES_ALL];
+ int[] props = new int[ MonitorModeProps.NUM_MONITOR_MODE_PROPERTIES_ALL ];
int i = 0;
- props[i++] = 0; // set later for verification of iterator
+ props[i++] = MonitorModeProps.NUM_MONITOR_MODE_PROPERTIES_ALL;
props[i++] = res[0]; // width
props[i++] = res[1]; // height
- props[i++] = ScreenImpl.default_sm_bpp; // FIXME
- props[i++] = res[2]; // widthmm
- props[i++] = res[3]; // heightmm
- props[i++] = rate; // rate
+ props[i++] = ScreenImpl.default_sm_bpp;
+ props[i++] = rate*100; // rate (Hz*100)
+ props[i++] = 0; // flags;
+ props[i++] = nres_idx; // mode_idx;
props[i++] = rot;
- props[i - ScreenModeUtil.NUM_SCREEN_MODE_PROPERTIES_ALL] = i; // count
- return ScreenModeUtil.streamIn(props, 0);
+ if( MonitorModeProps.NUM_MONITOR_MODE_PROPERTIES_ALL != i ) {
+ throw new InternalError("XX");
+ }
+ return props;
}
@Override
- public boolean setCurrentScreenModeImpl(final long dpy, final int screen_idx, final ScreenMode screenMode, final int screenModeIdx, final int resolutionIdx) {
+ public boolean setCurrentMonitorMode(final long dpy, final ScreenDriver screen, MonitorDevice monitor, final MonitorMode mode) {
final long t0 = System.currentTimeMillis();
boolean done = false;
+ final int screen_idx = screen.getIndex();
long screenConfigHandle = getScreenConfiguration0(dpy, screen_idx);
if(0 == screenConfigHandle) {
return Boolean.valueOf(done);
}
try {
- int resNumber = getNumScreenModeResolutions0(dpy, screen_idx);
- if(0>resolutionIdx || resolutionIdx>=resNumber) {
- throw new RuntimeException("Invalid resolution index: ! 0 < "+resolutionIdx+" < "+resNumber+", screenMode["+screenModeIdx+"] "+screenMode);
- }
-
- final int f = screenMode.getMonitorMode().getRefreshRate();
- final int r = screenMode.getRotation();
+ final int resId = mode.getId();
+ if(0>resId || resId>=resolutionCount) {
+ throw new RuntimeException("Invalid resolution index: ! 0 < "+resId+" < "+resolutionCount+", "+monitor+", "+mode);
+ }
+ final int f = (int)mode.getRefreshRate(); // simply cut-off, orig is int
+ final int r = mode.getRotation();
- if( setCurrentScreenModeStart0(dpy, screen_idx, screenConfigHandle, resolutionIdx, f, r) ) {
+ if( setCurrentScreenModeStart0(dpy, screen_idx, screenConfigHandle, resId, f, r) ) {
while(!done && System.currentTimeMillis()-t0 < ScreenImpl.SCREEN_MODE_CHANGE_TIMEOUT) {
- done = setCurrentScreenModePollEnd0(dpy, screen_idx, resolutionIdx, f, r);
+ done = setCurrentScreenModePollEnd0(dpy, screen_idx, resId, f, r);
if(!done) {
try { Thread.sleep(10); } catch (InterruptedException e) { }
}
@@ -218,14 +338,14 @@ public class RandR11 implements RandR {
}
/** @return int[] { rot1, .. } */
- private static native int[] getAvailableScreenModeRotations0(long display, int screen_index);
+ private static native int[] getAvailableScreenRotations0(long display, int screen_index);
- private static native int getNumScreenModeResolutions0(long display, int screen_index);
+ private static native int getNumScreenResolutions0(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[] getScreenResolution0(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[] getScreenRates0(long display, int screen_index, int mode_index);
private static native long getScreenConfiguration0(long display, int screen_index);
private static native void freeScreenConfiguration0(long screenConfiguration);
diff --git a/src/newt/classes/jogamp/newt/driver/x11/RandR13.java b/src/newt/classes/jogamp/newt/driver/x11/RandR13.java
index 24c9806af..d10591381 100644
--- a/src/newt/classes/jogamp/newt/driver/x11/RandR13.java
+++ b/src/newt/classes/jogamp/newt/driver/x11/RandR13.java
@@ -27,25 +27,283 @@
*/
package jogamp.newt.driver.x11;
-import com.jogamp.newt.ScreenMode;
+import java.util.Iterator;
+import jogamp.newt.MonitorModeProps;
+
+import com.jogamp.common.util.IntLongHashMap;
+import com.jogamp.common.util.VersionNumber;
+import com.jogamp.newt.MonitorDevice;
+import com.jogamp.newt.MonitorMode;
+
+/**
+ * Mapping details:
+ *
+ * MonitorMode.id == XRR mode-id (not index)
+ * MonitorDevice.id == XRR monitor-idx (not id)
+ *
+ */
public class RandR13 implements RandR {
+ private static final boolean DEBUG = ScreenDriver.DEBUG;
+
+ public static VersionNumber version = new VersionNumber(1, 3, 0);
- public int[] getScreenModeFirstImpl(final long dpy, final int screen_idx) {
+ public static RandR13 createInstance(VersionNumber rAndRVersion) {
+ if( rAndRVersion.compareTo(version) >= 0 ) {
+ return new RandR13();
+ }
return null;
+ }
+ private RandR13() {
+ }
+
+ @Override
+ public void dumpInfo(final long dpy, final int screen_idx) {
+ long screenResources = getScreenResources0(dpy, screen_idx);
+ if(0 == screenResources) {
+ return;
+ }
+ try {
+ dumpInfo0(dpy, screen_idx, screenResources);
+ } finally {
+ freeScreenResources0(screenResources);
+ }
+ }
+
+ long sessionScreenResources = 0;
+ IntLongHashMap crtInfoHandleMap = null;
+
+ @Override
+ public boolean beginInitialQuery(long dpy, ScreenDriver screen) {
+ final int screen_idx = screen.getIndex();
+ sessionScreenResources = getScreenResources0(dpy, screen_idx);
+ if( 0 != sessionScreenResources ) {
+ crtInfoHandleMap = new IntLongHashMap();
+ crtInfoHandleMap.setKeyNotFoundValue(0);
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ @Override
+ public void endInitialQuery(long dpy, ScreenDriver screen) {
+ if( null != crtInfoHandleMap ) {
+ for(Iterator iter = crtInfoHandleMap.iterator(); iter.hasNext(); ) {
+ final IntLongHashMap.Entry entry = iter.next();
+ freeMonitorInfoHandle0(entry.value);
+ }
+ crtInfoHandleMap.clear();
+ crtInfoHandleMap = null;
+ }
+ if( 0 != sessionScreenResources ) {
+ freeScreenResources0( sessionScreenResources );
+ sessionScreenResources = 0;
+ }
}
- public int[] getScreenModeNextImpl(final long dpy, final int screen_idx) {
- return null;
+
+ private final long getScreenResourceHandle(final long dpy, final int screen_idx) {
+ if( 0 != sessionScreenResources ) {
+ return sessionScreenResources;
+ }
+ return getScreenResources0(dpy, screen_idx);
+ }
+ private final void releaseScreenResourceHandle(final long screenResourceHandle) {
+ if( 0 == sessionScreenResources ) {
+ freeScreenResources0( screenResourceHandle );
+ }
}
- public ScreenMode getCurrentScreenModeImpl(final long dpy, final int screen_idx) {
- return null;
+
+ private final long getMonitorInfoHandle(final long dpy, final int screen_idx, long screenResources, final int monitor_idx) {
+ if( null != crtInfoHandleMap ) {
+ long h = crtInfoHandleMap.get(monitor_idx);
+ if( 0 == h ) {
+ h = getMonitorInfoHandle0(dpy, screen_idx, screenResources, monitor_idx);
+ crtInfoHandleMap.put(monitor_idx, h);
+ }
+ return h;
+ } else {
+ return getMonitorInfoHandle0(dpy, screen_idx, screenResources, monitor_idx);
+ }
}
+ private final void releaseMonitorInfoHandle(final long monitorInfoHandle) {
+ if( null == crtInfoHandleMap ) {
+ freeMonitorInfoHandle0(monitorInfoHandle);
+ }
+ }
- public boolean setCurrentScreenModeImpl(final long dpy, final int screen_idx, final ScreenMode screenMode, final int screenModeIdx, final int resolutionIdx) {
- return false;
+ @Override
+ public int getMonitorDeviceCount(final long dpy, final ScreenDriver screen) {
+ final int screen_idx = screen.getIndex();
+ final long screenResources = getScreenResourceHandle(dpy, screen_idx);
+ try {
+ return getMonitorDeviceCount0(screenResources);
+ } finally {
+ releaseScreenResourceHandle(screenResources);
+ }
}
+ @Override
+ public int[] getAvailableRotations(final long dpy, final ScreenDriver screen, final int crt_idx) {
+ final int screen_idx = screen.getIndex();
+ final long screenResources = getScreenResourceHandle(dpy, screen_idx);
+ try {
+ final long monitorInfo = getMonitorInfoHandle(dpy, screen_idx, screenResources, crt_idx);
+ try {
+ final int[] availRotations = getAvailableRotations0(monitorInfo);
+ if(null==availRotations || 0==availRotations.length) {
+ return null;
+ }
+ return availRotations;
+ } finally {
+ releaseMonitorInfoHandle(monitorInfo);
+ }
+ } finally {
+ releaseScreenResourceHandle(screenResources);
+ }
+ }
+
+ @Override
+ public int[] getMonitorModeProps(final long dpy, final ScreenDriver screen, final int mode_idx) {
+ final int screen_idx = screen.getIndex();
+ final long screenResources = getScreenResourceHandle(dpy, screen_idx);
+ try {
+ return getMonitorMode0(screenResources, mode_idx);
+ } finally {
+ releaseScreenResourceHandle(screenResources);
+ }
+ }
+
+ @Override
+ public int[] getMonitorDeviceProps(final long dpy, final ScreenDriver screen, MonitorModeProps.Cache cache, final int crt_idx) {
+ final int screen_idx = screen.getIndex();
+ final long screenResources = getScreenResourceHandle(dpy, screen_idx);
+ try {
+ final long monitorInfo = getMonitorInfoHandle(dpy, screen_idx, screenResources, crt_idx);
+ try {
+ return getMonitorDevice0(dpy, screenResources, monitorInfo, crt_idx);
+ } finally {
+ releaseMonitorInfoHandle(monitorInfo);
+ }
+ } finally {
+ releaseScreenResourceHandle(screenResources);
+ }
+ }
+
+ @Override
+ public int[] getMonitorDeviceViewport(final long dpy, final ScreenDriver screen, final int crt_idx) {
+ final int screen_idx = screen.getIndex();
+ final long screenResources = getScreenResourceHandle(dpy, screen_idx);
+ try {
+ final long monitorInfo = getMonitorInfoHandle(dpy, screen_idx, screenResources, crt_idx);
+ try {
+ return getMonitorViewport0(monitorInfo);
+ } finally {
+ releaseMonitorInfoHandle(monitorInfo);
+ }
+ } finally {
+ releaseScreenResourceHandle(screenResources);
+ }
+ }
+
+ @Override
+ public int[] getCurrentMonitorModeProps(final long dpy, final ScreenDriver screen, final int crt_idx) {
+ final int screen_idx = screen.getIndex();
+ final long screenResources = getScreenResourceHandle(dpy, screen_idx);
+ try {
+ final long monitorInfo = getMonitorInfoHandle(dpy, screen_idx, screenResources, crt_idx);
+ try {
+ return getMonitorCurrentMode0(screenResources, monitorInfo);
+ } finally {
+ releaseMonitorInfoHandle(monitorInfo);
+ }
+ } finally {
+ releaseScreenResourceHandle(screenResources);
+ }
+ }
+
+ @Override
+ public boolean setCurrentMonitorMode(final long dpy, final ScreenDriver screen, MonitorDevice monitor, final MonitorMode mode) {
+ final int screen_idx = screen.getIndex();
+ final long screenResources = getScreenResourceHandle(dpy, screen_idx);
+ final boolean res;
+ try {
+ final long monitorInfo = getMonitorInfoHandle(dpy, screen_idx, screenResources, monitor.getId());
+ try {
+ res = setMonitorMode0(dpy, screenResources, monitorInfo, monitor.getId(), mode.getId(), mode.getRotation(),
+ -1, -1); // no fixed position!
+ } finally {
+ releaseMonitorInfoHandle(monitorInfo);
+ }
+ } finally {
+ releaseScreenResourceHandle(screenResources);
+ }
+ /***
+ * TODO: Would need a complete re-layout of crt positions,
+ * which is _not_ implicit by XRandR .. sadly.
+ *
+ if( res ) {
+ updateScreenViewport(dpy, screen, monitor);
+ } */
+ return res;
+ }
+
+ /** See above ..
+ private final void updateScreenViewport(final long dpy, final ScreenDriver screen, MonitorDevice monitor) {
+ final int screen_idx = screen.getIndex();
+ final long screenResources = getScreenResourceHandle(dpy, screen_idx);
+ try {
+ RectangleImmutable newViewp = null;
+ final long monitorInfo = getMonitorInfoHandle(dpy, screen_idx, screenResources, monitor.getId());
+ try {
+ final int[] vprops = getMonitorViewport0(monitorInfo);
+ if( null != vprops ) {
+ newViewp = new Rectangle(vprops[0], vprops[1], vprops[2], vprops[3]);
+ }
+ System.err.println("XXX setScreenViewport: newVp "+newViewp);
+ } finally {
+ releaseMonitorInfoHandle(monitorInfo);
+ }
+ if( null != newViewp ) {
+ final List monitors = screen.getMonitorDevices();
+ final ArrayList viewports = new ArrayList();
+ for(int i=0; i "+newScrnViewp);
+ setScreenViewport0(dpy, screen_idx, screenResources, newScrnViewp.getX(), newScrnViewp.getY(), newScrnViewp.getWidth(), newScrnViewp.getHeight());
+ }
+ } finally {
+ dumpInfo0(dpy, screen_idx, screenResources);
+ releaseScreenResourceHandle(screenResources);
+ }
+ } */
+
private static native long getScreenResources0(long display, int screen_index);
- private static native void freeScreenResources0(long screenConfiguration);
+ private static native void freeScreenResources0(long screenResources);
+ private static native void dumpInfo0(long display, int screen_index, long screenResources);
+
+ private static native int getMonitorDeviceCount0(long screenResources);
+
+ private static native long getMonitorInfoHandle0(long display, int screen_index, long screenResources, int monitor_index);
+ private static native void freeMonitorInfoHandle0(long monitorInfoHandle);
+
+ private static native int[] getAvailableRotations0(long monitorInfo);
+ private static native int[] getMonitorViewport0(long monitorInfo);
+ private static native int[] getMonitorCurrentMode0(long monitorInfo);
+
+ private static native int[] getMonitorMode0(long screenResources, int mode_index);
+ private static native int[] getMonitorCurrentMode0(long screenResources, long monitorInfo);
+ private static native int[] getMonitorDevice0(long display, long screenResources, long monitorInfo, int monitor_idx);
+ private static native boolean setMonitorMode0(long display, long screenResources, long monitorInfo, int monitor_idx, int mode_id, int rotation, int x, int y);
+ private static native boolean setScreenViewport0(long display, int screen_index, long screenResources, int x, int y, int width, int height);
}
diff --git a/src/newt/classes/jogamp/newt/driver/x11/ScreenDriver.java b/src/newt/classes/jogamp/newt/driver/x11/ScreenDriver.java
index cd8da9b60..ba22a6ce4 100644
--- a/src/newt/classes/jogamp/newt/driver/x11/ScreenDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/x11/ScreenDriver.java
@@ -33,23 +33,29 @@
*/
package jogamp.newt.driver.x11;
+import java.util.ArrayList;
import java.util.List;
-import javax.media.nativewindow.util.Dimension;
-import javax.media.nativewindow.util.Point;
+import javax.media.nativewindow.AbstractGraphicsDevice;
+import javax.media.nativewindow.util.Rectangle;
import jogamp.nativewindow.x11.X11Util;
+import jogamp.newt.Debug;
import jogamp.newt.DisplayImpl;
+import jogamp.newt.MonitorModeProps;
import jogamp.newt.DisplayImpl.DisplayRunnable;
import jogamp.newt.ScreenImpl;
+import com.jogamp.common.util.ArrayHashSet;
import com.jogamp.common.util.VersionNumber;
import com.jogamp.nativewindow.x11.X11GraphicsDevice;
import com.jogamp.nativewindow.x11.X11GraphicsScreen;
-import com.jogamp.newt.ScreenMode;
-
-public class ScreenDriver extends ScreenImpl {
+import com.jogamp.newt.MonitorDevice;
+import com.jogamp.newt.MonitorMode;
+public class ScreenDriver extends ScreenImpl {
+ protected static final boolean DEBUG_TEST_RANDR13_DISABLED = Debug.isPropertyDefined("newt.test.Screen.disableRandR13", true);
+
static {
DisplayDriver.initSingleton();
}
@@ -57,12 +63,13 @@ public class ScreenDriver extends ScreenImpl {
public ScreenDriver() {
}
+ @Override
protected void createNativeImpl() {
// validate screen index
Long handle = runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable() {
public Long run(long dpy) {
return new Long(GetScreen0(dpy, screen_idx));
- } } );
+ } } );
if (handle.longValue() == 0) {
throw new RuntimeException("Error creating screen: " + screen_idx);
}
@@ -73,73 +80,116 @@ public class ScreenDriver extends ScreenImpl {
int v[] = getRandRVersion0(dpy);
randrVersion = new VersionNumber(v[0], v[1], 0);
}
- if( DEBUG ) {
- System.err.println("RandR "+randrVersion);
+ {
+ final RandR13 rAndR13 = DEBUG_TEST_RANDR13_DISABLED ? null : RandR13.createInstance(randrVersion);
+ if( null != rAndR13 ) {
+ rAndR = rAndR13;
+ } else {
+ rAndR = RandR11.createInstance(randrVersion);
+ }
}
- if( !randrVersion.isZero() ) {
- rAndR = new RandR11();
- } else {
- rAndR = null;
+ if( DEBUG ) {
+ System.err.println("RandR "+randrVersion+", "+rAndR);
+ rAndR.dumpInfo(dpy, screen_idx);
}
}
+ @Override
protected void closeNativeImpl() {
}
private VersionNumber randrVersion;
private RandR rAndR;
-
+
@Override
- protected int[] getScreenModeFirstImpl() {
- if( null == rAndR ) { return null; }
-
- return runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable() {
- public int[] run(long dpy) {
- return rAndR.getScreenModeFirstImpl(dpy, screen_idx);
- } } );
+ protected final void collectNativeMonitorModesAndDevicesImpl(MonitorModeProps.Cache cache) {
+ if( null == rAndR ) { return; }
+ final AbstractGraphicsDevice device = getDisplay().getGraphicsDevice();
+ device.lock();
+ try {
+ if( rAndR.beginInitialQuery(device.getHandle(), this) ) {
+ try {
+ final int crtCount = rAndR.getMonitorDeviceCount(device.getHandle(), this);
+
+ // Gather all available rotations
+ final ArrayHashSet availableRotations = new ArrayHashSet();
+ for(int i = 0; i < crtCount; i++) {
+ final int[] rotations = rAndR.getAvailableRotations(device.getHandle(), this, i);
+ if( null != rotations ) {
+ final List rotationList = new ArrayList(rotations.length);
+ for(int j=0; j 0 ) {
+ for(int i = 0; i < crtCount; i++) {
+ final int[] monitorProps = rAndR.getMonitorDeviceProps(device.getHandle(), this, cache, i);
+ if( null != monitorProps ) { // enabled
+ MonitorModeProps.streamInMonitorDevice(null, cache, this, monitorProps, 0);
+ }
+ }
+ }
+ } finally {
+ rAndR.endInitialQuery(device.getHandle(), this);
+ }
+ }
+ } finally {
+ device.unlock();
+ }
}
@Override
- protected int[] getScreenModeNextImpl() {
- if( null == rAndR ) { return null; }
-
- // assemble: w x h x bpp x f x r
- return runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable() {
- public int[] run(long dpy) {
- return rAndR.getScreenModeNextImpl(dpy, screen_idx);
- } } );
+ protected Rectangle getNativeMonitorDeviceViewportImpl(MonitorDevice monitor) {
+ final AbstractGraphicsDevice device = getDisplay().getGraphicsDevice();
+ device.lock();
+ try {
+ int[] viewportProps = rAndR.getMonitorDeviceViewport(device.getHandle(), this, monitor.getId());
+ return new Rectangle(viewportProps[0], viewportProps[1], viewportProps[2], viewportProps[3]);
+ } finally {
+ device.unlock();
+ }
}
-
+
@Override
- protected ScreenMode getCurrentScreenModeImpl() {
+ protected MonitorMode queryCurrentMonitorModeImpl(final MonitorDevice monitor) {
if( null == rAndR ) { return null; }
- return runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable() {
- public ScreenMode run(long dpy) {
- return rAndR.getCurrentScreenModeImpl(dpy, screen_idx);
+ return runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable() {
+ public MonitorMode run(long dpy) {
+ final int[] currentModeProps = rAndR.getCurrentMonitorModeProps(dpy, ScreenDriver.this, monitor.getId());
+ return MonitorModeProps.streamInMonitorMode(null, null, currentModeProps, 0);
} } );
}
@Override
- protected boolean setCurrentScreenModeImpl(final ScreenMode screenMode) {
+ protected boolean setCurrentMonitorModeImpl(final MonitorDevice monitor, final MonitorMode mode) {
if( null == rAndR ) { return false; }
- final List screenModes = this.getScreenModesOrig();
- final int screenModeIdx = screenModes.indexOf(screenMode);
- if(0>screenModeIdx) {
- throw new RuntimeException("ScreenMode not element of ScreenMode list: "+screenMode);
- }
final long t0 = System.currentTimeMillis();
boolean done = runWithTempDisplayHandle( new DisplayImpl.DisplayRunnable() {
public Boolean run(long dpy) {
- final int resIdx = getScreenModesIdx2NativeIdx().get(screenModeIdx);
- return Boolean.valueOf( rAndR.setCurrentScreenModeImpl(dpy, screen_idx, screenMode, screenModeIdx, resIdx) );
+ return Boolean.valueOf( rAndR.setCurrentMonitorMode(dpy, ScreenDriver.this, monitor, mode) );
}
}).booleanValue();
if(DEBUG || !done) {
System.err.println("X11Screen.setCurrentScreenModeImpl: TO ("+SCREEN_MODE_CHANGE_TIMEOUT+") reached: "+
- (System.currentTimeMillis()-t0)+"ms; Current: "+getCurrentScreenMode()+"; Desired: "+screenMode);
+ (System.currentTimeMillis()-t0)+"ms; "+monitor.getCurrentMode()+" -> "+mode);
}
return done;
}
@@ -149,6 +199,7 @@ public class ScreenDriver extends ScreenImpl {
return new Boolean(X11Util.XineramaIsEnabled(dpy));
} };
+ @Override
protected int validateScreenIndex(final int idx) {
final DisplayDriver x11Display = (DisplayDriver) getDisplay();
final Boolean r = x11Display.isXineramaEnabled();
@@ -159,13 +210,14 @@ public class ScreenDriver extends ScreenImpl {
}
}
- protected void getVirtualScreenOriginAndSize(final Point virtualOrigin, final Dimension virtualSize) {
+ @Override
+ protected void calcVirtualScreenOriginAndSize(final Rectangle vOriginSize) {
runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable