summaryrefslogtreecommitdiffstats
path: root/src/newt
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2013-05-06 17:27:09 +0200
committerSven Gothel <[email protected]>2013-05-06 17:27:09 +0200
commit6ebf649d1b87944257fe492e0aef842d1b8debc2 (patch)
treeec2f3f0bc98903eac7285f64824cc79abc416efb /src/newt
parent4d35eaa766071fd8dedab8b6e2ee53710831c567 (diff)
Fix Bug 600 and Bug 721: Adding support for multiple monitors w/ NEWT
- Support for all monitor devices and their available modes - X11: Use RandR 1.3 if available - Retrieve information - Changing a monitor device's mode - Support for dedicated and spannig fullscreen - See <http://jogamp.org/files/screenshots/newt-mmonitor/html/> - TODO: - X11 RandR does _not_ relayout the virtual screen size and neither the CRT's viewport. We may need to relayout them if they were covering a seamless region to achieve same experience! - OSX: No machine to attach a secondary CRT -> TEST! - Tested Manually for Regressions - Linux ARMv6hf (Rasp-Pi/BCM, Panda/X11) - Android (Huawei, Kindle) - Tested Manually and junit: - X11/Linux - NV, ATI-Catalyst w/ 2 CRTs - VBox w/ 4 CRTs - Win/Windows - NV, w/ 2 CRTs - VBox w/ 4 CRTs - X11/OpenIndiana, NV, 1 CRT
Diffstat (limited to 'src/newt')
-rw-r--r--src/newt/classes/com/jogamp/newt/MonitorDevice.java235
-rw-r--r--src/newt/classes/com/jogamp/newt/MonitorMode.java346
-rw-r--r--src/newt/classes/com/jogamp/newt/Screen.java93
-rw-r--r--src/newt/classes/com/jogamp/newt/ScreenMode.java208
-rw-r--r--src/newt/classes/com/jogamp/newt/Window.java38
-rw-r--r--src/newt/classes/com/jogamp/newt/event/MonitorEvent.java71
-rw-r--r--src/newt/classes/com/jogamp/newt/event/MonitorModeListener.java (renamed from src/newt/classes/com/jogamp/newt/event/ScreenModeListener.java)12
-rw-r--r--src/newt/classes/com/jogamp/newt/event/NEWTEvent.java7
-rw-r--r--src/newt/classes/com/jogamp/newt/event/OutputEvent.java51
-rw-r--r--src/newt/classes/com/jogamp/newt/opengl/GLWindow.java13
-rw-r--r--src/newt/classes/com/jogamp/newt/util/MonitorMode.java102
-rw-r--r--src/newt/classes/com/jogamp/newt/util/MonitorModeUtil.java247
-rw-r--r--src/newt/classes/com/jogamp/newt/util/ScreenModeUtil.java341
-rw-r--r--src/newt/classes/jogamp/newt/MonitorDeviceImpl.java147
-rw-r--r--src/newt/classes/jogamp/newt/MonitorModeProps.java355
-rw-r--r--src/newt/classes/jogamp/newt/OffscreenWindow.java13
-rw-r--r--src/newt/classes/jogamp/newt/ScreenImpl.java569
-rw-r--r--src/newt/classes/jogamp/newt/ScreenModeStatus.java231
-rw-r--r--src/newt/classes/jogamp/newt/ScreenMonitorState.java195
-rw-r--r--src/newt/classes/jogamp/newt/WindowImpl.java201
-rw-r--r--src/newt/classes/jogamp/newt/driver/android/ScreenDriver.java99
-rw-r--r--src/newt/classes/jogamp/newt/driver/android/WindowDriver.java16
-rw-r--r--src/newt/classes/jogamp/newt/driver/awt/ScreenDriver.java24
-rw-r--r--src/newt/classes/jogamp/newt/driver/bcm/egl/ScreenDriver.java56
-rw-r--r--src/newt/classes/jogamp/newt/driver/bcm/vc/iv/ScreenDriver.java56
-rw-r--r--src/newt/classes/jogamp/newt/driver/intel/gdl/ScreenDriver.java56
-rw-r--r--src/newt/classes/jogamp/newt/driver/kd/ScreenDriver.java54
-rw-r--r--src/newt/classes/jogamp/newt/driver/macosx/ScreenDriver.java129
-rw-r--r--src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java15
-rw-r--r--src/newt/classes/jogamp/newt/driver/windows/ScreenDriver.java146
-rw-r--r--src/newt/classes/jogamp/newt/driver/x11/RandR.java47
-rw-r--r--src/newt/classes/jogamp/newt/driver/x11/RandR11.java320
-rw-r--r--src/newt/classes/jogamp/newt/driver/x11/RandR13.java276
-rw-r--r--src/newt/classes/jogamp/newt/driver/x11/ScreenDriver.java146
-rw-r--r--src/newt/native/MacWindow.m235
-rw-r--r--src/newt/native/NewtMacWindow.h1
-rw-r--r--src/newt/native/NewtMacWindow.m4
-rw-r--r--src/newt/native/ScreenMode.h15
-rw-r--r--src/newt/native/Window.h17
-rw-r--r--src/newt/native/WindowsWindow.c305
-rw-r--r--src/newt/native/X11RandR11.c44
-rw-r--r--src/newt/native/X11RandR13.c597
-rw-r--r--src/newt/native/X11Screen.c31
-rw-r--r--src/newt/native/X11Screen.h1
-rw-r--r--src/newt/native/X11Window.c18
45 files changed, 4068 insertions, 2115 deletions
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:<br>
+ * <ui>
+ * <li>Immutable
+ * <ul>
+ * <li>nativeId</li>
+ * <li>{@link DimensionImmutable} size in [mm]</li>
+ * <li>{@link MonitorMode} original mode</li>
+ * <li><code>List&lt;MonitorMode&gt;</code> supportedModes</li>
+ * </ul></li>
+ * <li>Mutable
+ * <ul>
+ * <li>{@link MonitorMode} current mode</li>
+ * <li>{@link RectangleImmutable} viewport (rotated)</li>
+ * </ul></li>
+ * </ul>
+ */
+public abstract class MonitorDevice {
+ protected final Screen screen; // backref
+ protected final int nativeId; // unique monitor device ID
+ 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 Rectangle viewport;
+
+ protected MonitorDevice(Screen screen, int nativeId, DimensionImmutable sizeMM, Rectangle viewport, MonitorMode currentMode, ArrayHashSet<MonitorMode> supportedModes) {
+ this.screen = screen;
+ this.nativeId = nativeId;
+ this.sizeMM = sizeMM;
+ this.originalMode = currentMode;
+ this.supportedModes = supportedModes;
+ this.currentMode = currentMode;
+ this.viewport = viewport;
+ this.modeChanged = false;
+ }
+
+ /** Returns the {@link Screen} owning this monitor. */
+ public final Screen getScreen() {
+ return screen;
+ }
+
+ /**
+ * Tests equality of two <code>MonitorDevice</code> objects
+ * by evaluating equality of it's components:<br>
+ * <ul>
+ * <li><code>nativeID</code></li>
+ * </ul>
+ * <br>
+ */
+ public final boolean equals(Object obj) {
+ if (this == obj) { return true; }
+ if (obj instanceof MonitorDevice) {
+ MonitorDevice md = (MonitorDevice)obj;
+ return md.nativeId == nativeId;
+ }
+ return false;
+ }
+
+ /**
+ * Returns a combined hash code of it's elements:<br>
+ * <ul>
+ * <li><code>nativeID</code></li>
+ * </ul>
+ */
+ public final int hashCode() {
+ return nativeId;
+ }
+
+ /** @return the immutable unique native Id of this monitor device. */
+ public final int getId() { return nativeId; }
+
+ /**
+ * @return the immutable monitor size in millimeters.
+ */
+ public final DimensionImmutable getSizeMM() {
+ return sizeMM;
+ }
+
+ /**
+ * Return the immutable original {@link com.jogamp.newt.MonitorMode}, as used at NEWT initialization.
+ * @return original {@link MonitorMode} which is element of the list {@link #getSupportedModes()} and {@link Screen#getMonitorModes()}.
+ */
+ public final MonitorMode getOriginalMode() {
+ return originalMode;
+ }
+
+ /**
+ * FIXME: May need to support mutable mode, i.e. adding modes on the fly!
+ * @return the immutable list of {@link MonitorMode}s supported by this monitor. Use w/ care, it's not a copy!
+ */
+ public final List<MonitorMode> getSupportedModes() {
+ return supportedModes.getData();
+ }
+
+ /** @return the {@link RectangleImmutable rectangular} portion of the rotated virtual {@link Screen} size represented by this monitor. */
+ public final RectangleImmutable getViewport() {
+ return viewport;
+ }
+
+ /** Returns <code>true</code> if given coordinates are contained by this {@link #getViewport() viewport}, otherwise <code>false</code>. */
+ 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 <code>0.0</code> and <code>1.0</code>.
+ * <p>
+ * Coverage is computed by:
+ * <pre>
+ * isect = viewport.intersection(r);
+ * coverage = area( isect ) / area( viewport ) ;
+ * </pre>
+ * </p>
+ */
+ 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<MonitorDevice> monitors) {
+ int x1=Integer.MAX_VALUE, y1=Integer.MAX_VALUE;
+ int x2=Integer.MIN_VALUE, y2=Integer.MIN_VALUE;
+ for(int i=monitors.size()-1; i>=0; i--) {
+ final RectangleImmutable vp = monitors.get(i).getViewport();
+ x1 = Math.min(x1, vp.getX());
+ x2 = Math.max(x2, vp.getX() + vp.getWidth());
+ y1 = Math.min(y1, vp.getY());
+ y2 = Math.max(y2, vp.getY() + vp.getHeight());
+ }
+ result.setX(x1);
+ result.setY(y1);
+ result.setWidth(x2 - x1);
+ result.setHeight(y2 - y1);
+ return result;
+ }
+
+ public final boolean isOriginalMode() {
+ return currentMode.hashCode() == originalMode.hashCode();
+ }
+
+ /**
+ * Returns <code>true</true> if the {@link MonitorMode}
+ * has been changed programmatic via this API <i>only</i>, otherwise <code>false</code>.
+ * <p>
+ * Note: We cannot guarantee that we won't interfere w/ another running
+ * application's screen mode change or vice versa.
+ * </p>
+ */
+ public final boolean isModeChangedByUs() {
+ return modeChanged && !isOriginalMode();
+ }
+
+ /**
+ * Return the current cached {@link MonitorMode} w/o native query.
+ * <p>
+ * 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. </p>
+ *
+ * @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.
+ * <p>
+ * 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. </p>
+ *
+ * @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:<br>
+ * <ul>
+ * <li>nativeId</li>
+ * <li>{@link SizeAndRRate}, non rotated surfaceSize and refreshRate</li>
+ * <li><code>rotation</code>, measured counter clockwise (CCW)</li>
+ * </ul>
+ *
+ * <i>Aquire and filter MonitorMode</i><br>
+ * <ul>
+ * <li>A List of read only MonitorModes is being returned by {@link com.jogamp.newt.Screen#getMonitorModes()}.</li>
+ * <li>You may utilize {@link com.jogamp.newt.util.MonitorModeUtil} to filter and select a desired ScreenMode.</li>
+ * <li>The current ScreenMode can be obtained via {@link com.jogamp.newt.Screen#getCurrentScreenMode()}.</li>
+ * <li>The initial original ScreenMode (at startup) can be obtained via {@link com.jogamp.newt.Screen#getOriginalScreenMode()}.</li>
+ * </ul>
+ * <br>
+ *
+ * <i>Changing ScreenModes</i><br>
+ * FIXME!!!!!
+ * <ul>
+ * <li> Use {@link com.jogamp.newt.Screen#setCurrentScreenMode(com.jogamp.newt.MonitorMode)}</li>
+ * to change the current ScreenMode of all Screen's referenced via the full qualified name (FQN)
+ * {@link com.jogamp.newt.Screen#getFQName()}.</li>
+ * <li> When the last FQN referenced Screen closes, the original ScreenMode ({@link com.jogamp.newt.Screen#getOriginalScreenMode()})
+ * is restored.</li>
+ * </ul>
+ * <br>
+ * Example for changing the ScreenMode:
+ * <pre>
+ // determine target refresh rate
+ ScreenMode orig = screen.getOriginalScreenMode();
+ int freq = orig.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));
+ * </pre>
+ *
+ * X11 / AMD just works<br>
+ * <br>
+ * X11 / NVidia difficulties
+ * <pre>
+ NVidia RANDR RefreshRate Bug
+ If NVidia's 'DynamicTwinView' is enabled, all refresh rates are
+ unique, ie consequent numbers starting with the default refresh, ie 50, 51, ..
+ The only way to workaround it is to disable 'DynamicTwinView'.
+ Read: http://us.download.nvidia.com/XFree86/Linux-x86/260.19.12/README/configtwinview.html
+
+ Check to see if 'DynamicTwinView' is enable:
+ nvidia-settings -q :0/DynamicTwinview
+
+ To disable it (workaround), add the following option to your xorg.conf device section:
+ Option "DynamicTwinView" "False"
+
+ NVidia RANDR Rotation:
+ To enable it, add the following option to your xorg.conf device section:
+ Option "RandRRotation" "on"
+ * </pre>
+ *
+ */
+public class MonitorMode {
+ /**
+ * Immutable <i>surfaceSize and refreshRate</i> Class, consisting of it's read only components:<br>
+ * <ul>
+ * <li>nativeId</li>
+ * <li>{@link SurfaceSize} surface memory size</li>
+ * <li><code>refresh rate</code></li>
+ * </ul>
+ */
+ 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:<br/>
+ * <ul>
+ * <li><code>surfaceSize</code></li>
+ * <li><code>refreshRate</code></li>
+ * <li><code>flags</code></li>
+ * </ul>
+ */
+ 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:<br/>
+ * <ul>
+ * <li><code>surfaceSize</code></li>
+ * <li><code>refreshRate</code></li>
+ * <li><code>flags</code></li>
+ * </ul>
+ */
+ 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.
+ * <p>
+ * See {@link com.jogamp.newt.util.MonitorModeUtil} for filter utilities.
+ * </p>
+ * @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 <i>surfaceSize and refreshRate</i> 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 <code>getMonitorMode().getSurfaceSize().getResolution()</code>
+ * and <code>getRotation()</code>
+ */
+ public final int getRotatedWidth() {
+ return getRotatedWH(true);
+ }
+
+ /** Returns the rotated screen height,
+ * derived from <code>getMonitorMode().getSurfaceSize().getResolution()</code>
+ * and <code>getRotation()</code>
+ */
+ 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:<br/>
+ * <ul>
+ * <li><code>nativeId</code></li>
+ * <li><code>sizeAndRRate</code></li>
+ * <li><code>rotation</code></li>
+ * </ul>
+ */
+ 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:<br/>
+ * <ul>
+ * <li><code>nativeId</code></li>
+ * <li><code>sizeAndRRate</code></li>
+ * <li><code>rotation</code></li>
+ * </ul>
+ */
+ 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,26 +127,31 @@ 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 <b>rotated</b> virtual width.
+ * @return the <b>rotated</b> virtual viewport's width.
*/
public abstract int getWidth();
/**
- * @return the <b>rotated</b> virtual height.
+ * @return the <b>rotated</b> virtual viewport's height.
*/
public abstract int getHeight();
/**
+ * @return the <b>rotated</b> virtual viewport, i.e. origin and size.
+ */
+ public abstract RectangleImmutable getViewport();
+
+ /**
* @return the associated Display
*/
public abstract Display getDisplay();
@@ -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.
+ * <p>
+ * 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.</p>
*/
- public abstract void removeScreenModeListener(ScreenModeListener sml);
+ public abstract List<MonitorMode> getMonitorModes();
/**
- * Return a list of available {@link com.jogamp.newt.ScreenMode ScreenMode}s.
+ * Return a list of all available {@link MonitorDevice}s.
* <p>
- * 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.</p>
- *
- * @return a shallow copy of the internal immutable {@link com.jogamp.newt.ScreenMode ScreenMode}s.
*/
- public abstract List<ScreenMode> getScreenModes();
+ public abstract List<MonitorDevice> 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.
+ * <p>
+ * If no coverage is detected the first {@link MonitorDevice} is returned.
+ * </p>
*/
- public abstract ScreenMode getOriginalScreenMode();
+ public final MonitorDevice getMainMonitor(RectangleImmutable r) {
+ MonitorDevice res = null;
+ float maxCoverage = Float.MIN_VALUE;
+ final List<MonitorDevice> 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}.
* <p>
- * 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. </p>
- *
- * @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.
+ * </p>
+ * @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<Screen> screenList = new ArrayList<Screen>();
@@ -236,6 +266,7 @@ public abstract class Screen {
return null;
}
/** Returns the global display collection */
+ @SuppressWarnings("unchecked")
public static Collection<Screen> getAllScreens() {
ArrayList<Screen> 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:<br>
- * <ul>
- * <li>{@link com.jogamp.newt.util.MonitorMode}, non rotated values</li>
- * <li><code>rotation</code>, measured counter clockwise (CCW)</li>
- * </ul>
- *
- * <i>Aquire and filter ScreenModes</i><br>
- * <ul>
- * <li>A List of read only ScreenMode's is being returned by {@link com.jogamp.newt.Screen#getScreenModes()}.</li>
- * <li>You may utilize {@link com.jogamp.newt.util.ScreenModeUtil} to filter and select a desired ScreenMode.</li>
- * <li>The current ScreenMode can be obtained via {@link com.jogamp.newt.Screen#getCurrentScreenMode()}.</li>
- * <li>The initial original ScreenMode (at startup) can be obtained via {@link com.jogamp.newt.Screen#getOriginalScreenMode()}.</li>
- * </ul>
- * <br>
- *
- * <i>Changing ScreenModes</i><br>
- * <ul>
- * <li> Use {@link com.jogamp.newt.Screen#setCurrentScreenMode(com.jogamp.newt.ScreenMode)}</li>
- * to change the current ScreenMode of all Screen's referenced via the full qualified name (FQN)
- * {@link com.jogamp.newt.Screen#getFQName()}.</li>
- * <li> When the last FQN referenced Screen closes, the original ScreenMode ({@link com.jogamp.newt.Screen#getOriginalScreenMode()})
- * is restored.</li>
- * </ul>
- * <br>
- * Example for changing the ScreenMode:
- * <pre>
- // determine target refresh rate
- ScreenMode orig = screen.getOriginalScreenMode();
- int freq = orig.getMonitorMode().getRefreshRate();
-
- // target resolution
- Dimension res = new Dimension(800, 600);
-
- // target rotation
- int rot = 0;
-
- // filter available ScreenModes
- List screenModes = screen.getScreenModes();
- screenModes = ScreenModeUtil.filterByRate(screenModes, freq); // get the nearest ones
- screenModes = ScreenModeUtil.filterByRotation(screenModes, rot);
- screenModes = ScreenModeUtil.filterByResolution(screenModes, res); // get the nearest ones
- screenModes = ScreenModeUtil.getHighestAvailableBpp(screenModes);
-
- // pick 1st one ..
- screen.setCurrentScreenMode((ScreenMode) screenModes.get(0));
- * </pre>
- *
- * X11 / AMD just works<br>
- * <br>
- * X11 / NVidia difficulties
- * <pre>
- NVidia RANDR RefreshRate Bug
- If NVidia's 'DynamicTwinView' is enabled, all refresh rates are
- unique, ie consequent numbers starting with the default refresh, ie 50, 51, ..
- The only way to workaround it is to disable 'DynamicTwinView'.
- Read: http://us.download.nvidia.com/XFree86/Linux-x86/260.19.12/README/configtwinview.html
-
- Check to see if 'DynamicTwinView' is enable:
- nvidia-settings -q :0/DynamicTwinview
-
- To disable it (workaround), add the following option to your xorg.conf device section:
- Option "DynamicTwinView" "False"
-
- NVidia RANDR Rotation:
- To enable it, add the following option to your xorg.conf device section:
- Option "RandRRotation" "on"
- * </pre>
- *
- */
-public class ScreenMode {
- /** 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 <code>MonitorMode</code> */
- 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 <code>getMonitorMode().getSurfaceSize().getResolution()</code>
- * and <code>getRotation()</code>
- */
- public final int getRotatedWidth() {
- return getRotatedWH(true);
- }
-
- /** Returns the rotated screen height,
- * derived from <code>getMonitorMode().getSurfaceSize().getResolution()</code>
- * and <code>getRotation()</code>
- */
- public final int getRotatedHeight() {
- return getRotatedWH(false);
- }
-
- public final String toString() {
- return "[ " + getMonitorMode() + ", " + rotation + " degr ]";
- }
-
- /**
- * Tests equality of two <code>ScreenMode</code> objects
- * by evaluating equality of it's components:<br>
- * <ul>
- * <li><code>monitorMode</code></li>
- * <li><code>rotation</code></li>
- * </ul>
- * <br>
- */
- public final boolean equals(Object obj) {
- if (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:<br>
- * <ul>
- * <li><code>monitorMode</code></li>
- * <li><code>rotation</code></li>
- * </ul>
- */
- public final int hashCode() {
- // 31 * x == (x << 5) - x
- int hash = 31 + getMonitorMode().hashCode();
- hash = ((hash << 5) - hash) + getRotation();
- return hash;
- }
-
- 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,11 +83,20 @@ 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.
+ * <p>
+ * If no coverage is detected the first {@link MonitorDevice} is returned.
+ * </p>
+ */
+ MonitorDevice getMainMonitor();
+
+ /**
* Set the CapabilitiesChooser to help determine the native visual type.
*
* @param chooser the new CapabilitiesChooser
@@ -344,8 +356,32 @@ public interface Window extends NativeWindow, WindowClosingProtocol {
ReparentOperation reparentWindow(NativeWindow newParent, boolean forceDestroyCreate);
+ /**
+ * Enable or disable fullscreen mode for this window.
+ * <p>
+ * Fullscreen mode is established on the {@link #getMainMonitor() main monitor}.
+ * </p>
+ * @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.
+ * <p>
+ * Disable fullscreen via {@link #setFullscreen(boolean)}.
+ * </p>
+ * @param monitors if <code>null</code> 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<MonitorDevice> 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/ScreenModeListener.java b/src/newt/classes/com/jogamp/newt/event/MonitorModeListener.java
index 7bca23cfe..11e23def1 100644
--- a/src/newt/classes/com/jogamp/newt/event/ScreenModeListener.java
+++ b/src/newt/classes/com/jogamp/newt/event/MonitorModeListener.java
@@ -28,12 +28,10 @@
package com.jogamp.newt.event;
-import com.jogamp.newt.ScreenMode;
+public interface MonitorModeListener {
+ /** called before the monitor mode will be changed */
+ void monitorModeChangeNotify(MonitorEvent me);
-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);
+ /** 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:<br>
* <ul>
- * <li> WindowEvent <code>100..10x</code></li>
- * <li> MouseEvent <code>200..20x</code></li>
- * <li> KeyEvent <code>300..30x</code></li>
+ * <li> WindowEvent <code>100..10x</code></li>
+ * <li> MouseEvent <code>200..20x</code></li>
+ * <li> KeyEvent <code>300..30x</code></li>
+ * <li> MonitorEvent <code>600..60x</code></li>
* </ul><br>
*/
@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/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;
@@ -225,6 +228,11 @@ public class GLWindow extends GLAutoDrawableBase implements GLAutoDrawable, Wind
}
@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<MonitorDevice> 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:<br>
- * <ul>
- * <li>{@link javax.media.nativewindow.util.SurfaceSize} surface memory size</li>
- * <li>{@link javax.media.nativewindow.util.DimensionImmutable} size in [mm]</li>
- * <li><code>refresh rate</code></li>
- * </ul>
- */
-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 <code>MonitorMode</code> are equal if the three components
- * <code>surfaceSize</code> and <code>refreshRate</code>
- * are equal. <code>screenSizeMM</code> is kept out intentional to reduce the requirements for finding the current mode.
- * @return <code>true</code> if the two dimensions are equal;
- * otherwise <code>false</code>.
- */
- 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 <code>surfaceSize</code> and <code>refreshRate</code>.
- * <code>screenSizeMM</code> 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<MonitorMode> monitorModes, MonitorMode search) {
+ return monitorModes.indexOf(search);
+ }
+
+ public static int getIndexByHashCode(List<MonitorMode> monitorModes, MonitorMode search) {
+ if( null!=monitorModes && monitorModes.size()>0 ) {
+ for (int i=0; i<monitorModes.size(); i++) {
+ if ( search.hashCode() == monitorModes.get(i).hashCode() ) {
+ return i;
+ }
+ }
+ }
+ return -1;
+ }
+
+ public static MonitorMode getByNativeSizeRateIdAndRotation(List<MonitorMode> monitorModes, MonitorMode.SizeAndRRate sizeAndRate, int modeId, int rotation) {
+ if( null!=monitorModes && monitorModes.size()>0 ) {
+ for (int i=0; i<monitorModes.size(); i++) {
+ final MonitorMode mode = monitorModes.get(i);
+ if( mode.getSizeAndRRate().equals(sizeAndRate) && mode.getId() == modeId && mode.getRotation() == rotation ) {
+ return mode;
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ *
+ * @param monitorModes
+ * @param surfaceSize
+ * @return modes with exact {@link SurfaceSize}. May return zero sized list for non.
+ */
+ public static List<MonitorMode> filterBySurfaceSize(List<MonitorMode> monitorModes, SurfaceSize surfaceSize) {
+ final List<MonitorMode> out = new ArrayList<MonitorMode>();
+ if( null!=monitorModes && monitorModes.size()>0 ) {
+ for (int i=0; null!=monitorModes && i<monitorModes.size(); i++) {
+ final MonitorMode mode = monitorModes.get(i);
+ if(mode.getSurfaceSize().equals(surfaceSize)) {
+ out.add(mode);
+ }
+ }
+ }
+ return out;
+ }
+
+ /**
+ *
+ * @param monitorModes
+ * @param rotation
+ * @return modes with exact rotation. May return zero sized list for non.
+ */
+ public static List<MonitorMode> filterByRotation(List<MonitorMode> monitorModes, int rotation) {
+ final List<MonitorMode> out = new ArrayList<MonitorMode>();
+ if( null!=monitorModes && monitorModes.size()>0 ) {
+ for (int i=0; null!=monitorModes && i<monitorModes.size(); i++) {
+ final MonitorMode mode = monitorModes.get(i);
+ if(mode.getRotation() == rotation) {
+ out.add(mode);
+ }
+ }
+ }
+ return out;
+ }
+
+ /**
+ *
+ * @param monitorModes
+ * @param bitsPerPixel
+ * @return modes with exact bpp. May return zero sized list for non.
+ */
+ public static List<MonitorMode> filterByBpp(List<MonitorMode> monitorModes, int bitsPerPixel) {
+ final List<MonitorMode> out = new ArrayList<MonitorMode>();
+ if( null!=monitorModes && monitorModes.size()>0 ) {
+ for (int i=0; null!=monitorModes && i<monitorModes.size(); i++) {
+ final MonitorMode mode = monitorModes.get(i);
+ if(mode.getSurfaceSize().getBitsPerPixel() == bitsPerPixel) {
+ out.add(mode);
+ }
+ }
+ }
+ return out;
+ }
+
+ /**
+ *
+ * @param monitorModes
+ * @param flags
+ * @return modes with exact flags. May return zero sized list for non.
+ */
+ public static List<MonitorMode> filterByFlags(List<MonitorMode> monitorModes, int flags) {
+ final List<MonitorMode> out = new ArrayList<MonitorMode>();
+ if( null!=monitorModes && monitorModes.size()>0 ) {
+ for (int i=0; null!=monitorModes && i<monitorModes.size(); i++) {
+ final MonitorMode mode = monitorModes.get(i);
+ if(mode.getFlags() == flags) {
+ out.add(mode);
+ }
+ }
+ }
+ return out;
+ }
+
+ /**
+ * @param monitorModes
+ * @param resolution
+ * @return modes with nearest resolution, or matching ones. May return zero sized list for non.
+ */
+ public static List<MonitorMode> filterByResolution(List<MonitorMode> monitorModes, DimensionImmutable resolution) {
+ final List<MonitorMode> out = new ArrayList<MonitorMode>();
+ 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<monitorModes.size(); i++) {
+ final MonitorMode mode = monitorModes.get(i);
+ final DimensionImmutable res = mode.getSurfaceSize().getResolution();
+ final int dsq = Math.abs(resolution_sq - res.getHeight()*res.getWidth());
+ if(dsq<mode_dsq) {
+ mode_dsq = dsq;
+ mode_dsq_idx = i;
+ }
+ if(res.equals(resolution)) {
+ out.add(mode);
+ }
+ }
+ if(out.size() == 0 && 0 <= mode_dsq_idx ) {
+ // nearest ..
+ out.add(monitorModes.get(mode_dsq_idx));
+ }
+ }
+ return out;
+ }
+
+ /**
+ *
+ * @param monitorModes
+ * @param refreshRate
+ * @return modes with nearest refreshRate, or matching ones. May return zero sized list for non.
+ */
+ public static List<MonitorMode> filterByRate(List<MonitorMode> monitorModes, float refreshRate) {
+ final List<MonitorMode> out = new ArrayList<MonitorMode>();
+ if( null!=monitorModes && monitorModes.size()>0 ) {
+ float mode_dr = Float.MAX_VALUE;
+ int mode_dr_idx = -1;
+ for (int i=0; null!=monitorModes && i<monitorModes.size(); i++) {
+ final MonitorMode mode = monitorModes.get(i);
+ float dr = Math.abs(refreshRate - mode.getRefreshRate());
+ if(dr<mode_dr) {
+ mode_dr = dr;
+ mode_dr_idx = i;
+ }
+ if(0 == dr) {
+ out.add(mode);
+ }
+ }
+ if(out.size() == 0 && 0 <= mode_dr_idx ) {
+ // nearest ..
+ out.add(monitorModes.get(mode_dr_idx));
+ }
+ }
+ return out;
+ }
+
+ /**
+ * @param monitorModes
+ * @return modes with highest available bpp (color depth). May return zero sized list for non.
+ */
+ public static List<MonitorMode> getHighestAvailableBpp(List<MonitorMode> 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<MonitorMode>();
+ }
+
+ /**
+ *
+ * @param monitorModes
+ * @return modes with highest available refresh rate. May return zero sized list for non.
+ */
+ public static List<MonitorMode> getHighestAvailableRate(List<MonitorMode> 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<MonitorMode>();
+ }
+
+}
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<ScreenMode> screenModes, ScreenMode search) {
- return screenModes.indexOf(search);
- }
-
- public static int getIndexByHashCode(List<ScreenMode> screenModes, ScreenMode search) {
- for (int i=0; null!=screenModes && i<screenModes.size(); i++) {
- if ( search.hashCode() == screenModes.get(i).hashCode() ) {
- return i;
- }
- }
- return -1;
- }
-
- /**
- * @param screenModes
- * @param resolution
- * @return modes with nearest resolution, or matching ones
- */
- public static List<ScreenMode> filterByResolution(List<ScreenMode> screenModes, DimensionImmutable resolution) {
- if(null==screenModes || screenModes.size()==0) {
- return null;
- }
- List<ScreenMode> out = new ArrayList<ScreenMode>();
- int resolution_sq = resolution.getHeight()*resolution.getWidth();
- int sm_dsq=resolution_sq, sm_dsq_idx=0;
-
- for (int i=0; null!=screenModes && i<screenModes.size(); i++) {
- ScreenMode sm = screenModes.get(i);
- DimensionImmutable res = sm.getMonitorMode().getSurfaceSize().getResolution();
- int dsq = Math.abs(resolution_sq - res.getHeight()*res.getWidth());
- if(dsq<sm_dsq) {
- sm_dsq = dsq;
- sm_dsq_idx = i;
- }
- if(res.equals(resolution)) {
- out.add(sm);
- }
- }
- if(out.size()>0) {
- return out;
- }
- // nearest ..
- resolution = screenModes.get(sm_dsq_idx).getMonitorMode().getSurfaceSize().getResolution();
- return filterByResolution(screenModes, resolution);
- }
-
- public static List<ScreenMode> filterBySurfaceSize(List<ScreenMode> screenModes, SurfaceSize surfaceSize) {
- if(null==screenModes || screenModes.size()==0) {
- return null;
- }
- List<ScreenMode> out = new ArrayList<ScreenMode>();
- for (int i=0; null!=screenModes && i<screenModes.size(); i++) {
- ScreenMode sm = screenModes.get(i);
- if(sm.getMonitorMode().getSurfaceSize().equals(surfaceSize)) {
- out.add(sm);
- }
- }
- return out.size()>0 ? out : null;
- }
-
- public static List<ScreenMode> filterByRotation(List<ScreenMode> screenModes, int rotation) {
- if(null==screenModes || screenModes.size()==0) {
- return null;
- }
- List<ScreenMode> out = new ArrayList<ScreenMode>();
- for (int i=0; null!=screenModes && i<screenModes.size(); i++) {
- ScreenMode sm = screenModes.get(i);
- if(sm.getRotation() == rotation) {
- out.add(sm);
- }
- }
- return out.size()>0 ? out : null;
- }
-
- public static List<ScreenMode> filterByBpp(List<ScreenMode> screenModes, int bitsPerPixel) {
- if(null==screenModes || screenModes.size()==0) {
- return null;
- }
- List<ScreenMode> out = new ArrayList<ScreenMode>();
- for (int i=0; null!=screenModes && i<screenModes.size(); i++) {
- ScreenMode sm = screenModes.get(i);
- if(sm.getMonitorMode().getSurfaceSize().getBitsPerPixel() == bitsPerPixel) {
- out.add(sm);
- }
- }
- return out.size()>0 ? out : null;
- }
-
- /**
- *
- * @param screenModes
- * @param refreshRate
- * @return modes with nearest refreshRate, or matching ones
- */
- public static List<ScreenMode> filterByRate(List<ScreenMode> screenModes, int refreshRate) {
- if(null==screenModes || screenModes.size()==0) {
- return null;
- }
- int sm_dr = refreshRate;
- int sm_dr_idx = -1;
- List<ScreenMode> out = new ArrayList<ScreenMode>();
- for (int i=0; null!=screenModes && i<screenModes.size(); i++) {
- ScreenMode sm = screenModes.get(i);
- int dr = Math.abs(refreshRate - sm.getMonitorMode().getRefreshRate());
- if(dr<sm_dr) {
- sm_dr = dr;
- sm_dr_idx = i;
- }
- if(0 == dr) {
- out.add(sm);
- }
- }
- if(out.size()>0) {
- return out;
- }
- refreshRate = screenModes.get(sm_dr_idx).getMonitorMode().getRefreshRate();
- return filterByRate(screenModes, refreshRate);
- }
-
- public static List<ScreenMode> getHighestAvailableBpp(List<ScreenMode> 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<ScreenMode> getHighestAvailableRate(List<ScreenMode> 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 <code>modeProperties</code>,
- * 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 <code>screenModePool</code>,
- * matching the input <code>modeProperties</code>, or -1 if input could not be processed.
- */
- public static int streamIn(ArrayHashSet<DimensionImmutable> resolutionPool,
- ArrayHashSet<SurfaceSize> surfaceSizePool,
- ArrayHashSet<DimensionImmutable> screenSizeMMPool,
- ArrayHashSet<MonitorMode> monitorModePool,
- ArrayHashSet<ScreenMode> screenModePool,
- int[] modeProperties, int offset) {
- ScreenMode screenMode = streamInImpl(resolutionPool, surfaceSizePool, screenSizeMMPool, monitorModePool, screenModePool,
- modeProperties, offset);
- return screenModePool.indexOf(screenMode);
- }
-
-
- private static ScreenMode streamInImpl(ArrayHashSet<DimensionImmutable> resolutionPool,
- ArrayHashSet<SurfaceSize> surfaceSizePool,
- ArrayHashSet<DimensionImmutable> screenSizeMMPool,
- ArrayHashSet<MonitorMode> monitorModePool,
- ArrayHashSet<ScreenMode> 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<MonitorMode> 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<MonitorMode> 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<DimensionImmutable> resolutions = new ArrayHashSet<DimensionImmutable>();
+ public final ArrayHashSet<SurfaceSize> surfaceSizes = new ArrayHashSet<SurfaceSize>();
+ 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>();
+ }
+
+ /** 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 <code>modeProperties</code>, 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
+ * <p>
+ * Note: This variant only works for impl. w/ a unique mode key pair <i>modeId, rotation</i>.
+ * </p>
+ * @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 <code>modeProperties</code>, 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<MonitorMode> 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<MonitorMode> supportedModes = new ArrayHashSet<MonitorMode>();
+ while( offset < limit ) {
+ final int modeId = monitorProperties[offset++];
+ for (int i=0; i<allMonitorModes.size(); i++) {
+ final MonitorMode mode = allMonitorModes.get(i);
+ if( mode.getId() == modeId ) {
+ supportedModes.add(mode);
+ }
+ }
+ }
+ 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;
+ }
+ private static MonitorMode getByNativeIdAndRotation(List<MonitorMode> monitorModes, int modeId, int rotation) {
+ if( null!=monitorModes && monitorModes.size()>0 ) {
+ for (int i=0; i<monitorModes.size(); i++) {
+ final MonitorMode mode = monitorModes.get(i);
+ if( mode.getId() == modeId && mode.getRotation() == rotation ) {
+ return mode;
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * WARNING: must be synchronized with ScreenMode.h, native implementation
+ * <p>
+ * This variant expects <code>count</code> to be <code>{@link MIN_MONITOR_DEVICE_PROPERTIES} - 1 - {@link NUM_MONITOR_MODE_PROPERTIES}</code>,
+ * due to lack of supported mode and current mode.
+ * </p>
+ *
+ * @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 <code>modeProperties</code>, or null if input could not be processed.
+ */
+ public static MonitorDevice streamInMonitorDevice(int[] monitor_idx, Cache cache, ScreenImpl screen, ArrayHashSet<MonitorMode> 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<MonitorMode> supportedModes = monitorDevice.getSupportedModes();
+ for(int i=0; i<supportedModes.size(); i++) {
+ data[idx++] = supportedModes.get(i).getId();
+ }
+ if(data.length != idx) {
+ throw new InternalError("wrong number of attributes: got "+idx+" != should "+data.length);
+ }
+ return data;
+ }
+
+ public final void swapRotatePair(int rotation, int[] pairs, int offset, int numPairs) {
+ if( MonitorMode.ROTATE_0 == rotation || MonitorMode.ROTATE_180 == rotation ) {
+ // nop
+ return;
+ }
+ for(int i=0; i<numPairs; i++, offset+=2) {
+ final int tmp = pairs[offset];
+ pairs[offset] = pairs[offset+1];
+ pairs[offset+1] = tmp;
+ }
+ }
+
+}
diff --git a/src/newt/classes/jogamp/newt/OffscreenWindow.java b/src/newt/classes/jogamp/newt/OffscreenWindow.java
index c6c1814f6..911d371d5 100644
--- a/src/newt/classes/jogamp/newt/OffscreenWindow.java
+++ b/src/newt/classes/jogamp/newt/OffscreenWindow.java
@@ -34,6 +34,8 @@
package jogamp.newt;
+import java.util.List;
+
import javax.media.nativewindow.AbstractGraphicsConfiguration;
import javax.media.nativewindow.AbstractGraphicsScreen;
import javax.media.nativewindow.GraphicsConfigurationFactory;
@@ -43,6 +45,8 @@ import javax.media.nativewindow.VisualIDHolder;
import javax.media.nativewindow.util.Insets;
import javax.media.nativewindow.util.Point;
+import com.jogamp.newt.MonitorDevice;
+
public class OffscreenWindow extends WindowImpl implements MutableSurface {
long surfaceHandle;
@@ -100,10 +104,15 @@ public class OffscreenWindow extends WindowImpl implements MutableSurface {
@Override
public boolean setFullscreen(boolean fullscreen) {
- // nop
- return false;
+ return false; // nop
}
+ @Override
+ public boolean setFullscreen(List<MonitorDevice> 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<ScreenModeListener> referencedScreenModeListener = new ArrayList<ScreenModeListener>();
+ private ArrayList<MonitorModeListener> referencedScreenModeListener = new ArrayList<MonitorModeListener>();
+
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 <b>rotated</b> screen size.
* <p>
- * 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.
- * </p>
- * @param virtualOrigin the store for the virtual origin
- * @param virtualSize the store for the virtual rotated size
+ * </p>
+ * <p>
+ * Default implementation uses the union of all monitor's viewport,
+ * calculated via {@link #unionOfMonitorViewportSize()}.
+ * </p>
+ * @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 <b>rotated</b> 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<ScreenMode> getScreenModes() {
- ArrayHashSet<ScreenMode> screenModes = getScreenModesOrig();
- if(null != screenModes && 0 < screenModes.size()) {
- return screenModes.toArrayList();
- }
- return null;
+ //
+ // MonitorDevice and MonitorMode
+ //
+
+ /**
+ * To be implemented by the native specification.<br>
+ * Is called within a thread safe environment.<br>
+ * Is called only to collect the {@link MonitorMode}s and {@link MonitorDevice}s, usually at startup setting up modes.<br>
+ * <br>
+ * <b>WARNING</b>: must be synchronized with
+ * <ul>
+ * <li>{@link MonitorModeProps#NUM_SCREEN_MODE_PROPERTIES} and </li>
+ * <li>{@link MonitorModeProps#MIN_MONITOR_DEVICE_PROPERTIES}</li>
+ * </ul>, i.e.
+ * <ul>
+ * <li>{@link MonitorModeProps#streamInMonitorDevice(int[], jogamp.newt.MonitorModeProps.Cache, ScreenImpl, int[], int)}</li>
+ * <li>{@link MonitorModeProps#streamInMonitorDevice(int[], jogamp.newt.MonitorModeProps.Cache, ScreenImpl, ArrayHashSet, int[], int)}</li>
+ * <li>{@link MonitorModeProps#streamInMonitorMode(int[], jogamp.newt.MonitorModeProps.Cache, int[], int)}</li>
+ * </ul>
+ * @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.<br>
+ * Is called within a thread safe environment.<br>
+ * <p>
+ * Implementation shall not unify the result w/ monitor's supported modes or a locally
+ * saved {@link MonitorModeProps.Cache}, since caller will perform such tasks.
+ * </p>
+ */
+ protected abstract MonitorMode queryCurrentMonitorModeImpl(MonitorDevice monitor);
+
+ /**
+ * To be implemented by the native specification.<br>
+ * Is called within a thread safe environment.<br>
+ */
+ protected abstract boolean setCurrentMonitorModeImpl(MonitorDevice monitor, MonitorMode mode);
+
+ @Override
+ public final List<MonitorMode> getMonitorModes() {
+ final ScreenMonitorState sms = getScreenMonitorStatus(false);
+ return null != sms ? sms.getMonitorModes().getData() : null;
+ }
+
+ @Override
+ public final List<MonitorDevice> 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<referencedScreenModeListener.size(); i++) {
+ ((MonitorModeListener)referencedScreenModeListener.get(i)).monitorModeChangeNotify(me);
}
- return smU;
}
- public boolean setCurrentScreenMode(ScreenMode screenMode) {
- final ScreenMode smC = getCurrentScreenMode();
- ScreenMode smU = getScreenModesOrig().get(screenMode); // unify via value hash
- if(smU.equals(smC)) {
- if(DEBUG) {
- System.err.println("Screen.setCurrentScreenMode ("+(System.nanoTime()-tCreated)+"): 0.0 is-current (skip) "+smU+" == "+smC);
- }
- return true;
- }
- ScreenModeStatus sms = ScreenModeStatus.getScreenModeStatus(this.getFQName());
- if(null == sms) {
- throw new InternalError("ScreenModeStatus.getScreenModeStatus("+this.getFQName()+") == null");
- }
- boolean success;
- sms.lock();
- try {
- final long tStart;
- if(DEBUG) {
- tStart = System.nanoTime();
- } else {
- tStart = 0;
+ private void updateNativeMonitorDevicesViewport() {
+ final List<MonitorDevice> 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<referencedScreenModeListener.size(); i++) {
- ((ScreenModeListener)referencedScreenModeListener.get(i)).screenModeChangeNotify(sm);
- }
- }
-
- public void screenModeChanged(ScreenMode sm, boolean success) {
+
+ @Override
+ public void monitorModeChanged(MonitorEvent me, boolean success) {
if(success) {
+ updateNativeMonitorDevicesViewport();
updateVirtualScreenOriginAndSize();
}
+ if(DEBUG) {
+ System.err.println("monitorModeChanged: success "+success+", "+me);
+ }
for(int i=0; i<referencedScreenModeListener.size(); i++) {
- ((ScreenModeListener)referencedScreenModeListener.get(i)).screenModeChanged(sm, success);
+ ((MonitorModeListener)referencedScreenModeListener.get(i)).monitorModeChanged(me, success);
}
}
- public synchronized final void addScreenModeListener(ScreenModeListener sml) {
+ @Override
+ public synchronized final void addMonitorModeListener(MonitorModeListener sml) {
referencedScreenModeListener.add(sml);
}
- public synchronized final void removeScreenModeListener(ScreenModeListener sml) {
+ @Override
+ public synchronized final void removeMonitorModeListener(MonitorModeListener sml) {
referencedScreenModeListener.remove(sml);
}
-
- /** ScreenModeStatus bridge to native implementation */
- protected final ArrayHashSet<ScreenMode> getScreenModesOrig() {
- ScreenModeStatus sms = ScreenModeStatus.getScreenModeStatus(this.getFQName());
- if(null!=sms) {
- return sms.getScreenModes();
- }
- return null;
- }
-
- /** ScreenModeStatus bridge to native implementation */
- protected final IntIntHashMap getScreenModesIdx2NativeIdx() {
- ScreenModeStatus sms = ScreenModeStatus.getScreenModeStatus(this.getFQName());
- if(null!=sms) {
- return sms.getScreenModesIdx2NativeIdx();
- }
- return null;
- }
-
- /**
- * To be implemented by the native specification.<br>
- * Is called within a thread safe environment.<br>
- * Is called only to collect the ScreenModes, usually at startup setting up modes.<br>
- * <br>
- * <b>WARNING</b>: must be synchronized with {@link com.jogamp.newt.util.ScreenModeUtil#NUM_SCREEN_MODE_PROPERTIES},
- * ie {@link com.jogamp.newt.util.ScreenModeUtil#streamIn(com.jogamp.common.util.ArrayHashSet, com.jogamp.common.util.ArrayHashSet, com.jogamp.common.util.ArrayHashSet, com.jogamp.common.util.ArrayHashSet, int[], int)}<br>
- * <br>
- * <b>Note</b>: Additional 1st element is native mode id.
- */
- protected int[] getScreenModeFirstImpl() {
- return null;
- }
-
- /**
- * To be implemented by the native specification.<br>
- * Is called within a thread safe environment.<br>
- * Is called only to collect the ScreenModes, usually at startup setting up modes.<br>
- * <br>
- * <b>WARNING</b>: must be synchronized with {@link com.jogamp.newt.util.ScreenModeUtil#NUM_SCREEN_MODE_PROPERTIES},
- * ie {@link com.jogamp.newt.util.ScreenModeUtil#streamIn(com.jogamp.common.util.ArrayHashSet, com.jogamp.common.util.ArrayHashSet, com.jogamp.common.util.ArrayHashSet, com.jogamp.common.util.ArrayHashSet, int[], int)}<br>
- * <br>
- * <b>Note</b>: Additional 1st element is native mode id.
- */
- protected int[] getScreenModeNextImpl() {
- return null;
+
+ 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.<br>
- * Is called within a thread safe environment.<br>
- */
- 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.<br>
- * Is called within a thread safe environment.<br>
- */
- 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<ScreenMode> screenModes = collectNativeScreenModes(screenModesIdx2NativeIdx);
- screenModes.getOrAdd(currentSM);
if(DEBUG) {
int i=0;
- for(Iterator<ScreenMode> iter=screenModes.iterator(); iter.hasNext(); i++) {
- System.err.println(i+": "+iter.next());
+ for(Iterator<MonitorMode> iMode=cache.monitorModes.iterator(); iMode.hasNext(); i++) {
+ System.err.println("All["+i+"]: "+iMode.next());
+ }
+ i=0;
+ for(Iterator<MonitorDevice> iMonitor=cache.monitorDevices.iterator(); iMonitor.hasNext(); i++) {
+ final MonitorDevice crt = iMonitor.next();
+ System.err.println("["+i+"]: "+crt);
+ int j=0;
+ for(Iterator<MonitorMode> 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<ScreenMode> collectNativeScreenModes(IntIntHashMap screenModesIdx2NativeId) {
- ArrayHashSet<DimensionImmutable> resolutionPool = new ArrayHashSet<DimensionImmutable>();
- ArrayHashSet<SurfaceSize> surfaceSizePool = new ArrayHashSet<SurfaceSize>();
- ArrayHashSet<DimensionImmutable> screenSizeMMPool = new ArrayHashSet<DimensionImmutable>();
- ArrayHashSet<MonitorMode> monitorModePool = new ArrayHashSet<MonitorMode>();
- ArrayHashSet<ScreenMode> screenModePool = new ArrayHashSet<ScreenMode>();
-
- 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.
+ * <p>
+ * Collects {@link MonitorDevice}s and {@link MonitorMode}s within the given cache.
+ * </p>
+ */
+ 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<MonitorDevice> monitorDevices = sms.getMonitorDevices().getData();
+ for(int i=0; i<monitorDevices.size(); i++) {
+ final MonitorDevice monitor = monitorDevices.get(i);
+ if( monitor.isModeChangedByUs() ) {
+ System.err.println("Screen.destroy(): Reset "+monitor);
+ try {
+ monitor.setCurrentMode(monitor.getOriginalMode());
+ } catch (Throwable t) {
+ // be verbose but continue
+ t.printStackTrace();
+ }
}
}
- ScreenModeStatus.unmapScreenModeStatus(getFQName());
+ ScreenMonitorState.unmapScreenMonitorState(getFQName());
}
} finally {
sms.unlock();
}
}
} finally {
- ScreenModeStatus.unlockScreenModeStatus();
+ ScreenMonitorState.unlockScreenMonitorState();
}
}
private final void shutdown() {
- ScreenModeStatus sms = ScreenModeStatus.getScreenModeStatusUnlocked(getFQName());
+ ScreenMonitorState sms = ScreenMonitorState.getScreenMonitorStateUnlocked(getFQName());
if(null != sms) {
- if(sms.isOriginalModeChangedByOwner()) {
- try {
- System.err.println("Screen.shutdown(): "+sms.getCurrentScreenMode()+" -> "+sms.getOriginalScreenMode());
- setCurrentScreenModeImpl(sms.getOriginalScreenMode());
- } catch (Throwable t) {
- // be quiet .. shutdown
+ final ArrayList<MonitorDevice> monitorDevices = sms.getMonitorDevices().getData();
+ for(int i=0; i<monitorDevices.size(); i++) {
+ final MonitorDevice monitor = monitorDevices.get(i);
+ if( monitor.isModeChangedByUs() ) {
+ System.err.println("Screen.shutdown(): Reset "+monitor);
+ try {
+ monitor.setCurrentMode(monitor.getOriginalMode());
+ } catch (Throwable t) {
+ // be quiet .. shutdown
+ }
}
}
- ScreenModeStatus.unmapScreenModeStatusUnlocked(getFQName());
+ ScreenMonitorState.unmapScreenMonitorStateUnlocked(getFQName());
}
}
private static final void shutdownAll() {
@@ -688,5 +666,4 @@ public abstract class ScreenImpl extends Screen implements ScreenModeListener {
}
});
}
-}
-
+} \ No newline at end of file
diff --git a/src/newt/classes/jogamp/newt/ScreenModeStatus.java b/src/newt/classes/jogamp/newt/ScreenModeStatus.java
deleted file mode 100644
index 4075fb131..000000000
--- a/src/newt/classes/jogamp/newt/ScreenModeStatus.java
+++ /dev/null
@@ -1,231 +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 jogamp.newt;
-
-import com.jogamp.common.util.ArrayHashSet;
-import com.jogamp.common.util.IntIntHashMap;
-import com.jogamp.common.util.locks.LockFactory;
-import com.jogamp.common.util.locks.RecursiveLock;
-import com.jogamp.newt.Screen;
-import com.jogamp.newt.ScreenMode;
-import com.jogamp.newt.event.ScreenModeListener;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-
-public class ScreenModeStatus {
- private static boolean DEBUG = Screen.DEBUG;
-
- private RecursiveLock lock = LockFactory.createRecursiveLock();
- private ArrayHashSet<ScreenMode> screenModes;
- private IntIntHashMap screenModesIdx2NativeIdx;
- private ScreenMode currentScreenMode;
- private ScreenMode originalScreenMode;
- private boolean screenModeChangedByOwner;
- private ArrayList<ScreenModeListener> listener = new ArrayList<ScreenModeListener>();
-
- private static HashMap<String, ScreenModeStatus> screenFQN2ScreenModeStatus = new HashMap<String, ScreenModeStatus>();
- 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<ScreenMode> 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.
- * <p>
- * At least we only return <code>true</true> if the owner, ie. the Screen,
- * has changed the screen mode and if the original screen mode
- * is not current the current one.
- * </p>
- * @return
- */
- public final boolean isOriginalModeChangedByOwner() {
- lock();
- try {
- return screenModeChangedByOwner && !isCurrentModeOriginalMode();
- } finally {
- unlock();
- }
- }
-
- protected final boolean isCurrentModeOriginalMode() {
- if(null != currentScreenMode && null != originalScreenMode) {
- return currentScreenMode.hashCode() == originalScreenMode.hashCode();
- }
- return true;
- }
-
- protected final ArrayHashSet<ScreenMode> getScreenModes() {
- return screenModes;
- }
-
- protected final IntIntHashMap getScreenModesIdx2NativeIdx() {
- return screenModesIdx2NativeIdx;
- }
-
- protected final int addListener(ScreenModeListener l) {
- lock();
- try {
- listener.add(l);
- if(DEBUG) {
- System.err.println("ScreenModeStatus.addListener (size: "+listener.size()+"): "+l);
- }
- return listener.size();
- } finally {
- unlock();
- }
- }
-
- protected final int removeListener(ScreenModeListener l) {
- lock();
- try {
- if(!listener.remove(l)) {
- throw new RuntimeException("ScreenModeListener "+l+" not contained");
- }
- if(DEBUG) {
- System.err.println("ScreenModeStatus.removeListener (size: "+listener.size()+"): "+l);
- }
- return listener.size();
- } finally {
- unlock();
- }
- }
-
- protected final void fireScreenModeChangeNotify(ScreenMode desiredScreenMode) {
- lock();
- try {
- for(int i=0; i<listener.size(); i++) {
- listener.get(i).screenModeChangeNotify(desiredScreenMode);
- }
- } finally {
- unlock();
- }
- }
-
- protected void fireScreenModeChanged(ScreenMode currentScreenMode, boolean success) {
- lock();
- try {
- if(success) {
- this.currentScreenMode = currentScreenMode;
- this.screenModeChangedByOwner = !isCurrentModeOriginalMode();
- }
- for(int i=0; i<listener.size(); i++) {
- listener.get(i).screenModeChanged(currentScreenMode, success);
- }
- } finally {
- unlock();
- }
- }
-
- protected final void lock() throws RuntimeException {
- lock.lock();
- }
-
- protected final void unlock() throws RuntimeException {
- lock.unlock();
- }
-}
diff --git a/src/newt/classes/jogamp/newt/ScreenMonitorState.java b/src/newt/classes/jogamp/newt/ScreenMonitorState.java
new file mode 100644
index 000000000..beeb7b922
--- /dev/null
+++ b/src/newt/classes/jogamp/newt/ScreenMonitorState.java
@@ -0,0 +1,195 @@
+/**
+ * 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.common.util.locks.LockFactory;
+import com.jogamp.common.util.locks.RecursiveLock;
+import com.jogamp.newt.MonitorDevice;
+import com.jogamp.newt.Screen;
+import com.jogamp.newt.MonitorMode;
+import com.jogamp.newt.event.MonitorEvent;
+import com.jogamp.newt.event.MonitorModeListener;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+public class ScreenMonitorState {
+ private static boolean DEBUG = Screen.DEBUG;
+
+ private final RecursiveLock lock = LockFactory.createRecursiveLock();
+ private final ArrayHashSet<MonitorDevice> allMonitors;
+ private final ArrayHashSet<MonitorMode> allMonitorModes;
+ private ArrayList<MonitorModeListener> listener = new ArrayList<MonitorModeListener>();
+
+ private static HashMap<String, ScreenMonitorState> screenFQN2ScreenMonitorState = new HashMap<String, ScreenMonitorState>();
+ 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<MonitorDevice> allMonitors,
+ ArrayHashSet<MonitorMode> allMonitorModes) {
+ this.allMonitors = allMonitors;
+ this.allMonitorModes = allMonitorModes;
+ }
+
+ protected ArrayHashSet<MonitorDevice> getMonitorDevices() {
+ return allMonitors;
+ }
+
+ protected ArrayHashSet<MonitorMode> 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<listener.size(); i++) {
+ listener.get(i).monitorModeChangeNotify(me);
+ }
+ } finally {
+ unlock();
+ }
+ }
+
+ protected void fireScreenModeChanged(MonitorDevice monitor, MonitorMode currentMode, boolean success) {
+ lock();
+ try {
+ validateMonitor(monitor);
+ final MonitorEvent me = new MonitorEvent(MonitorEvent.EVENT_MONITOR_MODE_CHANGE_NOTIFY, monitor, System.currentTimeMillis(), currentMode);
+ for(int i=0; i<listener.size(); i++) {
+ listener.get(i).monitorModeChanged(me, success);
+ }
+ } finally {
+ unlock();
+ }
+ }
+
+ protected final void lock() throws RuntimeException {
+ lock.lock();
+ }
+
+ protected final void unlock() throws RuntimeException {
+ lock.unlock();
+ }
+}
diff --git a/src/newt/classes/jogamp/newt/WindowImpl.java b/src/newt/classes/jogamp/newt/WindowImpl.java
index bfb450f68..3a018d231 100644
--- a/src/newt/classes/jogamp/newt/WindowImpl.java
+++ b/src/newt/classes/jogamp/newt/WindowImpl.java
@@ -35,25 +35,27 @@
package jogamp.newt;
import java.util.ArrayList;
+import java.util.List;
import java.lang.reflect.Method;
import com.jogamp.common.util.IntBitfield;
import com.jogamp.common.util.ReflectionUtil;
+import com.jogamp.newt.MonitorDevice;
import com.jogamp.newt.NewtFactory;
import com.jogamp.newt.Display;
import com.jogamp.newt.Screen;
import com.jogamp.newt.Window;
import com.jogamp.common.util.locks.LockFactory;
import com.jogamp.common.util.locks.RecursiveLock;
-import com.jogamp.newt.ScreenMode;
import com.jogamp.newt.event.InputEvent;
import com.jogamp.newt.event.KeyEvent;
import com.jogamp.newt.event.KeyListener;
+import com.jogamp.newt.event.MonitorEvent;
import com.jogamp.newt.event.MouseEvent;
import com.jogamp.newt.event.MouseListener;
import com.jogamp.newt.event.NEWTEvent;
import com.jogamp.newt.event.NEWTEventConsumer;
-import com.jogamp.newt.event.ScreenModeListener;
+import com.jogamp.newt.event.MonitorModeListener;
import com.jogamp.newt.event.WindowEvent;
import com.jogamp.newt.event.WindowListener;
import com.jogamp.newt.event.WindowUpdateEvent;
@@ -68,11 +70,11 @@ import javax.media.nativewindow.NativeWindowException;
import javax.media.nativewindow.NativeWindowFactory;
import javax.media.nativewindow.SurfaceUpdatedListener;
import javax.media.nativewindow.WindowClosingProtocol;
-import javax.media.nativewindow.util.DimensionImmutable;
import javax.media.nativewindow.util.Insets;
import javax.media.nativewindow.util.InsetsImmutable;
import javax.media.nativewindow.util.Point;
import javax.media.nativewindow.util.Rectangle;
+import javax.media.nativewindow.util.RectangleImmutable;
import jogamp.nativewindow.SurfaceUpdatedHelper;
@@ -103,7 +105,9 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
private AbstractGraphicsConfiguration config = null; // control access due to delegation
protected CapabilitiesImmutable capsRequested = null;
protected CapabilitiesChooser capabilitiesChooser = null; // default null -> default
- private boolean fullscreen = false, brokenFocusChange = false;
+ private boolean fullscreen = false, brokenFocusChange = false;
+ private List<MonitorDevice> 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<MonitorDevice> monitors;
+ boolean useMainMonitor;
- private boolean init(boolean fullscreen) {
+ private boolean init(boolean fullscreen, boolean useMainMonitor, List<MonitorDevice> 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<MonitorDevice>();
+ 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<MonitorDevice> monitors) {
+ return setFullscreenImpl(true, false, monitors);
+ }
+
+ private boolean setFullscreenImpl(boolean fullscreen, boolean useMainMonitor, List<MonitorDevice> 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 <code>timeOut</code>, 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<sleep && this.visible != visible; sleep-=10 ) {
+ long remaining;
+ for(remaining = timeOut; 0<remaining && this.visible != visible; remaining-=10 ) {
try { Thread.sleep(10); } catch (InterruptedException ie) {}
display.dispatchMessagesNative(); // status up2date
}
@@ -2582,9 +2668,11 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
System.err.println(msg);
Thread.dumpStack();
}
- return false;
+ return -1;
+ } else if( 0 < remaining ){
+ return remaining;
} else {
- return true;
+ return 0;
}
}
@@ -2648,6 +2736,47 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
/**
+ * Wait until position is reached within tolerances, either auto-position or custom position.
+ * <p>
+ * 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.
+ * </p>
+ */
+ 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 ( 0<remaining && !ok );
+ if (DEBUG_IMPLEMENTATION) {
+ if( !ok ) {
+ if( useCustomPosition ) {
+ System.err.println("Custom position "+x+"/"+y+" not reached within timeout, has "+getX()+"/"+getY()+", remaining "+remaining);
+ } else {
+ System.err.println("Auto position not reached within timeout, has "+getX()+"/"+getY()+", autoPosition "+autoPosition+", remaining "+remaining);
+ }
+ Thread.dumpStack();
+ }
+ }
+ return ok;
+ }
+
+ /**
* Triggered by implementation's WM events to update the insets.
*
* @see #getInsets()
diff --git a/src/newt/classes/jogamp/newt/driver/android/ScreenDriver.java b/src/newt/classes/jogamp/newt/driver/android/ScreenDriver.java
index aee372f01..cc35ff710 100644
--- a/src/newt/classes/jogamp/newt/driver/android/ScreenDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/android/ScreenDriver.java
@@ -29,8 +29,9 @@
package jogamp.newt.driver.android;
import javax.media.nativewindow.DefaultGraphicsScreen;
-import javax.media.nativewindow.util.Dimension;
-import javax.media.nativewindow.util.Point;
+
+import jogamp.newt.MonitorModeProps;
+import jogamp.newt.MonitorModeProps.Cache;
import android.content.Context;
import android.graphics.PixelFormat;
@@ -38,8 +39,8 @@ import android.util.DisplayMetrics;
import android.view.Surface;
import android.view.WindowManager;
-import com.jogamp.newt.ScreenMode;
-import com.jogamp.newt.util.ScreenModeUtil;
+import com.jogamp.newt.MonitorDevice;
+import com.jogamp.newt.MonitorMode;
public class ScreenDriver extends jogamp.newt.ScreenImpl {
@@ -50,13 +51,36 @@ public class ScreenDriver extends jogamp.newt.ScreenImpl {
public ScreenDriver() {
}
+ @Override
protected void createNativeImpl() {
aScreen = new DefaultGraphicsScreen(getDisplay().getGraphicsDevice(), screen_idx);
}
+ @Override
protected void closeNativeImpl() { }
- protected ScreenMode getCurrentScreenModeImpl() {
+ @Override
+ protected int validateScreenIndex(int idx) {
+ return 0; // FIXME: only one screen available ?
+ }
+
+ private final MonitorMode getModeImpl(final Cache cache, final android.view.Display aDisplay, DisplayMetrics outMetrics, int modeIdx, int screenSizeNRot, int nrot) {
+ final int[] props = new int[MonitorModeProps.NUM_MONITOR_MODE_PROPERTIES_ALL];
+ int i = 0;
+ props[i++] = MonitorModeProps.NUM_MONITOR_MODE_PROPERTIES_ALL;
+ i = getScreenSize(outMetrics, screenSizeNRot, props, i); // width, height
+ i = getBpp(aDisplay, props, i); // bpp
+ props[i++] = (int) ( aDisplay.getRefreshRate() * 100.0f ); // Hz * 100
+ props[i++] = 0; // flags
+ props[i++] = modeIdx; // modeId;
+ props[i++] = nrot;
+ return MonitorModeProps.streamInMonitorMode(null, cache, props, 0);
+ }
+
+ @Override
+ protected void collectNativeMonitorModesAndDevicesImpl(Cache cache) {
+ // FIXME: Multi Monitor Implementation missing [for newer Android version ?]
+
final Context ctx = jogamp.common.os.android.StaticContext.getContext();
final WindowManager wmgr = (WindowManager) ctx.getSystemService(Context.WINDOW_SERVICE);
final DisplayMetrics outMetrics = new DisplayMetrics();
@@ -65,27 +89,44 @@ public class ScreenDriver extends jogamp.newt.ScreenImpl {
final int arot = aDisplay.getRotation();
final int nrot = androidRotation2NewtRotation(arot);
- int[] props = new int[ScreenModeUtil.NUM_SCREEN_MODE_PROPERTIES_ALL];
- int offset = 1; // set later for verification of iterator
- offset = getScreenSize(outMetrics, nrot, props, offset);
- offset = getBpp(aDisplay, props, offset);
- offset = getScreenSizeMM(outMetrics, props, offset);
- props[offset++] = (int) aDisplay.getRefreshRate();
- props[offset++] = nrot;
- props[offset - ScreenModeUtil.NUM_SCREEN_MODE_PROPERTIES_ALL] = offset; // count
- return ScreenModeUtil.streamIn(props, 0);
+
+ final int modeIdx=0; // no native modeId in use - use 0
+ MonitorMode currentMode = null;
+ for(int r=0; r<4; r++) { // for all rotations
+ final int nrot_i = r*MonitorMode.ROTATE_90;
+ MonitorMode mode = getModeImpl(cache, aDisplay, outMetrics, modeIdx, 0, nrot_i);
+ if( nrot == nrot_i ) {
+ currentMode = mode;
+ }
+ }
+
+ final int[] props = new int[MonitorModeProps.MIN_MONITOR_DEVICE_PROPERTIES - 1 - MonitorModeProps.NUM_MONITOR_MODE_PROPERTIES];
+ int i = 0;
+ props[i++] = props.length;
+ props[i++] = 0; // crt_idx
+ i = getScreenSizeMM(outMetrics, props, i); // sizeMM
+ props[i++] = 0; // rotated viewport x
+ props[i++] = 0; // rotated viewport y
+ props[i++] = outMetrics.widthPixels; // rotated viewport width
+ props[i++] = outMetrics.heightPixels; // rotated viewport height
+ MonitorModeProps.streamInMonitorDevice(null, cache, this, cache.monitorModes, currentMode, props, 0);
}
-
- protected int validateScreenIndex(int idx) {
- return 0; // FIXME: only one screen available ?
+
+ @Override
+ protected MonitorMode queryCurrentMonitorModeImpl(MonitorDevice monitor) {
+ final Context ctx = jogamp.common.os.android.StaticContext.getContext();
+ final WindowManager wmgr = (WindowManager) ctx.getSystemService(Context.WINDOW_SERVICE);
+ final DisplayMetrics outMetrics = new DisplayMetrics();
+ final android.view.Display aDisplay = wmgr.getDefaultDisplay();
+ aDisplay.getMetrics(outMetrics);
+
+ final int currNRot = androidRotation2NewtRotation(aDisplay.getRotation());
+ return getModeImpl(null, aDisplay, outMetrics, 0, currNRot, currNRot);
}
-
- protected void getVirtualScreenOriginAndSize(Point virtualOrigin, Dimension virtualSize) {
- virtualOrigin.setX(0);
- virtualOrigin.setY(0);
- final ScreenMode sm = getCurrentScreenMode();
- virtualSize.setWidth(sm.getRotatedWidth());
- virtualSize.setHeight(sm.getRotatedHeight());
+
+ @Override
+ protected boolean setCurrentMonitorModeImpl(MonitorDevice monitor, MonitorMode mode) {
+ return false;
}
//----------------------------------------------------------------------
@@ -93,16 +134,16 @@ public class ScreenDriver extends jogamp.newt.ScreenImpl {
//
static int androidRotation2NewtRotation(int arot) {
switch(arot) {
- case Surface.ROTATION_270: return ScreenMode.ROTATE_270;
- case Surface.ROTATION_180: return ScreenMode.ROTATE_180;
- case Surface.ROTATION_90: return ScreenMode.ROTATE_90;
+ case Surface.ROTATION_270: return MonitorMode.ROTATE_270;
+ case Surface.ROTATION_180: return MonitorMode.ROTATE_180;
+ case Surface.ROTATION_90: return MonitorMode.ROTATE_90;
case Surface.ROTATION_0:
}
- return ScreenMode.ROTATE_0;
+ return MonitorMode.ROTATE_0;
}
static int getScreenSize(DisplayMetrics outMetrics, int nrot, int[] props, int offset) {
// swap width and height, since Android reflects rotated dimension, we don't
- if (ScreenMode.ROTATE_90 == nrot || ScreenMode.ROTATE_270 == nrot) {
+ if (MonitorMode.ROTATE_90 == nrot || MonitorMode.ROTATE_270 == nrot) {
props[offset++] = outMetrics.heightPixels;
props[offset++] = outMetrics.widthPixels;
} else {
diff --git a/src/newt/classes/jogamp/newt/driver/android/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/android/WindowDriver.java
index 6f78a6f6b..803c7e1de 100644
--- a/src/newt/classes/jogamp/newt/driver/android/WindowDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/android/WindowDriver.java
@@ -41,14 +41,14 @@ import javax.media.nativewindow.NativeWindowException;
import javax.media.nativewindow.VisualIDHolder;
import javax.media.nativewindow.util.Insets;
import javax.media.nativewindow.util.Point;
+import javax.media.nativewindow.util.RectangleImmutable;
import javax.media.opengl.GLCapabilitiesChooser;
import javax.media.opengl.GLCapabilitiesImmutable;
import javax.media.opengl.GLException;
import com.jogamp.common.os.AndroidVersion;
import com.jogamp.nativewindow.egl.EGLGraphicsDevice;
-import com.jogamp.newt.Screen;
-import com.jogamp.newt.ScreenMode;
+import com.jogamp.newt.MonitorDevice;
import jogamp.opengl.egl.EGL;
import jogamp.opengl.egl.EGLDisplayUtil;
@@ -285,10 +285,10 @@ public class WindowDriver extends jogamp.newt.WindowImpl implements Callback2 {
}
if( isFullscreen() ) {
- final Screen screen = getScreen();
- final ScreenMode sm = screen.getCurrentScreenMode();
- definePosition(screen.getX(), screen.getY());
- defineSize(sm.getRotatedWidth(), sm.getRotatedHeight());
+ final MonitorDevice mainMonitor = getMainMonitor();
+ final RectangleImmutable viewport = mainMonitor.getViewport();
+ definePosition(viewport.getX(), viewport.getY());
+ defineSize(viewport.getWidth(), viewport.getHeight());
}
final boolean b;
@@ -562,7 +562,9 @@ public class WindowDriver extends jogamp.newt.WindowImpl implements Callback2 {
surface=null;
}
if(getScreen().isNativeValid()) {
- getScreen().getCurrentScreenMode(); // if ScreenMode changed .. trigger ScreenMode event
+ // if ScreenMode changed .. trigger ScreenMode event
+ final MonitorDevice mainMonitor = getMainMonitor();
+ mainMonitor.queryCurrentMode();
}
if(0>getX() || 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/*<int, DimensionImmutable>*/ 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<MonitorMode> supportedModes = new ArrayHashSet<MonitorMode>();
+ 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<MonitorMode>();
+ 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<ScreenMode> 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<MonitorMode> supportedModes = new ArrayHashSet<MonitorMode>();
+ 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<MonitorMode>();
+ }
+ }
+ 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:
+ * <ul>
+ * <li>{@link #getMonitorDeviceCount(long, ScreenDriver)}</li>
+ * <li>{@link #getAvailableRotations(long, ScreenDriver, int)}</li>
+ * <li>{@link #getMonitorModeProps(long, ScreenDriver, int)}</li>
+ * <li>{@link #getCurrentMonitorModeProps(long, ScreenDriver, int)</li>
+ * <li>{@link #getMonitorDeviceProps(long, ScreenDriver, List, int, MonitorMode)}</li>
+ * </ul>
+ * <p>
+ * Above methods may be called w/o begin/end, in which case no
+ * internal data structures can be cached:
+ * </p>
+ * @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<resolutionCount; i++) {
+ nrates[i] = getScreenRates0(dpy, screen_idx, i);
+ if(null==nrates[i] || 0==nrates[i].length) {
+ endInitialQuery(dpy, screen);
+ return false;
+ }
}
- nres_index = 0;
+
+ for(int nresIdx=0; nresIdx < resolutionCount; nresIdx++) {
+ modeCount += nrates[nresIdx].length;
+ }
+
+ idx_rate = new int[modeCount];
+ idx_res = new int[modeCount];
- nrates = getScreenModeRates0(dpy, screen_idx, nres_index);
- if(null==nrates || 0==nrates.length) {
+ int modeIdx=0;
+ for(int nresIdx=0; nresIdx < resolutionCount; nresIdx++) {
+ for(int nrateIdx=0; nrateIdx < nrates[nresIdx].length; nrateIdx++) {
+ idx_rate[modeIdx] = nrateIdx;
+ idx_res[modeIdx] = nresIdx;
+ modeIdx++;
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public void endInitialQuery(long dpy, ScreenDriver screen) {
+ idx_rate=null;
+ idx_res=null;
+ nrates=null;
+ }
+
+ @Override
+ public int getMonitorDeviceCount(final long dpy, final ScreenDriver screen) {
+ return 1;
+ }
+
+ @Override
+ public int[] getAvailableRotations(final long dpy, final ScreenDriver screen, final int crt_idx) {
+ if( 0 < crt_idx ) {
+ // RandR11 only supports 1 CRT
return null;
}
- nrate_index = 0;
-
- nmode_number = 0;
-
- return getScreenModeNextImpl(dpy, screen_idx);
+ final int screen_idx = screen.getIndex();
+ final int[] availRotations = getAvailableScreenRotations0(dpy, screen_idx);
+ if(null==availRotations || 0==availRotations.length) {
+ return null;
+ }
+ return availRotations;
}
-
+
@Override
- public int[] getScreenModeNextImpl(final long dpy, final int screen_idx) {
- /**
- System.err.println("******** mode: "+nmode_number);
- System.err.println("rot "+nrotation_index);
- System.err.println("rate "+nrate_index);
- System.err.println("res "+nres_index); */
-
- int[] res = getScreenModeResolution0(dpy, screen_idx, nres_index);
+ public int[] getMonitorModeProps(final long dpy, final ScreenDriver screen, final int mode_idx) {
+ if( mode_idx >= 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; j<allModesCount; j++) {
+ props[i++] = cache.monitorModes.get(j).getId();
}
-
return props;
}
+
+ @Override
+ public int[] getMonitorDeviceViewport(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;
+ final int nres_idx;
+ try {
+ int resNumber = getNumScreenResolutions0(dpy, screen_idx);
+ if(0==resNumber) {
+ return null;
+ }
+ nres_idx = getCurrentScreenResolutionIndex0(screenConfigHandle);
+ if(0>nres_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:
+ * <pre>
+ * MonitorMode.id == XRR mode-id (not index)
+ * MonitorDevice.id == XRR monitor-idx (not id)
+ * </pre>
+ */
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<IntLongHashMap.Entry> 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<MonitorDevice> monitors = screen.getMonitorDevices();
+ final ArrayList<RectangleImmutable> viewports = new ArrayList<RectangleImmutable>();
+ for(int i=0; i<monitors.size(); i++) {
+ final MonitorDevice crt = monitors.get(i);
+ if( crt.getId() != monitor.getId() ) {
+ System.err.println("XXX setScreenViewport: add.pre["+i+"]: "+crt.getViewport());
+ viewports.add( crt.getViewport() ) ;
+ } else {
+ System.err.println("XXX setScreenViewport: add.new["+i+"]: "+newViewp);
+ viewports.add( newViewp );
+ }
+ }
+ final RectangleImmutable newScrnViewp = new Rectangle().union(viewports);
+ System.err.println("XXX setScreenViewport: "+screen.getViewport()+" -> "+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<Long>() {
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<int[]>() {
- 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<Integer> availableRotations = new ArrayHashSet<Integer>();
+ for(int i = 0; i < crtCount; i++) {
+ final int[] rotations = rAndR.getAvailableRotations(device.getHandle(), this, i);
+ if( null != rotations ) {
+ final List<Integer> rotationList = new ArrayList<Integer>(rotations.length);
+ for(int j=0; j<rotations.length; j++ ) { rotationList.add(rotations[j]); }
+ availableRotations.addAll(rotationList);
+ }
+ }
+
+ // collect all modes, while injecting all available rotations
+ {
+ int modeIdx = 0;
+ int[] props;
+ do {
+ props = rAndR.getMonitorModeProps(device.getHandle(), this, modeIdx++);
+ if( null != props ) {
+ for(int i = 0; i < availableRotations.size(); i++) {
+ props[MonitorModeProps.IDX_MONITOR_MODE_ROT] = availableRotations.get(i);
+ MonitorModeProps.streamInMonitorMode(null, cache, props, 0);
+ }
+ }
+ } while( null != props);
+ }
+ if( cache.monitorModes.size() > 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<int[]>() {
- 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<ScreenMode>() {
- public ScreenMode run(long dpy) {
- return rAndR.getCurrentScreenModeImpl(dpy, screen_idx);
+ return runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable<MonitorMode>() {
+ 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<ScreenMode> 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<Boolean>() {
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<Object>() {
public Object run(long dpy) {
- virtualOrigin.setX(0);
- virtualOrigin.setY(0);
- virtualSize.setWidth(getWidth0(dpy, screen_idx));
- virtualSize.setHeight(getHeight0(dpy, screen_idx));
+ vOriginSize.setX(0);
+ vOriginSize.setY(0);
+ vOriginSize.setWidth(getWidth0(dpy, screen_idx));
+ vOriginSize.setHeight(getHeight0(dpy, screen_idx));
return null;
} } );
}
diff --git a/src/newt/native/MacWindow.m b/src/newt/native/MacWindow.m
index c0552216e..1c7064a66 100644
--- a/src/newt/native/MacWindow.m
+++ b/src/newt/native/MacWindow.m
@@ -285,47 +285,32 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_DisplayDriver_stopNSApplic
[pool release];
}
-static NSScreen * NewtScreen_getNSScreenByIndex(int screen_idx) {
+static NSScreen * NewtScreen_getNSScreenByIndex(int screen_idx, BOOL cap) {
NSArray *screens = [NSScreen screens];
- if(screen_idx<0) screen_idx=0;
- if(screen_idx>=[screens count]) screen_idx=0;
+ if( screen_idx<0 || screen_idx>=[screens count] ) {
+ if( cap ) {
+ screen_idx=0;
+ } else {
+ return NULL;
+ }
+ }
return (NSScreen *) [screens objectAtIndex: screen_idx];
}
-/*
- * Class: jogamp_newt_driver_macosx_ScreenDriver
- * Method: getWidthImpl
- * Signature: (I)I
- */
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_macosx_ScreenDriver_getWidthImpl0
- (JNIEnv *env, jclass clazz, jint screen_idx)
-{
- NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
-
- NSScreen *screen = NewtScreen_getNSScreenByIndex((int)screen_idx);
- NSRect rect = [screen frame];
-
- [pool release];
-
- return (jint) (rect.size.width);
-}
-
-/*
- * Class: jogamp_newt_driver_macosx_ScreenDriver
- * Method: getHeightImpl
- * Signature: (I)I
- */
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_macosx_ScreenDriver_getHeightImpl0
- (JNIEnv *env, jclass clazz, jint screen_idx)
-{
- NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
-
- NSScreen *screen = NewtScreen_getNSScreenByIndex((int)screen_idx);
- NSRect rect = [screen frame];
-
- [pool release];
-
- return (jint) (rect.size.height);
+static NSScreen * NewtScreen_getNSScreenByCoord(int x, int y) {
+ NSArray *screens = [NSScreen screens];
+ int i;
+ for(i=[screens count]-1; i>=0; i--) {
+ NSScreen * screen = (NSScreen *) [screens objectAtIndex: i];
+ NSRect frame = [screen frame];
+ if( x >= frame.origin.x &&
+ y >= frame.origin.y &&
+ x < frame.origin.x + frame.size.width &&
+ y < frame.origin.y + frame.size.height ) {
+ return screen;
+ }
+ }
+ return (NSScreen *) [screens objectAtIndex: 0];
}
static CGDirectDisplayID NewtScreen_getCGDirectDisplayIDByNSScreen(NSScreen *screen) {
@@ -362,11 +347,11 @@ static long GetDictionaryLong(CFDictionaryRef theDict, const void* key)
/*
* Class: jogamp_newt_driver_macosx_ScreenDriver
- * Method: getScreenSizeMM0
+ * Method: getMonitorProps0
* Signature: (I)[I
*/
-JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_macosx_ScreenDriver_getScreenSizeMM0
- (JNIEnv *env, jobject obj, jint scrn_idx)
+JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_macosx_ScreenDriver_getMonitorProps0
+ (JNIEnv *env, jobject obj, jint crt_idx)
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
@@ -376,33 +361,46 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_macosx_ScreenDriver_getScree
timespec_now(&t0);
#endif
- NSScreen *screen = NewtScreen_getNSScreenByIndex((int)scrn_idx);
#ifdef DBG_PERF
timespec_now(&t1); timespec_subtract(&td, &t1, &t0); td_ms = timespec_milliseconds(&td);
- fprintf(stderr, "MacScreen_getScreenSizeMM0.1: %ld ms\n", td_ms); fflush(NULL);
+ fprintf(stderr, "MacScreen_getMonitorProps0.1: %ld ms\n", td_ms); fflush(NULL);
#endif
-
+ NSScreen *screen = NewtScreen_getNSScreenByIndex((int)crt_idx, false);
+ if( NULL == screen ) {
+ [pool release];
+ return NULL;
+ }
CGDirectDisplayID display = NewtScreen_getCGDirectDisplayIDByNSScreen(screen);
#ifdef DBG_PERF
timespec_now(&t1); timespec_subtract(&td, &t1, &t0); td_ms = timespec_milliseconds(&td);
- fprintf(stderr, "MacScreen_getScreenSizeMM0.2: %ld ms\n", td_ms); fflush(NULL);
+ fprintf(stderr, "MacScreen_getMonitorProps0.2: %ld ms\n", td_ms); fflush(NULL);
#endif
- CGSize screenDim = CGDisplayScreenSize(display);
+ CGSize sizeMM = CGDisplayScreenSize(display);
#ifdef DBG_PERF
timespec_now(&t1); timespec_subtract(&td, &t1, &t0); td_ms = timespec_milliseconds(&td);
- fprintf(stderr, "MacScreen_getScreenSizeMM0.3: %ld ms\n", td_ms); fflush(NULL);
+ fprintf(stderr, "MacScreen_getMonitorProps0.3: %ld ms\n", td_ms); fflush(NULL);
#endif
- jint prop[ 2 ];
- prop[0] = (jint) screenDim.width;
- prop[1] = (jint) screenDim.height;
-
- jintArray properties = (*env)->NewIntArray(env, 2);
+ CGRect bounds = CGDisplayBounds (display);
+
+ jsize propCount = MIN_MONITOR_DEVICE_PROPERTIES - 1 - NUM_MONITOR_MODE_PROPERTIES;
+ jint prop[ propCount ];
+ int offset = 0;
+ prop[offset++] = propCount;
+ prop[offset++] = crt_idx;
+ prop[offset++] = (jint) sizeMM.width;
+ prop[offset++] = (jint) sizeMM.height;
+ prop[offset++] = (jint) bounds.origin.x; // rotated viewport x
+ prop[offset++] = (jint) bounds.origin.y; // rotated viewport y
+ prop[offset++] = (jint) bounds.size.width; // rotated viewport width
+ prop[offset++] = (jint) bounds.size.height; // rotated viewport height
+
+ jintArray properties = (*env)->NewIntArray(env, propCount);
if (properties == NULL) {
- NewtCommon_throwNewRuntimeException(env, "Could not allocate int array of size 2");
+ NewtCommon_throwNewRuntimeException(env, "Could not allocate int array of size %d", propCount);
}
- (*env)->SetIntArrayRegion(env, properties, 0, 2, prop);
+ (*env)->SetIntArrayRegion(env, properties, 0, propCount, prop);
[pool release];
@@ -411,16 +409,19 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_macosx_ScreenDriver_getScree
/*
* Class: jogamp_newt_driver_macosx_ScreenDriver
- * Method: getScreenMode0
- * Signature: (IIII)[I
+ * Method: getMonitorMode0
+ * Signature: (II)[I
*/
-JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_macosx_ScreenDriver_getScreenMode0
- (JNIEnv *env, jobject obj, jint scrn_idx, jint mode_idx, jint widthMM, jint heightMM)
+JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_macosx_ScreenDriver_getMonitorMode0
+ (JNIEnv *env, jobject obj, jint crt_idx, jint mode_idx)
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- int prop_num = NUM_SCREEN_MODE_PROPERTIES_ALL;
- NSScreen *screen = NewtScreen_getNSScreenByIndex((int)scrn_idx);
+ NSScreen *screen = NewtScreen_getNSScreenByIndex((int)crt_idx, false);
+ if( NULL == screen ) {
+ [pool release];
+ return NULL;
+ }
CGDirectDisplayID display = NewtScreen_getCGDirectDisplayIDByNSScreen(screen);
CFArrayRef availableModes = CGDisplayAvailableModes(display);
@@ -429,12 +430,13 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_macosx_ScreenDriver_getScree
CFDictionaryRef mode = NULL;
int currentCCWRot = (int)CGDisplayRotation(display);
jint ccwRot = 0;
+ int nativeId = 0;
#ifdef VERBOSE_ON
if(0 >= mode_idx) {
// only for current mode (-1) and first mode (scanning)
DBG_PRINT( "getScreenMode0: scrn %d (%p, %p), mode %d, avail: %d/%d, current rot %d ccw\n",
- (int)scrn_idx, screen, (void*)(intptr_t)display, (int)mode_idx, (int)numberOfAvailableModes, (int)numberOfAvailableModesRots, currentCCWRot);
+ (int)crt_idx, screen, (void*)(intptr_t)display, (int)mode_idx, (int)numberOfAvailableModes, (int)numberOfAvailableModesRots, currentCCWRot);
}
#endif
@@ -443,16 +445,18 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_macosx_ScreenDriver_getScree
DBG_PRINT( "getScreenMode0: end of modes: mode %d, avail: %d/%d\n",
(int)mode_idx, (int)numberOfAvailableModes, (int)numberOfAvailableModesRots);
[pool release];
- return (*env)->NewIntArray(env, 0);
+ return NULL;
} else if(-1 < mode_idx) {
// only at initialization time, where index >= 0
- prop_num++; // add 1st extra prop, mode_idx
- mode = (CFDictionaryRef)CFArrayGetValueAtIndex(availableModes, mode_idx / ROTMODES_PER_REALMODE);
+ nativeId = mode_idx / ROTMODES_PER_REALMODE;
ccwRot = mode_idx % ROTMODES_PER_REALMODE * 90;
+ mode = (CFDictionaryRef)CFArrayGetValueAtIndex(availableModes, nativeId);
} else {
// current mode
mode = CGDisplayCurrentMode(display);
ccwRot = currentCCWRot;
+ CFRange range = CFRangeMake (0, numberOfAvailableModes);
+ nativeId = CFArrayGetFirstIndexOfValue(availableModes, range, (CFDictionaryRef)mode);
}
// mode = CGDisplayModeRetain(mode); // 10.6 on CGDisplayModeRef
@@ -466,36 +470,30 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_macosx_ScreenDriver_getScree
mHeight = tempWidth;
}
- jint prop[ prop_num ];
+ jint prop[ NUM_MONITOR_MODE_PROPERTIES_ALL ];
int propIndex = 0;
- int propIndexRes = 0;
- if( -1 < mode_idx ) {
- prop[propIndex++] = mode_idx;
- }
int refreshRate = CGDDGetModeRefreshRate(mode);
int fRefreshRate = ( 0 < refreshRate ) ? refreshRate : 60; // default .. (experienced on OSX 10.6.8)
- prop[propIndex++] = 0; // set later for verification of iterator
- propIndexRes = propIndex;
+ prop[propIndex++] = NUM_MONITOR_MODE_PROPERTIES_ALL;
prop[propIndex++] = mWidth;
prop[propIndex++] = mHeight;
prop[propIndex++] = CGDDGetModeBitsPerPixel(mode);
- prop[propIndex++] = widthMM;
- prop[propIndex++] = heightMM;
- prop[propIndex++] = fRefreshRate;
+ prop[propIndex++] = fRefreshRate * 100; // Hz*100
+ prop[propIndex++] = 0; // flags
+ prop[propIndex++] = nativeId;
prop[propIndex++] = ccwRot;
- prop[propIndex - NUM_SCREEN_MODE_PROPERTIES_ALL] = ( -1 < mode_idx ) ? propIndex-1 : propIndex ; // count == NUM_SCREEN_MODE_PROPERTIES_ALL
- DBG_PRINT( "getScreenMode0: Mode %d/%d (%d): %dx%d, %d bpp, %dx%d mm, %d / %d Hz, rot %d ccw\n",
+ DBG_PRINT( "getScreenMode0: Mode %d/%d (%d): %dx%d, %d bpp, %d / %d Hz, nativeId %d, rot %d ccw\n",
(int)mode_idx, (int)numberOfAvailableModesRots, (int)numberOfAvailableModes,
- (int)prop[propIndexRes+0], (int)prop[propIndexRes+1], (int)prop[propIndexRes+2],
- (int)prop[propIndexRes+3], (int)prop[propIndexRes+4], (int)prop[propIndexRes+5], refreshRate, (int)prop[propIndexRes+6]);
+ (int)prop[1], (int)prop[2], (int)prop[3],
+ (int)prop[4], refreshRate, (int)prop[6], (int)prop[7]);
- jintArray properties = (*env)->NewIntArray(env, prop_num);
+ jintArray properties = (*env)->NewIntArray(env, NUM_MONITOR_MODE_PROPERTIES_ALL);
if (properties == NULL) {
- NewtCommon_throwNewRuntimeException(env, "Could not allocate int array of size %d", prop_num);
+ NewtCommon_throwNewRuntimeException(env, "Could not allocate int array of size %d", NUM_MONITOR_MODE_PROPERTIES_ALL);
}
- (*env)->SetIntArrayRegion(env, properties, 0, prop_num, prop);
+ (*env)->SetIntArrayRegion(env, properties, 0, NUM_MONITOR_MODE_PROPERTIES_ALL, prop);
// CGDisplayModeRelease(mode); // 10.6 on CGDisplayModeRef
[pool release];
@@ -505,36 +503,47 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_macosx_ScreenDriver_getScree
/*
* Class: jogamp_newt_driver_macosx_ScreenDriver
- * Method: setScreenMode0
- * Signature: (II)Z
+ * Method: setMonitorMode0
+ * Signature: (III)Z
*/
-JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_ScreenDriver_setScreenMode0
- (JNIEnv *env, jobject object, jint scrn_idx, jint mode_idx)
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_ScreenDriver_setMonitorMode0
+ (JNIEnv *env, jobject object, jint crt_idx, jint nativeId, jint ccwRot)
{
jboolean res = JNI_TRUE;
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- NSScreen *screen = NewtScreen_getNSScreenByIndex((int)scrn_idx);
+ NSScreen *screen = NewtScreen_getNSScreenByIndex((int)crt_idx, false);
+ if( NULL == screen ) {
+ [pool release];
+ return JNI_FALSE;
+ }
CGDirectDisplayID display = NewtScreen_getCGDirectDisplayIDByNSScreen(screen);
CFArrayRef availableModes = CGDisplayAvailableModes(display);
-#ifdef VERBOSE_ON
CFIndex numberOfAvailableModes = CFArrayGetCount(availableModes);
+#ifdef VERBOSE_ON
CFIndex numberOfAvailableModesRots = ROTMODES_PER_REALMODE * numberOfAvailableModes;
#endif
- CFDictionaryRef mode = (CFDictionaryRef)CFArrayGetValueAtIndex(availableModes, mode_idx / ROTMODES_PER_REALMODE);
- // mode = CGDisplayModeRetain(mode); // 10.6 on CGDisplayModeRef
- int ccwRot = mode_idx % ROTMODES_PER_REALMODE * 90;
- DBG_PRINT( "setScreenMode0: scrn %d (%p, %p), mode %d, rot %d ccw, avail: %d/%d\n",
- (int)scrn_idx, screen, (void*)(intptr_t)display, (int)mode_idx, ccwRot, (int)numberOfAvailableModes, (int)numberOfAvailableModesRots);
+ DBG_PRINT( "setScreenMode0: scrn %d (%p, %p), nativeID %d, rot %d ccw, avail: %d/%d\n",
+ (int)crt_idx, screen, (void*)(intptr_t)display, (int)nativeId, ccwRot, (int)numberOfAvailableModes, (int)numberOfAvailableModesRots);
+
+ CFDictionaryRef mode = NULL;
- if(ccwRot!=0) {
+ if( 0 != ccwRot ) {
// FIXME: How to rotate the display/screen on OSX programmatically ?
DBG_PRINT( "setScreenMode0: Don't know how to rotate screen on OS X: rot %d ccw\n", ccwRot);
res = JNI_FALSE;
+ } else {
+ if( numberOfAvailableModes <= nativeId ) {
+ res = JNI_FALSE;
+ } else {
+ mode = (CFDictionaryRef)CFArrayGetValueAtIndex(availableModes, nativeId);
+ // mode = CGDisplayModeRetain(mode); // 10.6 on CGDisplayModeRef
+ }
}
- if(JNI_TRUE == res) {
+
+ if( NULL != mode ) {
CGError err = CGDisplaySwitchToMode(display, mode);
if(kCGErrorSuccess != err) {
DBG_PRINT( "setScreenMode0: SetMode failed: %d\n", (int)err);
@@ -593,21 +602,18 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_initIDs0
/**
* Class: jogamp_newt_driver_macosx_WindowDriver
* Method: createView0
- * Signature: (IIIIZI)J
+ * Signature: (IIIIZ)J
*/
JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_createView0
(JNIEnv *env, jobject jthis, jint x, jint y, jint w, jint h,
- jboolean fullscreen, jint screen_idx)
+ jboolean fullscreen)
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- DBG_PRINT( "createView0 - %p (this), %d/%d %dx%d, fs %d, screenidx %d (START)\n",
- (void*)(intptr_t)jthis, (int)x, (int)y, (int)w, (int)h, (int)fullscreen, (int)screen_idx);
+ DBG_PRINT( "createView0 - %p (this), %d/%d %dx%d, fs %d (START)\n",
+ (void*)(intptr_t)jthis, (int)x, (int)y, (int)w, (int)h, (int)fullscreen);
- NSArray *screens = [NSScreen screens];
- if(screen_idx<0) screen_idx=0;
- if(screen_idx>=[screens count]) screen_idx=0;
- NSScreen *myScreen = (NSScreen *) [screens objectAtIndex: screen_idx];
+ NSScreen *myScreen = NewtScreen_getNSScreenByCoord(x, y);
NSRect rectWin;
if (fullscreen) {
@@ -634,24 +640,21 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_createView0
*
* Class: jogamp_newt_driver_macosx_WindowDriver
* Method: createWindow0
- * Signature: (IIIIZIIIJ)J
+ * Signature: (IIIIZIIJ)J
*/
JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_createWindow0
(JNIEnv *env, jobject jthis, jint x, jint y, jint w, jint h,
- jboolean fullscreen, jint styleMask, jint bufferingType, jint screen_idx, jlong jview)
+ jboolean fullscreen, jint styleMask, jint bufferingType, jlong jview)
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NewtView* myView = (NewtView*) (intptr_t) jview ;
DBG_PRINT( "createWindow0 - %p (this), %d/%d %dx%d, fs %d, style %X, buffType %X, screenidx %d, view %p (START)\n",
(void*)(intptr_t)jthis, (int)x, (int)y, (int)w, (int)h, (int)fullscreen,
- (int)styleMask, (int)bufferingType, (int)screen_idx, myView);
+ (int)styleMask, (int)bufferingType, myView);
(void)myView;
- NSArray *screens = [NSScreen screens];
- if(screen_idx<0) screen_idx=0;
- if(screen_idx>=[screens count]) screen_idx=0;
- NSScreen *myScreen = (NSScreen *) [screens objectAtIndex: screen_idx];
+ NSScreen *myScreen = NewtScreen_getNSScreenByCoord(x, y);
NSRect rectWin;
if (fullscreen) {
@@ -670,7 +673,6 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_createWindow
styleMask: (NSUInteger) styleMask
backing: (NSBackingStoreType) bufferingType
defer: YES
- screen: myScreen
isFullscreenWindow: fullscreen];
// DBG_PRINT( "createWindow0.1 - %p, isVisible %d\n", myWindow, [myWindow isVisible]);
@@ -687,26 +689,23 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_createWindow
*
* Class: jogamp_newt_driver_macosx_WindowDriver
* Method: initWindow0
- * Signature: (JJIIIIZZZIJ)V
+ * Signature: (JJIIIIZZZJ)V
*/
JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_initWindow0
(JNIEnv *env, jobject jthis, jlong parent, jlong window, jint x, jint y, jint w, jint h,
- jboolean opaque, jboolean fullscreen, jboolean visible, jint screen_idx, jlong jview)
+ jboolean opaque, jboolean fullscreen, jboolean visible, jlong jview)
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NewtMacWindow* myWindow = (NewtMacWindow*) ((intptr_t) window);
NewtView* myView = (NewtView*) (intptr_t) jview ;
- DBG_PRINT( "initWindow0 - %p (this), %p (parent), %p (window), %d/%d %dx%d, opaque %d, fs %d, visible %d, screenidx %d, view %p (START)\n",
+ DBG_PRINT( "initWindow0 - %p (this), %p (parent), %p (window), %d/%d %dx%d, opaque %d, fs %d, visible %d, view %p (START)\n",
(void*)(intptr_t)jthis, (void*)(intptr_t)parent, myWindow, (int)x, (int)y, (int)w, (int)h,
- (int) opaque, (int)fullscreen, (int)visible, (int)screen_idx, myView);
+ (int) opaque, (int)fullscreen, (int)visible, myView);
- NSArray *screens = [NSScreen screens];
- if(screen_idx<0) screen_idx=0;
- if(screen_idx>=[screens count]) screen_idx=0;
- NSScreen *myScreen = (NSScreen *) [screens objectAtIndex: screen_idx];
- NSRect rectWin;
+ NSScreen *myScreen = NewtScreen_getNSScreenByCoord(x, y);
+ NSRect rectWin;
if (fullscreen) {
rectWin = [myScreen frame];
x = 0;
diff --git a/src/newt/native/NewtMacWindow.h b/src/newt/native/NewtMacWindow.h
index 09f4a1fd3..c9d53f53b 100644
--- a/src/newt/native/NewtMacWindow.h
+++ b/src/newt/native/NewtMacWindow.h
@@ -128,7 +128,6 @@
styleMask: (NSUInteger) windowStyle
backing: (NSBackingStoreType) bufferingType
defer: (BOOL) deferCreation
- screen:(NSScreen *)screen
isFullscreenWindow:(BOOL)isfs;
#ifdef DBG_LIFECYCLE
- (void) release;
diff --git a/src/newt/native/NewtMacWindow.m b/src/newt/native/NewtMacWindow.m
index 005e82d72..35d3ffbc5 100644
--- a/src/newt/native/NewtMacWindow.m
+++ b/src/newt/native/NewtMacWindow.m
@@ -439,14 +439,12 @@ static UniChar CKCH_CharForKeyCode(jshort keyCode) {
styleMask: (NSUInteger) windowStyle
backing: (NSBackingStoreType) bufferingType
defer: (BOOL) deferCreation
- screen:(NSScreen *)screen
isFullscreenWindow:(BOOL)isfs
{
id res = [super initWithContentRect: contentRect
styleMask: windowStyle
backing: bufferingType
- defer: deferCreation
- screen: screen];
+ defer: deferCreation];
isFullscreenWindow = isfs;
// Why is this necessary? Without it we don't get any of the
// delegate methods like resizing and window movement.
diff --git a/src/newt/native/ScreenMode.h b/src/newt/native/ScreenMode.h
index bb782910e..110f1c493 100644
--- a/src/newt/native/ScreenMode.h
+++ b/src/newt/native/ScreenMode.h
@@ -33,12 +33,17 @@
#ifndef _SCREEN_MODE_H
#define _SCREEN_MODE_H
-#define NUM_RESOLUTION_PROPERTIES 2 /* width, height */
-#define NUM_SURFACE_SIZE_PROPERTIES 1 /* bpp */
-#define NUM_MONITOR_MODE_PROPERTIES 3 /* ScreenSizeMM[width, height], refresh-rate */
-#define NUM_SCREEN_MODE_PROPERTIES 1 /* rotation */
+#define NUM_RESOLUTION_PROPERTIES 2 /* width, height */
+#define NUM_SURFACE_SIZE_PROPERTIES 1 /* bpp */
+#define NUM_SIZEANDRATE_PROPERTIES 2 /* refresh-rate, flags */
+#define NUM_MONITOR_MODE_PROPERTIES 2 /* id, rotation */
-#define NUM_SCREEN_MODE_PROPERTIES_ALL 8 /* count + the above */
+#define NUM_MONITOR_MODE_PROPERTIES_ALL 8 /* count + the above */
+
+#define MIN_MONITOR_DEVICE_PROPERTIES 11 /* count + id, ScreenSizeMM[width, height], rotated Viewport[x, y, width, height], currentMonitorModeId, rotation, supportedModeId+ */
+
+#define FLAG_INTERLACE ( 1 << 0 )
+#define FLAG_DOUBLESCAN ( 1 << 1 )
#endif
diff --git a/src/newt/native/Window.h b/src/newt/native/Window.h
index 4755c4fc5..d9ee5fd1f 100644
--- a/src/newt/native/Window.h
+++ b/src/newt/native/Window.h
@@ -38,8 +38,9 @@
#define FLAG_HAS_PARENT ( 1 << 8 )
#define FLAG_IS_UNDECORATED ( 1 << 9 )
#define FLAG_IS_FULLSCREEN ( 1 << 10 )
-#define FLAG_IS_ALWAYSONTOP ( 1 << 11 )
-#define FLAG_IS_VISIBLE ( 1 << 12 )
+#define FLAG_IS_FULLSCREEN_SPAN ( 1 << 11 )
+#define FLAG_IS_ALWAYSONTOP ( 1 << 12 )
+#define FLAG_IS_VISIBLE ( 1 << 13 )
#define TST_FLAG_CHANGE_PARENTING(f) ( 0 != ( (f) & FLAG_CHANGE_PARENTING ) )
#define TST_FLAG_CHANGE_DECORATION(f) ( 0 != ( (f) & FLAG_CHANGE_DECORATION ) )
@@ -47,11 +48,11 @@
#define TST_FLAG_CHANGE_ALWAYSONTOP(f) ( 0 != ( (f) & FLAG_CHANGE_ALWAYSONTOP ) )
#define TST_FLAG_CHANGE_VISIBILITY(f) ( 0 != ( (f) & FLAG_CHANGE_VISIBILITY ) )
-#define TST_FLAG_HAS_PARENT(f) ( 0 != ( (f) & FLAG_HAS_PARENT ) )
-#define TST_FLAG_IS_UNDECORATED(f) ( 0 != ( (f) & FLAG_IS_UNDECORATED ) )
-#define TST_FLAG_IS_FULLSCREEN(f) ( 0 != ( (f) & FLAG_IS_FULLSCREEN ) )
-#define TST_FLAG_IS_FULLSCREEN(f) ( 0 != ( (f) & FLAG_IS_FULLSCREEN ) )
-#define TST_FLAG_IS_ALWAYSONTOP(f) ( 0 != ( (f) & FLAG_IS_ALWAYSONTOP ) )
-#define TST_FLAG_IS_VISIBLE(f) ( 0 != ( (f) & FLAG_IS_VISIBLE ) )
+#define TST_FLAG_HAS_PARENT(f) ( 0 != ( (f) & FLAG_HAS_PARENT ) )
+#define TST_FLAG_IS_UNDECORATED(f) ( 0 != ( (f) & FLAG_IS_UNDECORATED ) )
+#define TST_FLAG_IS_FULLSCREEN(f) ( 0 != ( (f) & FLAG_IS_FULLSCREEN ) )
+#define TST_FLAG_IS_FULLSCREEN_SPAN(f) ( 0 != ( (f) & FLAG_IS_FULLSCREEN_SPAN ) )
+#define TST_FLAG_IS_ALWAYSONTOP(f) ( 0 != ( (f) & FLAG_IS_ALWAYSONTOP ) )
+#define TST_FLAG_IS_VISIBLE(f) ( 0 != ( (f) & FLAG_IS_VISIBLE ) )
#endif
diff --git a/src/newt/native/WindowsWindow.c b/src/newt/native/WindowsWindow.c
index 5c1115592..7ede3a20d 100644
--- a/src/newt/native/WindowsWindow.c
+++ b/src/newt/native/WindowsWindow.c
@@ -101,6 +101,9 @@
#ifndef DISPLAY_DEVICE_ACTIVE
#define DISPLAY_DEVICE_ACTIVE 0x00000001
#endif
+#ifndef DM_INTERLACED
+#define DM_INTERLACED 2
+#endif
#include "jogamp_newt_driver_windows_DisplayDriver.h"
#include "jogamp_newt_driver_windows_ScreenDriver.h"
@@ -1116,11 +1119,11 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_DisplayDriver_DispatchMes
/*
* Class: jogamp_newt_driver_windows_ScreenDriver
- * Method: getOriginX0
- * Signature: (I)I
+ * Method: getVirtualOriginX0
+ * Signature: ()I
*/
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getOriginX0
- (JNIEnv *env, jobject obj, jint scrn_idx)
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getVirtualOriginX0
+ (JNIEnv *env, jobject obj)
{
if( GetSystemMetrics( SM_CMONITORS) > 1) {
return (jint)GetSystemMetrics(SM_XVIRTUALSCREEN);
@@ -1131,11 +1134,11 @@ JNIEXPORT jint JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getOriginX0
/*
* Class: jogamp_newt_driver_windows_ScreenDriver
- * Method: getOriginY0
- * Signature: (I)I
+ * Method: getVirtualOriginY0
+ * Signature: ()I
*/
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getOriginY0
- (JNIEnv *env, jobject obj, jint scrn_idx)
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getVirtualOriginY0
+ (JNIEnv *env, jobject obj)
{
if( GetSystemMetrics( SM_CMONITORS ) > 1) {
return (jint)GetSystemMetrics(SM_YVIRTUALSCREEN);
@@ -1146,11 +1149,11 @@ JNIEXPORT jint JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getOriginY0
/*
* Class: jogamp_newt_driver_windows_ScreenDriver
- * Method: getWidthImpl
- * Signature: (I)I
+ * Method: getVirtualWidthImpl
+ * Signature: ()I
*/
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getWidthImpl0
- (JNIEnv *env, jobject obj, jint scrn_idx)
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getVirtualWidthImpl0
+ (JNIEnv *env, jobject obj)
{
if( GetSystemMetrics( SM_CMONITORS) > 1) {
return (jint)GetSystemMetrics(SM_CXVIRTUALSCREEN);
@@ -1161,11 +1164,11 @@ JNIEXPORT jint JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getWidthImpl
/*
* Class: jogamp_newt_driver_windows_ScreenDriver
- * Method: getHeightImpl
- * Signature: (I)I
+ * Method: getVirtualHeightImpl
+ * Signature: ()I
*/
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getHeightImpl0
- (JNIEnv *env, jobject obj, jint scrn_idx)
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getVirtualHeightImpl0
+ (JNIEnv *env, jobject obj)
{
if( GetSystemMetrics( SM_CMONITORS ) > 1) {
return (jint)GetSystemMetrics(SM_CYVIRTUALSCREEN);
@@ -1217,65 +1220,137 @@ static int NewtScreen_RotationNewtCCW2NativeCCW(JNIEnv *env, jint newt) {
return native;
}
-/*
-static void NewtScreen_scanDisplayDevices() {
- DISPLAY_DEVICE device;
- int i = 0;
- LPCTSTR name;
- while(NULL != (name = NewtScreen_getDisplayDeviceName(&device, i))) {
- DBG_PRINT("*** [%d]: <%s> active %d\n", i, name, ( 0 != ( device.StateFlags & DISPLAY_DEVICE_ACTIVE ) ) );
- i++;
+static LPCTSTR NewtScreen_getAdapterName(DISPLAY_DEVICE * device, int crt_idx) {
+ memset(device, 0, sizeof(DISPLAY_DEVICE));
+ device->cb = sizeof(DISPLAY_DEVICE);
+ if( FALSE == EnumDisplayDevices(NULL, crt_idx, device, 0) ) {
+ DBG_PRINT("*** WindowsWindow: getAdapterName.EnumDisplayDevices(crt_idx %d) -> FALSE\n", crt_idx);
+ return NULL;
}
-}*/
-static LPCTSTR NewtScreen_getDisplayDeviceName(DISPLAY_DEVICE * device, int scrn_idx) {
- device->cb = sizeof(DISPLAY_DEVICE);
- if( FALSE == EnumDisplayDevices(NULL, scrn_idx, device, 0) ) {
- DBG_PRINT("*** WindowsWindow: getDisplayDeviceName.EnumDisplayDevices(scrn_idx %d) -> FALSE\n", scrn_idx);
+ if( NULL == device->DeviceName || 0 == _tcslen(device->DeviceName) ) {
return NULL;
}
- if( 0 == ( device->StateFlags & DISPLAY_DEVICE_ACTIVE ) ) {
- DBG_PRINT("*** WindowsWindow: !DISPLAY_DEVICE_ACTIVE(scrn_idx %d)\n", scrn_idx);
+ return device->DeviceName;
+}
+
+static LPCTSTR NewtScreen_getMonitorName(LPCTSTR adapterName, DISPLAY_DEVICE * device, int monitor_idx, BOOL onlyActive) {
+ memset(device, 0, sizeof(DISPLAY_DEVICE));
+ device->cb = sizeof(DISPLAY_DEVICE);
+ if( 0 == monitor_idx ) {
+ if( FALSE == EnumDisplayDevices(adapterName, monitor_idx, device, 0) ) {
+ DBG_PRINT("*** WindowsWindow: getDisplayName.EnumDisplayDevices(monitor_idx %d).adapter -> FALSE\n", monitor_idx);
+ return NULL;
+ }
+ }
+
+ if( onlyActive && 0 == ( device->StateFlags & DISPLAY_DEVICE_ACTIVE ) ) {
+ DBG_PRINT("*** WindowsWindow: !DISPLAY_DEVICE_ACTIVE(monitor_idx %d).display\n", monitor_idx);
+ return NULL;
+ }
+ if( NULL == device->DeviceName || 0 == _tcslen(device->DeviceName) ) {
return NULL;
}
return device->DeviceName;
}
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_dumpMonitorInfo0
+ (JNIEnv *env, jclass clazz)
+{
+ DISPLAY_DEVICE aDevice, dDevice;
+ int i = 0, j;
+ LPCTSTR aName, dName;
+ while(NULL != (aName = NewtScreen_getAdapterName(&aDevice, i))) {
+ fprintf(stderr, "*** [%d]: <%s> flags 0x%X active %d\n", i, aName, aDevice.StateFlags, ( 0 != ( aDevice.StateFlags & DISPLAY_DEVICE_ACTIVE ) ) );
+ j=0;
+ while(NULL != (dName = NewtScreen_getMonitorName(aName, &dDevice, j, FALSE))) {
+ fprintf(stderr, "*** [%d][%d]: <%s> flags 0x%X active %d\n", i, j, dName, dDevice.StateFlags, ( 0 != ( dDevice.StateFlags & DISPLAY_DEVICE_ACTIVE ) ) );
+ j++;
+ }
+ i++;
+ }
+}
+
static HDC NewtScreen_createDisplayDC(LPCTSTR displayDeviceName) {
return CreateDC("DISPLAY", displayDeviceName, NULL, NULL);
}
/*
* Class: jogamp_newt_driver_windows_ScreenDriver
- * Method: getScreenMode0
- * Signature: (II)[I
+ * Method: getAdapterName0
+ * Signature: (I)Ljava/lang/String;
*/
-JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getScreenMode0
- (JNIEnv *env, jobject obj, jint scrn_idx, jint mode_idx)
+JNIEXPORT jstring JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getAdapterName0
+ (JNIEnv *env, jobject obj, jint crt_idx)
{
DISPLAY_DEVICE device;
- int prop_num = NUM_SCREEN_MODE_PROPERTIES_ALL;
- LPCTSTR deviceName = NewtScreen_getDisplayDeviceName(&device, scrn_idx);
- if(NULL == deviceName) {
- DBG_PRINT("*** WindowsWindow: getScreenMode.getDisplayDeviceName(scrn_idx %d) -> NULL\n", scrn_idx);
- return (*env)->NewIntArray(env, 0);
+ LPCTSTR adapterName = NewtScreen_getAdapterName(&device, crt_idx);
+ DBG_PRINT("*** WindowsWindow: getAdapterName(crt_idx %d) -> %s, active %d\n", crt_idx,
+ (NULL==adapterName?"nil":adapterName), 0 == ( device.StateFlags & DISPLAY_DEVICE_ACTIVE ));
+ if(NULL == adapterName) {
+ return NULL;
}
+#ifdef UNICODE
+ return (*env)->NewString(env, adapterName, wcslen(adapterName));
+#else
+ return (*env)->NewStringUTF(env, adapterName);
+#endif
+}
+
+/*
+ * Class: jogamp_newt_driver_windows_ScreenDriver
+ * Method: getActiveMonitorName0
+ * Signature: (Ljava/lang/String;I)Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getActiveMonitorName0
+ (JNIEnv *env, jobject obj, jstring jAdapterName, jint monitor_idx)
+{
+ DISPLAY_DEVICE device;
+ LPCTSTR monitorName;
+#ifdef UNICODE
+ LPCTSTR adapterName = NewtCommon_GetNullTerminatedStringChars(env, jAdapterName);
+ monitorName = NewtScreen_getMonitorName(adapterName, &device, monitor_idx, TRUE);
+ DBG_PRINT("*** WindowsWindow: getMonitorName(%s, monitor_idx %d) -> %s\n", adapterName, monitor_idx, (NULL==monitorName?"nil":monitorName));
+ free((void*) adapterName);
+#else
+ LPCTSTR adapterName = (*env)->GetStringUTFChars(env, jAdapterName, NULL);
+ monitorName = NewtScreen_getMonitorName(adapterName, &device, monitor_idx, TRUE);
+ DBG_PRINT("*** WindowsWindow: getMonitorName(%s, monitor_idx %d) -> %s\n", adapterName, monitor_idx, (NULL==monitorName?"nil":monitorName));
+ (*env)->ReleaseStringUTFChars(env, jAdapterName, adapterName);
+#endif
+ if(NULL == monitorName) {
+ return NULL;
+ }
+#ifdef UNICODE
+ return (*env)->NewString(env, monitorName, wcslen(monitorName));
+#else
+ return (*env)->NewStringUTF(env, monitorName);
+#endif
+}
+/*
+ * Class: jogamp_newt_driver_windows_ScreenDriver
+ * Method: getMonitorMode0
+ * Signature: (Ljava/lang/String;I)[I
+ */
+JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getMonitorMode0
+ (JNIEnv *env, jobject obj, jstring jAdapterName, jint mode_idx)
+{
+ DISPLAY_DEVICE device;
+ LPCTSTR adapterName;
+ {
+#ifdef UNICODE
+ adapterName = NewtCommon_GetNullTerminatedStringChars(env, jAdapterName);
+#else
+ adapterName = (*env)->GetStringUTFChars(env, jAdapterName, NULL);
+#endif
+ }
int devModeID;
- int widthmm, heightmm;
if(-1 < mode_idx) {
- // only at initialization time, where index >= 0
- HDC hdc = NewtScreen_createDisplayDC(deviceName);
- widthmm = GetDeviceCaps(hdc, HORZSIZE);
- heightmm = GetDeviceCaps(hdc, VERTSIZE);
- DeleteDC(hdc);
devModeID = (int) mode_idx;
- prop_num++; // add 1st extra prop, mode_idx
} else {
- widthmm = 0;
- heightmm = 0;
devModeID = ENUM_CURRENT_SETTINGS;
}
@@ -1283,11 +1358,18 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getScre
ZeroMemory(&dm, sizeof(dm));
dm.dmSize = sizeof(dm);
- if (0 == EnumDisplaySettingsEx(deviceName, devModeID, &dm, ( ENUM_CURRENT_SETTINGS == devModeID ) ? 0 : EDS_ROTATEDMODE)) {
- DBG_PRINT("*** WindowsWindow: getScreenMode.EnumDisplaySettingsEx(mode_idx %d/%d) -> NULL\n", mode_idx, devModeID);
+ int res = EnumDisplaySettingsEx(adapterName, devModeID, &dm, ( ENUM_CURRENT_SETTINGS == devModeID ) ? 0 : EDS_ROTATEDMODE);
+ DBG_PRINT("*** WindowsWindow: getMonitorMode.EnumDisplaySettingsEx(%s, mode_idx %d/%d) -> %d\n", adapterName, mode_idx, devModeID, res);
+#ifdef UNICODE
+ free((void*) adapterName);
+#else
+ (*env)->ReleaseStringUTFChars(env, jAdapterName, adapterName);
+#endif
+
+ if (0 == res) {
return (*env)->NewIntArray(env, 0);
}
-
+
// swap width and height, since Windows reflects rotated dimension, we don't
if (DMDO_90 == dm.dmDisplayOrientation || DMDO_270 == dm.dmDisplayOrientation) {
int tempWidth = dm.dmPelsWidth;
@@ -1295,43 +1377,110 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getScre
dm.dmPelsHeight = tempWidth;
}
- jint prop[ prop_num ];
+ int flags = 0;
+ if( 0 != ( dm.dmDisplayFlags & DM_INTERLACED ) ) {
+ flags |= FLAG_INTERLACE;
+ }
+
+ jint prop[ NUM_MONITOR_MODE_PROPERTIES_ALL ];
int propIndex = 0;
- if( -1 < mode_idx ) {
- prop[propIndex++] = mode_idx;
- }
- prop[propIndex++] = 0; // set later for verification of iterator
+ prop[propIndex++] = NUM_MONITOR_MODE_PROPERTIES_ALL;
prop[propIndex++] = dm.dmPelsWidth;
prop[propIndex++] = dm.dmPelsHeight;
prop[propIndex++] = dm.dmBitsPerPel;
- prop[propIndex++] = widthmm;
- prop[propIndex++] = heightmm;
- prop[propIndex++] = dm.dmDisplayFrequency;
+ prop[propIndex++] = dm.dmDisplayFrequency * 100; // Hz*100
+ prop[propIndex++] = flags;
+ prop[propIndex++] = 0; // not bound to id
prop[propIndex++] = NewtScreen_RotationNativeCCW2NewtCCW(env, dm.dmDisplayOrientation);
- prop[propIndex - NUM_SCREEN_MODE_PROPERTIES_ALL] = ( -1 < mode_idx ) ? propIndex-1 : propIndex ; // count == NUM_SCREEN_MODE_PROPERTIES_ALL
- jintArray properties = (*env)->NewIntArray(env, prop_num);
+ jintArray properties = (*env)->NewIntArray(env, NUM_MONITOR_MODE_PROPERTIES_ALL);
if (properties == NULL) {
- NewtCommon_throwNewRuntimeException(env, "Could not allocate int array of size %d", prop_num);
+ NewtCommon_throwNewRuntimeException(env, "Could not allocate int array of size %d", NUM_MONITOR_MODE_PROPERTIES_ALL);
}
- (*env)->SetIntArrayRegion(env, properties, 0, prop_num, prop);
+ (*env)->SetIntArrayRegion(env, properties, 0, NUM_MONITOR_MODE_PROPERTIES_ALL, prop);
return properties;
}
/*
* Class: jogamp_newt_driver_windows_ScreenDriver
- * Method: setScreenMode0
- * Signature: (IIIIII)Z
+ * Method: getMonitorDevice0
+ * Signature: (Ljava/lang/String;I)[I
*/
-JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_setScreenMode0
- (JNIEnv *env, jobject object, jint scrn_idx, jint width, jint height, jint bits, jint rate, jint rot)
+JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getMonitorDevice0
+ (JNIEnv *env, jobject obj, jstring jAdapterName, jint monitor_idx)
{
DISPLAY_DEVICE device;
- LPCTSTR deviceName = NewtScreen_getDisplayDeviceName(&device, scrn_idx);
- if(NULL == deviceName) {
- DBG_PRINT("*** WindowsWindow: setScreenMode.getDisplayDeviceName(scrn_idx %d) -> NULL\n", scrn_idx);
+ LPCTSTR adapterName;
+ {
+#ifdef UNICODE
+ adapterName = NewtCommon_GetNullTerminatedStringChars(env, jAdapterName);
+#else
+ adapterName = (*env)->GetStringUTFChars(env, jAdapterName, NULL);
+#endif
+ }
+
+ HDC hdc = NewtScreen_createDisplayDC(adapterName);
+ int widthmm = GetDeviceCaps(hdc, HORZSIZE);
+ int heightmm = GetDeviceCaps(hdc, VERTSIZE);
+ DeleteDC(hdc);
+ int devModeID = ENUM_CURRENT_SETTINGS;
+
+ DEVMODE dm;
+ ZeroMemory(&dm, sizeof(dm));
+ dm.dmSize = sizeof(dm);
+
+ int res = EnumDisplaySettingsEx(adapterName, devModeID, &dm, 0);
+ DBG_PRINT("*** WindowsWindow: getMonitorDevice.EnumDisplaySettingsEx(%s, devModeID %d) -> %d\n", adapterName, devModeID, res);
+#ifdef UNICODE
+ free((void*) adapterName);
+#else
+ (*env)->ReleaseStringUTFChars(env, jAdapterName, adapterName);
+#endif
+ if (0 == res) {
+ return (*env)->NewIntArray(env, 0);
+ }
+
+ jsize propCount = MIN_MONITOR_DEVICE_PROPERTIES - 1 - NUM_MONITOR_MODE_PROPERTIES;
+ jint prop[ propCount ];
+ int propIndex = 0;
+
+ prop[propIndex++] = propCount;
+ prop[propIndex++] = monitor_idx;
+ prop[propIndex++] = widthmm;
+ prop[propIndex++] = heightmm;
+ prop[propIndex++] = dm.dmPosition.x; // rotated viewport
+ prop[propIndex++] = dm.dmPosition.y; // rotated viewport
+ prop[propIndex++] = dm.dmPelsWidth; // rotated viewport
+ prop[propIndex++] = dm.dmPelsHeight; // rotated viewport
+
+ jintArray properties = (*env)->NewIntArray(env, propCount);
+ if (properties == NULL) {
+ NewtCommon_throwNewRuntimeException(env, "Could not allocate int array of size %d", propCount);
+ }
+ (*env)->SetIntArrayRegion(env, properties, 0, propCount, prop);
+
+ return properties;
+}
+
+/*
+ * Class: jogamp_newt_driver_windows_ScreenDriver
+ * Method: setMonitorMode0
+ * Signature: (IIIIIIIII)Z
+ */
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_setMonitorMode0
+ (JNIEnv *env, jobject object, jint monitor_idx, jint x, jint y, jint width, jint height, jint bits, jint rate, jint flags, jint rot)
+{
+ DISPLAY_DEVICE adapterDevice, monitorDevice;
+ LPCTSTR adapterName = NewtScreen_getAdapterName(&adapterDevice, monitor_idx);
+ if(NULL == adapterName) {
+ DBG_PRINT("*** WindowsWindow: setMonitorMode.getAdapterName(monitor_idx %d) -> NULL\n", monitor_idx);
+ return JNI_FALSE;
+ }
+ LPCTSTR monitorName = NewtScreen_getMonitorName(adapterName, &monitorDevice, 0, TRUE);
+ if(NULL == monitorName) {
+ DBG_PRINT("*** WindowsWindow: setMonitorMode.getMonitorName(monitor_idx 0) -> NULL\n");
return JNI_FALSE;
}
@@ -1339,10 +1488,17 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_setScree
// initialize the DEVMODE structure
ZeroMemory(&dm, sizeof(dm));
dm.dmSize = sizeof(dm);
+ if( 0 <= x && 0 <= y ) {
+ dm.dmPosition.x = (int)x;
+ dm.dmPosition.y = (int)y;
+ }
dm.dmPelsWidth = (int)width;
dm.dmPelsHeight = (int)height;
dm.dmBitsPerPel = (int)bits;
dm.dmDisplayFrequency = (int)rate;
+ if( 0 != ( flags & FLAG_INTERLACE ) ) {
+ dm.dmDisplayFlags |= DM_INTERLACED;
+ }
dm.dmDisplayOrientation = NewtScreen_RotationNewtCCW2NativeCCW(env, rot);
// swap width and height, since Windows reflects rotated dimension, we don't
@@ -1352,9 +1508,12 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_setScree
dm.dmPelsHeight = tempWidth;
}
- dm.dmFields = DM_DISPLAYORIENTATION | DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL | DM_DISPLAYFREQUENCY;
+ dm.dmFields = DM_DISPLAYORIENTATION | DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL | DM_DISPLAYFREQUENCY | DM_DISPLAYFLAGS;
+ if( 0 <= x && 0 <= y ) {
+ dm.dmFields |= DM_POSITION;
+ }
- return ( DISP_CHANGE_SUCCESSFUL == ChangeDisplaySettings(&dm, 0) ) ? JNI_TRUE : JNI_FALSE ;
+ return ( DISP_CHANGE_SUCCESSFUL == ChangeDisplaySettingsEx(adapterName, &dm, NULL, 0, NULL) ) ? JNI_TRUE : JNI_FALSE ;
}
/*
diff --git a/src/newt/native/X11RandR11.c b/src/newt/native/X11RandR11.c
index cbf911a38..81a6726b5 100644
--- a/src/newt/native/X11RandR11.c
+++ b/src/newt/native/X11RandR11.c
@@ -30,10 +30,10 @@
/*
* Class: jogamp_newt_driver_x11_RandR11
- * Method: getAvailableScreenModeRotations0
+ * Method: getAvailableScreenRotations0
* Signature: (JI)I
*/
-JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_RandR11_getAvailableScreenModeRotations0
+JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_RandR11_getAvailableScreenRotations0
(JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
{
Display *dpy = (Display *) (intptr_t) display;
@@ -75,10 +75,10 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_RandR11_getAvailableScre
/*
* Class: jogamp_newt_driver_x11_RandR11
- * Method: getNumScreenModeResolution0
+ * Method: getNumScreenResolution0
* Signature: (JI)I
*/
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_RandR11_getNumScreenModeResolutions0
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_RandR11_getNumScreenResolutions0
(JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
{
Display *dpy = (Display *) (intptr_t) display;
@@ -90,7 +90,7 @@ JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_RandR11_getNumScreenModeResol
#ifdef DBG_PERF
timespec_now(&t1); timespec_subtract(&td, &t1, &t0); td_ms = timespec_milliseconds(&td);
- fprintf(stderr, "X11Screen_getNumScreenModeResolution0.1: %ld ms\n", td_ms); fflush(NULL);
+ fprintf(stderr, "X11Screen_getNumScreenResolution0.1: %ld ms\n", td_ms); fflush(NULL);
#endif
int num_sizes;
@@ -98,20 +98,20 @@ JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_RandR11_getNumScreenModeResol
#ifdef DBG_PERF
timespec_now(&t1); timespec_subtract(&td, &t1, &t0); td_ms = timespec_milliseconds(&td);
- fprintf(stderr, "X11Screen_getNumScreenModeResolution0.2 (XRRSizes): %ld ms\n", td_ms); fflush(NULL);
+ fprintf(stderr, "X11Screen_getNumScreenResolution0.2 (XRRSizes): %ld ms\n", td_ms); fflush(NULL);
#endif
- DBG_PRINT("getNumScreenModeResolutions0: %p:%d -> %d\n", dpy, (int)scrn_idx, num_sizes);
+ DBG_PRINT("getNumScreenResolutions0: %p:%d -> %d\n", dpy, (int)scrn_idx, num_sizes);
return num_sizes;
}
/*
* Class: jogamp_newt_driver_x11_RandR11
- * Method: getScreenModeResolutions0
+ * Method: getScreenResolutions0
* Signature: (JII)[I
*/
-JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_RandR11_getScreenModeResolution0
+JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_RandR11_getScreenResolution0
(JNIEnv *env, jclass clazz, jlong display, jint scrn_idx, jint resMode_idx)
{
Display *dpy = (Display *) (intptr_t) display;
@@ -145,10 +145,10 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_RandR11_getScreenModeRes
/*
* Class: jogamp_newt_driver_x11_RandR11
- * Method: getScreenModeRates0
+ * Method: getScreenRates0
* Signature: (JII)[I
*/
-JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_RandR11_getScreenModeRates0
+JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_RandR11_getScreenRates0
(JNIEnv *env, jclass clazz, jlong display, jint scrn_idx, jint resMode_idx)
{
Display *dpy = (Display *) (intptr_t) display;
@@ -289,36 +289,20 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_RandR11_setCurrentScreenM
int num_sizes;
XRRScreenSize *xrrs = XRRSizes(dpy, (int)screen_idx, &num_sizes); //get possible screen resolutions
- int rot;
if( 0 > resMode_idx || resMode_idx >= num_sizes ) {
NewtCommon_throwNewRuntimeException(env, "Invalid resolution index: ! 0 < %d < %d", resMode_idx, num_sizes);
}
- switch(rotation) {
- case 0:
- rot = RR_Rotate_0;
- break;
- case 90:
- rot = RR_Rotate_90;
- break;
- case 180:
- rot = RR_Rotate_180;
- break;
- case 270:
- rot = RR_Rotate_270;
- break;
- default:
- NewtCommon_throwNewRuntimeException(env, "Invalid rotation: %d", rotation);
- }
-
DBG_PRINT("X11Screen.setCurrentScreenMode0: CHANGED TO %d: %d x %d PIXELS, %d Hz, %d degree\n",
resMode_idx, xrrs[resMode_idx].width, xrrs[resMode_idx].height, (int)freq, rotation);
+ int xrot = NewtScreen_Degree2XRotation(env, rotation);
+
XRRSelectInput (dpy, root, RRScreenChangeNotifyMask);
XSync(dpy, False);
- XRRSetScreenConfigAndRate(dpy, conf, root, (int)resMode_idx, rot, (short)freq, CurrentTime);
+ XRRSetScreenConfigAndRate(dpy, conf, root, (int)resMode_idx, xrot, (short)freq, CurrentTime);
XSync(dpy, False);
return JNI_TRUE;
diff --git a/src/newt/native/X11RandR13.c b/src/newt/native/X11RandR13.c
index ea72cd35d..92c20e893 100644
--- a/src/newt/native/X11RandR13.c
+++ b/src/newt/native/X11RandR13.c
@@ -38,22 +38,9 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_RandR13_getScreenResources0
{
Display *dpy = (Display *) (intptr_t) display;
Window root = RootWindow(dpy, (int)screen_idx);
-#ifdef DBG_PERF
- struct timespec t0, t1, td;
- long td_ms;
- timespec_now(&t0);
-#endif
-
-#ifdef DBG_PERF
- timespec_now(&t1); timespec_subtract(&td, &t1, &t0); td_ms = timespec_milliseconds(&td);
- fprintf(stderr, "X11Screen_getScreenResources0.1: %ld ms\n", td_ms); fflush(NULL);
-#endif
-
- XRRScreenResources *res = XRRGetScreenResourcesCurrent( dpy, root);
-#ifdef DBG_PERF
- timespec_now(&t1); timespec_subtract(&td, &t1, &t0); td_ms = timespec_milliseconds(&td);
- fprintf(stderr, "X11Screen_getScreenResources0.2 (XRRScreenResources): %ld ms\n", td_ms); fflush(NULL);
-#endif
+
+ XRRScreenResources *res = XRRGetScreenResourcesCurrent( dpy, root); // 1.3
+ // XRRScreenResources *res = XRRGetScreenResources( dpy, root); // 1.2
return (jlong) (intptr_t) res;
}
@@ -66,48 +53,166 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_RandR13_getScreenResources0
JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_RandR13_freeScreenResources0
(JNIEnv *env, jclass clazz, jlong screenResources)
{
- XRRFreeScreenResources( (XRRScreenResources *) (intptr_t) screenResources );
+ XRRScreenResources *resources = (XRRScreenResources *) (intptr_t) screenResources;
+ if( NULL != resources ) {
+ XRRFreeScreenResources( resources );
+ }
+}
+
+#define SAFE_STRING(s) (NULL==s?"":s)
+
+static void dumpOutputs(const char *prefix, Display *dpy, XRRScreenResources *resources, int noutput, RROutput * outputs) {
+ int i, j;
+ fprintf(stderr, "%s %p: Output count %d\n", prefix, resources, noutput);
+ 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);
+ for(j=0; j<xrrOutputInfo->nmode; j++) {
+ fprintf(stderr, " Output[%d].Mode[%d].id %#lx\n", i, j, xrrOutputInfo->modes[j]);
+ }
+ XRRFreeOutputInfo (xrrOutputInfo);
+ }
}
-JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_RandR13_getOrigin0
- (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
+/** Returns vertical refresh rate in hertz */
+static float getVRefresh(XRRModeInfo *mode) {
+ float rate;
+ unsigned int vTotal = mode->vTotal;
+
+ if (mode->modeFlags & RR_DoubleScan) {
+ /* doublescan doubles the number of lines */
+ vTotal *= 2;
+ }
+
+ if (mode->modeFlags & RR_Interlace) {
+ /* interlace splits the frame into two fields */
+ /* the field rate is what is typically reported by monitors */
+ vTotal /= 2;
+ }
+
+ if (mode->hTotal && vTotal) {
+ rate = ( (float) mode->dotClock /
+ ( (float) mode->hTotal * (float) vTotal )
+ );
+ } else {
+ rate = 0;
+ }
+ return rate;
+}
+
+
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_RandR13_dumpInfo0
+ (JNIEnv *env, jclass clazz, jlong display, jint screen_idx, jlong screenResources)
{
Display * dpy = (Display *) (intptr_t) display;
- Window root = RootWindow(dpy, (int)scrn_idx);
+ Window root = RootWindow(dpy, (int)screen_idx);
+ XRRScreenResources *resources = (XRRScreenResources *) (intptr_t) screenResources;
int pos[] = { 0, 0 } ;
+ int i, j, minWidth, minHeight, maxWidth, maxHeight;
- int i;
- XRRScreenResources *xrrScreenResources = XRRGetScreenResources(dpy, root);
- fprintf(stderr, "XRRScreenResources %p: RRCrtc crtcs %d\n", xrrScreenResources, xrrScreenResources->ncrtc);
- for(i=0; i<xrrScreenResources->ncrtc; i++) {
- RRCrtc crtc = xrrScreenResources->crtcs[i];
- XRRCrtcInfo *xrrCrtcInfo = XRRGetCrtcInfo (dpy, xrrScreenResources, crtc);
- fprintf(stderr, "RRCrtc %d: %d/%d %dx%d\n", i, xrrCrtcInfo->x, xrrCrtcInfo->y, xrrCrtcInfo->width, xrrCrtcInfo->height);
+ int vs_width = DisplayWidth(dpy, screen_idx);
+ int vs_height = DisplayHeight(dpy, screen_idx);
+ int vs_width_mm = DisplayWidthMM(dpy, screen_idx);
+ int vs_height_mm = DisplayHeightMM(dpy, screen_idx);
+ fprintf(stderr, "ScreenVirtualSize: %dx%d %dx%d mm\n", vs_width, vs_height, vs_width_mm, vs_height_mm);
+
+ XRRGetScreenSizeRange (dpy, root, &minWidth, &minHeight, &maxWidth, &maxHeight);
+ fprintf(stderr, "XRRGetScreenSizeRange: %dx%d .. %dx%d\n", minWidth, minHeight, maxWidth, maxHeight);
+
+ if( NULL == resources ) {
+ fprintf(stderr, "XRRScreenResources NULL\n");
+ return;
+ }
+ fprintf(stderr, "XRRScreenResources %p: Crtc count %d\n", resources, resources->ncrtc);
+ for(i=0; i<resources->ncrtc; i++) {
+ RRCrtc crtc = resources->crtcs[i];
+ XRRCrtcInfo *xrrCrtcInfo = XRRGetCrtcInfo (dpy, resources, crtc);
+ fprintf(stderr, "Crtc[%d]: %d/%d %dx%d, rot 0x%X, mode.id %#lx\n",
+ i, xrrCrtcInfo->x, xrrCrtcInfo->y, xrrCrtcInfo->width, xrrCrtcInfo->height, xrrCrtcInfo->rotations, xrrCrtcInfo->mode);
+ for(j=0; j<xrrCrtcInfo->noutput; j++) {
+ fprintf(stderr, " Crtc[%d].Output[%d].id %#lx\n", i, j, xrrCrtcInfo->outputs[j]);
+ }
XRRFreeCrtcInfo(xrrCrtcInfo);
}
- jintArray jpos = (*env)->NewIntArray(env, num_rotations);
- if (properties == NULL) {
- NewtCommon_throwNewRuntimeException(env, "Could not allocate int array of size %d", 2);
+ dumpOutputs("XRRScreenResources.outputs", dpy, resources, resources->noutput, resources->outputs);
+
+ fprintf(stderr, "XRRScreenResources %p: Mode count %d\n", resources, resources->nmode);
+ for(i=0; i<resources->nmode; i++) {
+ XRRModeInfo *mode = &resources->modes[i];
+
+ unsigned int dots = mode->hTotal * mode->vTotal;
+ float refresh = getVRefresh(mode);
+ fprintf(stderr, "Mode[%d, id %#lx]: %ux%u@%f, name %s\n", i, mode->id, mode->width, mode->height, refresh, SAFE_STRING(mode->name));
}
-
- // move from the temp structure to the java structure
- (*env)->SetIntArrayRegion(env, jpos, 0, 2, pos);
- return jpos;
}
-JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_RandR13_getAvailableScreenModeRotations0
- (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
+/*
+ * Class: jogamp_newt_driver_x11_RandR13
+ * Method: getMonitorDeviceCount0
+ * Signature: (J)I
+ */
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_RandR13_getMonitorDeviceCount0
+ (JNIEnv *env, jclass clazz, jlong screenResources)
+{
+ XRRScreenResources *resources = (XRRScreenResources *) (intptr_t) screenResources;
+ return ( NULL != resources ) ? resources->ncrtc : 0;
+}
+
+/*
+ * Class: jogamp_newt_driver_x11_RandR13
+ * Method: getMonitorInfoHandle0
+ * Signature: (JIJI)J
+ */
+JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_RandR13_getMonitorInfoHandle0
+ (JNIEnv *env, jclass clazz, jlong display, jint screen_idx, jlong screenResources, jint crt_idx)
{
Display *dpy = (Display *) (intptr_t) display;
- Window root = RootWindow(dpy, (int)scrn_idx);
- int num_rotations = 0;
- Rotation cur_rotation, rotations_supported;
- int rotations[4];
- int major, minor;
+ Window root = RootWindow(dpy, (int)screen_idx);
+ XRRScreenResources *resources = (XRRScreenResources *) (intptr_t) screenResources;
- rotations_supported = XRRRotations (dpy, (int)scrn_idx, &cur_rotation);
+ if( NULL == resources || crt_idx >= resources->ncrtc ) {
+ return 0;
+ }
+ RRCrtc crtc = resources->crtcs[crt_idx];
+ XRRCrtcInfo *xrrCrtcInfo = XRRGetCrtcInfo (dpy, resources, crtc);
+ return (jlong) (intptr_t) xrrCrtcInfo;
+}
+
+/*
+ * Class: jogamp_newt_driver_x11_RandR13
+ * Method: freeMonitorInfoHandle0
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_RandR13_freeMonitorInfoHandle0
+ (JNIEnv *env, jclass clazz, jlong monitorInfo)
+{
+ XRRCrtcInfo *xrrCrtcInfo = (XRRCrtcInfo *) (intptr_t) monitorInfo;
+ if( NULL != xrrCrtcInfo ) {
+ XRRFreeCrtcInfo( xrrCrtcInfo );
+ }
+}
+
+/*
+ * Class: jogamp_newt_driver_x11_RandR13
+ * Method: getAvailableRotations0
+ * Signature: (J)I
+ */
+JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_RandR13_getAvailableRotations0
+ (JNIEnv *env, jclass clazz, jlong monitorInfo)
+{
+ XRRCrtcInfo *xrrCrtcInfo = (XRRCrtcInfo *) (intptr_t) monitorInfo;
+ if( NULL == xrrCrtcInfo ) {
+ return NULL;
+ }
+ Rotation rotations_supported = xrrCrtcInfo->rotations;
+
+ int num_rotations = 0;
+ int rotations[4];
if(0 != (rotations_supported & RR_Rotate_0)) {
rotations[num_rotations++] = 0;
}
@@ -120,7 +225,7 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_RandR13_getAvailableScre
if(0 != (rotations_supported & RR_Rotate_270)) {
rotations[num_rotations++] = 270;
}
-
+
jintArray properties = NULL;
if(num_rotations>0) {
@@ -136,273 +241,275 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_RandR13_getAvailableScre
return properties;
}
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_RandR13_getNumScreenModeResolutions0
- (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
+/*
+ * Class: jogamp_newt_driver_x11_RandR13
+ * Method: getMonitorViewport0
+ * Signature: (J)[I
+ */
+JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_RandR13_getMonitorViewport0
+ (JNIEnv *env, jclass clazz, jlong monitorInfo)
{
- Display *dpy = (Display *) (intptr_t) display;
- Window root = RootWindow(dpy, (int)scrn_idx);
-
- int num_sizes;
- XRRScreenSize *xrrs = XRRSizes(dpy, (int)scrn_idx, &num_sizes); //get possible screen resolutions
-
- DBG_PRINT("getNumScreenModeResolutions0: %d\n", num_sizes);
+ XRRCrtcInfo *xrrCrtcInfo = (XRRCrtcInfo *) (intptr_t) monitorInfo;
- int i;
- XRRScreenResources *xrrScreenResources = XRRGetScreenResources(dpy, root);
- fprintf(stderr, "XRRScreenResources %p: RRCrtc crtcs %d\n", xrrScreenResources, xrrScreenResources->ncrtc);
- for(i=0; i<xrrScreenResources->ncrtc; i++) {
- RRCrtc crtc = xrrScreenResources->crtcs[i];
- XRRCrtcInfo *xrrCrtcInfo = XRRGetCrtcInfo (dpy, xrrScreenResources, crtc);
- fprintf(stderr, "RRCrtc %d: %d/%d %dx%d\n", i, xrrCrtcInfo->x, xrrCrtcInfo->y, xrrCrtcInfo->width, xrrCrtcInfo->height);
- XRRFreeCrtcInfo(xrrCrtcInfo);
+ if( NULL == xrrCrtcInfo ) {
+ // n/a
+ return NULL;
}
- fprintf(stderr, "XRRScreenResources %p: XRRModeInfo modes %d\n", xrrScreenResources, xrrScreenResources->nmode);
- for(i=0; i<xrrScreenResources->nmode; i++) {
- XRRModeInfo xrrModeInfo = xrrScreenResources->modes[i];
- fprintf(stderr, "XRRModeInfo %d: %dx%d, %s, %X\n", i, xrrModeInfo.width, xrrModeInfo.height, xrrModeInfo.name, xrrModeInfo.id);
+
+ if( None == xrrCrtcInfo->mode || 0 == xrrCrtcInfo->noutput ) {
+ // disabled
+ return NULL;
}
- XRRFreeScreenResources(xrrScreenResources);
- return num_sizes;
+ jsize propCount = 4;
+ jint prop[ propCount ];
+ int propIndex = 0;
+
+ prop[propIndex++] = xrrCrtcInfo->x;
+ prop[propIndex++] = xrrCrtcInfo->y;
+ prop[propIndex++] = xrrCrtcInfo->width;
+ prop[propIndex++] = xrrCrtcInfo->height;
+
+ jintArray properties = (*env)->NewIntArray(env, propCount);
+ if (properties == NULL) {
+ NewtCommon_throwNewRuntimeException(env, "Could not allocate int array of size %d", propCount);
+ }
+ (*env)->SetIntArrayRegion(env, properties, 0, propCount, prop);
+
+ return properties;
}
/*
* Class: jogamp_newt_driver_x11_RandR13
- * Method: getScreenModeResolutions0
- * Signature: (JII)[I
+ * Method: getMonitorMode0
+ * Signature: (JI)[I
*/
-JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_RandR13_getScreenModeResolution0
- (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx, jint resMode_idx)
+JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_RandR13_getMonitorMode0
+ (JNIEnv *env, jclass clazz, jlong screenResources, jint mode_idx)
{
- Display *dpy = (Display *) (intptr_t) display;
-
- int num_sizes;
- XRRScreenSize *xrrs = XRRSizes(dpy, (int)scrn_idx, &num_sizes); //get possible screen resolutions
+ XRRScreenResources *resources = (XRRScreenResources *) (intptr_t) screenResources;
+
+ if( NULL == resources || mode_idx >= resources->nmode ) {
+ return NULL;
+ }
- if( 0 > resMode_idx || resMode_idx >= num_sizes ) {
- NewtCommon_throwNewRuntimeException(env, "Invalid resolution index: ! 0 < %d < %d", resMode_idx, num_sizes);
+ XRRModeInfo *mode = &resources->modes[mode_idx];
+ unsigned int dots = mode->hTotal * mode->vTotal;
+ int refresh = (int) ( getVRefresh(mode) * 100.0f ); // Hz * 100
+ int flags = 0;
+ if (mode->modeFlags & RR_Interlace) {
+ flags |= FLAG_INTERLACE;
}
-
- // Fill the properties in temp jint array
+ if (mode->modeFlags & RR_DoubleScan) {
+ flags |= FLAG_DOUBLESCAN;
+ }
+
+ jint prop[ NUM_MONITOR_MODE_PROPERTIES_ALL ];
int propIndex = 0;
- jint prop[4];
-
- prop[propIndex++] = xrrs[(int)resMode_idx].width;
- prop[propIndex++] = xrrs[(int)resMode_idx].height;
- prop[propIndex++] = xrrs[(int)resMode_idx].mwidth;
- prop[propIndex++] = xrrs[(int)resMode_idx].mheight;
-
- jintArray properties = (*env)->NewIntArray(env, 4);
+
+ prop[propIndex++] = NUM_MONITOR_MODE_PROPERTIES_ALL;
+ prop[propIndex++] = mode->width;
+ prop[propIndex++] = mode->height;
+ prop[propIndex++] = 32; // TODO: XRandR > 1.4 may support bpp
+ prop[propIndex++] = refresh;
+ prop[propIndex++] = flags;
+ prop[propIndex++] = mode->id;
+ prop[propIndex++] = -1; // rotation placeholder
+
+ jintArray properties = (*env)->NewIntArray(env, NUM_MONITOR_MODE_PROPERTIES_ALL);
if (properties == NULL) {
- NewtCommon_throwNewRuntimeException(env, "Could not allocate int array of size %d", 4);
+ NewtCommon_throwNewRuntimeException(env, "Could not allocate int array of size %d", NUM_MONITOR_MODE_PROPERTIES_ALL);
}
-
- // move from the temp structure to the java structure
- (*env)->SetIntArrayRegion(env, properties, 0, 4, prop);
+ (*env)->SetIntArrayRegion(env, properties, 0, NUM_MONITOR_MODE_PROPERTIES_ALL, prop);
return properties;
}
/*
* Class: jogamp_newt_driver_x11_RandR13
- * Method: getScreenModeRates0
- * Signature: (JII)[I
+ * Method: getMonitorCurrentMode0
+ * Signature: (JJ)[I
*/
-JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_RandR13_getScreenModeRates0
- (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx, jint resMode_idx)
+JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_RandR13_getMonitorCurrentMode0
+ (JNIEnv *env, jclass clazz, jlong screenResources, jlong monitorInfo)
{
- Display *dpy = (Display *) (intptr_t) display;
-
- int num_sizes;
- XRRScreenSize *xrrs = XRRSizes(dpy, (int)scrn_idx, &num_sizes); //get possible screen resolutions
+ XRRScreenResources *resources = (XRRScreenResources *) (intptr_t) screenResources;
+ XRRCrtcInfo *xrrCrtcInfo = (XRRCrtcInfo *) (intptr_t) monitorInfo;
- if( 0 > resMode_idx || resMode_idx >= num_sizes ) {
- NewtCommon_throwNewRuntimeException(env, "Invalid resolution index: ! 0 < %d < %d", resMode_idx, num_sizes);
+ if( NULL == resources || NULL == xrrCrtcInfo ) {
+ // n/a
+ return NULL;
}
-
- int num_rates;
- short *rates = XRRRates(dpy, (int)scrn_idx, (int)resMode_idx, &num_rates);
-
- jint prop[num_rates];
+
+ if( None == xrrCrtcInfo->mode || 0 == xrrCrtcInfo->noutput ) {
+ // disabled
+ return NULL;
+ }
+
+ int modeId = xrrCrtcInfo->mode;
+ XRRModeInfo *mode = NULL;
int i;
- for(i=0; i<num_rates; i++) {
- prop[i] = (int) rates[i];
- /** fprintf(stderr, "rate[%d, %d, %d/%d]: %d\n", (int)scrn_idx, resMode_idx, i, num_rates, prop[i]); */
+ for(i=0; i<resources->nmode; i++) {
+ XRRModeInfo *imode = &resources->modes[i];
+ if( imode->id == modeId ) {
+ mode = imode;
+ break;
+ }
}
-
- jintArray properties = (*env)->NewIntArray(env, num_rates);
+ if( NULL == mode ) {
+ // oops ..
+ return NULL;
+ }
+
+ unsigned int dots = mode->hTotal * mode->vTotal;
+ int refresh = (int) ( getVRefresh(mode) * 100.0f ); // Hz * 100
+ int flags = 0;
+ if (mode->modeFlags & RR_Interlace) {
+ flags |= FLAG_INTERLACE;
+ }
+ if (mode->modeFlags & RR_DoubleScan) {
+ flags |= FLAG_DOUBLESCAN;
+ }
+
+ jint prop[ NUM_MONITOR_MODE_PROPERTIES_ALL ];
+ int propIndex = 0;
+
+ prop[propIndex++] = NUM_MONITOR_MODE_PROPERTIES_ALL;
+ prop[propIndex++] = mode->width;
+ prop[propIndex++] = mode->height;
+ prop[propIndex++] = 32; // TODO: XRandR > 1.4 may support bpp
+ prop[propIndex++] = refresh;
+ prop[propIndex++] = flags;
+ prop[propIndex++] = mode->id;
+ prop[propIndex++] = NewtScreen_XRotation2Degree(env, xrrCrtcInfo->rotation);
+
+ jintArray properties = (*env)->NewIntArray(env, NUM_MONITOR_MODE_PROPERTIES_ALL);
if (properties == NULL) {
- NewtCommon_throwNewRuntimeException(env, "Could not allocate int array of size %d", num_rates);
+ NewtCommon_throwNewRuntimeException(env, "Could not allocate int array of size %d", NUM_MONITOR_MODE_PROPERTIES_ALL);
}
-
- // move from the temp structure to the java structure
- (*env)->SetIntArrayRegion(env, properties, 0, num_rates, prop);
+ (*env)->SetIntArrayRegion(env, properties, 0, NUM_MONITOR_MODE_PROPERTIES_ALL, prop);
return properties;
}
/*
* Class: jogamp_newt_driver_x11_RandR13
- * Method: getCurrentScreenRate0
- * Signature: (JI)I
+ * Method: getMonitorDevice0
+ * Signature: (JJJJ)[I
*/
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_RandR13_getCurrentScreenRate0
- (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
+JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_RandR13_getMonitorDevice0
+ (JNIEnv *env, jclass clazz, jlong display, jlong screenResources, jlong monitorInfo, jint crt_idx)
{
- Display *dpy = (Display *) (intptr_t) display;
- Window root = RootWindow(dpy, (int)scrn_idx);
-
- // get current resolutions and frequencies
- XRRScreenConfiguration *conf = XRRGetScreenInfo(dpy, root);
- short original_rate = XRRConfigCurrentRate(conf);
+ Display * dpy = (Display *) (intptr_t) display;
+ XRRScreenResources *resources = (XRRScreenResources *) (intptr_t) screenResources;
+ XRRCrtcInfo *xrrCrtcInfo = (XRRCrtcInfo *) (intptr_t) monitorInfo;
- //free
- XRRFreeScreenConfigInfo(conf);
-
- DBG_PRINT("getCurrentScreenRate0: %d\n", (int)original_rate);
+ if( NULL == resources || NULL == xrrCrtcInfo || crt_idx >= resources->ncrtc ) {
+ // n/a
+ return NULL;
+ }
- return (jint) original_rate;
-}
+ if( None == xrrCrtcInfo->mode || 0 == xrrCrtcInfo->noutput ) {
+ // disabled
+ return NULL;
+ }
-/*
- * Class: jogamp_newt_driver_x11_RandR13
- * Method: getCurrentScreenRotation0
- * Signature: (JI)I
- */
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_RandR13_getCurrentScreenRotation0
- (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
-{
- Display *dpy = (Display *) (intptr_t) display;
- Window root = RootWindow(dpy, (int)scrn_idx);
-
- //get current resolutions and frequencies
- XRRScreenConfiguration *conf = XRRGetScreenInfo(dpy, root);
-
- Rotation rotation;
- XRRConfigCurrentConfiguration(conf, &rotation);
+ RROutput output = xrrCrtcInfo->outputs[0];
+ XRROutputInfo * xrrOutputInfo = XRRGetOutputInfo (dpy, resources, output);
+ int numModes = xrrOutputInfo->nmode;
- //free
- XRRFreeScreenConfigInfo(conf);
-
- return NewtScreen_XRotation2Degree(env, rotation);
-}
+ jsize propCount = MIN_MONITOR_DEVICE_PROPERTIES - 1 + numModes;
+ jint prop[ propCount ];
+ int propIndex = 0;
+ prop[propIndex++] = propCount;
+ prop[propIndex++] = crt_idx;
+ prop[propIndex++] = xrrOutputInfo->mm_width;
+ prop[propIndex++] = xrrOutputInfo->mm_height;
+ prop[propIndex++] = xrrCrtcInfo->x;
+ prop[propIndex++] = xrrCrtcInfo->y;
+ prop[propIndex++] = xrrCrtcInfo->width;
+ prop[propIndex++] = xrrCrtcInfo->height;
+ prop[propIndex++] = xrrCrtcInfo->mode; // current mode id
+ prop[propIndex++] = NewtScreen_XRotation2Degree(env, xrrCrtcInfo->rotation);
+ int i;
+ for(i=0; i<numModes; i++) {
+ // avail modes ..
+ prop[propIndex++] = xrrOutputInfo->modes[i];
+ }
-/*
- * Class: jogamp_newt_driver_x11_RandR13
- * Method: getCurrentScreenResolutionIndex0
- * Signature: (JI)I
- */
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_RandR13_getCurrentScreenResolutionIndex0
- (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
-{
- Display *dpy = (Display *) (intptr_t) display;
- Window root = RootWindow(dpy, (int)scrn_idx);
-
- // get current resolutions and frequency configuration
- XRRScreenConfiguration *conf = XRRGetScreenInfo(dpy, root);
- short original_rate = XRRConfigCurrentRate(conf);
-
- Rotation original_rotation;
- SizeID original_size_id = XRRConfigCurrentConfiguration(conf, &original_rotation);
-
- //free
- XRRFreeScreenConfigInfo(conf);
-
- DBG_PRINT("getCurrentScreenResolutionIndex0: %d\n", (int)original_size_id);
- return (jint)original_size_id;
+ XRRFreeOutputInfo (xrrOutputInfo);
+
+ jintArray properties = (*env)->NewIntArray(env, propCount);
+ if (properties == NULL) {
+ NewtCommon_throwNewRuntimeException(env, "Could not allocate int array of size %d", propCount);
+ }
+ (*env)->SetIntArrayRegion(env, properties, 0, propCount, prop);
+
+ return properties;
}
/*
* Class: jogamp_newt_driver_x11_RandR13
- * Method: setCurrentScreenModeStart0
- * Signature: (JIIII)Z
+ * Method: setMonitorMode0
+ * Signature: (JJJIIIII)Z
*/
-JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_RandR13_setCurrentScreenModeStart0
- (JNIEnv *env, jclass clazz, jlong display, jint screen_idx, jint resMode_idx, jint freq, jint rotation)
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_RandR13_setMonitorMode0
+ (JNIEnv *env, jclass clazz, jlong display, jlong screenResources, jlong monitorInfo, jint crt_idx, jint modeId, jint rotation, jint x, jint y)
{
- Display *dpy = (Display *) (intptr_t) display;
- Window root = RootWindow(dpy, (int)screen_idx);
+ Display * dpy = (Display *) (intptr_t) display;
+ XRRScreenResources *resources = (XRRScreenResources *) (intptr_t) screenResources;
+ XRRCrtcInfo *xrrCrtcInfo = (XRRCrtcInfo *) (intptr_t) monitorInfo;
+ jboolean res = JNI_FALSE;
- int num_sizes;
- XRRScreenSize *xrrs = XRRSizes(dpy, (int)screen_idx, &num_sizes); //get possible screen resolutions
- XRRScreenConfiguration *conf;
- int rot;
-
- if( 0 > resMode_idx || resMode_idx >= num_sizes ) {
- NewtCommon_throwNewRuntimeException(env, "Invalid resolution index: ! 0 < %d < %d", resMode_idx, num_sizes);
+ if( NULL == resources || NULL == xrrCrtcInfo || crt_idx >= resources->ncrtc ) {
+ // n/a
+ return res;
}
- conf = XRRGetScreenInfo(dpy, root);
-
- rot = int NewtScreen_Degree2XRotation(env, rotation);
-
- DBG_PRINT("X11Screen.setCurrentScreenMode0: CHANGED TO %d: %d x %d PIXELS, %d Hz, %d degree\n",
- resMode_idx, xrrs[resMode_idx].width, xrrs[resMode_idx].height, (int)freq, rotation);
+ if( None == xrrCrtcInfo->mode || 0 == xrrCrtcInfo->noutput ) {
+ // disabled
+ return res;
+ }
- XRRSelectInput (dpy, root, RRScreenChangeNotifyMask);
+ if( 0 >= modeId ) {
+ // oops ..
+ return res;
+ }
- XSync(dpy, False);
- XRRSetScreenConfigAndRate(dpy, conf, root, (int)resMode_idx, rot, (short)freq, CurrentTime);
- XSync(dpy, False);
+ if( 0 > x || 0 > y ) {
+ x = xrrCrtcInfo->x;
+ y = xrrCrtcInfo->y;
+ }
- //free
- XRRFreeScreenConfigInfo(conf);
- XSync(dpy, False);
+ Status status = XRRSetCrtcConfig( dpy, resources, resources->crtcs[crt_idx], CurrentTime,
+ x, y, modeId, NewtScreen_Degree2XRotation(env, rotation),
+ xrrCrtcInfo->outputs, xrrCrtcInfo->noutput );
+ res = status == RRSetConfigSuccess;
- return JNI_TRUE;
+ return res;
}
/*
* Class: jogamp_newt_driver_x11_RandR13
- * Method: setCurrentScreenModePollEnd0
- * Signature: (J)Z
+ * Method: setScreenViewport0
+ * Signature: (JIJIIII)Z
*/
-JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_RandR13_setCurrentScreenModePollEnd0
- (JNIEnv *env, jclass clazz, jlong display, jint screen_idx, jint resMode_idx, jint freq, jint rotation)
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_RandR13_setScreenViewport0
+ (JNIEnv *env, jclass clazz, jlong display, jint screen_idx, jlong screenResources, jint x, jint y, jint width, jint height)
{
- Display *dpy = (Display *) (intptr_t) display;
- int randr_event_base, randr_error_base;
- XEvent evt;
- XRRScreenChangeNotifyEvent * scn_event = (XRRScreenChangeNotifyEvent *) &evt;
+ Display * dpy = (Display *) (intptr_t) display;
+ Window root = RootWindow(dpy, (int)screen_idx);
+ XRRScreenResources *resources = (XRRScreenResources *) (intptr_t) screenResources;
+ jboolean res = JNI_FALSE;
- int num_sizes;
- XRRScreenSize *xrrs = XRRSizes(dpy, (int)screen_idx, &num_sizes); //get possible screen resolutions
- XRRScreenConfiguration *conf;
-
- if( 0 > resMode_idx || resMode_idx >= num_sizes ) {
- NewtCommon_throwNewRuntimeException(env, "Invalid resolution index: ! 0 < %d < %d", resMode_idx, num_sizes);
+ if( NULL == resources ) {
+ // n/a
+ return JNI_FALSE;
}
- XRRQueryExtension(dpy, &randr_event_base, &randr_error_base);
-
- int done = 0;
- int rot;
- do {
- if ( 0 >= XEventsQueued(dpy, QueuedAfterFlush) ) {
- return;
- }
- XNextEvent(dpy, &evt);
-
- switch (evt.type - randr_event_base) {
- case RRScreenChangeNotify:
- rot = NewtScreen_XRotation2Degree(env, (int)scn_event->rotation);
- DBG_PRINT( "XRANDR: event . RRScreenChangeNotify call %p (root %p) resIdx %d rot %d %dx%d\n",
- (void*)scn_event->window, (void*)scn_event->root,
- (int)scn_event->size_index, rot,
- scn_event->width, scn_event->height);
- // done = scn_event->size_index == resMode_idx; // not reliable ..
- done = rot == rotation &&
- scn_event->width == xrrs[resMode_idx].width &&
- scn_event->height == xrrs[resMode_idx].height;
- break;
- default:
- DBG_PRINT("RANDR: event . unhandled %d 0x%X call %p\n", (int)evt.type, (int)evt.type, (void*)evt.xany.window);
- }
- XRRUpdateConfiguration(&evt);
- } while(!done);
-
- XSync(dpy, False);
-
+ XRRSetScreenSize (dpy, root, width, height, DisplayWidthMM(dpy, screen_idx), DisplayHeightMM(dpy, screen_idx));
+ return JNI_TRUE;
}
+
diff --git a/src/newt/native/X11Screen.c b/src/newt/native/X11Screen.c
index 3d4b2a26c..152a092c9 100644
--- a/src/newt/native/X11Screen.c
+++ b/src/newt/native/X11Screen.c
@@ -75,22 +75,41 @@ JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_ScreenDriver_getHeight0
}
int NewtScreen_XRotation2Degree(JNIEnv *env, int xrotation) {
- int rot;
+ int degree;
if(xrotation == RR_Rotate_0) {
- rot = 0;
+ degree = 0;
}
else if(xrotation == RR_Rotate_90) {
- rot = 90;
+ degree = 90;
}
else if(xrotation == RR_Rotate_180) {
- rot = 180;
+ degree = 180;
}
else if(xrotation == RR_Rotate_270) {
- rot = 270;
+ degree = 270;
} else {
NewtCommon_throwNewRuntimeException(env, "invalid native rotation: %d", xrotation);
}
- return rot;
+ return degree;
+}
+
+int NewtScreen_Degree2XRotation(JNIEnv *env, int degree) {
+ int xrot;
+ if(degree == 0) {
+ xrot = RR_Rotate_0;
+ }
+ else if(degree == 90) {
+ xrot = RR_Rotate_90;
+ }
+ else if(degree == 180) {
+ xrot = RR_Rotate_180;
+ }
+ else if(degree == 270) {
+ xrot = RR_Rotate_270;
+ } else {
+ NewtCommon_throwNewRuntimeException(env, "invalid degree: %d", degree);
+ }
+ return xrot;
}
/*
diff --git a/src/newt/native/X11Screen.h b/src/newt/native/X11Screen.h
index 1a1440054..c81ee05d5 100644
--- a/src/newt/native/X11Screen.h
+++ b/src/newt/native/X11Screen.h
@@ -33,5 +33,6 @@
#include "X11Common.h"
int NewtScreen_XRotation2Degree(JNIEnv *env, int xrotation);
+int NewtScreen_Degree2XRotation(JNIEnv *env, int degree);
#endif /* _X11SCREEN_H */
diff --git a/src/newt/native/X11Window.c b/src/newt/native/X11Window.c
index 9e96169f5..6c5a127b6 100644
--- a/src/newt/native/X11Window.c
+++ b/src/newt/native/X11Window.c
@@ -438,7 +438,7 @@ Status NewtWindows_updateInsets(JNIEnv *env, jobject jwindow, Display *dpy, Wind
return 0; // Error
}
-static void NewtWindows_requestFocus (JNIEnv *env, jobject window, Display *dpy, Window w, jboolean force) {
+static void NewtWindows_requestFocus (Display *dpy, Window w, Bool force) {
XWindowAttributes xwa;
Window focus_return;
int revert_to_return;
@@ -447,7 +447,7 @@ static void NewtWindows_requestFocus (JNIEnv *env, jobject window, Display *dpy,
XGetInputFocus(dpy, &focus_return, &revert_to_return);
DBG_PRINT( "X11: requestFocus dpy %p,win %p, force %d, hasFocus %d\n", dpy, (void*)w, force, focus_return==w);
- if( JNI_TRUE==force || focus_return!=w) {
+ if( True==force || focus_return!=w) {
DBG_PRINT( "X11: XRaiseWindow dpy %p, win %p\n", dpy, (void*)w);
XRaiseWindow(dpy, w);
NewtWindows_setCWAbove(dpy, w);
@@ -743,7 +743,9 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_reconfigureWindo
Bool tempInvisible = ( TST_FLAG_CHANGE_FULLSCREEN(flags) || TST_FLAG_CHANGE_PARENTING(flags) ) && isVisible ;
int fsEWMHFlags = 0;
if( TST_FLAG_CHANGE_FULLSCREEN(flags) ) {
- fsEWMHFlags |= _NET_WM_FULLSCREEN;
+ if( !TST_FLAG_IS_FULLSCREEN_SPAN(flags) ) { // doesn't work w/ spanning across monitors
+ fsEWMHFlags |= _NET_WM_FULLSCREEN;
+ }
if( TST_FLAG_IS_FULLSCREEN(flags) ) {
if( TST_FLAG_IS_ALWAYSONTOP(flags) ) {
fsEWMHFlags |= _NET_WM_ABOVE; // fs on, above on
@@ -756,12 +758,12 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_reconfigureWindo
fsEWMHFlags |= _NET_WM_ABOVE; // toggle above
}
- DBG_PRINT( "X11: reconfigureWindow0 dpy %p, scrn %d, parent %p/%p, win %p, %d/%d %dx%d, parentChange %d, hasParent %d, decorationChange %d, undecorated %d, fullscreenChange %d, fullscreen %d, alwaysOnTopChange %d, alwaysOnTop %d, visibleChange %d, visible %d, tempInvisible %d, fsEWMHFlags %d\n",
+ DBG_PRINT( "X11: reconfigureWindow0 dpy %p, scrn %d, parent %p/%p, win %p, %d/%d %dx%d, parentChange %d, hasParent %d, decorationChange %d, undecorated %d, fullscreenChange %d, fullscreen %d (span %d), alwaysOnTopChange %d, alwaysOnTop %d, visibleChange %d, visible %d, tempInvisible %d, fsEWMHFlags %d\n",
(void*)dpy, screen_index, (void*) jparent, (void*)parent, (void*)w,
x, y, width, height,
TST_FLAG_CHANGE_PARENTING(flags), TST_FLAG_HAS_PARENT(flags),
TST_FLAG_CHANGE_DECORATION(flags), TST_FLAG_IS_UNDECORATED(flags),
- TST_FLAG_CHANGE_FULLSCREEN(flags), TST_FLAG_IS_FULLSCREEN(flags),
+ TST_FLAG_CHANGE_FULLSCREEN(flags), TST_FLAG_IS_FULLSCREEN(flags), TST_FLAG_IS_FULLSCREEN_SPAN(flags),
TST_FLAG_CHANGE_ALWAYSONTOP(flags), TST_FLAG_IS_ALWAYSONTOP(flags),
TST_FLAG_CHANGE_VISIBILITY(flags), TST_FLAG_IS_VISIBLE(flags), tempInvisible, fsEWMHFlags);
@@ -769,9 +771,13 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_reconfigureWindo
// However, we have to consider other cases like reparenting and WM which don't support it.
if( fsEWMHFlags && !TST_FLAG_CHANGE_PARENTING(flags) && isVisible &&
+ !TST_FLAG_IS_FULLSCREEN_SPAN(flags) &&
( TST_FLAG_CHANGE_FULLSCREEN(flags) || TST_FLAG_CHANGE_ALWAYSONTOP(flags) ) ) {
Bool enable = TST_FLAG_CHANGE_FULLSCREEN(flags) ? TST_FLAG_IS_FULLSCREEN(flags) : TST_FLAG_IS_ALWAYSONTOP(flags) ;
if( NewtWindows_setFullscreenEWMH(dpy, root, w, fsEWMHFlags, isVisible, enable) ) {
+ if ( TST_FLAG_CHANGE_FULLSCREEN(flags) && !TST_FLAG_IS_FULLSCREEN(flags) ) { // FS off - restore decoration
+ NewtWindows_setDecorations (dpy, w, TST_FLAG_IS_UNDECORATED(flags) ? False : True);
+ }
#ifdef FS_GRAB_KEYBOARD
if(TST_FLAG_CHANGE_FULLSCREEN(flags)) {
if(TST_FLAG_IS_FULLSCREEN(flags)) {
@@ -866,7 +872,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_reconfigureWindo
JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_WindowDriver_requestFocus0
(JNIEnv *env, jobject obj, jlong display, jlong window, jboolean force)
{
- NewtWindows_requestFocus ( env, obj, (Display *) (intptr_t) display, (Window)window, force ) ;
+ NewtWindows_requestFocus ( (Display *) (intptr_t) display, (Window)window, JNI_TRUE==force?True:False ) ;
}
/*