aboutsummaryrefslogtreecommitdiffstats
path: root/src/newt/classes/jogamp
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/classes/jogamp
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/classes/jogamp')
-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
21 files changed, 2224 insertions, 927 deletions
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;
} } );
}