aboutsummaryrefslogtreecommitdiffstats
path: root/src/newt
diff options
context:
space:
mode:
Diffstat (limited to 'src/newt')
-rw-r--r--src/newt/classes/com/jogamp/newt/MonitorDevice.java97
-rw-r--r--src/newt/classes/com/jogamp/newt/Screen.java52
-rw-r--r--src/newt/classes/com/jogamp/newt/Window.java23
-rw-r--r--src/newt/classes/jogamp/newt/MonitorDeviceImpl.java11
-rw-r--r--src/newt/classes/jogamp/newt/MonitorModeProps.java19
-rw-r--r--src/newt/classes/jogamp/newt/ScreenImpl.java66
-rw-r--r--src/newt/classes/jogamp/newt/WindowImpl.java26
-rw-r--r--src/newt/classes/jogamp/newt/driver/android/WindowDriver.java3
-rw-r--r--src/newt/classes/jogamp/newt/driver/awt/AWTCanvas.java6
-rw-r--r--src/newt/classes/jogamp/newt/driver/awt/WindowDriver.java11
-rw-r--r--src/newt/classes/jogamp/newt/driver/bcm/egl/ScreenDriver.java4
-rw-r--r--src/newt/classes/jogamp/newt/driver/bcm/vc/iv/ScreenDriver.java4
-rw-r--r--src/newt/classes/jogamp/newt/driver/bcm/vc/iv/WindowDriver.java6
-rw-r--r--src/newt/classes/jogamp/newt/driver/intel/gdl/ScreenDriver.java4
-rw-r--r--src/newt/classes/jogamp/newt/driver/kd/ScreenDriver.java4
-rw-r--r--src/newt/classes/jogamp/newt/driver/macosx/ScreenDriver.java148
-rw-r--r--src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java117
-rw-r--r--src/newt/classes/jogamp/newt/driver/windows/ScreenDriver.java26
-rw-r--r--src/newt/classes/jogamp/newt/driver/x11/ScreenDriver.java24
-rw-r--r--src/newt/native/MacWindow.m133
-rw-r--r--src/newt/native/NewtMacWindow.h5
-rw-r--r--src/newt/native/NewtMacWindow.m39
-rw-r--r--src/newt/native/ScreenMode.h3
-rw-r--r--src/newt/native/WindowsWindow.c12
-rw-r--r--src/newt/native/X11RandR13.c12
25 files changed, 593 insertions, 262 deletions
diff --git a/src/newt/classes/com/jogamp/newt/MonitorDevice.java b/src/newt/classes/com/jogamp/newt/MonitorDevice.java
index af0ce0146..8e5d305dd 100644
--- a/src/newt/classes/com/jogamp/newt/MonitorDevice.java
+++ b/src/newt/classes/com/jogamp/newt/MonitorDevice.java
@@ -52,6 +52,9 @@ import com.jogamp.common.util.ArrayHashSet;
* <li>{@link RectangleImmutable} viewport (rotated)</li>
* </ul></li>
* </ul>
+ * <p>
+ * All values of this interface are represented in pixel units, if not stated otherwise.
+ * </p>
*/
public abstract class MonitorDevice {
protected final Screen screen; // backref
@@ -61,16 +64,18 @@ public abstract class MonitorDevice {
protected final ArrayHashSet<MonitorMode> supportedModes; // FIXME: May need to support mutable mode, i.e. adding modes on the fly!
protected MonitorMode currentMode;
protected boolean modeChanged;
- protected Rectangle viewport;
+ protected Rectangle viewportPU; // in pixel units
+ protected Rectangle viewportWU; // in window units
- protected MonitorDevice(Screen screen, int nativeId, DimensionImmutable sizeMM, Rectangle viewport, MonitorMode currentMode, ArrayHashSet<MonitorMode> supportedModes) {
+ protected MonitorDevice(Screen screen, int nativeId, DimensionImmutable sizeMM, Rectangle viewportPU, Rectangle viewportWU, MonitorMode currentMode, ArrayHashSet<MonitorMode> supportedModes) {
this.screen = screen;
this.nativeId = nativeId;
this.sizeMM = sizeMM;
this.originalMode = currentMode;
this.supportedModes = supportedModes;
this.currentMode = currentMode;
- this.viewport = viewport;
+ this.viewportPU = viewportPU;
+ this.viewportWU = viewportWU;
this.modeChanged = false;
}
@@ -170,11 +175,22 @@ public abstract class MonitorDevice {
/**
* Returns the {@link RectangleImmutable rectangular} portion
- * of the rotated virtual {@link Screen} size in pixel units
- * represented by this monitor.
+ * of the <b>rotated</b> virtual {@link Screen} size in pixel units
+ * represented by this monitor, i.e. top-left origin and size.
+ * @see Screen
*/
public final RectangleImmutable getViewport() {
- return viewport;
+ return viewportPU;
+ }
+
+ /**
+ * Returns the {@link RectangleImmutable rectangular} portion
+ * of the <b>rotated</b> virtual {@link Screen} size in window units
+ * represented by this monitor, i.e. top-left origin and size.
+ * @see Screen
+ */
+ public final RectangleImmutable getViewportInWindowUnits() {
+ return viewportWU;
}
/**
@@ -184,46 +200,45 @@ public abstract class MonitorDevice {
* @param y y-coord in pixel units
*/
public final boolean contains(final int x, final int y) {
- return x >= viewport.getX() &&
- x < viewport.getX() + viewport.getWidth() &&
- y >= viewport.getY() &&
- y < viewport.getY() + viewport.getHeight() ;
+ return x >= viewportPU.getX() &&
+ x < viewportPU.getX() + viewportPU.getWidth() &&
+ y >= viewportPU.getY() &&
+ y < viewportPU.getY() + viewportPU.getHeight() ;
}
/**
- * Returns the coverage of given rectangle in pixel units
- * w/ this {@link #getViewport() viewport}, i.e. between <code>0.0</code> and <code>1.0</code>.
- * <p>
- * Coverage is computed by:
- * <pre>
- * isect = viewport.intersection(r);
- * coverage = area( isect ) / area( viewport ) ;
- * </pre>
- * </p>
- * @param r {@link RectangleImmutable rectangle} in pixel units
- */
- public final float coverage(final RectangleImmutable r) {
- return viewport.coverage(r);
- }
-
- /**
- * Returns the union of the given monitor's {@link #getViewport() viewport} in pixel units.
- * @param result storage for result, will be returned
+ * Calculates the union of the given monitor's {@link #getViewport() viewport} in pixel- and window units.
+ * @param viewport storage for result in pixel units, maybe null
+ * @param viewportInWindowUnits storage for result in window units, maybe null
* @param monitors given list of monitors
- * @return viewport representing the union of given monitor's viewport in pixel units, i.e. result storage for chaining
*/
- public static Rectangle unionOfViewports(final Rectangle result, final List<MonitorDevice> monitors) {
- int x1=Integer.MAX_VALUE, y1=Integer.MAX_VALUE;
- int x2=Integer.MIN_VALUE, y2=Integer.MIN_VALUE;
+ public static void unionOfViewports(final Rectangle viewport, final Rectangle viewportInWindowUnits, final List<MonitorDevice> monitors) {
+ int x1PU=Integer.MAX_VALUE, y1PU=Integer.MAX_VALUE;
+ int x2PU=Integer.MIN_VALUE, y2PU=Integer.MIN_VALUE;
+ int x1WU=Integer.MAX_VALUE, y1WU=Integer.MAX_VALUE;
+ int x2WU=Integer.MIN_VALUE, y2WU=Integer.MIN_VALUE;
for(int i=monitors.size()-1; i>=0; i--) {
- final RectangleImmutable vp = monitors.get(i).getViewport();
- x1 = Math.min(x1, vp.getX());
- x2 = Math.max(x2, vp.getX() + vp.getWidth());
- y1 = Math.min(y1, vp.getY());
- y2 = Math.max(y2, vp.getY() + vp.getHeight());
+ if( null != viewport ) {
+ final RectangleImmutable viewPU = monitors.get(i).getViewport();
+ x1PU = Math.min(x1PU, viewPU.getX());
+ x2PU = Math.max(x2PU, viewPU.getX() + viewPU.getWidth());
+ y1PU = Math.min(y1PU, viewPU.getY());
+ y2PU = Math.max(y2PU, viewPU.getY() + viewPU.getHeight());
+ }
+ if( null != viewportInWindowUnits ) {
+ final RectangleImmutable viewWU = monitors.get(i).getViewportInWindowUnits();
+ x1WU = Math.min(x1WU, viewWU.getX());
+ x2WU = Math.max(x2WU, viewWU.getX() + viewWU.getWidth());
+ y1WU = Math.min(y1WU, viewWU.getY());
+ y2WU = Math.max(y2WU, viewWU.getY() + viewWU.getHeight());
+ }
+ }
+ if( null != viewport ) {
+ viewport.set(x1PU, y1PU, x2PU - x1PU, y2PU - y1PU);
+ }
+ if( null != viewportInWindowUnits ) {
+ viewportInWindowUnits.set(x1WU, y1WU, x2WU - x1WU, y2WU - y1WU);
}
- result.set(x1, y1, x2 - x1, y2 - y1);
- return result;
}
public final boolean isOriginalMode() {
@@ -247,6 +262,7 @@ public abstract class MonitorDevice {
* <p>
* The returned {@link MonitorMode} is element of the lists {@link #getSupportedModes()} and {@link Screen#getMonitorModes()}.
* </p>
+ * @see #queryCurrentMode()
*/
public final MonitorMode getCurrentMode() {
return currentMode;
@@ -257,6 +273,7 @@ public abstract class MonitorDevice {
* <p>
* The returned {@link MonitorMode} is element of the lists {@link #getSupportedModes()} and {@link Screen#getMonitorModes()}.
* </p>
+ * @see #getCurrentMode()
*/
public abstract MonitorMode queryCurrentMode();
@@ -269,7 +286,7 @@ public abstract class MonitorDevice {
@Override
public String toString() {
- return "Monitor[Id "+Display.toHexString(nativeId)+", "+sizeMM+" mm, viewport "+viewport+ ", orig "+originalMode+", curr "+currentMode+
+ return "Monitor[Id "+Display.toHexString(nativeId)+", "+sizeMM+" mm, viewport "+viewportPU+ " [pixels], "+viewportWU+" [window], orig "+originalMode+", curr "+currentMode+
", modeChanged "+modeChanged+", modeCount "+supportedModes.size()+"]";
}
}
diff --git a/src/newt/classes/com/jogamp/newt/Screen.java b/src/newt/classes/com/jogamp/newt/Screen.java
index 919b98b45..cef254634 100644
--- a/src/newt/classes/com/jogamp/newt/Screen.java
+++ b/src/newt/classes/com/jogamp/newt/Screen.java
@@ -28,12 +28,14 @@
package com.jogamp.newt;
import com.jogamp.newt.event.MonitorModeListener;
+
import jogamp.newt.Debug;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
+
import javax.media.nativewindow.AbstractGraphicsScreen;
import javax.media.nativewindow.NativeWindowException;
import javax.media.nativewindow.util.Rectangle;
@@ -41,7 +43,18 @@ import javax.media.nativewindow.util.RectangleImmutable;
/**
* A screen may span multiple {@link MonitorDevice}s representing their combined virtual size.
- */
+ * <p>
+ * All values of this interface are represented in pixel units, if not stated otherwise.
+ * </p>
+ *
+ * <a name="coordinateSystem"><h5>Coordinate System</h5></a>
+ * <p>
+ * <ul>
+ * <li>Screen space has it's origin in the top-left corner, and may not be at 0/0.</li>
+ * <li>{@link #getViewport() Virtual viewport} covers all {@link MonitorDevice}s {@link MonitorDevice#getViewport() viewports} and has it's origin in the top-left corner, and may not be at 0/0.</li>
+ * </ul>
+ * </p>
+*/
public abstract class Screen {
/**
@@ -131,11 +144,15 @@ public abstract class Screen {
public abstract int getIndex();
/**
+ * See <a href="#coordinateSystem"> Coordinate System</a>.
+ *
* @return the x position of the virtual viewport's top-left origin in pixel units.
*/
public abstract int getX();
/**
+ * See <a href="#coordinateSystem"> Coordinate System</a>.
+ *
* @return the y position of the virtual viewport's top-left origin in pixel units.
*/
public abstract int getY();
@@ -151,20 +168,20 @@ public abstract class Screen {
public abstract int getHeight();
/**
- * @return the <b>rotated</b> virtual viewport, i.e. origin and size in pixel units.
- * @see #getViewportInWindowUnits(Window)
+ * See <a href="#coordinateSystem"> Coordinate System</a>.
+ *
+ * @return the <b>rotated</b> virtual viewport, i.e. top-left origin and size, in pixel units.
+ * @see #getViewportInWindowUnits()
*/
public abstract RectangleImmutable getViewport();
/**
- * Returns a newly created {@link Rectangle} containing the <b>rotated</b> virtual viewport
- * in window units of the given {@link Window} instance.
- * @return rotated viewport values, i.e. origin and size, in pixel units.
+ * See <a href="#coordinateSystem"> Coordinate System</a>.
+ *
+ * @return the <b>rotated</b> virtual viewport, i.e. top-left origin and size, in window units.
* @see #getViewport()
*/
- public final Rectangle getViewportInWindowUnits(final Window win) {
- return win.convertToWindowUnits( (Rectangle) getViewport().cloneMutable() );
- }
+ public abstract RectangleImmutable getViewportInWindowUnits();
/**
* @return the associated Display
@@ -192,12 +209,12 @@ public abstract class Screen {
public abstract List<MonitorDevice> getMonitorDevices();
/**
- * Returns the {@link MonitorDevice} with the highest {@link MonitorDevice#getViewport() viewport}
- * {@link MonitorDevice#coverage(RectangleImmutable) coverage} of the given rectangle in pixel units.
+ * Returns the {@link MonitorDevice} with the highest {@link MonitorDevice#getViewportInWindowUnits() viewport}
+ * {@link RectangleImmutable#coverage(RectangleImmutable) coverage} of the given rectangle in window units.
* <p>
* If no coverage is detected the first {@link MonitorDevice} is returned.
* </p>
- * @param r arbitrary rectangle in pixel units
+ * @param r arbitrary rectangle in window units
*/
public final MonitorDevice getMainMonitor(final RectangleImmutable r) {
MonitorDevice res = null;
@@ -205,7 +222,7 @@ public abstract class Screen {
final List<MonitorDevice> monitors = getMonitorDevices();
for(int i=monitors.size()-1; i>=0; i--) {
final MonitorDevice monitor = monitors.get(i);
- final float coverage = monitor.coverage(r);
+ final float coverage = monitor.getViewportInWindowUnits().coverage(r);
if( coverage > maxCoverage ) {
maxCoverage = coverage;
res = monitor;
@@ -218,15 +235,16 @@ public abstract class Screen {
}
/**
- * Returns the union of all monitor's {@link MonitorDevice#getViewport() viewport} in pixel units.
+ * Calculates the union of all monitor's {@link MonitorDevice#getViewport() viewport} in pixel- and window units.
* <p>
* Should be equal to {@link #getX()}, {@link #getY()}, {@link #getWidth()} and {@link #getHeight()},
* however, some native toolkits may choose a different virtual screen area.
* </p>
- * @param result storage for result, will be returned
+ * @param viewport storage for result in pixel units, maybe null
+ * @param viewportInWindowUnits storage for result in window units, maybe null
*/
- public final Rectangle unionOfMonitorViewportSize(final Rectangle result) {
- return MonitorDevice.unionOfViewports(result, getMonitorDevices());
+ public final void unionOfMonitorViewports(final Rectangle viewport, final Rectangle viewportInWindowUnits) {
+ MonitorDevice.unionOfViewports(viewport, viewportInWindowUnits, getMonitorDevices());
}
/**
diff --git a/src/newt/classes/com/jogamp/newt/Window.java b/src/newt/classes/com/jogamp/newt/Window.java
index 872d67087..57fcb626d 100644
--- a/src/newt/classes/com/jogamp/newt/Window.java
+++ b/src/newt/classes/com/jogamp/newt/Window.java
@@ -46,7 +46,6 @@ import javax.media.nativewindow.CapabilitiesChooser;
import javax.media.nativewindow.CapabilitiesImmutable;
import javax.media.nativewindow.NativeWindow;
import javax.media.nativewindow.WindowClosingProtocol;
-import javax.media.nativewindow.util.Point;
import javax.media.nativewindow.util.Rectangle;
import javax.media.nativewindow.util.RectangleImmutable;
@@ -65,6 +64,20 @@ import javax.media.nativewindow.util.RectangleImmutable;
* window operation to an instance of this interface while providing OpenGL
* functionality.
* </p>
+ * <p>
+ * All values of this interface are represented in window units, if not stated otherwise.
+ * </p>
+ *
+ * <a name="coordinateSystem"><h5>Coordinate System</h5></a>
+ * <p>
+ * <ul>
+ * <li>Screen space has it's origin in the top-left corner, and may not be at 0/0.</li>
+ * <li>Window origin is in it's top-left corner, see {@link #getX()} and {@link #getY()}. </li>
+ * <li>Window client-area excludes {@link #getInsets() insets}, i.e. window decoration.</li>
+ * <li>Window origin is relative to it's parent window if exist, or the screen position (top-level).</li>
+ * </ul>
+ * See {@link NativeWindow} and {@link Screen}.
+ * </p>
* <a name="customwindowicons"><h5>Custom Window Icons</h5></a>
* <p>
* Custom window icons can be defined via system property <code>newt.window.icons</code>,
@@ -108,8 +121,8 @@ public interface Window extends NativeWindow, WindowClosingProtocol {
Screen getScreen();
/**
- * Returns the {@link MonitorDevice} which {@link MonitorDevice#getViewport() viewport}
- * {@link MonitorDevice#coverage(RectangleImmutable) covers} this window the most.
+ * Returns the {@link MonitorDevice} with the highest {@link MonitorDevice#getViewportInWindowUnits() viewport}
+ * {@link RectangleImmutable#coverage(RectangleImmutable) coverage} of this window.
* <p>
* If no coverage is detected the first {@link MonitorDevice} is returned.
* </p>
@@ -242,6 +255,10 @@ public interface Window extends NativeWindow, WindowClosingProtocol {
/**
* Returns a newly created {@link Rectangle} containing the scaled window origin, {@link #getX()} & {@link #getY()},
* and size, {@link #getSurfaceWidth()} & {@link #getSurfaceHeight()}, in pixel units.
+ *
+ * @deprecated The returned position in pixel units might be erroneous in case of multiple monitor setup where a mixed pixel-scale exist,
+ * since this method currently does not take the monitor viewport and each of it's pixel-scale into account (expensive).
+ * Either we fix this issue or remove this method at a later time.
*/
Rectangle getSurfaceBounds();
diff --git a/src/newt/classes/jogamp/newt/MonitorDeviceImpl.java b/src/newt/classes/jogamp/newt/MonitorDeviceImpl.java
index 9e10879c4..e9e41a0ef 100644
--- a/src/newt/classes/jogamp/newt/MonitorDeviceImpl.java
+++ b/src/newt/classes/jogamp/newt/MonitorDeviceImpl.java
@@ -38,8 +38,8 @@ 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);
+ public MonitorDeviceImpl(ScreenImpl screen, int nativeId, DimensionImmutable sizeMM, Rectangle viewportPU, Rectangle viewportWU, MonitorMode currentMode, ArrayHashSet<MonitorMode> supportedModes) {
+ super(screen, nativeId, sizeMM, viewportPU, viewportWU, currentMode, supportedModes);
}
@Override
@@ -136,11 +136,10 @@ public class MonitorDeviceImpl extends MonitorDevice {
this.currentMode = currentMode;
}
- /* pp */ final void setViewportValue(Rectangle viewport) {
- this.viewport = viewport;
- }
+ /* pp */ final Rectangle getMutuableViewportPU() { return viewportPU; }
+ /* pp */ final Rectangle getMutuableViewportWU() { return viewportWU; }
- /* pp */ ArrayHashSet<MonitorMode> getSupportedModesImpl() {
+ /* pp */ final ArrayHashSet<MonitorMode> getSupportedModesImpl() {
return supportedModes;
}
diff --git a/src/newt/classes/jogamp/newt/MonitorModeProps.java b/src/newt/classes/jogamp/newt/MonitorModeProps.java
index 9d8f4919c..55cbf77f3 100644
--- a/src/newt/classes/jogamp/newt/MonitorModeProps.java
+++ b/src/newt/classes/jogamp/newt/MonitorModeProps.java
@@ -81,9 +81,10 @@ public class MonitorModeProps {
;
/** WARNING: must be synchronized with ScreenMode.h, native implementation
- * 10: count + id, ScreenSizeMM[width, height], rotated Viewport[x, y, width, height], currentMonitorModeId, rotation, supportedModeId+
+ * 15: count + id, ScreenSizeMM[width, height], rotated Viewport pixel-units, rotated viewport window-units, currentMonitorModeId, rotation, supportedModeId+
+ * Viewport := [x, y, width, height] (4 elements)
*/
- public static final int MIN_MONITOR_DEVICE_PROPERTIES = 11;
+ public static final int MIN_MONITOR_DEVICE_PROPERTIES = 15;
public static final int IDX_MONITOR_DEVICE_VIEWPORT = 1 // count
+ 1 // native mode
@@ -223,7 +224,8 @@ public class MonitorModeProps {
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 Rectangle viewportPU = new Rectangle(monitorProperties[offset++], monitorProperties[offset++], monitorProperties[offset++], monitorProperties[offset++]);
+ final Rectangle viewportWU = new Rectangle(monitorProperties[offset++], monitorProperties[offset++], monitorProperties[offset++], monitorProperties[offset++]);
final MonitorMode currentMode;
{
final int modeId = monitorProperties[offset++];
@@ -240,7 +242,7 @@ public class MonitorModeProps {
}
}
}
- MonitorDevice monitorDevice = new MonitorDeviceImpl(screen, id, sizeMM, viewport, currentMode, supportedModes);
+ MonitorDevice monitorDevice = new MonitorDeviceImpl(screen, id, sizeMM, viewportPU, viewportWU, currentMode, supportedModes);
if(null!=cache) {
monitorDevice = cache.monitorDevices.getOrAdd(monitorDevice);
}
@@ -296,8 +298,9 @@ public class MonitorModeProps {
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);
+ final Rectangle viewportPU = new Rectangle(monitorProperties[offset++], monitorProperties[offset++], monitorProperties[offset++], monitorProperties[offset++]);
+ final Rectangle viewportWU = new Rectangle(monitorProperties[offset++], monitorProperties[offset++], monitorProperties[offset++], monitorProperties[offset++]);
+ MonitorDevice monitorDevice = new MonitorDeviceImpl(screen, id, sizeMM, viewportPU, viewportWU, currentMode, supportedModes);
if(null!=cache) {
monitorDevice = cache.monitorDevices.getOrAdd(monitorDevice);
}
@@ -328,6 +331,10 @@ public class MonitorModeProps {
data[idx++] = monitorDevice.getViewport().getY();
data[idx++] = monitorDevice.getViewport().getWidth();
data[idx++] = monitorDevice.getViewport().getHeight();
+ data[idx++] = monitorDevice.getViewportInWindowUnits().getX();
+ data[idx++] = monitorDevice.getViewportInWindowUnits().getY();
+ data[idx++] = monitorDevice.getViewportInWindowUnits().getWidth();
+ data[idx++] = monitorDevice.getViewportInWindowUnits().getHeight();
data[idx++] = monitorDevice.getCurrentMode().getId();
data[idx++] = monitorDevice.getCurrentMode().getRotation();
final List<MonitorMode> supportedModes = monitorDevice.getSupportedModes();
diff --git a/src/newt/classes/jogamp/newt/ScreenImpl.java b/src/newt/classes/jogamp/newt/ScreenImpl.java
index d7e6c641c..949e7fa3b 100644
--- a/src/newt/classes/jogamp/newt/ScreenImpl.java
+++ b/src/newt/classes/jogamp/newt/ScreenImpl.java
@@ -81,10 +81,11 @@ public abstract class ScreenImpl extends Screen implements MonitorModeListener {
protected int hashCode;
protected AbstractGraphicsScreen aScreen;
protected int refCount; // number of Screen references by Window
- protected Rectangle vOriginSize = new Rectangle(0, 0, 0, 0); // virtual rotated screen origin and size
+ protected Rectangle virtViewportPU = new Rectangle(0, 0, 0, 0); // virtual rotated viewport in pixel units
+ protected Rectangle virtViewportWU = new Rectangle(0, 0, 0, 0); // virtual rotated viewport in window units
protected static Dimension usrSize = null; // property values: newt.ws.swidth and newt.ws.sheight
protected static volatile boolean usrSizeQueried = false;
- private ArrayList<MonitorModeListener> refMonitorModeListener = new ArrayList<MonitorModeListener>();
+ private final ArrayList<MonitorModeListener> refMonitorModeListener = new ArrayList<MonitorModeListener>();
private long tCreated; // creationTime
@@ -130,6 +131,7 @@ public abstract class ScreenImpl extends Screen implements MonitorModeListener {
screen.screen_idx = idx;
screen.fqname = display.getFQName()+"-s"+idx;
screen.hashCode = screen.fqname.hashCode();
+ screen.instantiationFinished();
Screen.addScreen2List(screen);
if(DEBUG) {
System.err.println("Screen.create() NEW: "+screen+" "+Display.getThreadName());
@@ -141,6 +143,14 @@ public abstract class ScreenImpl extends Screen implements MonitorModeListener {
}
}
+ /**
+ * Notifies the driver impl. that the instantiation is finished,
+ * ie. instance created and all fields set.
+ */
+ protected void instantiationFinished() {
+ // nop
+ }
+
@Override
public boolean equals(Object obj) {
if (obj == null) {
@@ -260,19 +270,20 @@ public abstract class ScreenImpl extends Screen implements MonitorModeListener {
protected abstract int validateScreenIndex(int idx);
/**
- * Stores the virtual origin and virtual <b>rotated</b> screen size.
+ * Calculates the virtual rotated viewport in pixel- and window units.
* <p>
* This method is called after the MonitorMode has been set or changed,
* hence you may utilize it.
* </p>
* <p>
* Default implementation uses the union of all monitor's viewport,
- * calculated via {@link #unionOfMonitorViewportSize()}.
+ * calculated via {@link #unionOfMonitorViewportSize()}, however driver impl. may chose a different methodology.
* </p>
- * @param vOriginSize storage for result
+ * @param viewport storage for result in pixel units
+ * @param viewportInWindowUnits storage for result in window units
*/
- protected void calcVirtualScreenOriginAndSize(final Rectangle vOriginSize) {
- unionOfMonitorViewportSize(vOriginSize);
+ protected void calcVirtualScreenOriginAndSize(final Rectangle viewport, final Rectangle viewportInWindowUnits) {
+ unionOfMonitorViewports(viewport, viewportInWindowUnits);
}
@Override
@@ -281,18 +292,19 @@ public abstract class ScreenImpl extends Screen implements MonitorModeListener {
}
/**
- * Updates the <b>rotated</b> virtual ScreenSize using the native impl.
+ * Updates the <b>rotated</b> virtual viewport, may use native impl.
*/
protected void updateVirtualScreenOriginAndSize() {
if(null != usrSize ) {
- vOriginSize.set(0, 0, usrSize.getWidth(), usrSize.getHeight());
+ virtViewportPU.set(0, 0, usrSize.getWidth(), usrSize.getHeight());
+ virtViewportWU.set(0, 0, usrSize.getWidth(), usrSize.getHeight());
if(DEBUG) {
- System.err.println("Update user virtual screen viewport @ "+Thread.currentThread().getName()+": "+vOriginSize);
+ System.err.println("Update user virtual screen viewport @ "+Thread.currentThread().getName()+": "+virtViewportPU);
}
} else {
- calcVirtualScreenOriginAndSize(vOriginSize);
+ calcVirtualScreenOriginAndSize(virtViewportPU, virtViewportWU);
if(DEBUG) {
- System.err.println("Updated virtual screen viewport @ "+Thread.currentThread().getName()+": "+vOriginSize);
+ System.err.println("Updated virtual screen viewport @ "+Thread.currentThread().getName()+": "+virtViewportPU+" [pixel], "+virtViewportWU+" [window]");
}
}
}
@@ -318,19 +330,21 @@ public abstract class ScreenImpl extends Screen implements MonitorModeListener {
}
@Override
- public final int getX() { return vOriginSize.getX(); }
+ public final int getX() { return virtViewportPU.getX(); }
@Override
- public final int getY() { return vOriginSize.getY(); }
+ public final int getY() { return virtViewportPU.getY(); }
@Override
- public final int getWidth() { return vOriginSize.getWidth(); }
+ public final int getWidth() { return virtViewportPU.getWidth(); }
@Override
- public final int getHeight() { return vOriginSize.getHeight(); }
+ public final int getHeight() { return virtViewportPU.getHeight(); }
@Override
- public final RectangleImmutable getViewport() { return vOriginSize; }
+ public final RectangleImmutable getViewport() { return virtViewportPU; }
+ @Override
+ public final RectangleImmutable getViewportInWindowUnits() { return virtViewportWU; }
@Override
public String toString() {
- return "NEWT-Screen["+getFQName()+", idx "+screen_idx+", refCount "+refCount+", vsize "+vOriginSize+", "+aScreen+", "+display+
+ return "NEWT-Screen["+getFQName()+", idx "+screen_idx+", refCount "+refCount+", vsize "+virtViewportPU+" [pixels], "+virtViewportWU+" [window], "+aScreen+", "+display+
", monitors: "+getMonitorDevices()+"]";
}
@@ -357,7 +371,10 @@ public abstract class ScreenImpl extends Screen implements MonitorModeListener {
*/
protected abstract void collectNativeMonitorModesAndDevicesImpl(MonitorModeProps.Cache cache);
- protected Rectangle getNativeMonitorDeviceViewportImpl(MonitorDevice monitor) { return null; }
+ protected boolean updateNativeMonitorDeviceViewportImpl(final MonitorDevice monitor,
+ final Rectangle viewportPU, final Rectangle viewportWU) {
+ return false;
+ }
/**
* To be implemented by the native specification.<br>
@@ -402,7 +419,7 @@ public abstract class ScreenImpl extends Screen implements MonitorModeListener {
System.err.println("monitorModeChangeNotify @ "+Thread.currentThread().getName()+": "+me);
}
for(int i=0; i<refMonitorModeListener.size(); i++) {
- ((MonitorModeListener)refMonitorModeListener.get(i)).monitorModeChangeNotify(me);
+ refMonitorModeListener.get(i).monitorModeChangeNotify(me);
}
}
@@ -410,12 +427,9 @@ public abstract class ScreenImpl extends Screen implements MonitorModeListener {
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);
+ final boolean viewportUpdated = updateNativeMonitorDeviceViewportImpl(monitor, monitor.getMutuableViewportPU(), monitor.getMutuableViewportWU());
if( DEBUG ) {
- System.err.println("Screen.updateMonitorViewport["+i+"] @ "+Thread.currentThread().getName()+": "+monitor.getViewport()+" -> "+newViewport);
- }
- if( null != newViewport ) {
- monitor.setViewportValue(newViewport);
+ System.err.println("Screen.updateMonitorViewport["+i+"] @ "+Thread.currentThread().getName()+": updated: "+viewportUpdated+", PU "+monitor.getViewport()+", WU "+monitor.getViewportInWindowUnits());
}
}
}
@@ -430,7 +444,7 @@ public abstract class ScreenImpl extends Screen implements MonitorModeListener {
System.err.println("monitorModeChangeNotify @ "+Thread.currentThread().getName()+": success "+success+", "+me);
}
for(int i=0; i<refMonitorModeListener.size(); i++) {
- ((MonitorModeListener)refMonitorModeListener.get(i)).monitorModeChanged(me, success);
+ refMonitorModeListener.get(i).monitorModeChanged(me, success);
}
}
diff --git a/src/newt/classes/jogamp/newt/WindowImpl.java b/src/newt/classes/jogamp/newt/WindowImpl.java
index 6a5fc5de0..08559c14d 100644
--- a/src/newt/classes/jogamp/newt/WindowImpl.java
+++ b/src/newt/classes/jogamp/newt/WindowImpl.java
@@ -910,9 +910,14 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
return screen;
}
+ protected void setScreen(ScreenImpl newScreen) { // never null !
+ removeScreenReference();
+ screen = newScreen;
+ }
+
@Override
public final MonitorDevice getMainMonitor() {
- return screen.getMainMonitor( getSurfaceBounds() );
+ return screen.getMainMonitor( getBounds() );
}
/**
@@ -1072,7 +1077,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
@Override
public final void setSurfaceSize(final int pixelWidth, final int pixelHeight) {
// FIXME HiDPI: Shortcut, may need to adjust if we change scaling methodology
- setSize(pixelWidth * getPixelScaleX(), pixelHeight * getPixelScaleY());
+ setSize(pixelWidth / getPixelScaleX(), pixelHeight / getPixelScaleY());
}
@Override
public final void setTopLevelSize(final int width, final int height) {
@@ -1232,11 +1237,6 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
return operation;
}
- private void setScreen(ScreenImpl newScreen) { // never null !
- removeScreenReference();
- screen = newScreen;
- }
-
@Override
public final void run() {
if( WindowImpl.this.isFullscreen() ) {
@@ -2249,8 +2249,8 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
int x,y,w,h;
- final RectangleImmutable sviewport = screen.getViewportInWindowUnits(WindowImpl.this);
- final RectangleImmutable viewport;
+ final RectangleImmutable sviewport = screen.getViewportInWindowUnits(); // window units
+ final RectangleImmutable viewport; // window units
final int fs_span_flag;
final boolean alwaysOnTopChange;
if(_fullscreen) {
@@ -2262,7 +2262,11 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
fullscreenMonitors = getScreen().getMonitorDevices();
}
}
- viewport = convertToWindowUnits(MonitorDevice.unionOfViewports(new Rectangle(), fullscreenMonitors));
+ {
+ final Rectangle viewportInWindowUnits = new Rectangle();
+ MonitorDevice.unionOfViewports(null, viewportInWindowUnits, fullscreenMonitors);
+ viewport = viewportInWindowUnits;
+ }
if( isReconfigureFlagSupported(FLAG_IS_FULLSCREEN_SPAN) &&
( fullscreenMonitors.size() > 1 || sviewport.compareTo(viewport) > 0 ) ) {
fs_span_flag = FLAG_IS_FULLSCREEN_SPAN;
@@ -2620,7 +2624,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
// Native MouseEvents pre-processed to be enqueued or consumed directly
//
- public void sendMouseEvent(final short eventType, final int modifiers,
+ public final void sendMouseEvent(final short eventType, final int modifiers,
final int x, final int y, final short button, final float rotation) {
doMouseEvent(false, false, eventType, modifiers, x, y, button, MouseEvent.getRotationXYZ(rotation, modifiers), 1f);
}
diff --git a/src/newt/classes/jogamp/newt/driver/android/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/android/WindowDriver.java
index 7a571318b..5671a05e4 100644
--- a/src/newt/classes/jogamp/newt/driver/android/WindowDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/android/WindowDriver.java
@@ -286,8 +286,7 @@ public class WindowDriver extends jogamp.newt.WindowImpl implements Callback2 {
if( isFullscreen() ) {
final MonitorDevice mainMonitor = getMainMonitor();
- final RectangleImmutable screenRect = mainMonitor.getViewport();
- final RectangleImmutable winRect = this.convertToWindowUnits((Rectangle)screenRect.cloneMutable());
+ final RectangleImmutable winRect = mainMonitor.getViewportInWindowUnits();
definePosition(winRect.getX(), winRect.getY());
defineSize(winRect.getWidth(), winRect.getHeight());
}
diff --git a/src/newt/classes/jogamp/newt/driver/awt/AWTCanvas.java b/src/newt/classes/jogamp/newt/driver/awt/AWTCanvas.java
index f7722c91c..5dab64e39 100644
--- a/src/newt/classes/jogamp/newt/driver/awt/AWTCanvas.java
+++ b/src/newt/classes/jogamp/newt/driver/awt/AWTCanvas.java
@@ -65,7 +65,7 @@ public class AWTCanvas extends Canvas {
private AWTGraphicsConfiguration awtConfig;
private volatile JAWTWindow jawtWindow=null; // the JAWTWindow presentation of this AWT Canvas, bound to the 'drawable' lifecycle
private CapabilitiesChooser chooser=null;
- private CapabilitiesImmutable capabilities;
+ private final CapabilitiesImmutable capabilities;
private boolean displayConfigChanged=false;
@@ -152,6 +152,10 @@ public class AWTCanvas extends Canvas {
}
}
+ public int getPixelScale() {
+ final JAWTWindow _jawtWindow = jawtWindow;
+ return (null != _jawtWindow) ? _jawtWindow.getPixelScale() : 1;
+ }
public NativeWindow getNativeWindow() {
final JAWTWindow _jawtWindow = jawtWindow;
return (null != _jawtWindow) ? _jawtWindow : null;
diff --git a/src/newt/classes/jogamp/newt/driver/awt/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/awt/WindowDriver.java
index f99476851..1f0ba6f09 100644
--- a/src/newt/classes/jogamp/newt/driver/awt/WindowDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/awt/WindowDriver.java
@@ -99,6 +99,17 @@ public class WindowDriver extends WindowImpl {
}
@Override
+ protected final int getPixelScaleX() {
+ final AWTCanvas _awtCanvas = awtCanvas;
+ return null != _awtCanvas ? _awtCanvas.getPixelScale() : 1;
+ }
+
+ @Override
+ protected final int getPixelScaleY() {
+ return getPixelScaleX();
+ }
+
+ @Override
protected void createNativeImpl() {
if(0!=getParentWindowHandle()) {
throw new RuntimeException("Window parenting not supported in AWT, use AWTWindow(Frame) cstr for wrapping instead");
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 d3231557f..64bc87a41 100644
--- a/src/newt/classes/jogamp/newt/driver/bcm/egl/ScreenDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/bcm/egl/ScreenDriver.java
@@ -104,8 +104,8 @@ public class ScreenDriver extends jogamp.newt.ScreenImpl {
}
@Override
- protected void calcVirtualScreenOriginAndSize(Rectangle vOriginSize) {
- vOriginSize.set(0, 0, fixedWidth, fixedHeight); // FIXME
+ protected void calcVirtualScreenOriginAndSize(Rectangle viewport, Rectangle viewportInWindowUnits) {
+ viewport.set(0, 0, fixedWidth, 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 dc2a8459a..e0228c10f 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
@@ -97,8 +97,8 @@ public class ScreenDriver extends ScreenImpl {
}
@Override
- protected void calcVirtualScreenOriginAndSize(Rectangle vOriginSize) {
- vOriginSize.set(0, 0, cachedWidth, cachedHeight);
+ protected void calcVirtualScreenOriginAndSize(Rectangle viewport, Rectangle viewportInWindowUnits) {
+ viewport.set(0, 0, cachedWidth, cachedHeight);
}
/** Called from {@link #initNative()}. */
diff --git a/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/WindowDriver.java
index 1c927acc4..188e5b964 100644
--- a/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/WindowDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/WindowDriver.java
@@ -170,13 +170,13 @@ public class WindowDriver extends WindowImpl {
}
@Override
- public final void sendMouseEvent(final short eventType, final int modifiers,
- final int x, final int y, final short button, final float rotation) {
+ protected final void doMouseEvent(final boolean enqueue, final boolean wait, final short eventType, final int modifiers,
+ final int x, final int y, final short button, final float[] rotationXYZ, final float rotationScale) {
if( MouseEvent.EVENT_MOUSE_MOVED == eventType ) {
final DisplayDriver display = (DisplayDriver) getScreen().getDisplay();
display.moveActivePointerIcon(x, y);
}
- super.sendMouseEvent(eventType, modifiers, x, y, button, rotation);
+ super.doMouseEvent(enqueue, wait, eventType, modifiers, x, y, button, rotationXYZ, rotationScale);
}
@Override
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 44802e348..20c60565a 100644
--- a/src/newt/classes/jogamp/newt/driver/intel/gdl/ScreenDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/intel/gdl/ScreenDriver.java
@@ -106,8 +106,8 @@ public class ScreenDriver extends jogamp.newt.ScreenImpl {
}
@Override
- protected void calcVirtualScreenOriginAndSize(Rectangle vOriginSize) {
- vOriginSize.set(0, 0, cachedWidth, cachedHeight);
+ protected void calcVirtualScreenOriginAndSize(Rectangle viewport, Rectangle viewportInWindowUnits) {
+ viewport.set(0, 0, cachedWidth, cachedHeight);
}
//----------------------------------------------------------------------
diff --git a/src/newt/classes/jogamp/newt/driver/kd/ScreenDriver.java b/src/newt/classes/jogamp/newt/driver/kd/ScreenDriver.java
index 9ebe2629a..541576250 100644
--- a/src/newt/classes/jogamp/newt/driver/kd/ScreenDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/kd/ScreenDriver.java
@@ -102,8 +102,8 @@ public class ScreenDriver extends ScreenImpl {
}
@Override
- protected void calcVirtualScreenOriginAndSize(Rectangle vOriginSize) {
- vOriginSize.set(0, 0, cachedWidth, cachedHeight);
+ protected void calcVirtualScreenOriginAndSize(Rectangle viewport, Rectangle viewportInWindowUnits) {
+ viewport.set(0, 0, cachedWidth, 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 4f3cc691b..5f458e2c9 100644
--- a/src/newt/classes/jogamp/newt/driver/macosx/ScreenDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/macosx/ScreenDriver.java
@@ -35,13 +35,16 @@
package jogamp.newt.driver.macosx;
import javax.media.nativewindow.DefaultGraphicsScreen;
+import javax.media.nativewindow.util.Rectangle;
+import jogamp.nativewindow.macosx.OSXUtil;
import jogamp.newt.MonitorModeProps;
import jogamp.newt.ScreenImpl;
import com.jogamp.common.util.ArrayHashSet;
import com.jogamp.newt.MonitorDevice;
import com.jogamp.newt.MonitorMode;
+import com.jogamp.opengl.math.FloatUtil;
public class ScreenDriver extends ScreenImpl {
@@ -60,7 +63,7 @@ public class ScreenDriver extends ScreenImpl {
@Override
protected void closeNativeImpl() { }
- private MonitorMode getMonitorModeImpl(MonitorModeProps.Cache cache, int crt_idx, int mode_idx) {
+ private MonitorMode getMonitorModeImpl(final MonitorModeProps.Cache cache, final int crt_idx, final int mode_idx) {
final int[] modeProps = getMonitorMode0(crt_idx, mode_idx);
final MonitorMode res;
if (null == modeProps || 0 >= modeProps.length) {
@@ -71,56 +74,133 @@ public class ScreenDriver extends ScreenImpl {
return res;
}
- @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");
+ private class CrtProps {
+ CrtProps() {
+ count = getMonitorCount0();
+ pixelScaleArray = new int[count];
+ propsOrigArray = new int[count][];
+ propsFixedArray = new int[count][];
+
+ //
+ // Gather whole topology of monitors (NSScreens)
+ //
+ for(int crtIdx=0; crtIdx<count; crtIdx++) {
+ final float pixelScaleRaw = (float) OSXUtil.GetPixelScale(crtIdx);
+ pixelScaleArray[crtIdx] = FloatUtil.isZero(pixelScaleRaw, FloatUtil.EPSILON) ? 1 : (int)pixelScaleRaw;
+ propsOrigArray[crtIdx] = getMonitorProps0(crtIdx);
+ if ( null == propsOrigArray[crtIdx] ) {
+ throw new InternalError("Could not gather device props "+crtIdx+"/"+count);
}
- final int[] monitorProps = getMonitorProps0(crtIdx);
- if ( null == monitorProps ) {
- throw new InternalError("Could not gather device "+crtIdx+", but gathered "+modeIdx+" modes");
+ // copy orig -> fixed
+ final int propsLen = propsOrigArray[crtIdx].length;
+ propsFixedArray[crtIdx] = new int[propsLen];
+ System.arraycopy(propsOrigArray[crtIdx], 0, propsFixedArray[crtIdx], 0, propsLen);
+ }
+
+ //
+ // Fix scaled viewport w/ pixelScale of each monitorProps,
+ // i.e. size by its own pixelScale and x/y offset by querying it's neighbors.
+ //
+ for(int crtIdx=0; crtIdx<count; crtIdx++) {
+ final int[] thisMonitorProps = propsFixedArray[crtIdx];
+ final int x = thisMonitorProps[MonitorModeProps.IDX_MONITOR_DEVICE_VIEWPORT+0];
+ final int y = thisMonitorProps[MonitorModeProps.IDX_MONITOR_DEVICE_VIEWPORT+1];
+ final int thisPixelScale = pixelScaleArray[crtIdx];
+ thisMonitorProps[MonitorModeProps.IDX_MONITOR_DEVICE_VIEWPORT+2] *= thisPixelScale; // fix width
+ thisMonitorProps[MonitorModeProps.IDX_MONITOR_DEVICE_VIEWPORT+3] *= thisPixelScale; // fix height
+ if( 0 != x ) {
+ // find matching viewport width for x-offset to apply it's pixelSize
+ for(int i=0; i<count; i++) {
+ if( i != crtIdx && x == propsOrigArray[i][MonitorModeProps.IDX_MONITOR_DEVICE_VIEWPORT+2] ) {
+ thisMonitorProps[MonitorModeProps.IDX_MONITOR_DEVICE_VIEWPORT+0] *= pixelScaleArray[i];
+ break;
+ }
+ }
+ }
+ if( 0 != y ) {
+ // find matching viewport height for y-offset to apply it's pixelSize
+ for(int i=0; i<count; i++) {
+ if( i != crtIdx && y == propsOrigArray[i][MonitorModeProps.IDX_MONITOR_DEVICE_VIEWPORT+3] ) {
+ thisMonitorProps[MonitorModeProps.IDX_MONITOR_DEVICE_VIEWPORT+1] *= pixelScaleArray[i];
+ break;
+ }
+ }
}
- // 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 );
+ }
+ final int count;
+ final int[] pixelScaleArray;
+ final int[][] propsOrigArray;
+ final int[][] propsFixedArray;
+ }
+
+ @Override
+ protected final void collectNativeMonitorModesAndDevicesImpl(final MonitorModeProps.Cache cache) {
+ final CrtProps crtProps = new CrtProps();
+
+ //
+ // Collect all monitorModes for all monitorDevices
+ //
+ for(int crtIdx=0; crtIdx<crtProps.count; crtIdx++) {
+ final ArrayHashSet<MonitorMode> supportedModes = new ArrayHashSet<MonitorMode>();
+ int modeIdx = 0;
+ {
+ // Get all supported modes for this monitorDevice
+ MonitorMode mode;
+ while( true ) {
+ mode = getMonitorModeImpl(cache, crtIdx, modeIdx);
+ if( null != mode ) {
+ if( mode.getSurfaceSize().getBitsPerPixel() >= 24 ) { // drop otherwise
+ supportedModes.getOrAdd(mode);
+ }
+ modeIdx++; // next mode on same monitor
+ } else {
+ break; // done with modes on this monitor
+ }
+ }
+ }
+ if( 0 >= modeIdx ) {
+ throw new InternalError("Could not gather single mode of device "+crtIdx+"/"+crtProps.count);
+ }
+ final MonitorMode currentMode = getMonitorModeImpl(cache, crtIdx, -1);
+ if ( null == currentMode ) {
+ throw new InternalError("Could not gather current mode of device "+crtIdx+"/"+crtProps.count+", but gathered "+modeIdx+" modes");
+ }
+ // merge monitor-props + supported modes
+ MonitorModeProps.streamInMonitorDevice(null, cache, this, supportedModes, currentMode, crtProps.propsFixedArray[crtIdx], 0);
+ }
+ }
+
+ @Override
+ protected boolean updateNativeMonitorDeviceViewportImpl(final MonitorDevice monitor, final Rectangle viewportPU, final Rectangle viewportWU) {
+ final CrtProps crtProps = new CrtProps();
+ final int crtIdx = monitor.getId();
+ if( 0 > crtIdx || crtIdx >= crtProps.count ) {
+ throw new IndexOutOfBoundsException("monitor id "+crtIdx+" not withon [0.."+(crtProps.count-1)+"]");
+ }
+ final int[] fixedMonitorProps = crtProps.propsFixedArray[crtIdx];
+ int offset = MonitorModeProps.IDX_MONITOR_DEVICE_VIEWPORT;
+ viewportPU.set(fixedMonitorProps[offset++], fixedMonitorProps[offset++], fixedMonitorProps[offset++], fixedMonitorProps[offset++]);
+ viewportWU.set(fixedMonitorProps[offset++], fixedMonitorProps[offset++], fixedMonitorProps[offset++], fixedMonitorProps[offset++]);
+ return true;
}
@Override
- protected MonitorMode queryCurrentMonitorModeImpl(MonitorDevice monitor) {
+ protected MonitorMode queryCurrentMonitorModeImpl(final MonitorDevice monitor) {
return getMonitorModeImpl(null, monitor.getId(), -1);
}
@Override
- protected boolean setCurrentMonitorModeImpl(MonitorDevice monitor, MonitorMode mode) {
+ protected boolean setCurrentMonitorModeImpl(final MonitorDevice monitor, final MonitorMode mode) {
return setMonitorMode0(monitor.getId(), mode.getId(), mode.getRotation());
}
@Override
- protected int validateScreenIndex(int idx) {
+ protected int validateScreenIndex(final int idx) {
return 0; // big-desktop w/ multiple monitor attached, only one screen available
}
+ private native int getMonitorCount0();
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 eebf280de..540186f2e 100644
--- a/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java
@@ -46,12 +46,15 @@ import javax.media.nativewindow.util.PointImmutable;
import jogamp.nativewindow.macosx.OSXUtil;
import jogamp.newt.PointerIconImpl;
+import jogamp.newt.ScreenImpl;
import jogamp.newt.WindowImpl;
import jogamp.newt.driver.DriverClearFocus;
import jogamp.newt.driver.DriverUpdatePosition;
import com.jogamp.newt.event.InputEvent;
import com.jogamp.newt.event.KeyEvent;
+import com.jogamp.newt.event.MonitorEvent;
+import com.jogamp.opengl.math.FloatUtil;
public class WindowDriver extends WindowImpl implements MutableSurface, DriverClearFocus, DriverUpdatePosition {
@@ -59,7 +62,81 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl
DisplayDriver.initSingleton();
}
+ private int pixelScale;
+
public WindowDriver() {
+ pixelScale = 1;
+ }
+
+ private boolean updatePixelScale(final boolean sendEvent, final boolean defer, final float newPixelScaleRaw) {
+ final int newPixelScaleSafe = FloatUtil.isZero(newPixelScaleRaw, FloatUtil.EPSILON) ? 1 : (int) newPixelScaleRaw;
+ final boolean changed = pixelScale != newPixelScaleSafe;
+ if( DEBUG_IMPLEMENTATION ) {
+ System.err.println("WindowDriver.updatePixelScale.X: "+pixelScale+" -> "+newPixelScaleSafe+" (raw "+newPixelScaleRaw+") - changed "+changed);
+ }
+ if( changed ) {
+ pixelScale = newPixelScaleSafe;
+ if( sendEvent ) {
+ super.sizeChanged(defer, getWindowWidth(), getWindowHeight(), true);
+ } else {
+ defineSize(getWindowWidth(), getWindowHeight());
+ }
+ }
+ return changed;
+ }
+
+ private boolean updatePixelScaleByScreenIdx(final boolean sendEvent) {
+ final float newPixelScaleRaw = (float) OSXUtil.GetPixelScale(getScreen().getIndex());
+ if( DEBUG_IMPLEMENTATION ) {
+ System.err.println("WindowDriver.updatePixelScale.1: "+pixelScale+" -> "+newPixelScaleRaw);
+ }
+ return updatePixelScale(sendEvent, true /* defer */, newPixelScaleRaw);
+ }
+
+ private boolean updatePixelScaleByWindowHandle(final boolean sendEvent) {
+ final long wh = getWindowHandle();
+ if( 0 != wh ) {
+ final float newPixelScaleRaw = (float)OSXUtil.GetPixelScale(wh);
+ if( DEBUG_IMPLEMENTATION ) {
+ System.err.println("WindowDriver.updatePixelScale.2: "+pixelScale+" -> "+newPixelScaleRaw);
+ }
+ return updatePixelScale(sendEvent, true /* defer */, newPixelScaleRaw);
+ } else {
+ return false;
+ }
+ }
+
+ /** Called from native code */
+ protected void updatePixelScale(final boolean defer, final float newPixelScaleRaw) {
+ final long handle = getWindowHandle();
+ if( 0 != handle ) {
+ if( DEBUG_IMPLEMENTATION ) {
+ System.err.println("WindowDriver.updatePixelScale.3: "+pixelScale+" -> "+newPixelScaleRaw);
+ }
+ updatePixelScale(true /* sendEvent*/, defer, newPixelScaleRaw);
+ }
+ }
+
+ @Override
+ protected final void instantiationFinished() {
+ updatePixelScaleByScreenIdx(false /* sendEvent*/);
+ }
+
+ @Override
+ protected void setScreen(ScreenImpl newScreen) { // never null !
+ super.setScreen(newScreen);
+ updatePixelScaleByScreenIdx(false /* sendEvent*/); // caller (reparent, ..) will send reshape event
+ }
+
+
+ @Override
+ protected final int getPixelScaleX() {
+ return pixelScale;
+ }
+
+ @Override
+ protected final int getPixelScaleY() {
+ return pixelScale;
}
@Override
@@ -210,16 +287,6 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl
private boolean useParent(NativeWindow parent) { return null != parent && 0 != parent.getWindowHandle(); }
@Override
- protected final int getPixelScaleX() {
- return 1; // FIXME HiDPI: Use pixelScale
- }
-
- @Override
- protected final int getPixelScaleY() {
- return 1; // FIXME HiDPI: Use pixelScale
- }
-
- @Override
public void updatePosition(int x, int y) {
final long handle = getWindowHandle();
if( 0 != handle && !isOffscreenInstance ) {
@@ -263,11 +330,12 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl
}
@Override
- protected boolean reconfigureWindowImpl(final int x, final int y, final int width, final int height, int flags) {
+ protected boolean reconfigureWindowImpl(int x, int y, final int width, final int height, int flags) {
final boolean _isOffscreenInstance = isOffscreenInstance(this, this.getParent());
isOffscreenInstance = 0 != sscSurfaceHandle || _isOffscreenInstance;
final PointImmutable pClientLevelOnSreen;
if( isOffscreenInstance ) {
+ x = 0; y = 0;
pClientLevelOnSreen = new Point(0, 0);
} else {
final NativeWindow parent = getParent();
@@ -313,9 +381,9 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl
0 != ( FLAG_CHANGE_PARENTING & flags) ||
0 != ( FLAG_CHANGE_FULLSCREEN & flags) ) {
if(isOffscreenInstance) {
- createWindow(true, 0 != getWindowHandle(), pClientLevelOnSreen, 64, 64, false, setVisible, false);
+ createWindow(true, 0 != getWindowHandle(), pClientLevelOnSreen, x, y, 64, 64, false, setVisible, false);
} else {
- createWindow(false, 0 != getWindowHandle(), pClientLevelOnSreen, width, height,
+ createWindow(false, 0 != getWindowHandle(), pClientLevelOnSreen, x, y, width, height,
0 != ( FLAG_IS_FULLSCREEN & flags), setVisible, 0 != ( FLAG_IS_ALWAYSONTOP & flags));
}
} else {
@@ -329,7 +397,7 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl
} // else offscreen size is realized via recreation
// no native event (fullscreen, some reparenting)
positionChanged(true, x, y);
- sizeChanged(true, width, height, false);
+ super.sizeChanged(true, width, height, false);
}
if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) && setVisible ) {
if( !isOffscreenInstance ) {
@@ -439,11 +507,17 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl
@Override
protected void warpPointerImpl(final int x, final int y) {
if( !isOffscreenInstance ) {
- warpPointer0(getWindowHandle(), x, y);
+ warpPointer0(getWindowHandle(), x / getPixelScaleX(), y / getPixelScaleY());
} // else may need offscreen solution ? FIXME
}
@Override
+ protected final void doMouseEvent(final boolean enqueue, final boolean wait, final short eventType, final int modifiers,
+ final int x, final int y, final short button, final float[] rotationXYZ, final float rotationScale) {
+ super.doMouseEvent(enqueue, wait, eventType, modifiers, x * getPixelScaleX(), y * getPixelScaleY(), button, rotationXYZ, rotationScale);
+ }
+
+ @Override
public final void sendKeyEvent(short eventType, int modifiers, short keyCode, short keySym, char keyChar) {
throw new InternalError("XXX: Adapt Java Code to Native Code Changes");
}
@@ -499,8 +573,8 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl
//
private void createWindow(final boolean offscreenInstance, final boolean recreate,
- final PointImmutable pS, final int width, final int height,
- final boolean fullscreen, final boolean visible, final boolean alwaysOnTop) {
+ final PointImmutable pS, final int x, final int y,
+ final int width, final int height, final boolean fullscreen, final boolean visible, final boolean alwaysOnTop) {
final long parentWinHandle = getParentWindowHandle();
final long preWinHandle = getWindowHandle();
@@ -558,8 +632,12 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl
setTitle0(newWin, getTitle());
setAlwaysOnTop0(getWindowHandle(), alwaysOnTop);
}
- visibleChanged(true, visible);
} } );
+ // no native event (fullscreen, some reparenting)
+ positionChanged(false, x, y);
+ updatePixelScaleByWindowHandle(false /* sendEvent */);
+ super.sizeChanged(false, width, height, true);
+ visibleChanged(false, visible);
} catch (Exception ie) {
ie.printStackTrace();
}
@@ -569,7 +647,8 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl
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 visible, long view);
+ private native void initWindow0(long parentWindow, long window, int x, int y, int w, int h,
+ boolean opaque, 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 e789b995f..af265cfd3 100644
--- a/src/newt/classes/jogamp/newt/driver/windows/ScreenDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/windows/ScreenDriver.java
@@ -65,14 +65,14 @@ public class ScreenDriver extends ScreenImpl {
protected void closeNativeImpl() {
}
- private final String getAdapterName(int crt_idx) {
+ private final String getAdapterName(final int crt_idx) {
return getAdapterName0(crt_idx);
}
- private final String getActiveMonitorName(String adapterName, int monitor_idx) {
+ private final String getActiveMonitorName(final String adapterName, final int monitor_idx) {
return getActiveMonitorName0(adapterName, monitor_idx);
}
- private final MonitorMode getMonitorModeImpl(MonitorModeProps.Cache cache, String adapterName, int crtModeIdx) {
+ private final MonitorMode getMonitorModeImpl(final MonitorModeProps.Cache cache, final String adapterName, final int crtModeIdx) {
if( null == adapterName ) {
return null;
}
@@ -85,7 +85,7 @@ public class ScreenDriver extends ScreenImpl {
}
@Override
- protected void collectNativeMonitorModesAndDevicesImpl(MonitorModeProps.Cache cache) {
+ protected void collectNativeMonitorModesAndDevicesImpl(final MonitorModeProps.Cache cache) {
int crtIdx = 0;
ArrayHashSet<MonitorMode> supportedModes = new ArrayHashSet<MonitorMode>();
String adapterName = getAdapterName(crtIdx);
@@ -118,26 +118,28 @@ public class ScreenDriver extends ScreenImpl {
}
@Override
- protected Rectangle getNativeMonitorDeviceViewportImpl(MonitorDevice monitor) {
+ protected boolean updateNativeMonitorDeviceViewportImpl(final MonitorDevice monitor, final Rectangle viewportPU, final Rectangle viewportWU) {
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++]);
+ viewportPU.set(monitorProps[offset++], monitorProps[offset++], monitorProps[offset++], monitorProps[offset++]);
+ viewportWU.set(monitorProps[offset++], monitorProps[offset++], monitorProps[offset++], monitorProps[offset++]);
+ return true;
}
}
- return null;
+ return false;
}
@Override
- protected MonitorMode queryCurrentMonitorModeImpl(MonitorDevice monitor) {
+ protected MonitorMode queryCurrentMonitorModeImpl(final MonitorDevice monitor) {
return getMonitorModeImpl(null, getAdapterName(monitor.getId()), -1);
}
@Override
- protected boolean setCurrentMonitorModeImpl(MonitorDevice monitor, MonitorMode mode) {
+ protected boolean setCurrentMonitorModeImpl(final MonitorDevice monitor, final MonitorMode mode) {
return setMonitorMode0(monitor.getId(),
-1, -1, // no fixed position!
mode.getSurfaceSize().getResolution().getWidth(),
@@ -149,13 +151,13 @@ public class ScreenDriver extends ScreenImpl {
}
@Override
- protected int validateScreenIndex(int idx) {
+ protected int validateScreenIndex(final int idx) {
return 0; // big-desktop w/ multiple monitor attached, only one screen available
}
@Override
- protected void calcVirtualScreenOriginAndSize(Rectangle vOriginSize) {
- vOriginSize.set(getVirtualOriginX0(), getVirtualOriginY0(), getVirtualWidthImpl0(), getVirtualHeightImpl0());
+ protected void calcVirtualScreenOriginAndSize(final Rectangle viewport, Rectangle viewportInWindowUnits) {
+ viewport.set(getVirtualOriginX0(), getVirtualOriginY0(), getVirtualWidthImpl0(), getVirtualHeightImpl0());
}
// Native calls
diff --git a/src/newt/classes/jogamp/newt/driver/x11/ScreenDriver.java b/src/newt/classes/jogamp/newt/driver/x11/ScreenDriver.java
index bef7f60ec..2d7c6509d 100644
--- a/src/newt/classes/jogamp/newt/driver/x11/ScreenDriver.java
+++ b/src/newt/classes/jogamp/newt/driver/x11/ScreenDriver.java
@@ -111,7 +111,7 @@ public class ScreenDriver extends ScreenImpl {
private RandR rAndR;
@Override
- protected final void collectNativeMonitorModesAndDevicesImpl(MonitorModeProps.Cache cache) {
+ protected final void collectNativeMonitorModesAndDevicesImpl(final MonitorModeProps.Cache cache) {
if( null == rAndR ) { return; }
final AbstractGraphicsDevice device = getDisplay().getGraphicsDevice();
device.lock();
@@ -165,12 +165,14 @@ public class ScreenDriver extends ScreenImpl {
}
@Override
- protected Rectangle getNativeMonitorDeviceViewportImpl(MonitorDevice monitor) {
+ protected boolean updateNativeMonitorDeviceViewportImpl(final MonitorDevice monitor, final Rectangle viewportPU, final Rectangle viewportWU) {
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]);
+ viewportPU.set(viewportProps[0], viewportProps[1], viewportProps[2], viewportProps[3]);
+ viewportWU.set(viewportProps[0], viewportProps[1], viewportProps[2], viewportProps[3]); // equal window-units and pixel-units
+ return true;
} finally {
device.unlock();
}
@@ -207,7 +209,7 @@ public class ScreenDriver extends ScreenImpl {
return done;
}
- private DisplayImpl.DisplayRunnable<Boolean> xineramaEnabledQueryWithTemp = new DisplayImpl.DisplayRunnable<Boolean>() {
+ private final DisplayImpl.DisplayRunnable<Boolean> xineramaEnabledQueryWithTemp = new DisplayImpl.DisplayRunnable<Boolean>() {
@Override
public Boolean run(long dpy) {
return new Boolean(X11Util.XineramaIsEnabled(dpy));
@@ -225,8 +227,8 @@ public class ScreenDriver extends ScreenImpl {
}
@Override
- protected void calcVirtualScreenOriginAndSize(final Rectangle vOriginSize) {
- final RectangleImmutable ov = (RectangleImmutable) getViewport().cloneMutable();
+ protected void calcVirtualScreenOriginAndSize(final Rectangle viewport, Rectangle viewportInWindowUnits) {
+ final RectangleImmutable ov = DEBUG ? (RectangleImmutable) getViewport().cloneMutable() : null;
/**
if( null != rAndR && rAndR.getVersion().compareTo(RandR.version130) >= 0 && getMonitorDevices().size()>0 ) {
super.calcVirtualScreenOriginAndSize(vOriginSize);
@@ -242,11 +244,11 @@ public class ScreenDriver extends ScreenImpl {
runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable<Object>() {
@Override
public Object run(long dpy) {
- vOriginSize.set(0, 0, getWidth0(dpy, screen_idx), getHeight0(dpy, screen_idx));
+ viewport.set(0, 0, getWidth0(dpy, screen_idx), getHeight0(dpy, screen_idx));
return null;
} } );
if( DEBUG ) {
- System.err.println("X11Screen.calcVirtualScreenOriginAndSize: Querying X11: "+ov+" -> "+vOriginSize);
+ System.err.println("X11Screen.calcVirtualScreenOriginAndSize: Querying X11: "+ov+" -> "+viewport);
}
}
}
@@ -254,11 +256,11 @@ public class ScreenDriver extends ScreenImpl {
//----------------------------------------------------------------------
// Internals only
//
- private final <T> T runWithLockedDisplayDevice(DisplayRunnable<T> action) {
+ private final <T> T runWithLockedDisplayDevice(final DisplayRunnable<T> action) {
return display.runWithLockedDisplayDevice(action);
}
- private final <T> T runWithTempDisplayHandle(DisplayRunnable<T> action) {
+ private final <T> T runWithTempDisplayHandle(final DisplayRunnable<T> action) {
final long displayHandle = X11Util.openDisplay(display.getName());
if(0 == displayHandle) {
throw new RuntimeException("null device");
@@ -272,7 +274,7 @@ public class ScreenDriver extends ScreenImpl {
return res;
}
- private final <T> T runWithOptTempDisplayHandle(DisplayRunnable<T> action) {
+ private final <T> T runWithOptTempDisplayHandle(final DisplayRunnable<T> action) {
if( null != rAndR && rAndR.getVersion().compareTo(RandR.version130) >= 0 ) {
return display.runWithLockedDisplayDevice(action);
} else {
diff --git a/src/newt/native/MacWindow.m b/src/newt/native/MacWindow.m
index 25ea47c47..80e70216e 100644
--- a/src/newt/native/MacWindow.m
+++ b/src/newt/native/MacWindow.m
@@ -366,7 +366,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_DisplayDriver_destroyPoint
[pool release];
}
-static NSScreen * NewtScreen_getNSScreenByIndex(int screen_idx, BOOL cap) {
+NSScreen * NewtScreen_getNSScreenByIndex(int screen_idx, BOOL cap) {
NSArray *screens = [NSScreen screens];
if( screen_idx<0 || screen_idx>=[screens count] ) {
if( cap ) {
@@ -378,7 +378,7 @@ static NSScreen * NewtScreen_getNSScreenByIndex(int screen_idx, BOOL cap) {
return (NSScreen *) [screens objectAtIndex: screen_idx];
}
-static NSScreen * NewtScreen_getNSScreenByCoord(int x, int y) {
+NSScreen * NewtScreen_getNSScreenByCoord(int x, int y) {
NSArray *screens = [NSScreen screens];
int i;
for(i=[screens count]-1; i>=0; i--) {
@@ -394,7 +394,32 @@ static NSScreen * NewtScreen_getNSScreenByCoord(int x, int y) {
return (NSScreen *) [screens objectAtIndex: 0];
}
-static CGDirectDisplayID NewtScreen_getCGDirectDisplayIDByNSScreen(NSScreen *screen) {
+static void NewtScreen_dump() {
+#ifdef VERBOSE_ON
+ NSArray *screens = [NSScreen screens];
+ int i;
+ for(i=0; i<[screens count]; i++) {
+ NSScreen * screen = (NSScreen *) [screens objectAtIndex: i];
+ NSRect screenFrame = [screen frame];
+ NSRect screenVisibleFrame = [screen visibleFrame];
+ CGFloat pixelScale = 1.0; // default
+NS_DURING
+ // Available >= 10.7
+ pixelScale = [screen backingScaleFactor]; // HiDPI scaling
+NS_HANDLER
+NS_ENDHANDLER
+ NSWindowDepth depth = [screen depth]; // an (int) value!
+ DBG_PRINT( "NSScreen #%d (%p): Frame %lf/%lf %lfx%lf (vis %lf/%lf %lfx%lf), scale %lf, depth %d\n",
+ i, screen,
+ screenFrame.origin.x, screenFrame.origin.y, screenFrame.size.width, screenFrame.size.height,
+ screenVisibleFrame.origin.x, screenVisibleFrame.origin.y, screenVisibleFrame.size.width, screenVisibleFrame.size.height,
+ pixelScale, depth);
+ }
+#endif
+}
+
+
+CGDirectDisplayID NewtScreen_getCGDirectDisplayIDByNSScreen(NSScreen *screen) {
// Mind: typedef uint32_t CGDirectDisplayID; - however, we assume it's 64bit on 64bit ?!
NSDictionary * dict = [screen deviceDescription];
NSNumber * val = (NSNumber *) [dict objectForKey: @"NSScreenNumber"];
@@ -428,6 +453,20 @@ static long GetDictionaryLong(CFDictionaryRef theDict, const void* key)
/*
* Class: jogamp_newt_driver_macosx_ScreenDriver
+ * Method: getMonitorCount0
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_macosx_ScreenDriver_getMonitorCount0
+ (JNIEnv *env, jobject obj)
+{
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ NSArray *screens = [NSScreen screens];
+ [pool release];
+ return (jint) [screens count];
+}
+
+/*
+ * Class: jogamp_newt_driver_macosx_ScreenDriver
* Method: getMonitorProps0
* Signature: (I)[I
*/
@@ -463,8 +502,16 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_macosx_ScreenDriver_getMonit
fprintf(stderr, "MacScreen_getMonitorProps0.3: %ld ms\n", td_ms); fflush(NULL);
#endif
- CGRect bounds = CGDisplayBounds (display);
-
+ CGRect dBounds = CGDisplayBounds (display); // origin top-left
+#ifdef VERBOSE_ON
+ BOOL usesGL = CGDisplayUsesOpenGLAcceleration(display);
+ NSRect sFrame = [screen frame]; // origin bottom-left
+ DBG_PRINT( "getMonitorProps0: scrn %d, top-left displayBounds[%d/%d %dx%d], bottom-left screenFrame[%d/%d %dx%d], usesGL %d\n", (int)crt_idx,
+ (int)dBounds.origin.x, (int)dBounds.origin.y, (int)dBounds.size.width, (int)dBounds.size.height,
+ (int)sFrame.origin.x, (int)sFrame.origin.y, (int)sFrame.size.width, (int)sFrame.size.height,
+ (int)usesGL);
+#endif
+
jsize propCount = MIN_MONITOR_DEVICE_PROPERTIES - 1 - NUM_MONITOR_MODE_PROPERTIES;
jint prop[ propCount ];
int offset = 0;
@@ -472,10 +519,14 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_macosx_ScreenDriver_getMonit
prop[offset++] = crt_idx;
prop[offset++] = (jint) sizeMM.width;
prop[offset++] = (jint) sizeMM.height;
- prop[offset++] = (jint) bounds.origin.x; // rotated viewport x
- prop[offset++] = (jint) bounds.origin.y; // rotated viewport y
- prop[offset++] = (jint) bounds.size.width; // rotated viewport width
- prop[offset++] = (jint) bounds.size.height; // rotated viewport height
+ prop[offset++] = (jint) dBounds.origin.x; // rotated viewport x (pixel units, will be fixed in java code)
+ prop[offset++] = (jint) dBounds.origin.y; // rotated viewport y (pixel units, will be fixed in java code)
+ prop[offset++] = (jint) dBounds.size.width; // rotated viewport width (pixel units, will be fixed in java code)
+ prop[offset++] = (jint) dBounds.size.height; // rotated viewport height (pixel units, will be fixed in java code)
+ prop[offset++] = (jint) dBounds.origin.x; // rotated viewport x (window units, will be fixed in java code)
+ prop[offset++] = (jint) dBounds.origin.y; // rotated viewport y (window units, will be fixed in java code)
+ prop[offset++] = (jint) dBounds.size.width; // rotated viewport width (window units, will be fixed in java code)
+ prop[offset++] = (jint) dBounds.size.height; // rotated viewport height (window units, will be fixed in java code)
jintArray properties = (*env)->NewIntArray(env, propCount);
if (properties == NULL) {
@@ -503,6 +554,13 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_macosx_ScreenDriver_getMonit
[pool release];
return NULL;
}
+ CGFloat pixelScale = 1.0; // default
+NS_DURING
+ // Available >= 10.7
+ pixelScale = [screen backingScaleFactor]; // HiDPI scaling
+NS_HANDLER
+NS_ENDHANDLER
+
CGDirectDisplayID display = NewtScreen_getCGDirectDisplayIDByNSScreen(screen);
CFArrayRef availableModes = CGDisplayAvailableModes(display);
@@ -516,8 +574,8 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_macosx_ScreenDriver_getMonit
#ifdef VERBOSE_ON
if(0 >= mode_idx) {
// only for current mode (-1) and first mode (scanning)
- DBG_PRINT( "getScreenMode0: scrn %d (%p, %p), mode %d, avail: %d/%d, current rot %d ccw\n",
- (int)crt_idx, screen, (void*)(intptr_t)display, (int)mode_idx, (int)numberOfAvailableModes, (int)numberOfAvailableModesRots, currentCCWRot);
+ DBG_PRINT( "getScreenMode0: scrn %d (s %p, d %p, pscale %lf), mode %d, avail: %d/%d, current rot %d ccw\n",
+ (int)crt_idx, screen, (void*)(intptr_t)display, pixelScale, (int)mode_idx, (int)numberOfAvailableModes, (int)numberOfAvailableModesRots, currentCCWRot);
}
#endif
@@ -543,6 +601,10 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_macosx_ScreenDriver_getMonit
int mWidth = CGDDGetModeWidth(mode);
int mHeight = CGDDGetModeHeight(mode);
+ if( -1 == mode_idx ) {
+ mWidth *= (int)pixelScale; // accomodate HiDPI
+ mHeight *= (int)pixelScale; // accomodate HiDPI
+ }
// swap width and height, since OSX reflects rotated dimension, we don't
if ( 90 == currentCCWRot || 270 == currentCCWRot ) {
@@ -564,7 +626,7 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_macosx_ScreenDriver_getMonit
prop[propIndex++] = 0; // flags
prop[propIndex++] = nativeId;
prop[propIndex++] = ccwRot;
-
+
DBG_PRINT( "getScreenMode0: Mode %d/%d (%d): %dx%d, %d bpp, %d / %d Hz, nativeId %d, rot %d ccw\n",
(int)mode_idx, (int)numberOfAvailableModesRots, (int)numberOfAvailableModes,
(int)prop[1], (int)prop[2], (int)prop[3],
@@ -653,6 +715,8 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_initIDs0
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ NewtScreen_dump();
+
jclass c;
c = (*env)->FindClass(env, ClazzNamePoint);
if(NULL==c) {
@@ -694,21 +758,13 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_createView0
DBG_PRINT( "createView0 - %p (this), %d/%d %dx%d, fs %d (START)\n",
(void*)(intptr_t)jthis, (int)x, (int)y, (int)w, (int)h, (int)fullscreen);
- NSScreen *myScreen = NewtScreen_getNSScreenByCoord(x, y);
- NSRect rectWin;
-
- if (fullscreen) {
- rectWin = [myScreen frame];
- x = 0;
- y = 0;
- w = (jint) (rectWin.size.width);
- h = (jint) (rectWin.size.height);
- } else {
- rectWin = NSMakeRect(x, y, w, h);
- }
-
NSRect rectView = NSMakeRect(0, 0, w, h);
NewtView *myView = [[NewtView alloc] initWithFrame: rectView] ;
+NS_DURING
+ // Available >= 10.7
+ [myView setWantsBestResolutionOpenGLSurface: YES]; // HiDPI scaling: Always desired
+NS_HANDLER
+NS_ENDHANDLER
DBG_PRINT( "createView0.X - new view: %p\n", myView);
[pool release];
@@ -735,19 +791,10 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_createWindow
(int)styleMask, (int)bufferingType, myView);
(void)myView;
- NSScreen *myScreen = NewtScreen_getNSScreenByCoord(x, y);
-
- NSRect rectWin;
if (fullscreen) {
styleMask = NSBorderlessWindowMask;
- rectWin = [myScreen frame];
- x = 0;
- y = 0;
- w = (jint) (rectWin.size.width);
- h = (jint) (rectWin.size.height);
- } else {
- rectWin = NSMakeRect(x, y, w, h);
}
+ NSRect rectWin = NSMakeRect(x, y, w, h);
// Allocate the window
NewtMacWindow* myWindow = [[NewtMacWindow alloc] initWithContentRect: rectWin
@@ -772,7 +819,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_createWindow
* Signature: (JJIIIIZZZJ)V
*/
JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_initWindow0
- (JNIEnv *env, jobject jthis, jlong parent, jlong window, jint x, jint y, jint w, jint h,
+ (JNIEnv *env, jobject jthis, jlong parent, jlong window, jint x, jint y, jint w, jint h,
jboolean opaque, jboolean visible, jlong jview)
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
@@ -784,19 +831,6 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_initWindow0
(void*)(intptr_t)jthis, (void*)(intptr_t)parent, myWindow, (int)x, (int)y, (int)w, (int)h,
(int) opaque, (int)fullscreen, (int)visible, myView);
- NSScreen *myScreen = NewtScreen_getNSScreenByCoord(x, y);
-
- NSRect rectWin;
- if (fullscreen) {
- rectWin = [myScreen frame];
- x = 0;
- y = 0;
- w = (jint) (rectWin.size.width);
- h = (jint) (rectWin.size.height);
- } else {
- rectWin = NSMakeRect(x, y, w, h);
- }
-
[myWindow setReleasedWhenClosed: NO]; // We control NSWindow destruction!
[myWindow setPreservesContentDuringLiveResize: NO];
NS_DURING
@@ -927,6 +961,7 @@ NS_DURING
* Shall have no penalty on modern GPU and is also recommended, see bottom box @
* <https://developer.apple.com/library/mac/documentation/graphicsimaging/Conceptual/QuartzDisplayServicesConceptual/Articles/DisplayCapture.html>
*
+ NSScreen *myScreen = NewtScreen_getNSScreenByCoord(x, y);
if ( [myView respondsToSelector:@selector(enterFullScreenMode:withOptions:)] ) {
// Available >= 10.5 - Makes the menubar disapear
[myView enterFullScreenMode: myScreen withOptions:NULL];
diff --git a/src/newt/native/NewtMacWindow.h b/src/newt/native/NewtMacWindow.h
index 8f6362ac2..0f80df2d7 100644
--- a/src/newt/native/NewtMacWindow.h
+++ b/src/newt/native/NewtMacWindow.h
@@ -49,6 +49,10 @@
// #define DBG_LIFECYCLE 1
+NSScreen * NewtScreen_getNSScreenByIndex(int screen_idx, BOOL cap);
+NSScreen * NewtScreen_getNSScreenByCoord(int x, int y);
+CGDirectDisplayID NewtScreen_getCGDirectDisplayIDByNSScreen(NSScreen *screen);
+
@interface NewtView : NSView
{
jobject javaWindowObject;
@@ -129,6 +133,7 @@
- (void) handleFlagsChanged:(int) keyMask keyIndex: (int) keyIdx keyCode: (int) keyCode modifiers: (NSUInteger) mods;
- (void) sendKeyEvent: (NSEvent*) event eventType: (jshort) evType;
- (void) sendKeyEvent: (jshort) keyCode characters: (NSString*) chars modifiers: (NSUInteger)mods eventType: (jshort) evType;
+- (void) viewDidChangeBackingProperties;
@end
diff --git a/src/newt/native/NewtMacWindow.m b/src/newt/native/NewtMacWindow.m
index b4133ac7e..1a70de445 100644
--- a/src/newt/native/NewtMacWindow.m
+++ b/src/newt/native/NewtMacWindow.m
@@ -174,6 +174,7 @@ static jmethodID requestFocusID = NULL;
static jmethodID insetsChangedID = NULL;
static jmethodID sizeChangedID = NULL;
+static jmethodID updatePixelScaleID = NULL;
static jmethodID visibleChangedID = NULL;
static jmethodID positionChangedID = NULL;
static jmethodID focusChangedID = NULL;
@@ -330,8 +331,8 @@ static jmethodID windowRepaintID = NULL;
NSRect viewFrame = [self frame];
(*env)->CallVoidMethod(env, javaWindowObject, windowRepaintID, JNI_TRUE, // defer ..
- dirtyRect.origin.x, viewFrame.size.height - dirtyRect.origin.y,
- dirtyRect.size.width, dirtyRect.size.height);
+ (int)dirtyRect.origin.x, (int)viewFrame.size.height - (int)dirtyRect.origin.y,
+ (int)dirtyRect.size.width, (int)dirtyRect.size.height);
// detaching thread not required - daemon
// NewtCommon_ReleaseJNIEnv(shallBeDetached);
@@ -761,6 +762,31 @@ static jmethodID windowRepaintID = NULL;
// NewtCommon_ReleaseJNIEnv(shallBeDetached);
}
+- (void)viewDidChangeBackingProperties
+{
+ [super viewDidChangeBackingProperties];
+
+ CGFloat pixelScale = [[self window] backingScaleFactor];
+ [[self layer] setContentsScale: pixelScale];
+
+ if (javaWindowObject == NULL) {
+ DBG_PRINT("viewDidChangeBackingProperties: null javaWindowObject\n");
+ return;
+ }
+ int shallBeDetached = 0;
+ JNIEnv* env = NewtCommon_GetJNIEnv(1 /* asDaemon */, &shallBeDetached);
+ if(NULL==env) {
+ DBG_PRINT("viewDidChangeBackingProperties: null JNIEnv\n");
+ return;
+ }
+
+ (*env)->CallVoidMethod(env, javaWindowObject, updatePixelScaleID, JNI_TRUE, (jfloat)pixelScale); // defer
+
+ // detaching thread not required - daemon
+ // NewtCommon_ReleaseJNIEnv(shallBeDetached);
+}
+
+
@end
@implementation NewtMacWindow
@@ -769,7 +795,8 @@ static jmethodID windowRepaintID = NULL;
{
enqueueMouseEventID = (*env)->GetMethodID(env, clazz, "enqueueMouseEvent", "(ZSIIISF)V");
enqueueKeyEventID = (*env)->GetMethodID(env, clazz, "enqueueKeyEvent", "(ZSISCC)V");
- sizeChangedID = (*env)->GetMethodID(env, clazz, "sizeChanged", "(ZIIZ)V");
+ sizeChangedID = (*env)->GetMethodID(env, clazz, "sizeChanged", "(ZIIZ)V");
+ updatePixelScaleID = (*env)->GetMethodID(env, clazz, "updatePixelScale", "(ZF)V");
visibleChangedID = (*env)->GetMethodID(env, clazz, "visibleChanged", "(ZZ)V");
insetsChangedID = (*env)->GetMethodID(env, clazz, "insetsChanged", "(ZIIII)V");
positionChangedID = (*env)->GetMethodID(env, clazz, "screenPositionChanged", "(ZII)V");
@@ -777,7 +804,7 @@ static jmethodID windowRepaintID = NULL;
windowDestroyNotifyID = (*env)->GetMethodID(env, clazz, "windowDestroyNotify", "(Z)Z");
windowRepaintID = (*env)->GetMethodID(env, clazz, "windowRepaint", "(ZIIII)V");
requestFocusID = (*env)->GetMethodID(env, clazz, "requestFocus", "(Z)V");
- if (enqueueMouseEventID && enqueueKeyEventID && sizeChangedID && visibleChangedID && insetsChangedID &&
+ if (enqueueMouseEventID && enqueueKeyEventID && sizeChangedID && updatePixelScaleID && visibleChangedID && insetsChangedID &&
positionChangedID && focusChangedID && windowDestroyNotifyID && requestFocusID && windowRepaintID)
{
CKCH_CreateDictionaries();
@@ -824,10 +851,12 @@ static jmethodID windowRepaintID = NULL;
// Why is this necessary? Without it we don't get any of the
// delegate methods like resizing and window movement.
[self setDelegate: self];
+
cachedInsets[0] = 0; // l
cachedInsets[1] = 0; // r
cachedInsets[2] = 0; // t
cachedInsets[3] = 0; // b
+
realized = YES;
DBG_PRINT("NewtWindow::create: %p, realized %d, hasPresentationSwitch %d[defaultOptions 0x%X, fullscreenOptions 0x%X], (refcnt %d)\n",
res, realized, (int)hasPresentationSwitch, (int)defaultPresentationOptions, (int)fullscreenPresentationOptions, (int)[res retainCount]);
@@ -1123,7 +1152,7 @@ static jmethodID windowRepaintID = NULL;
NSRect frameRect = [self frame];
NSRect contentRect = [self contentRectForFrameRect: frameRect];
- (*env)->CallVoidMethod(env, javaWindowObject, sizeChangedID, JNI_FALSE,
+ (*env)->CallVoidMethod(env, javaWindowObject, sizeChangedID, JNI_TRUE, // defer
(jint) contentRect.size.width,
(jint) contentRect.size.height, JNI_FALSE);
}
diff --git a/src/newt/native/ScreenMode.h b/src/newt/native/ScreenMode.h
index 110f1c493..56c424b11 100644
--- a/src/newt/native/ScreenMode.h
+++ b/src/newt/native/ScreenMode.h
@@ -40,7 +40,8 @@
#define NUM_MONITOR_MODE_PROPERTIES_ALL 8 /* count + the above */
-#define MIN_MONITOR_DEVICE_PROPERTIES 11 /* count + id, ScreenSizeMM[width, height], rotated Viewport[x, y, width, height], currentMonitorModeId, rotation, supportedModeId+ */
+#define MIN_MONITOR_DEVICE_PROPERTIES 15 /* count + id, ScreenSizeMM[width, height], rotated Viewport pixel-units, rotated Viewport pixel-units, currentMonitorModeId, rotation, supportedModeId+ */
+ /* Viewport := [x, y, width, height] (4 elements) */
#define FLAG_INTERLACE ( 1 << 0 )
#define FLAG_DOUBLESCAN ( 1 << 1 )
diff --git a/src/newt/native/WindowsWindow.c b/src/newt/native/WindowsWindow.c
index c20e156c1..70d0c6f83 100644
--- a/src/newt/native/WindowsWindow.c
+++ b/src/newt/native/WindowsWindow.c
@@ -1859,10 +1859,14 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_windows_ScreenDriver_getMoni
prop[propIndex++] = monitor_idx;
prop[propIndex++] = widthmm;
prop[propIndex++] = heightmm;
- prop[propIndex++] = dm.dmPosition.x; // rotated viewport
- prop[propIndex++] = dm.dmPosition.y; // rotated viewport
- prop[propIndex++] = dm.dmPelsWidth; // rotated viewport
- prop[propIndex++] = dm.dmPelsHeight; // rotated viewport
+ prop[propIndex++] = dm.dmPosition.x; // rotated viewport pixel units
+ prop[propIndex++] = dm.dmPosition.y; // rotated viewport pixel units
+ prop[propIndex++] = dm.dmPelsWidth; // rotated viewport pixel units
+ prop[propIndex++] = dm.dmPelsHeight; // rotated viewport pixel units
+ prop[propIndex++] = dm.dmPosition.x; // rotated viewport window units (same)
+ prop[propIndex++] = dm.dmPosition.y; // rotated viewport window units (same)
+ prop[propIndex++] = dm.dmPelsWidth; // rotated viewport window units (same)
+ prop[propIndex++] = dm.dmPelsHeight; // rotated viewport window units (same)
jintArray properties = (*env)->NewIntArray(env, propCount);
if (properties == NULL) {
diff --git a/src/newt/native/X11RandR13.c b/src/newt/native/X11RandR13.c
index 92c20e893..4e92a32b4 100644
--- a/src/newt/native/X11RandR13.c
+++ b/src/newt/native/X11RandR13.c
@@ -426,10 +426,14 @@ JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_RandR13_getMonitorDevice
prop[propIndex++] = crt_idx;
prop[propIndex++] = xrrOutputInfo->mm_width;
prop[propIndex++] = xrrOutputInfo->mm_height;
- prop[propIndex++] = xrrCrtcInfo->x;
- prop[propIndex++] = xrrCrtcInfo->y;
- prop[propIndex++] = xrrCrtcInfo->width;
- prop[propIndex++] = xrrCrtcInfo->height;
+ prop[propIndex++] = xrrCrtcInfo->x; // rotated viewport pixel units
+ prop[propIndex++] = xrrCrtcInfo->y; // rotated viewport pixel units
+ prop[propIndex++] = xrrCrtcInfo->width; // rotated viewport pixel units
+ prop[propIndex++] = xrrCrtcInfo->height; // rotated viewport pixel units
+ prop[propIndex++] = xrrCrtcInfo->x; // rotated viewport window units (same)
+ prop[propIndex++] = xrrCrtcInfo->y; // rotated viewport window units (same)
+ prop[propIndex++] = xrrCrtcInfo->width; // rotated viewport window units (same)
+ prop[propIndex++] = xrrCrtcInfo->height; // rotated viewport window units (same)
prop[propIndex++] = xrrCrtcInfo->mode; // current mode id
prop[propIndex++] = NewtScreen_XRotation2Degree(env, xrrCrtcInfo->rotation);
int i;