diff options
author | Sven Gothel <[email protected]> | 2015-02-17 01:14:49 +0100 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2015-02-17 01:14:49 +0100 |
commit | 559ecad2a2387ba0aa34ce9e35ca8a2c5a31e655 (patch) | |
tree | a9ba7f77524851deb54269fc455aa529edfbd018 | |
parent | 42d88f99cfa62304943a7b37700653e627b13e61 (diff) |
NEWT MonitorDevice: Identify cloned devices (fully covered) ; Windows: Iterate-over and identify all adapter:monitor. (Bug 1129)
- Identify cloned devices (fully covered)
- MonitorDevice gets 'isCloned()' to identify whether
it is a cloned device, i.e. fully covered by another monitor.
This detection may happen natively but will always performed
platform agnostic.
- getMainMonitor(..) now exclude 'cloned' devices
- Windows: Iterate-over and identify all adapter:monitor
- Since we also list cloned monitor,
we need to iterate over all adapter and all it's monitor-devices.
- The native monitor-id is now defined as: ( adapter-idx << 8 ) | monitor-idx.
- Bug 1129 <- listed under this bug entry for convenience
20 files changed, 177 insertions, 97 deletions
diff --git a/src/newt/classes/com/jogamp/newt/MonitorDevice.java b/src/newt/classes/com/jogamp/newt/MonitorDevice.java index 4d9c6493a..9c12dcb58 100644 --- a/src/newt/classes/com/jogamp/newt/MonitorDevice.java +++ b/src/newt/classes/com/jogamp/newt/MonitorDevice.java @@ -65,15 +65,17 @@ public abstract class MonitorDevice { protected final DimensionImmutable sizeMM; // in [mm] protected final MonitorMode originalMode; protected final ArrayHashSet<MonitorMode> supportedModes; // FIXME: May need to support mutable mode, i.e. adding modes on the fly! - protected MonitorMode currentMode; - protected boolean modeChanged; protected final float[] pixelScale; protected final Rectangle viewportPU; // in pixel units protected final Rectangle viewportWU; // in window units + protected boolean isClone; + protected MonitorMode currentMode; + protected boolean modeChanged; /** * @param screen associated {@link Screen} * @param nativeId unique monitor device ID + * @param isClone flag * @param sizeMM size in millimeters * @param currentMode * @param pixelScale pre-fetched current pixel-scale, maybe {@code null} for {@link ScalableSurface#IDENTITY_PIXELSCALE}. @@ -81,19 +83,21 @@ public abstract class MonitorDevice { * @param viewportWU viewport in window-units * @param supportedModes all supported {@link MonitorMode}s */ - protected MonitorDevice(final Screen screen, final int nativeId, final DimensionImmutable sizeMM, - final MonitorMode currentMode, - final float[] pixelScale, final Rectangle viewportPU, final Rectangle viewportWU, - final ArrayHashSet<MonitorMode> supportedModes) { + protected MonitorDevice(final Screen screen, final int nativeId, final boolean isClone, + final DimensionImmutable sizeMM, + final MonitorMode currentMode, final float[] pixelScale, final Rectangle viewportPU, + final Rectangle viewportWU, final ArrayHashSet<MonitorMode> supportedModes) { this.screen = screen; this.nativeId = nativeId; this.sizeMM = sizeMM; this.originalMode = currentMode; this.supportedModes = supportedModes; - this.currentMode = currentMode; this.pixelScale = null != pixelScale ? pixelScale : new float[] { 1.0f, 1.0f }; this.viewportPU = viewportPU; this.viewportWU = viewportWU; + + this.isClone = isClone; + this.currentMode = currentMode; this.modeChanged = false; } @@ -134,6 +138,9 @@ public abstract class MonitorDevice { /** @return the immutable unique native Id of this monitor device. */ public final int getId() { return nativeId; } + /** @return {@code true} if this device represents a <i>clone</i>, otherwise return {@code false}. */ + public final boolean isClone() { return isClone; } + /** * @return the immutable monitor size in millimeters. */ @@ -323,7 +330,7 @@ public abstract class MonitorDevice { @Override public String toString() { - return "Monitor[Id "+Display.toHexString(nativeId)+", "+sizeMM+" mm, pixelScale ["+pixelScale[0]+", "+pixelScale[1]+ + return "Monitor[Id "+Display.toHexString(nativeId)+", clone "+isClone+", "+sizeMM+" mm, pixelScale ["+pixelScale[0]+", "+pixelScale[1]+ "], viewport "+viewportPU+ " [pixels], "+viewportWU+" [window], orig "+originalMode+", curr "+currentMode+ ", modeChanged "+modeChanged+", modeCount "+supportedModes.size()+"]"; } diff --git a/src/newt/classes/com/jogamp/newt/Screen.java b/src/newt/classes/com/jogamp/newt/Screen.java index 65031a565..0e6895d4b 100644 --- a/src/newt/classes/com/jogamp/newt/Screen.java +++ b/src/newt/classes/com/jogamp/newt/Screen.java @@ -210,7 +210,8 @@ public abstract class Screen { /** * Returns the {@link MonitorDevice} with the highest {@link MonitorDevice#getViewportInWindowUnits() viewport} - * {@link RectangleImmutable#coverage(RectangleImmutable) coverage} of the given rectangle in window units. + * {@link RectangleImmutable#coverage(RectangleImmutable) coverage} of the given rectangle in window units, + * which is not a {@link MonitorDevice#isClone() clone}. * <p> * If no coverage is detected the first {@link MonitorDevice} is returned. * </p> @@ -220,12 +221,15 @@ public abstract class Screen { MonitorDevice res = null; float maxCoverage = Float.MIN_VALUE; final List<MonitorDevice> monitors = getMonitorDevices(); - for(int i=monitors.size()-1; i>=0; i--) { + final int monitorCount = monitors.size(); + for(int i=0; i<monitorCount; i++) { final MonitorDevice monitor = monitors.get(i); - final float coverage = monitor.getViewportInWindowUnits().coverage(r); - if( coverage > maxCoverage ) { - maxCoverage = coverage; - res = monitor; + if( !monitor.isClone() ) { + final float coverage = monitor.getViewportInWindowUnits().coverage(r); + if( coverage > maxCoverage ) { + maxCoverage = coverage; + res = monitor; + } } } if( maxCoverage > 0.0f && null != res ) { diff --git a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java index e15f52730..3ef017d1b 100644 --- a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java +++ b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java @@ -1007,8 +1007,8 @@ public class GLWindow extends GLAutoDrawableBase implements GLAutoDrawable, Wind final MonitorDevice monitor = glWindow.getMainMonitor(); System.err.println("Main Monitor: "+monitor); final float[] pixelPerMM = monitor.getPixelsPerMM(new float[2]); - System.err.println(" pp/mm ["+pixelPerMM[0]+", "+pixelPerMM[1]+"]"); - System.err.println(" pp/in ["+pixelPerMM[0]*25.4f+", "+pixelPerMM[1]*25.4f+"]"); + System.err.println(" pixel/mm ["+pixelPerMM[0]+", "+pixelPerMM[1]+"]"); + System.err.println(" pixel/in ["+pixelPerMM[0]*25.4f+", "+pixelPerMM[1]*25.4f+"]"); final GL gl = drawable.getGL(); System.err.println(JoglVersion.getGLInfo(gl, null)); System.err.println("Requested: "+drawable.getNativeSurface().getGraphicsConfiguration().getRequestedCapabilities()); diff --git a/src/newt/classes/jogamp/newt/MonitorDeviceImpl.java b/src/newt/classes/jogamp/newt/MonitorDeviceImpl.java index 7c7d54680..138aedc29 100644 --- a/src/newt/classes/jogamp/newt/MonitorDeviceImpl.java +++ b/src/newt/classes/jogamp/newt/MonitorDeviceImpl.java @@ -28,10 +28,11 @@ package jogamp.newt; +import java.util.ArrayList; + import com.jogamp.nativewindow.ScalableSurface; import com.jogamp.nativewindow.util.DimensionImmutable; import com.jogamp.nativewindow.util.Rectangle; - import com.jogamp.common.util.ArrayHashSet; import com.jogamp.newt.MonitorDevice; import com.jogamp.newt.MonitorMode; @@ -42,6 +43,7 @@ public class MonitorDeviceImpl extends MonitorDevice { /** * @param screen associated {@link Screen} * @param nativeId unique monitor device ID + * @param isClone TODO * @param sizeMM size in millimeters * @param currentMode * @param pixelScale pre-fetched current pixel-scale, maybe {@code null} for {@link ScalableSurface#IDENTITY_PIXELSCALE}. @@ -49,11 +51,11 @@ public class MonitorDeviceImpl extends MonitorDevice { * @param viewportWU viewport in window-units * @param supportedModes all supported {@link MonitorMode}s */ - public MonitorDeviceImpl(final ScreenImpl screen, final int nativeId, final DimensionImmutable sizeMM, - final MonitorMode currentMode, - final float[] pixelScale, final Rectangle viewportPU, final Rectangle viewportWU, - final ArrayHashSet<MonitorMode> supportedModes) { - super(screen, nativeId, sizeMM, currentMode, pixelScale, viewportPU, viewportWU, supportedModes); + public MonitorDeviceImpl(final ScreenImpl screen, final int nativeId, final boolean isClone, + final DimensionImmutable sizeMM, + final MonitorMode currentMode, final float[] pixelScale, final Rectangle viewportPU, + final Rectangle viewportWU, final ArrayHashSet<MonitorMode> supportedModes) { + super(screen, nativeId, isClone, sizeMM, currentMode, pixelScale, viewportPU, viewportWU, supportedModes); } @Override @@ -157,4 +159,7 @@ public class MonitorDeviceImpl extends MonitorDevice { return supportedModes; } + /* pp */ final void setIsClone(final boolean isClone) { + this.isClone = isClone; + } } diff --git a/src/newt/classes/jogamp/newt/MonitorModeProps.java b/src/newt/classes/jogamp/newt/MonitorModeProps.java index 3f9e0be78..eacf77e25 100644 --- a/src/newt/classes/jogamp/newt/MonitorModeProps.java +++ b/src/newt/classes/jogamp/newt/MonitorModeProps.java @@ -31,13 +31,17 @@ package jogamp.newt; import com.jogamp.common.util.ArrayHashSet; import com.jogamp.newt.MonitorDevice; import com.jogamp.newt.MonitorMode; +import com.jogamp.newt.Screen; +import java.util.ArrayList; import java.util.List; + import com.jogamp.nativewindow.ScalableSurface; import com.jogamp.nativewindow.util.Dimension; import com.jogamp.nativewindow.util.DimensionImmutable; import com.jogamp.nativewindow.util.Rectangle; import com.jogamp.nativewindow.util.SurfaceSize; +import com.jogamp.opengl.math.FloatUtil; import jogamp.newt.MonitorDeviceImpl; import jogamp.newt.ScreenImpl; @@ -128,6 +132,7 @@ public class MonitorModeProps { * <ul> * <li>count</li> * <li>id</li> + * <li>IsClone</li> * <li>ScreenSizeMM[width, height] (2 elements)</li> * <li>Rotated Viewport pixel-units (4 elements)</li> * <li>Rotated Viewport window-units (4 elements)</li> @@ -142,7 +147,7 @@ public class MonitorModeProps { * WARNING: must be synchronized with ScreenMode.h, native implementation * </p> */ - public static final int MIN_MONITOR_DEVICE_PROPERTIES = 15; + public static final int MIN_MONITOR_DEVICE_PROPERTIES = 16; public static final int IDX_MONITOR_DEVICE_VIEWPORT = 1 // count + 1 // native mode @@ -285,6 +290,7 @@ public class MonitorModeProps { offset++; final List<MonitorMode> allMonitorModes = cache.monitorModes.getData(); final int id = monitorProperties[offset++]; + final boolean isClone = 0 == monitorProperties[offset++] ? false : true; final DimensionImmutable sizeMM = streamInResolution(monitorProperties, offset); offset+=NUM_RESOLUTION_PROPERTIES; final Rectangle viewportPU = new Rectangle(monitorProperties[offset++], monitorProperties[offset++], monitorProperties[offset++], monitorProperties[offset++]); final Rectangle viewportWU = new Rectangle(monitorProperties[offset++], monitorProperties[offset++], monitorProperties[offset++], monitorProperties[offset++]); @@ -304,7 +310,7 @@ public class MonitorModeProps { } } } - MonitorDevice monitorDevice = new MonitorDeviceImpl(screen, id, sizeMM, currentMode, pixelScale, viewportPU, viewportWU, supportedModes); + MonitorDevice monitorDevice = new MonitorDeviceImpl(screen, id, isClone, sizeMM, currentMode, pixelScale, viewportPU, viewportWU, supportedModes); if(null!=cache) { monitorDevice = cache.monitorDevices.getOrAdd(monitorDevice); } @@ -365,10 +371,11 @@ public class MonitorModeProps { } offset++; final int id = monitorProperties[offset++]; + final boolean isClone = 0 == monitorProperties[offset++] ? false : true; final DimensionImmutable sizeMM = streamInResolution(monitorProperties, offset); offset+=NUM_RESOLUTION_PROPERTIES; final Rectangle viewportPU = new Rectangle(monitorProperties[offset++], monitorProperties[offset++], monitorProperties[offset++], monitorProperties[offset++]); final Rectangle viewportWU = new Rectangle(monitorProperties[offset++], monitorProperties[offset++], monitorProperties[offset++], monitorProperties[offset++]); - MonitorDevice monitorDevice = new MonitorDeviceImpl(screen, id, sizeMM, currentMode, pixelScale, viewportPU, viewportWU, supportedModes); + MonitorDevice monitorDevice = new MonitorDeviceImpl(screen, id, isClone, sizeMM, currentMode, pixelScale, viewportPU, viewportWU, supportedModes); if(null!=cache) { monitorDevice = cache.monitorDevices.getOrAdd(monitorDevice); } @@ -393,6 +400,7 @@ public class MonitorModeProps { int idx=0; data[idx++] = data.length; data[idx++] = monitorDevice.getId(); + data[idx++] = monitorDevice.isClone() ? 1 : 0; data[idx++] = monitorDevice.getSizeMM().getWidth(); data[idx++] = monitorDevice.getSizeMM().getHeight(); data[idx++] = monitorDevice.getViewport().getX(); @@ -415,7 +423,36 @@ public class MonitorModeProps { return data; } - public final void swapRotatePair(final int rotation, final int[] pairs, int offset, final int numPairs) { + /** Identify monitor devices in <i>cloned</i> mode, i.e. consecutive devices being 100% covered by preceding devices. */ + /* pp */ static void identifyClonedMonitorDevices(final MonitorModeProps.Cache cache) { + final ArrayList<MonitorDevice> monitors = cache.monitorDevices.toArrayList(); + final int monitorCount = monitors.size(); + for(int i=0; i<monitorCount; i++) { + final MonitorDevice a = monitors.get(i); + if( !a.isClone() ) { + for(int j=i+1; j<monitorCount; j++) { + final MonitorDevice b = monitors.get(j); + if( !b.isClone() ) { + final float coverage = b.getViewport().coverage( a.getViewport() ); + if( FloatUtil.isZero( 1f - coverage, FloatUtil.EPSILON ) ) { + ((MonitorDeviceImpl)b).setIsClone(true); + if( Screen.DEBUG ) { + System.err.printf("MonitorCloneTest[%d of %d]: %f -> _is_ covered%n", j, i, coverage); + System.err.printf(" Monitor[%d] %s%n", j, b.toString()); + System.err.printf(" Monitor[%d] %s%n", i, a.toString()); + } + } else if( Screen.DEBUG ) { + System.err.printf("MonitorDevice-CloneTest[%d of %d]: %f -> not covered%n", j, i, coverage); + System.err.printf(" Monitor[%d] %s%n", j, b.toString()); + System.err.printf(" Monitor[%d] %s%n", i, a.toString()); + } + } + } + } + } + } + + public static final void swapRotatePair(final int rotation, final int[] pairs, int offset, final int numPairs) { if( MonitorMode.ROTATE_0 == rotation || MonitorMode.ROTATE_180 == rotation ) { // nop return; diff --git a/src/newt/classes/jogamp/newt/ScreenImpl.java b/src/newt/classes/jogamp/newt/ScreenImpl.java index b8383b631..36e42e52c 100644 --- a/src/newt/classes/jogamp/newt/ScreenImpl.java +++ b/src/newt/classes/jogamp/newt/ScreenImpl.java @@ -500,6 +500,7 @@ public abstract class ScreenImpl extends Screen implements MonitorModeListener { int i = 0; props[i++] = MonitorModeProps.MIN_MONITOR_DEVICE_PROPERTIES; props[i++] = monitorId; + props[i++] = 0; // is-clone props[i++] = default_sm_widthmm; props[i++] = default_sm_heightmm; props[i++] = 0; // rotated viewport x pixel-units @@ -608,6 +609,7 @@ public abstract class ScreenImpl extends Screen implements MonitorModeListener { private final int collectNativeMonitorModes(final MonitorModeProps.Cache cache) { if(!DEBUG_TEST_SCREENMODE_DISABLED) { collectNativeMonitorModesAndDevicesImpl(cache); + MonitorModeProps.identifyClonedMonitorDevices(cache); } // filter out insufficient modes for(int i=cache.monitorModes.size()-1; i>=0; i--) { diff --git a/src/newt/classes/jogamp/newt/driver/android/ScreenDriver.java b/src/newt/classes/jogamp/newt/driver/android/ScreenDriver.java index 273ff2b45..60e6e7d5f 100644 --- a/src/newt/classes/jogamp/newt/driver/android/ScreenDriver.java +++ b/src/newt/classes/jogamp/newt/driver/android/ScreenDriver.java @@ -104,6 +104,7 @@ public class ScreenDriver extends jogamp.newt.ScreenImpl { int i = 0; props[i++] = props.length; props[i++] = 0; // crt_idx + props[i++] = 0; // is-clone i = getScreenSizeMM(outMetrics, props, i); // sizeMM props[i++] = 0; // rotated viewport x pixel-units props[i++] = 0; // rotated viewport y pixel-units diff --git a/src/newt/classes/jogamp/newt/driver/awt/ScreenDriver.java b/src/newt/classes/jogamp/newt/driver/awt/ScreenDriver.java index eb92e0d13..aba7a1ab9 100644 --- a/src/newt/classes/jogamp/newt/driver/awt/ScreenDriver.java +++ b/src/newt/classes/jogamp/newt/driver/awt/ScreenDriver.java @@ -109,6 +109,7 @@ public class ScreenDriver extends ScreenImpl { int i = 0; props[i++] = props.length; props[i++] = 0; // crt_idx + props[i++] = 0; // is-clone props[i++] = ScreenImpl.default_sm_widthmm; // FIXME props[i++] = ScreenImpl.default_sm_heightmm; // FIXME props[i++] = 0; // rotated viewport x pixel-units 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 e65d79e2a..704fad73f 100644 --- a/src/newt/classes/jogamp/newt/driver/bcm/egl/ScreenDriver.java +++ b/src/newt/classes/jogamp/newt/driver/bcm/egl/ScreenDriver.java @@ -84,6 +84,7 @@ public class ScreenDriver extends jogamp.newt.ScreenImpl { i = 0; props[i++] = props.length; props[i++] = 0; // crt_idx + props[i++] = 0; // is-clone props[i++] = ScreenImpl.default_sm_widthmm; // FIXME props[i++] = ScreenImpl.default_sm_heightmm; // FIXME props[i++] = 0; // rotated viewport x pixel-units 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 42a63f91e..8d46adeab 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 @@ -77,6 +77,7 @@ public class ScreenDriver extends ScreenImpl { i = 0; props[i++] = props.length; props[i++] = 0; // crt_idx + props[i++] = 0; // is-clone props[i++] = ScreenImpl.default_sm_widthmm; // FIXME props[i++] = ScreenImpl.default_sm_heightmm; // FIXME props[i++] = 0; // rotated viewport x pixel-units 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 bd99fd18c..b55378459 100644 --- a/src/newt/classes/jogamp/newt/driver/intel/gdl/ScreenDriver.java +++ b/src/newt/classes/jogamp/newt/driver/intel/gdl/ScreenDriver.java @@ -86,6 +86,7 @@ public class ScreenDriver extends jogamp.newt.ScreenImpl { i = 0; props[i++] = props.length; props[i++] = 0; // crt_idx + props[i++] = 0; // is-clone props[i++] = ScreenImpl.default_sm_widthmm; // FIXME props[i++] = ScreenImpl.default_sm_heightmm; // FIXME props[i++] = 0; // rotated viewport x pixel-units diff --git a/src/newt/classes/jogamp/newt/driver/kd/ScreenDriver.java b/src/newt/classes/jogamp/newt/driver/kd/ScreenDriver.java index 975e0f96e..1e878bc3a 100644 --- a/src/newt/classes/jogamp/newt/driver/kd/ScreenDriver.java +++ b/src/newt/classes/jogamp/newt/driver/kd/ScreenDriver.java @@ -82,6 +82,7 @@ public class ScreenDriver extends ScreenImpl { i = 0; props[i++] = props.length; props[i++] = 0; // crt_idx + props[i++] = 0; // is-clone props[i++] = ScreenImpl.default_sm_widthmm; // FIXME props[i++] = ScreenImpl.default_sm_heightmm; // FIXME props[i++] = 0; // rotated viewport x pixel-units diff --git a/src/newt/classes/jogamp/newt/driver/windows/ScreenDriver.java b/src/newt/classes/jogamp/newt/driver/windows/ScreenDriver.java index 947ea27f4..013f9f9ca 100644 --- a/src/newt/classes/jogamp/newt/driver/windows/ScreenDriver.java +++ b/src/newt/classes/jogamp/newt/driver/windows/ScreenDriver.java @@ -71,9 +71,6 @@ public class ScreenDriver extends ScreenImpl { private final String getMonitorName(final String adapterName, final int monitor_idx, final boolean onlyActive) { return getMonitorName0(adapterName, monitor_idx, onlyActive); } - private final int getFirstActiveMonitor(final String adapterName) { - return getFirstActiveMonitor0(adapterName); - } private final MonitorMode getMonitorModeImpl(final MonitorModeProps.Cache cache, final String adapterName, final int mode_idx) { if( null == adapterName ) { @@ -86,29 +83,43 @@ public class ScreenDriver extends ScreenImpl { return MonitorModeProps.streamInMonitorMode(null, cache, modeProps, 0); } + private static final int getMonitorId(final int adapterIdx, final int monitorIdx) { + if( adapterIdx > 0xff ) { + throw new InternalError("Unsupported adapter idx > 0xff: "+adapterIdx); + } + if( monitorIdx > 0xff ) { + throw new InternalError("Unsupported monitor idx > 0xff: "+monitorIdx); + } + return ( adapterIdx & 0x000000ff ) << 8 | ( monitorIdx & 0x000000ff ); + } + private static final int getAdapterIndex(final int monitorId) { + return ( monitorId >>> 8 ) & 0x000000ff; + } + private static final int getMonitorIndex(final int monitorId) { + return monitorId & 0x000000ff; + } + @Override protected void collectNativeMonitorModesAndDevicesImpl(final MonitorModeProps.Cache cache) { ArrayHashSet<MonitorMode> supportedModes = new ArrayHashSet<MonitorMode>(); - int adapter_idx; String adapterName; - for(adapter_idx=0; null != ( adapterName = getAdapterName(adapter_idx) ); adapter_idx++ ) { - final int activeMonitorIdx = getFirstActiveMonitor(adapterName); - if( 0 <= activeMonitorIdx ) { - int mode_idx = 0; + for(int adapterIdx=0; null != ( adapterName = getAdapterName(adapterIdx) ); adapterIdx++ ) { + for(int monitorIdx=0; null != getMonitorName(adapterName, monitorIdx, true); monitorIdx++ ) { + int modeIdx = 0; MonitorMode mode; do { - mode = getMonitorModeImpl(cache, adapterName, mode_idx); + mode = getMonitorModeImpl(cache, adapterName, modeIdx); if( null != mode ) { supportedModes.getOrAdd(mode); // next mode on same monitor - mode_idx++; + modeIdx++; } } while( null != mode); - if( 0 < mode_idx ) { + if( 0 < modeIdx ) { // has at least one mode -> add device final MonitorMode currentMode = getMonitorModeImpl(cache, adapterName, -1); if ( null != currentMode ) { // enabled - final int[] monitorProps = getMonitorDevice0(adapterName, adapter_idx); + final int[] monitorProps = getMonitorDevice0(adapterName, adapterIdx, monitorIdx, getMonitorId(adapterIdx, monitorIdx)); // merge monitor-props + supported modes MonitorModeProps.streamInMonitorDevice(cache, this, currentMode, null, supportedModes, monitorProps, 0, null); @@ -122,11 +133,13 @@ public class ScreenDriver extends ScreenImpl { @Override protected boolean updateNativeMonitorDeviceViewportImpl(final MonitorDevice monitor, final float[] pixelScale, final Rectangle viewportPU, final Rectangle viewportWU) { - final String adapterName = getAdapterName(monitor.getId()); + final int monitorId = monitor.getId(); + final int adapterIdx = getAdapterIndex(monitorId); + final int monitorIdx = getMonitorIndex(monitorId); + final String adapterName = getAdapterName(adapterIdx); if( null != adapterName ) { - final int activeMonitorIdx = getFirstActiveMonitor(adapterName); - if( 0 <= activeMonitorIdx ) { - final int[] monitorProps = getMonitorDevice0(adapterName, monitor.getId()); + if( null != getMonitorName(adapterName, monitorIdx, true) ) { + final int[] monitorProps = getMonitorDevice0(adapterName, adapterIdx, monitorIdx, getMonitorId(adapterIdx, monitorIdx)); int offset = MonitorModeProps.IDX_MONITOR_DEVICE_VIEWPORT; viewportPU.set(monitorProps[offset++], monitorProps[offset++], monitorProps[offset++], monitorProps[offset++]); viewportWU.set(monitorProps[offset++], monitorProps[offset++], monitorProps[offset++], monitorProps[offset++]); @@ -138,12 +151,12 @@ public class ScreenDriver extends ScreenImpl { @Override protected MonitorMode queryCurrentMonitorModeImpl(final MonitorDevice monitor) { - return getMonitorModeImpl(null, getAdapterName(monitor.getId()), -1); + return getMonitorModeImpl(null, getAdapterName(getAdapterIndex(monitor.getId())), -1); } @Override protected boolean setCurrentMonitorModeImpl(final MonitorDevice monitor, final MonitorMode mode) { - return setMonitorMode0(monitor.getId(), + return setMonitorMode0(getAdapterIndex(monitor.getId()), -1, -1, // no fixed position! mode.getSurfaceSize().getResolution().getWidth(), mode.getSurfaceSize().getResolution().getHeight(), @@ -173,8 +186,7 @@ public class ScreenDriver extends ScreenImpl { private static native void dumpMonitorInfo0(); private native String getAdapterName0(int adapter_idx); private native String getMonitorName0(String adapterName, int monitor_idx, boolean onlyActive); - private native int getFirstActiveMonitor0(String adapterName); private native int[] getMonitorMode0(String adapterName, int mode_idx); - private native int[] getMonitorDevice0(String adapterName, int adapter_idx); + private native int[] getMonitorDevice0(String adapterName, int adapter_idx, int monitor_idx, int monitorId); private native boolean setMonitorMode0(int adapter_idx, 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/RandR11.java b/src/newt/classes/jogamp/newt/driver/x11/RandR11.java index d11703e47..a4c578b26 100644 --- a/src/newt/classes/jogamp/newt/driver/x11/RandR11.java +++ b/src/newt/classes/jogamp/newt/driver/x11/RandR11.java @@ -186,6 +186,7 @@ class RandR11 implements RandR { int i = 0; props[i++] = props.length; props[i++] = crt_idx; + props[i++] = 0; // is-clone props[i++] = widthMM; props[i++] = heightMM; props[i++] = 0; // rotated viewport x pixel-units diff --git a/src/newt/classes/jogamp/newt/driver/x11/ScreenDriver.java b/src/newt/classes/jogamp/newt/driver/x11/ScreenDriver.java index 993ff58f9..93d758655 100644 --- a/src/newt/classes/jogamp/newt/driver/x11/ScreenDriver.java +++ b/src/newt/classes/jogamp/newt/driver/x11/ScreenDriver.java @@ -147,6 +147,7 @@ public class ScreenDriver extends ScreenImpl { } while( null != props); } if( cache.monitorModes.size() > 0 ) { + final ArrayHashSet<MonitorDevice> monitorDevices = new ArrayHashSet<MonitorDevice>(); for(int i = 0; i < crtCount; i++) { final int[] monitorProps = rAndR.getMonitorDeviceProps(device.getHandle(), this, cache, i); if( null != monitorProps && diff --git a/src/newt/native/MacWindow.m b/src/newt/native/MacWindow.m index e0f8be856..690aaa505 100644 --- a/src/newt/native/MacWindow.m +++ b/src/newt/native/MacWindow.m @@ -517,6 +517,7 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_macosx_ScreenDriver_getMonit int offset = 0; prop[offset++] = propCount; prop[offset++] = crt_idx; + prop[offset++] = 0; // is-clone prop[offset++] = (jint) sizeMM.width; prop[offset++] = (jint) sizeMM.height; prop[offset++] = (jint) dBounds.origin.x; // rotated viewport x (pixel units, will be fixed in java code) diff --git a/src/newt/native/ScreenMode.h b/src/newt/native/ScreenMode.h index 56c424b11..18e773107 100644 --- a/src/newt/native/ScreenMode.h +++ b/src/newt/native/ScreenMode.h @@ -40,7 +40,7 @@ #define NUM_MONITOR_MODE_PROPERTIES_ALL 8 /* count + the above */ -#define MIN_MONITOR_DEVICE_PROPERTIES 15 /* count + id, ScreenSizeMM[width, height], rotated Viewport pixel-units, rotated Viewport pixel-units, currentMonitorModeId, rotation, supportedModeId+ */ +#define MIN_MONITOR_DEVICE_PROPERTIES 16 /* count + id + is_clone, ScreenSizeMM[width, height], rotated Viewport pixel-units, rotated Viewport pixel-units, currentMonitorModeId, rotation, supportedModeId+ */ /* Viewport := [x, y, width, height] (4 elements) */ #define FLAG_INTERLACE ( 1 << 0 ) diff --git a/src/newt/native/WindowsWindow.c b/src/newt/native/WindowsWindow.c index d3ad69f92..7e15cd925 100644 --- a/src/newt/native/WindowsWindow.c +++ b/src/newt/native/WindowsWindow.c @@ -1638,6 +1638,10 @@ static int NewtScreen_RotationNewtCCW2NativeCCW(JNIEnv *env, jint newt) { } static LPCTSTR NewtScreen_getAdapterName(DISPLAY_DEVICE * device, int adapter_idx) { + if( 0 > adapter_idx ) { + DBG_PRINT("*** WindowsWindow: getAdapterName(adapter_idx %d < 0)\n", adapter_idx); + return NULL; + } memset(device, 0, sizeof(DISPLAY_DEVICE)); device->cb = sizeof(DISPLAY_DEVICE); if( FALSE == EnumDisplayDevices(NULL, adapter_idx, device, 0) ) { @@ -1653,10 +1657,14 @@ static LPCTSTR NewtScreen_getAdapterName(DISPLAY_DEVICE * device, int adapter_id } static LPCTSTR NewtScreen_getMonitorName(LPCTSTR adapterName, DISPLAY_DEVICE * device, int monitor_idx, BOOL onlyActive) { + if( 0 > monitor_idx ) { + DBG_PRINT("*** WindowsWindow: getMonitorName(monitor_idx %d < 0)\n", monitor_idx); + return NULL; + } memset(device, 0, sizeof(DISPLAY_DEVICE)); device->cb = sizeof(DISPLAY_DEVICE); if( FALSE == EnumDisplayDevices(adapterName, monitor_idx, device, EDD_GET_DEVICE_INTERFACE_NAME) ) { - DBG_PRINT("*** WindowsWindow: getDisplayName.EnumDisplayDevices(monitor_idx %d).adapter -> FALSE\n", monitor_idx); + DBG_PRINT("*** WindowsWindow: getMonitorName.EnumDisplayDevices(monitor_idx %d).adapter -> FALSE\n", monitor_idx); return NULL; } if( onlyActive ) { @@ -1664,10 +1672,6 @@ static LPCTSTR NewtScreen_getMonitorName(LPCTSTR adapterName, DISPLAY_DEVICE * d DBG_PRINT("*** WindowsWindow: !DISPLAY_DEVICE_ACTIVE(monitor_idx %d).display\n", monitor_idx); return NULL; } - if( 0 != ( device->StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER ) ) { - DBG_PRINT("*** WindowsWindow: DISPLAY_DEVICE_MIRRORING_DRIVER(monitor_idx %d).display\n", monitor_idx); - return NULL; - } } if( NULL == device->DeviceName || 0 == _tcslen(device->DeviceName) ) { return NULL; @@ -1676,7 +1680,7 @@ static LPCTSTR NewtScreen_getMonitorName(LPCTSTR adapterName, DISPLAY_DEVICE * d return device->DeviceName; } -static int NewtScreen_getFirstActiveMonitor(LPCTSTR adapterName, DISPLAY_DEVICE * device) { +static int NewtScreen_getFirstActiveNonCloneMonitor(LPCTSTR adapterName, DISPLAY_DEVICE * device) { memset(device, 0, sizeof(DISPLAY_DEVICE)); device->cb = sizeof(DISPLAY_DEVICE); int monitor_idx; @@ -1706,8 +1710,10 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_dumpMonitorI STD_PRINT(" deviceID <%s> \n", aDevice.DeviceID); j=0; while(NULL != (dName = NewtScreen_getMonitorName(aName, &dDevice, j, FALSE))) { - STD_PRINT("*** [%02d:%02d]: deviceName <%s> flags 0x%X active %d\n", - i, j, dDevice.DeviceName, dDevice.StateFlags, ( 0 != ( dDevice.StateFlags & DISPLAY_DEVICE_ACTIVE ) ) ); + STD_PRINT("*** [%02d:%02d]: deviceName <%s> flags 0x%X active %d, mirror %d\n", + i, j, dDevice.DeviceName, dDevice.StateFlags, + 0 != ( dDevice.StateFlags & DISPLAY_DEVICE_ACTIVE ), + 0 != ( dDevice.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER ) ); STD_PRINT(" deviceString <%s> \n", dDevice.DeviceString); STD_PRINT(" deviceID <%s> \n", dDevice.DeviceID); j++; @@ -1775,30 +1781,6 @@ JNIEXPORT jstring JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getMonito /* * Class: jogamp_newt_driver_windows_ScreenDriver - * Method: getFirstActiveMonitor0 - * Signature: (Ljava/lang/String;)I - */ -JNIEXPORT jint JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getFirstActiveMonitor0 - (JNIEnv *env, jobject obj, jstring jAdapterName) -{ - DISPLAY_DEVICE device; - int monitorIdx; -#ifdef UNICODE - LPCTSTR adapterName = NewtCommon_GetNullTerminatedStringChars(env, jAdapterName); - monitorIdx = NewtScreen_getFirstActiveMonitor(adapterName, &device); - DBG_PRINT("*** WindowsWindow: getFirstActiveMonitor(%s) -> monitor_idx %d, %s\n", adapterName, monitorIdx, (NULL==device.DeviceName?"nil":device.DeviceName)); - free((void*) adapterName); -#else - LPCTSTR adapterName = (*env)->GetStringUTFChars(env, jAdapterName, NULL); - monitorIdx = NewtScreen_getFirstActiveMonitor(adapterName, &device); - DBG_PRINT("*** WindowsWindow: getFirstActiveMonitor(%s) -> monitor_idx %d, %s\n", adapterName, monitorIdx, (NULL==device.DeviceName?"nil":device.DeviceName)); - (*env)->ReleaseStringUTFChars(env, jAdapterName, adapterName); -#endif - return monitorIdx; -} - -/* - * Class: jogamp_newt_driver_windows_ScreenDriver * Method: getMonitorMode0 * Signature: (Ljava/lang/String;I)[I */ @@ -1873,10 +1855,10 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getMoni /* * Class: jogamp_newt_driver_windows_ScreenDriver * Method: getMonitorDevice0 - * Signature: (Ljava/lang/String;I)[I + * Signature: (Ljava/lang/String;II)[I */ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getMonitorDevice0 - (JNIEnv *env, jobject obj, jstring jAdapterName, jint adapter_idx) + (JNIEnv *env, jobject obj, jstring jAdapterName, jint adapter_idx, jint monitor_idx, jint monitor_id) { LPCTSTR adapterName; { @@ -1887,14 +1869,15 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getMoni #endif } - DBG_PRINT("*** WindowsWindow: adapter[name %s, idx %d], EDID-avail %d\n", adapterName, adapter_idx, NewtEDID_avail); + DBG_PRINT("*** WindowsWindow: adapter[name %s, idx %d], monitor[idx %d, id %d], EDID-avail %d\n", + adapterName, adapter_idx, monitor_idx, monitor_id, NewtEDID_avail); int gotsize = 0; int widthmm, heightmm; + DISPLAY_DEVICE monitorDevice; + LPCTSTR monitorName = NewtScreen_getMonitorName(adapterName, &monitorDevice, monitor_idx, TRUE); if( NewtEDID_avail ) { int widthcm, heightcm; - DISPLAY_DEVICE monitorDevice; - int monitor_idx = NewtScreen_getFirstActiveMonitor(adapterName, &monitorDevice); - if( 0 <= monitor_idx && + if( NULL != monitorName && NewtEDID_GetMonitorSizeFromEDIDByDevice(&monitorDevice, &widthmm, &heightmm, &widthcm, &heightcm) ) { DBG_PRINT("*** WindowsWindow: EDID %d x %d [mm], %d x %d [cm]\n", widthmm, heightmm, widthcm, heightcm); if( 0 <= widthmm && 0 <= heightmm ) { @@ -1939,7 +1922,8 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getMoni int propIndex = 0; prop[propIndex++] = propCount; - prop[propIndex++] = adapter_idx; + prop[propIndex++] = monitor_id; + prop[propIndex++] = NULL != monitorName && 0 != ( monitorDevice.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER ); prop[propIndex++] = widthmm; prop[propIndex++] = heightmm; prop[propIndex++] = dm.dmPosition.x; // rotated viewport pixel units @@ -1974,10 +1958,14 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_setMonit DBG_PRINT("*** WindowsWindow: setMonitorMode.getAdapterName(adapter_idx %d) -> NULL\n", adapter_idx); return JNI_FALSE; } - int monitor_idx = NewtScreen_getFirstActiveMonitor(adapterName, &monitorDevice); - if( 0 > monitor_idx ) { - DBG_PRINT("*** WindowsWindow: setMonitorMode.getFirstActiveMonitor(%s) -> n/a\n", adapterName); - return JNI_FALSE; + + { + // Just test whether there is an active non-mirror monitor attached + int monitor_idx = NewtScreen_getFirstActiveNonCloneMonitor(adapterName, &monitorDevice); + if( 0 > monitor_idx ) { + DBG_PRINT("*** WindowsWindow: setMonitorMode.getFirstActiveNonCloneMonitor(%s) -> n/a\n", adapterName); + return JNI_FALSE; + } } DEVMODE dm; diff --git a/src/newt/native/X11RandR13.c b/src/newt/native/X11RandR13.c index 4e92a32b4..5eacbf216 100644 --- a/src/newt/native/X11RandR13.c +++ b/src/newt/native/X11RandR13.c @@ -67,9 +67,16 @@ static void dumpOutputs(const char *prefix, Display *dpy, XRRScreenResources *re for(i=0; i<noutput; i++) { RROutput output = outputs[i]; XRROutputInfo * xrrOutputInfo = XRRGetOutputInfo (dpy, resources, output); - fprintf(stderr, " Output[%d]: id %#lx, crtx 0x%X, name %s (%d), %lux%lu, ncrtc %d, .., nmode %d (preferred %d)\n", - i, output, xrrOutputInfo->crtc, SAFE_STRING(xrrOutputInfo->name), xrrOutputInfo->nameLen, xrrOutputInfo->mm_width, xrrOutputInfo->mm_height, - xrrOutputInfo->ncrtc, xrrOutputInfo->nmode, xrrOutputInfo->npreferred); + fprintf(stderr, " Output[%d]: id %#lx, crtx 0x%X, name %s (%d), %lux%lu, ncrtc %d, nclone %d, nmode %d (preferred %d)\n", + i, output, xrrOutputInfo->crtc, SAFE_STRING(xrrOutputInfo->name), xrrOutputInfo->nameLen, + xrrOutputInfo->mm_width, xrrOutputInfo->mm_height, + xrrOutputInfo->ncrtc, xrrOutputInfo->nclone, xrrOutputInfo->nmode, xrrOutputInfo->npreferred); + for(j=0; j<xrrOutputInfo->ncrtc; j++) { + fprintf(stderr, " Output[%d].Crtc[%d].id %#lx\n", i, j, xrrOutputInfo->crtcs[j]); + } + for(j=0; j<xrrOutputInfo->nclone; j++) { + fprintf(stderr, " Output[%d].Clones[%d].id %#lx\n", i, j, xrrOutputInfo->clones[j]); + } for(j=0; j<xrrOutputInfo->nmode; j++) { fprintf(stderr, " Output[%d].Mode[%d].id %#lx\n", i, j, xrrOutputInfo->modes[j]); } @@ -424,6 +431,7 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_RandR13_getMonitorDevice prop[propIndex++] = propCount; prop[propIndex++] = crt_idx; + prop[propIndex++] = 0; // is_clone, does not work: 0 < xrrOutputInfo->nclone ? 1 : 0; prop[propIndex++] = xrrOutputInfo->mm_width; prop[propIndex++] = xrrOutputInfo->mm_height; prop[propIndex++] = xrrCrtcInfo->x; // rotated viewport pixel units diff --git a/src/test/com/jogamp/opengl/test/junit/newt/mm/TestScreenMode00aNEWT.java b/src/test/com/jogamp/opengl/test/junit/newt/mm/TestScreenMode00aNEWT.java index e103fc490..5285673e9 100644 --- a/src/test/com/jogamp/opengl/test/junit/newt/mm/TestScreenMode00aNEWT.java +++ b/src/test/com/jogamp/opengl/test/junit/newt/mm/TestScreenMode00aNEWT.java @@ -112,7 +112,7 @@ public class TestScreenMode00aNEWT extends UITestCase { final Rectangle viewport = new Rectangle(0, 0, 1920, 1080); final ArrayHashSet<MonitorMode> supportedModes = new ArrayHashSet<MonitorMode>(); supportedModes.add(modeOut); - final MonitorDevice monOut = new MonitorDeviceImpl(null, -1, sizeMM, modeOut, null, viewport, viewport, supportedModes); + final MonitorDevice monOut = new MonitorDeviceImpl(null, -1, false, sizeMM, modeOut, null, viewport, viewport, supportedModes); System.err.println("01 out : "+monOut); cache.monitorDevices.add(monOut); { @@ -169,13 +169,12 @@ public class TestScreenMode00aNEWT extends UITestCase { final List<MonitorDevice> monitors = screen.getMonitorDevices(); Assert.assertTrue(monitors.size()>0); + + // Dump all Monitor's and its modes int j=0; for(final Iterator<MonitorDevice> iMonitor=monitors.iterator(); iMonitor.hasNext(); j++) { final MonitorDevice monitor = iMonitor.next(); System.err.println(j+": "+monitor); - final float[] pixelPerMM = monitor.getPixelsPerMM(new float[2]); - System.err.println(j+" pp/mm ["+pixelPerMM[0]+", "+pixelPerMM[1]+"]"); - System.err.println(j+" pp/in ["+pixelPerMM[0]*25.4f+", "+pixelPerMM[1]*25.4f+"]"); final List<MonitorMode> modes = monitor.getSupportedModes(); Assert.assertTrue(modes.size()>0); int i=0; @@ -189,7 +188,16 @@ public class TestScreenMode00aNEWT extends UITestCase { mmPre = mm; } Assert.assertTrue(allMonitorModes.containsAll(modes)); + } + // Dump all Monitor's and its DPI and current/original mode + j=0; + for(final Iterator<MonitorDevice> iMonitor=monitors.iterator(); iMonitor.hasNext(); j++) { + final MonitorDevice monitor = iMonitor.next(); + System.err.println(j+": "+monitor); + final float[] pixelPerMM = monitor.getPixelsPerMM(new float[2]); + System.err.println(j+" pixel/mm ["+pixelPerMM[0]+", "+pixelPerMM[1]+"]"); + System.err.println(j+" pixel/in ["+pixelPerMM[0]*25.4f+", "+pixelPerMM[1]*25.4f+"]"); final MonitorMode sm_o = monitor.getOriginalMode(); Assert.assertNotNull(sm_o); final MonitorMode sm_c = monitor.queryCurrentMode(); |