Skip to content

Commit

Permalink
Bug 1142 - NEWT: Add support to retrieve the primary MonitorDevice
Browse files Browse the repository at this point in the history
Support added for
  - Windows
  - X11 XRandR 1.3
  - OSX

Note: Our whole MonitorMode association handling is currently _not_ dynamic.
 - only on Windows we actually use native unique ID,
   which might not change (adapter and monitor idx)

 - On OSX and X11 we simply use indices,
   but if monitor setup changes - they refer to different instances.

In case it is desired to cover dynamic monitor setup change,
we need to address this issue in a new bug entry.
  • Loading branch information
sgothel committed Mar 9, 2015
1 parent f0f6ee4 commit 0adbc97
Show file tree
Hide file tree
Showing 23 changed files with 282 additions and 112 deletions.
15 changes: 7 additions & 8 deletions make/scripts/tests-win.bat
Expand Up @@ -167,15 +167,15 @@ REM scripts\java-win.bat com.jogamp.opengl.test.junit.newt.TestGLWindows02NEWTAn
REM scripts\java-win.bat com.jogamp.opengl.test.junit.newt.TestGLWindowInvisiblePointer01NEWT %*
REM scripts\java-win.bat com.jogamp.opengl.test.junit.nativewindow.TestRecursiveToolkitLockCORE

REM scripts\java-win.bat com.jogamp.opengl.test.junit.newt.mm.TestScreenMode00aNEWT %*
scripts\java-win.bat com.jogamp.opengl.test.junit.newt.mm.TestScreenMode00aNEWT %*
REM scripts\java-win.bat com.jogamp.opengl.test.junit.newt.mm.TestScreenMode00bNEWT %*
REM scripts\java-win.bat com.jogamp.opengl.test.junit.newt.mm.TestScreenMode00cNEWT %*
REM scripts\java-win.bat com.jogamp.opengl.test.junit.newt.mm.TestScreenMode01aNEWT %*
REM scripts\java-win.bat com.jogamp.opengl.test.junit.newt.mm.TestScreenMode01bNEWT %*
REM scripts\java-win.bat com.jogamp.opengl.test.junit.newt.mm.TestScreenMode01cNEWT %*
REM scripts\java-win.bat com.jogamp.opengl.test.junit.newt.mm.TestScreenMode01dNEWT %*
REM scripts\java-win.bat com.jogamp.opengl.test.junit.newt.mm.TestScreenMode02aNEWT %*
scripts\java-win.bat com.jogamp.opengl.test.junit.newt.mm.TestScreenMode02bNEWT %*
REM scripts\java-win.bat com.jogamp.opengl.test.junit.newt.mm.TestScreenMode02bNEWT %*
REM scripts\java-win.bat com.jogamp.opengl.test.junit.newt.mm.ManualScreenMode03sNEWT %*

REM scripts\java-win.bat com.jogamp.opengl.test.junit.newt.TestDisplayLifecycle01NEWT
Expand Down Expand Up @@ -209,12 +209,11 @@ REM scripts\java-win.bat com.jogamp.opengl.test.junit.graph.TestRegionRendererNE
REM scripts\java-win.bat com.jogamp.opengl.test.junit.graph.TestTextRendererNEWT01
REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.glsl.TestGLSLShaderState02NEWT
REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.glsl.TestGLSLShaderState02NEWT
REM scripts\java-win.bat com.jogamp.opengl.test.junit.graph.demos.ui.UINewtDemo01
REM scripts\java-win.bat com.jogamp.opengl.test.junit.graph.demos.GPUTextNewtDemo01
REM scripts\java-win.bat com.jogamp.opengl.test.junit.graph.demos.GPUTextNewtDemo02
REM scripts\java-win.bat com.jogamp.opengl.test.junit.graph.demos.GPURegionNewtDemo01
REM scripts\java-win.bat com.jogamp.opengl.test.junit.graph.demos.GPURegionNewtDemo02

REM scripts\java-win.bat com.jogamp.opengl.test.junit.graph.demos.ui.UINewtDemo01 %*
REM scripts\java-win.bat com.jogamp.opengl.test.junit.graph.demos.GPUTextNewtDemo %*
REM scripts\java-win.bat com.jogamp.opengl.test.junit.graph.demos.GPURegionNewtDemo %*
REM scripts\java-win.bat com.jogamp.opengl.test.junit.graph.demos.GPUUISceneNewtDemo %*
REM scripts\java-win.bat com.jogamp.opengl.test.junit.graph.demos.GPUUISceneNewtCanvasAWTDemo %*
REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.awt.TestBug461FBOSupersamplingSwingAWT
REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.glsl.TestRulerNEWT01

4 changes: 2 additions & 2 deletions make/scripts/tests-x64-dbg.bat
Expand Up @@ -67,7 +67,7 @@ REM set D_ARGS="-Djogl.debug.GLCanvas" "-Djogl.debug.GLJPanel" "-Djogl.debug.Til
REM set D_ARGS="-Djogl.debug.GLCanvas" "-Djogl.debug.GLJPanel" "-Djogl.debug.TileRenderer"
REM set D_ARGS="-Djogl.debug.GLContext" "-Djogl.debug.GLJPanel"
REM set D_ARGS="-Djogl.gljpanel.noverticalflip"
REM set D_ARGS="-Dnewt.debug=all"
set D_ARGS="-Dnewt.debug=all"
REM set D_ARGS="-Dnewt.debug.Window"
REM set D_ARGS="-Dnewt.debug.Window.KeyEvent"
REM set D_ARGS="-Dnewt.debug.Window" "-Dnewt.debug.Window.KeyEvent" "-Dnewt.debug.EDT"
Expand All @@ -82,7 +82,7 @@ REM set D_ARGS="-Dnativewindow.debug.TraceLock"
REM set D_ARGS="-Dnewt.debug.Display" "-Dnewt.debug.EDT" "-Dnewt.debug.Window"
REM set D_ARGS="-Dnewt.debug.Window" "-Dnewt.debug.Display" "-Dnewt.debug.EDT" "-Djogl.debug.GLContext"
REM set D_ARGS="-Dnewt.debug.Screen" "-Dnewt.debug.EDT" "-Dnativewindow.debug=all"
set D_ARGS="-Dnewt.debug.Screen"
REM set D_ARGS="-Dnewt.debug.Screen"
REM set D_ARGS="-Dnewt.debug.Screen" "-Dnewt.debug.Window"
REM set D_ARGS="-Dnewt.debug.Window" "-Dnewt.debug.Display" "-Dnewt.test.Window.reparent.incompatible=true"

Expand Down
4 changes: 2 additions & 2 deletions make/scripts/tests.sh
Expand Up @@ -613,15 +613,15 @@ function testawtswt() {
#testnoawt com.jogamp.opengl.test.junit.newt.TestDisplayLifecycle01NEWT
#testnoawt com.jogamp.opengl.test.junit.newt.TestDisplayLifecycle02NEWT
#testnoawt com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT $*
#testnoawt com.jogamp.opengl.test.junit.newt.mm.TestScreenMode00aNEWT $*
testnoawt com.jogamp.opengl.test.junit.newt.mm.TestScreenMode00aNEWT $*
#testnoawt com.jogamp.opengl.test.junit.newt.mm.TestScreenMode00bNEWT $*
#testnoawt com.jogamp.opengl.test.junit.newt.mm.TestScreenMode00cNEWT $*
#testnoawt com.jogamp.opengl.test.junit.newt.mm.TestScreenMode01aNEWT $*
#testnoawt com.jogamp.opengl.test.junit.newt.mm.TestScreenMode01bNEWT $*
#testnoawt com.jogamp.opengl.test.junit.newt.mm.TestScreenMode01cNEWT $*
#testnoawt com.jogamp.opengl.test.junit.newt.mm.TestScreenMode01dNEWT $*
#testnoawt com.jogamp.opengl.test.junit.newt.mm.TestScreenMode02aNEWT $*
testnoawt com.jogamp.opengl.test.junit.newt.mm.TestScreenMode02bNEWT $*
#testnoawt com.jogamp.opengl.test.junit.newt.mm.TestScreenMode02bNEWT $*
#testnoawt com.jogamp.opengl.test.junit.newt.mm.ManualScreenMode03aNEWT $*
#testnoawt -Djava.awt.headless=true com.jogamp.opengl.test.junit.newt.TestGLWindows01NEWT $*
#testnoawt com.jogamp.opengl.test.junit.newt.TestGLWindowWarpPointer01NEWT $*
Expand Down
42 changes: 35 additions & 7 deletions src/newt/classes/com/jogamp/newt/MonitorDevice.java
Expand Up @@ -68,24 +68,26 @@ public abstract class MonitorDevice {
protected final Rectangle viewportPU; // in pixel units
protected final Rectangle viewportWU; // in window units
protected boolean isClone;
protected boolean isPrimary;
protected MonitorMode currentMode;
protected boolean modeChanged;

/**
* @param screen associated {@link Screen}
* @param nativeId unique monitor device ID
* @param isClone flag
* @param isPrimary flag
* @param sizeMM size in millimeters
* @param currentMode
* @param pixelScale pre-fetched current pixel-scale, maybe {@code null} for {@link ScalableSurface#IDENTITY_PIXELSCALE}.
* @param viewportPU viewport in pixel-units
* @param viewportWU viewport in window-units
* @param supportedModes all supported {@link MonitorMode}s
*/
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) {
protected MonitorDevice(final Screen screen, final int nativeId,
final boolean isClone, final boolean isPrimary,
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;
Expand All @@ -96,6 +98,7 @@ protected MonitorDevice(final Screen screen, final int nativeId, final boolean i
this.viewportWU = viewportWU;

this.isClone = isClone;
this.isPrimary = isPrimary;
this.currentMode = currentMode;
this.modeChanged = false;
}
Expand Down Expand Up @@ -140,6 +143,12 @@ public final int hashCode() {
/** @return {@code true} if this device represents a <i>clone</i>, otherwise return {@code false}. */
public final boolean isClone() { return isClone; }

/**
* Returns {@code true} if this device represents the <i>primary device</i>, otherwise return {@code false}.
* @see Screen#getPrimaryMonitor()
*/
public final boolean isPrimary() { return isPrimary; }

/**
* @return the immutable monitor size in millimeters.
*/
Expand Down Expand Up @@ -331,9 +340,28 @@ public final MonitorMode getCurrentMode() {

@Override
public String toString() {
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()+"]";
boolean preComma = false;
final StringBuilder sb = new StringBuilder();
sb.append("Monitor[Id ").append(Display.toHexString(nativeId)).append(", options[");
{
if( isClone() ) {
sb.append("clone");
preComma = true;
}
if( isPrimary() ) {
if( preComma ) {
sb.append(", ");
}
sb.append("primary");
}
}
preComma = false;
sb.append("], ").append(sizeMM).append(" mm, pixelScale [").append(pixelScale[0]).append(", ")
.append(pixelScale[1]).append("], viewport ").append(viewportPU).append(" [pixels], ").append(viewportWU)
.append(" [window], orig ").append(originalMode).append(", curr ")
.append(currentMode).append(", modeChanged ").append(modeChanged).append(", modeCount ")
.append(supportedModes.size()).append("]");
return sb.toString();
}
}

7 changes: 7 additions & 0 deletions src/newt/classes/com/jogamp/newt/Screen.java
Expand Up @@ -208,6 +208,13 @@ public boolean equals(final Object obj) {
*/
public abstract List<MonitorDevice> getMonitorDevices();

/**
* Returns the windowing manager's primary {@link MonitorDevice},
* which holds the system menu bar, etc.
* @see MonitorDevice#isPrimary()
*/
public abstract MonitorDevice getPrimaryMonitor();

/**
* Returns the {@link MonitorDevice} with the highest {@link MonitorDevice#getViewportInWindowUnits() viewport}
* {@link RectangleImmutable#coverage(RectangleImmutable) coverage} of the given rectangle in window units,
Expand Down
23 changes: 14 additions & 9 deletions src/newt/classes/jogamp/newt/MonitorDeviceImpl.java
Expand Up @@ -41,19 +41,20 @@ public class MonitorDeviceImpl extends MonitorDevice {
/**
* @param screen associated {@link Screen}
* @param nativeId unique monitor device ID
* @param isClone TODO
* @param isClone flag
* @param isPrimary flag
* @param sizeMM size in millimeters
* @param currentMode
* @param pixelScale pre-fetched current pixel-scale, maybe {@code null} for {@link ScalableSurface#IDENTITY_PIXELSCALE}.
* @param viewportPU viewport in pixel-units
* @param viewportWU viewport in window-units
* @param supportedModes all supported {@link MonitorMode}s
*/
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);
public MonitorDeviceImpl(final ScreenImpl screen, final int nativeId,
final boolean isClone, final boolean isPrimary,
final DimensionImmutable sizeMM, final MonitorMode currentMode, final float[] pixelScale,
final Rectangle viewportPU, final Rectangle viewportWU, final ArrayHashSet<MonitorMode> supportedModes) {
super(screen, nativeId, isClone, isPrimary, sizeMM, currentMode, pixelScale, viewportPU, viewportWU, supportedModes);
}

@Override
Expand All @@ -80,7 +81,7 @@ public final MonitorMode queryCurrentMode() throws IllegalStateException {
}
// if mode has changed somehow, update it ..
if( getCurrentMode().hashCode() != mmU.hashCode() ) {
setCurrentModeValue(mmU);
setCurrentModeValue(mmU, isPrimary);
sms.fireMonitorModeChanged(this, mmU, true);
}
return mmU;
Expand Down Expand Up @@ -139,7 +140,7 @@ public final boolean setCurrentMode(final MonitorMode mode) throws IllegalStateE
}
}
if( success ) {
setCurrentModeValue(mmU);
setCurrentModeValue(mmU, isPrimary);
modeChanged = !isOriginalMode();
}
sms.fireMonitorModeChanged(this, mmU, success);
Expand All @@ -152,8 +153,9 @@ public final boolean setCurrentMode(final MonitorMode mode) throws IllegalStateE
}
}

private final void setCurrentModeValue(final MonitorMode currentMode) {
private final void setCurrentModeValue(final MonitorMode currentMode, final boolean isPrimary) {
this.currentMode = currentMode;
this.isPrimary = isPrimary;
}

/* pp */ final Rectangle getMutuableViewportPU() { return viewportPU; }
Expand All @@ -166,4 +168,7 @@ private final void setCurrentModeValue(final MonitorMode currentMode) {
/* pp */ final void setIsClone(final boolean isClone) {
this.isClone = isClone;
}
/* pp */ final void setIsPrimary(final boolean isPrimary) {
this.isPrimary = isPrimary;
}
}
36 changes: 30 additions & 6 deletions src/newt/classes/jogamp/newt/MonitorModeProps.java
Expand Up @@ -133,6 +133,7 @@ public class MonitorModeProps {
* <li>count</li>
* <li>id</li>
* <li>IsClone</li>
* <li>IsPrimary</li>
* <li>ScreenSizeMM[width, height] (2 elements)</li>
* <li>Rotated Viewport pixel-units (4 elements)</li>
* <li>Rotated Viewport window-units (4 elements)</li>
Expand All @@ -141,17 +142,18 @@ public class MonitorModeProps {
* <li>SupportedModeId+</li>
* </ul>
* <p>
* Viewport := [x, y, width, height] (4 elements)
* with Viewport := [x, y, width, height] (4 elements)
* </p>
* <p>
* WARNING: must be synchronized with ScreenMode.h, native implementation
* </p>
*/
public static final int MIN_MONITOR_DEVICE_PROPERTIES = 16;
public static final int MIN_MONITOR_DEVICE_PROPERTIES = 17;

public static final int IDX_MONITOR_DEVICE_VIEWPORT = 1 // count
+ 1 // native mode
+ 1 // isClone
+ 1 // isPrimary
+ MonitorModeProps.NUM_RESOLUTION_PROPERTIES // sizeMM
;

Expand All @@ -161,6 +163,10 @@ public static class Cache {
public final ArrayHashSet<MonitorMode.SizeAndRRate> sizeAndRates = new ArrayHashSet<MonitorMode.SizeAndRRate>();
public final ArrayHashSet<MonitorMode> monitorModes = new ArrayHashSet<MonitorMode>();
public final ArrayHashSet<MonitorDevice> monitorDevices = new ArrayHashSet<MonitorDevice>();

public final void setPrimary(final MonitorDevice p) { primary = p; }
public final MonitorDevice getPrimary() { return primary;}
private MonitorDevice primary = null;
}

/** WARNING: must be synchronized with ScreenMode.h, native implementation */
Expand Down Expand Up @@ -292,6 +298,7 @@ public static MonitorDevice streamInMonitorDevice(final Cache cache, final Scree
final List<MonitorMode> allMonitorModes = cache.monitorModes.getData();
final int id = monitorProperties[offset++];
final boolean isClone = 0 == monitorProperties[offset++] ? false : true;
final boolean isPrimary = 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++]);
Expand All @@ -311,9 +318,14 @@ public static MonitorDevice streamInMonitorDevice(final Cache cache, final Scree
}
}
}
MonitorDevice monitorDevice = new MonitorDeviceImpl(screen, id, isClone, sizeMM, currentMode, pixelScale, viewportPU, viewportWU, supportedModes);
MonitorDevice monitorDevice = new MonitorDeviceImpl(screen, id, isClone, isPrimary,
sizeMM, currentMode, pixelScale,
viewportPU, viewportWU, supportedModes);
if(null!=cache) {
monitorDevice = cache.monitorDevices.getOrAdd(monitorDevice);
if( monitorDevice.isPrimary() ) {
cache.setPrimary(monitorDevice);
}
}
if( null != monitor_idx ) {
final int _monitorIdx = cache.monitorDevices.indexOf(monitorDevice);
Expand Down Expand Up @@ -373,12 +385,18 @@ public static MonitorDevice streamInMonitorDevice(final Cache cache, final Scree
offset++;
final int id = monitorProperties[offset++];
final boolean isClone = 0 == monitorProperties[offset++] ? false : true;
final boolean isPrimary = 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, isClone, sizeMM, currentMode, pixelScale, viewportPU, viewportWU, supportedModes);
MonitorDevice monitorDevice = new MonitorDeviceImpl(screen, id, isClone, isPrimary,
sizeMM, currentMode, pixelScale,
viewportPU, viewportWU, supportedModes);
if(null!=cache) {
monitorDevice = cache.monitorDevices.getOrAdd(monitorDevice);
if( monitorDevice.isPrimary() ) {
cache.setPrimary(monitorDevice);
}
}
if( null != monitor_idx ) {
final int _monitorIdx = cache.monitorDevices.indexOf(monitorDevice);
Expand All @@ -402,6 +420,7 @@ public static int[] streamOutMonitorDevice (final MonitorDevice monitorDevice) {
data[idx++] = data.length;
data[idx++] = monitorDevice.getId();
data[idx++] = monitorDevice.isClone() ? 1 : 0;
data[idx++] = monitorDevice.isPrimary() ? 1 : 0;
data[idx++] = monitorDevice.getSizeMM().getWidth();
data[idx++] = monitorDevice.getSizeMM().getHeight();
data[idx++] = monitorDevice.getViewport().getX();
Expand All @@ -424,8 +443,13 @@ public static int[] streamOutMonitorDevice (final MonitorDevice monitorDevice) {
return data;
}

/** 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) {
/**
* Identify monitor devices:
* <ul>
* <li><i>cloned</i> mode, i.e. consecutive devices being 100% covered by preceding devices.</li>
* </ul>
*/
/* pp */ static void identifyMonitorDevices(final MonitorModeProps.Cache cache) {
final ArrayList<MonitorDevice> monitors = cache.monitorDevices.toArrayList();
final int monitorCount = monitors.size();
for(int i=0; i<monitorCount; i++) {
Expand Down

0 comments on commit 0adbc97

Please sign in to comment.