summaryrefslogtreecommitdiffstats
path: root/src/nativewindow
diff options
context:
space:
mode:
Diffstat (limited to 'src/nativewindow')
-rw-r--r--src/nativewindow/classes/com/jogamp/nativewindow/awt/JAWTWindow.java124
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/NativeSurface.java2
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/ScalableSurface.java52
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/util/Point.java31
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/SurfaceScaleUtils.java233
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/WrappedSurface.java33
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java67
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java13
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java66
-rw-r--r--src/nativewindow/native/macosx/OSXmisc.m83
10 files changed, 392 insertions, 312 deletions
diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/awt/JAWTWindow.java b/src/nativewindow/classes/com/jogamp/nativewindow/awt/JAWTWindow.java
index 32e4add75..97dba9598 100644
--- a/src/nativewindow/classes/com/jogamp/nativewindow/awt/JAWTWindow.java
+++ b/src/nativewindow/classes/com/jogamp/nativewindow/awt/JAWTWindow.java
@@ -47,6 +47,8 @@ import com.jogamp.nativewindow.MutableGraphicsConfiguration;
import java.awt.Component;
import java.awt.Container;
import java.awt.Cursor;
+import java.awt.EventQueue;
+import java.awt.GraphicsConfiguration;
import java.awt.Window;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
@@ -103,10 +105,11 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
protected Insets insets;
private volatile long offscreenSurfaceLayer;
- private final int[] nativePixelScale = new int[] { ScalableSurface.IDENTITY_PIXELSCALE, ScalableSurface.IDENTITY_PIXELSCALE };
- private final int[] hasPixelScale = new int[] { ScalableSurface.IDENTITY_PIXELSCALE, ScalableSurface.IDENTITY_PIXELSCALE };
- protected final int[] reqPixelScale = new int[] { ScalableSurface.AUTOMAX_PIXELSCALE, ScalableSurface.AUTOMAX_PIXELSCALE };
-
+ private final float[] minPixelScale = new float[] { ScalableSurface.IDENTITY_PIXELSCALE, ScalableSurface.IDENTITY_PIXELSCALE };
+ private final float[] maxPixelScale = new float[] { ScalableSurface.IDENTITY_PIXELSCALE, ScalableSurface.IDENTITY_PIXELSCALE };
+ private final float[] hasPixelScale = new float[] { ScalableSurface.IDENTITY_PIXELSCALE, ScalableSurface.IDENTITY_PIXELSCALE };
+ private final float[] reqPixelScale = new float[] { ScalableSurface.AUTOMAX_PIXELSCALE, ScalableSurface.AUTOMAX_PIXELSCALE };
+ private volatile boolean hasPixelScaleChanged = false;
private long drawable_old;
/**
@@ -269,38 +272,41 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
insets = new Insets();
hasPixelScale[0] = ScalableSurface.IDENTITY_PIXELSCALE;
hasPixelScale[1] = ScalableSurface.IDENTITY_PIXELSCALE;
- nativePixelScale[0] = ScalableSurface.IDENTITY_PIXELSCALE;
- nativePixelScale[1] = ScalableSurface.IDENTITY_PIXELSCALE;
+ minPixelScale[0] = ScalableSurface.IDENTITY_PIXELSCALE;
+ minPixelScale[1] = ScalableSurface.IDENTITY_PIXELSCALE;
+ maxPixelScale[0] = ScalableSurface.IDENTITY_PIXELSCALE;
+ maxPixelScale[1] = ScalableSurface.IDENTITY_PIXELSCALE;
+ hasPixelScaleChanged = false;
}
protected abstract void invalidateNative();
- /**
- * {@inheritDoc}
- * <p>
- * Per default impl. only works for not yet {@link #isRealized() realized} instances,
- * current exception OSX.
- * </p>
- */
@Override
- public void setSurfaceScale(final int[] pixelScale) {
- SurfaceScaleUtils.validateReqPixelScale(reqPixelScale, pixelScale, DEBUG ? getClass().getSimpleName() : null);
+ public boolean setSurfaceScale(final float[] pixelScale) {
+ System.arraycopy(pixelScale, 0, reqPixelScale, 0, 2);
+ return false;
}
@Override
- public final int[] getRequestedSurfaceScale(final int[] result) {
+ public final float[] getRequestedSurfaceScale(final float[] result) {
System.arraycopy(reqPixelScale, 0, result, 0, 2);
return result;
}
@Override
- public final int[] getCurrentSurfaceScale(final int[] result) {
+ public final float[] getCurrentSurfaceScale(final float[] result) {
System.arraycopy(hasPixelScale, 0, result, 0, 2);
return result;
}
@Override
- public final int[] getNativeSurfaceScale(final int[] result) {
- System.arraycopy(nativePixelScale, 0, result, 0, 2);
+ public float[] getMinimumSurfaceScale(final float[] result) {
+ System.arraycopy(minPixelScale, 0, result, 0, 2);
+ return result;
+ }
+
+ @Override
+ public final float[] getMaximumSurfaceScale(final float[] result) {
+ System.arraycopy(maxPixelScale, 0, result, 0, 2);
return result;
}
@@ -323,31 +329,75 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
insets.set(contInsets.left, contInsets.right, contInsets.top, contInsets.bottom);
}
}
- {
- final int ps = JAWTUtil.getPixelScale(config.getAWTGraphicsConfiguration());
- nativePixelScale[0] = ps;
- nativePixelScale[1] = ps;
- }
- return updatePixelScale() || changedBounds;
+ updatePixelScale(false);
+ return hasPixelScaleChanged || changedBounds;
+ }
+
+ /**
+ * Updates the minimum and maximum pixel-scale values
+ * and returns {@code true} if they were updated.
+ * @param clearFlag if {@code true}, the {@code hasPixelScaleChanged} flag will be cleared
+ * @return {@code true} if values were updated, otherwise {@code false}.
+ * @see #hasPixelScaleChanged()
+ */
+ public final boolean updatePixelScale(final boolean clearFlag) {
+ // Using GraphicsConfiguration from component, which may change by moving to diff monitor
+ if( EventQueue.isDispatchThread() || Thread.holdsLock(component.getTreeLock()) ) {
+ if( JAWTUtil.getPixelScale(component.getGraphicsConfiguration(), minPixelScale, maxPixelScale) ) {
+ hasPixelScaleChanged = true;
+ if( DEBUG ) {
+ System.err.println("JAWTWindow.updatePixelScale: updated req["+
+ reqPixelScale[0]+", "+reqPixelScale[1]+"], min["+
+ minPixelScale[0]+", "+minPixelScale[1]+"], max["+
+ maxPixelScale[0]+", "+maxPixelScale[1]+"], has["+
+ hasPixelScale[0]+", "+hasPixelScale[1]+"]");
+ }
+ }
+ }
+ if( clearFlag ) {
+ final boolean r = hasPixelScaleChanged;
+ hasPixelScaleChanged = false;
+ return r;
+ } else {
+ return hasPixelScaleChanged;
+ }
+ }
+
+ /**
+ * Returns and clears the {@code hasPixelScaleChanged} flag, as set via {@link #lockSurface()}.
+ * <p>
+ * {@code hasPixelScaleChanged} is {@code true},
+ * if the {@link #getMinimumSurfaceScale(float[]) minimum} or {@link #getMaximumSurfaceScale(float[]) maximum}
+ * pixel scale has changed.
+ * User needs to {@link #setSurfaceScale(float[]) set the current pixel scale} in this case
+ * using the {@link #getRequestedSurfaceScale(float[]) requested pixel scale}
+ * to update the surface pixel scale.
+ * </p>
+ */
+ public final boolean hasPixelScaleChanged() {
+ final boolean v = hasPixelScaleChanged;
+ hasPixelScaleChanged = false;
+ return v;
}
/**
- * Update pixelScale
+ * set requested pixelScale
* @return true if pixelScale has changed, otherwise false
*/
- protected final boolean updatePixelScale() {
- return SurfaceScaleUtils.computePixelScale(hasPixelScale, hasPixelScale, reqPixelScale, nativePixelScale, DEBUG ? getClass().getSimpleName() : null);
+ protected final boolean setReqPixelScale() {
+ updatePixelScale(true);
+ return SurfaceScaleUtils.setNewPixelScale(hasPixelScale, hasPixelScale, reqPixelScale, minPixelScale, maxPixelScale, DEBUG ? getClass().getSimpleName() : null);
}
/** @return the JAWT_DrawingSurfaceInfo's (JAWT_Rectangle) bounds, updated with lock */
public final RectangleImmutable getBounds() { return bounds; }
/** @return the safe pixelScale value for x-direction, i.e. never negative or zero. Updated with lock. */
- protected final int getPixelScaleX() { return hasPixelScale[0]; }
+ protected final float getPixelScaleX() { return hasPixelScale[0]; }
/** @return the safe pixelScale value for y-direction, i.e. never negative or zero. Updated with lock. */
- protected final int getPixelScaleY() { return hasPixelScale[1]; }
+ protected final float getPixelScaleY() { return hasPixelScale[1]; }
@Override
public final InsetsImmutable getInsets() { return insets; }
@@ -671,26 +721,22 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
@Override
public final int getSurfaceWidth() {
- return getWidth() * getPixelScaleX();
+ return SurfaceScaleUtils.scale(getWidth(), getPixelScaleX());
}
@Override
public final int getSurfaceHeight() {
- return getHeight() * getPixelScaleY();
+ return SurfaceScaleUtils.scale(getHeight(), getPixelScaleY());
}
@Override
public final int[] convertToWindowUnits(final int[] pixelUnitsAndResult) {
- pixelUnitsAndResult[0] /= getPixelScaleX();
- pixelUnitsAndResult[1] /= getPixelScaleY();
- return pixelUnitsAndResult;
+ return SurfaceScaleUtils.scaleInv(pixelUnitsAndResult, pixelUnitsAndResult, hasPixelScale);
}
@Override
public final int[] convertToPixelUnits(final int[] windowUnitsAndResult) {
- windowUnitsAndResult[0] *= getPixelScaleX();
- windowUnitsAndResult[1] *= getPixelScaleY();
- return windowUnitsAndResult;
+ return SurfaceScaleUtils.scale(windowUnitsAndResult, windowUnitsAndResult, hasPixelScale);
}
@Override
@@ -874,7 +920,7 @@ public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface,
", bounds "+bounds+", insets "+insets
);
sb.append(", window ["+getX()+"/"+getY()+" "+getWidth()+"x"+getHeight()+
- "], pixels[s "+getPixelScaleX()+"x"+getPixelScaleY()+" -> "+getSurfaceWidth()+"x"+getSurfaceHeight()+"]"+
+ "], pixels[scale "+getPixelScaleX()+", "+getPixelScaleY()+" -> "+getSurfaceWidth()+"x"+getSurfaceHeight()+"]"+
", visible "+component.isVisible());
sb.append(", lockedExt "+isSurfaceLockedByOtherThread()+
",\n\tconfig "+config+
diff --git a/src/nativewindow/classes/javax/media/nativewindow/NativeSurface.java b/src/nativewindow/classes/javax/media/nativewindow/NativeSurface.java
index 4d764dc4f..d5ac56178 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/NativeSurface.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/NativeSurface.java
@@ -198,6 +198,7 @@ public interface NativeSurface extends SurfaceUpdatedListener {
* @param pixelUnitsAndResult int[2] storage holding the pixel units for the x- and y-coord to convert
* and the resulting values.
* @return result int[2] storage pixelUnitsAndResult for chaining holding the converted values
+ * @see ScalableSurface
*/
public int[] convertToWindowUnits(final int[] pixelUnitsAndResult);
@@ -206,6 +207,7 @@ public interface NativeSurface extends SurfaceUpdatedListener {
* @param windowUnitsAndResult int[2] storage holding the window units for the x- and y-coord to convert
* and the resulting values.
* @return result int[2] storage windowUnitsAndResult for chaining holding the converted values
+ * @see ScalableSurface
*/
public int[] convertToPixelUnits(final int[] windowUnitsAndResult);
diff --git a/src/nativewindow/classes/javax/media/nativewindow/ScalableSurface.java b/src/nativewindow/classes/javax/media/nativewindow/ScalableSurface.java
index ffd5c224c..0cd2c7961 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/ScalableSurface.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/ScalableSurface.java
@@ -30,16 +30,17 @@ package javax.media.nativewindow;
/**
* Adding mutable surface pixel scale property to implementing class, usually to a {@link NativeSurface} implementation,
- * see {@link #setSurfaceScale(int[])}.
+ * see {@link #setSurfaceScale(float[])}.
*/
public interface ScalableSurface {
/** Setting surface-pixel-scale of {@value}, results in same pixel- and window-units. */
- public static final int IDENTITY_PIXELSCALE = 1;
+ public static final float IDENTITY_PIXELSCALE = 1f;
/** Setting surface-pixel-scale of {@value}, results in maximum platform dependent pixel-scale, i.e. pixel-units >> window-units where available. */
- public static final int AUTOMAX_PIXELSCALE = 0;
+ public static final float AUTOMAX_PIXELSCALE = 0f;
/**
- * Request a pixel scale in x- and y-direction for the associated {@link NativeSurface}.
+ * Request a pixel scale in x- and y-direction for the associated {@link NativeSurface},
+ * where {@code size_in_pixel_units = pixel_scale * size_in_window_units}.
* <p>
* Default pixel scale request for both directions is {@link #AUTOMAX_PIXELSCALE}.
* </p>
@@ -50,48 +51,57 @@ public interface ScalableSurface {
* <p>
* The <i>requested</i> pixel scale will be validated against platform limits before native scale-setup,
* i.e. clipped to {@link #IDENTITY_PIXELSCALE} if not supported or clipped to the platform maximum.
- * It can be queried via {@link #getRequestedSurfaceScale(int[])}.
+ * It can be queried via {@link #getRequestedSurfaceScale(float[])}.
* </p>
* <p>
* The actual <i>realized</i> pixel scale values of the {@link NativeSurface}
- * can be queried via {@link #getCurrentSurfaceScale(int[])} or
+ * can be queried via {@link #getCurrentSurfaceScale(float[])} or
* computed via <code>surface.{@link NativeSurface#convertToPixelUnits(int[]) convertToPixelUnits}(new int[] { 1, 1 })</code>
* </p>
- * @param pixelScale <i>requested</i> surface pixel scale int[2] values for x- and y-direction.
+ * @param pixelScale <i>requested</i> surface pixel scale float[2] values for x- and y-direction.
+ * @return {@code true} if the {@link #getCurrentSurfaceScale(float[]) current pixel scale} has changed, otherwise {@code false}.
+ * @see #getRequestedSurfaceScale(float[])
*/
- public void setSurfaceScale(final int[] pixelScale);
+ public boolean setSurfaceScale(final float[] pixelScale);
/**
- * Returns the requested pixel scale of the associated {@link NativeSurface}.
+ * Returns the {@link #setSurfaceScale(float[]) requested} pixel scale of the associated {@link NativeSurface}.
*
- * @param result int[2] storage for the result
- * @return the passed storage containing the requested pixelScale for chaining
+ * @param result float[2] storage for the result
+ * @return the passed storage containing the current pixelScale for chaining
+ * @see #setSurfaceScale(float[])
*/
- int[] getRequestedSurfaceScale(final int[] result);
+ public float[] getRequestedSurfaceScale(final float[] result);
/**
* Returns the current pixel scale of the associated {@link NativeSurface}.
*
- * @param result int[2] storage for the result
+ * @param result float[2] storage for the result
* @return the passed storage containing the current pixelScale for chaining
*/
- public int[] getCurrentSurfaceScale(final int[] result);
+ public float[] getCurrentSurfaceScale(final float[] result);
+
+ /**
+ * Returns the minimum pixel scale of the associated {@link NativeSurface}.
+ * @param result float[2] storage for the result
+ * @return the passed storage containing the minimum pixelScale for chaining
+ */
+ public float[] getMinimumSurfaceScale(final float[] result);
/**
- * Returns the native pixel scale of the associated {@link NativeSurface}
- * reflecting it's currently bound <i>monitor surface resolution in pixels</i>.
+ * Returns the maximum pixel scale of the associated {@link NativeSurface}.
* <p>
- * The native pixel scale maybe used to determine the proper <i>dpi</i>
- * value of this {@link NativeSurface}:
+ * The maximum pixel scale maybe used to determine the proper <i>dpi</i>
+ * value of the monitor displaying this {@link NativeSurface}.
* <pre>
* surfacePpMM = monitorPpMM * currentSurfaceScale / nativeSurfaceScale,
* with PpMM == pixel per millimeter
* </pre>
* </p>
*
- * @param result int[2] storage for the result
- * @return the passed storage containing the native pixelScale for chaining
+ * @param result float[2] storage for the result
+ * @return the passed storage containing the maximum pixelScale for chaining
*/
- public int[] getNativeSurfaceScale(final int[] result);
+ public float[] getMaximumSurfaceScale(final float[] result);
}
diff --git a/src/nativewindow/classes/javax/media/nativewindow/util/Point.java b/src/nativewindow/classes/javax/media/nativewindow/util/Point.java
index 3576a7dd0..3d416d2f5 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/util/Point.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/util/Point.java
@@ -145,6 +145,22 @@ public class Point implements Cloneable, PointImmutable {
}
/**
+ * Scale this instance's x- and y-components,
+ * i.e. multiply them by the given scale factors.
+ * <p>
+ * The product is rounded back to integer.
+ * </p>
+ * @param sx scale factor for x
+ * @param sy scale factor for y
+ * @return this instance for scaling
+ */
+ public final Point scale(final float sx, final float sy) {
+ x = (int)(x * sx + 0.5f);
+ y = (int)(y * sy + 0.5f);
+ return this;
+ }
+
+ /**
* Inverse scale this instance's x- and y-components,
* i.e. divide them by the given scale factors.
* @param sx inverse scale factor for x
@@ -156,4 +172,19 @@ public class Point implements Cloneable, PointImmutable {
y /= sy ;
return this;
}
+ /**
+ * Inverse scale this instance's x- and y-components,
+ * i.e. divide them by the given scale factors.
+ * <p>
+ * The product is rounded back to integer.
+ * </p>
+ * @param sx inverse scale factor for x
+ * @param sy inverse scale factor for y
+ * @return this instance for scaling
+ */
+ public final Point scaleInv(final float sx, final float sy) {
+ x = (int)(x / sx + 0.5f);
+ y = (int)(y / sy + 0.5f);
+ return this;
+ }
}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/SurfaceScaleUtils.java b/src/nativewindow/classes/jogamp/nativewindow/SurfaceScaleUtils.java
index 73413cf59..70eec7b24 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/SurfaceScaleUtils.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/SurfaceScaleUtils.java
@@ -27,7 +27,6 @@
*/
package jogamp.nativewindow;
-import javax.media.nativewindow.NativeWindowFactory;
import javax.media.nativewindow.ScalableSurface;
/**
@@ -35,138 +34,162 @@ import javax.media.nativewindow.ScalableSurface;
*/
public class SurfaceScaleUtils {
- private static final int[] PlatformMaxPixelScale;
- private static final boolean PlatformUniformPixelScale;
- private static final boolean PlatformPixelScaleSupported;
+ private static final float EPSILON = 1.1920929E-7f; // Float.MIN_VALUE == 1.4e-45f ; double EPSILON 2.220446049250313E-16d
- static {
- if( NativeWindowFactory.TYPE_MACOSX == NativeWindowFactory.getNativeWindowType(true) ) {
- PlatformMaxPixelScale = new int[] { jogamp.nativewindow.macosx.OSXUtil.MAX_PIXELSCALE, jogamp.nativewindow.macosx.OSXUtil.MAX_PIXELSCALE };
- PlatformUniformPixelScale = true;
- PlatformPixelScaleSupported = true;
- } else {
- PlatformMaxPixelScale = new int[] { ScalableSurface.IDENTITY_PIXELSCALE, ScalableSurface.IDENTITY_PIXELSCALE };
- PlatformUniformPixelScale = false;
- PlatformPixelScaleSupported = false;
- }
+ private static boolean isZero(final float a) {
+ return Math.abs(a) < EPSILON;
}
/**
- * Compute a new valid pixelScale to be used by {@link NativeSurface} implementations,
- * based on the given request and surface's pixelScale
+ * Returns integer rounded product, i.e. {@code (int) ( a * pixelScale + 0.5f )}
*
- * @param result int[2] storage for result, maybe same as <code>prePixelScale</code> for in-place
- * @param prePixelScale previous pixelScale
- * @param reqPixelScale requested pixelScale, validated via {@link #validateReqPixelScale(int[], int, String)}.
- * @param newPixelScaleRaw new raw surface pixelScale
- * @param DEBUG_PREFIX if set, dumps debug info on stderr using this prefix
- * @return true if pixelScale has changed, otherwise false
+ * @param a the int value
+ * @param pixelScale the float scale factor
+ * @return the integer rounded product
*/
- public static boolean computePixelScale(final int[] result, final int[] prePixelScale, final int[] reqPixelScale, final int[] newPixelScaleRaw, final String DEBUG_PREFIX) {
- final int newPixelScaleSafeX = 0 < newPixelScaleRaw[0] ? newPixelScaleRaw[0] : ScalableSurface.IDENTITY_PIXELSCALE;
- final int newPixelScaleSafeY = 0 < newPixelScaleRaw[1] ? newPixelScaleRaw[1] : ScalableSurface.IDENTITY_PIXELSCALE;
- final boolean useHiDPI = ScalableSurface.IDENTITY_PIXELSCALE != reqPixelScale[0] || ScalableSurface.IDENTITY_PIXELSCALE != reqPixelScale[1];
- final int prePixelScaleX = prePixelScale[0];
- final int prePixelScaleY = prePixelScale[1];
-
- if( useHiDPI ) {
- result[0] = newPixelScaleSafeX;
- result[1] = newPixelScaleSafeY;
- } else {
- result[0] = ScalableSurface.IDENTITY_PIXELSCALE;
- result[1] = ScalableSurface.IDENTITY_PIXELSCALE;
- }
-
- final boolean changed = result[0] != prePixelScaleX || result[1] != prePixelScaleY;
- if( null != DEBUG_PREFIX ) {
- System.err.println(DEBUG_PREFIX+".computePixelScale: useHiDPI "+useHiDPI+", ["+prePixelScaleX+"x"+prePixelScaleY+" (pre), "+
- reqPixelScale[0]+"x"+reqPixelScale[1]+" (req)] -> "+
- newPixelScaleRaw[0]+"x"+newPixelScaleRaw[1]+" (raw) -> "+
- newPixelScaleSafeX+"x"+newPixelScaleSafeY+" (safe) -> "+
- result[0]+"x"+result[1]+" (use), changed "+changed);
- }
- return changed;
+ public static int scale(final int a, final float pixelScale) {
+ return (int) ( a * pixelScale + 0.5f );
}
/**
- * Validate the given requested pixelScale value pair, i.e. clip it to the
- * limits of {@link ScalableSurface#AUTOMAX_PIXELSCALE} and {@link #getPlatformMaxPixelScale(int[])}
- * <p>
- * To be used by {@link ScalableSurface#setSurfaceScale(int[])} implementations.
- * </p>
+ * Returns integer rounded product, i.e. {@code (int) ( a / pixelScale + 0.5f )}
*
- * @param result int[2] storage for result
- * @param reqPixelScale requested pixelScale
- * @param DEBUG_PREFIX if set, dumps debug info on stderr using this prefix
+ * @param a the int value
+ * @param pixelScale the float scale factor
+ * @return the integer rounded product
*/
- public static void validateReqPixelScale(final int[] result, final int[] reqPixelScale, final String DEBUG_PREFIX) {
- final int minPS = Math.min(reqPixelScale[0], reqPixelScale[1]);
- if( ScalableSurface.AUTOMAX_PIXELSCALE >= minPS ) {
- result[0] = ScalableSurface.AUTOMAX_PIXELSCALE;
- result[1] = ScalableSurface.AUTOMAX_PIXELSCALE;
- } else if( PlatformUniformPixelScale ) {
- final int maxPS = Math.max(reqPixelScale[0], reqPixelScale[1]);
- if( maxPS >= PlatformMaxPixelScale[0] ) {
- result[0] = PlatformMaxPixelScale[0];
- result[1] = PlatformMaxPixelScale[1];
- } else {
- result[0] = maxPS;
- result[1] = maxPS;
- }
- } else {
- if( reqPixelScale[0] >= PlatformMaxPixelScale[0] ) {
- result[0] = PlatformMaxPixelScale[0];
- } else {
- result[0] = reqPixelScale[0];
- }
- if( reqPixelScale[1] >= PlatformMaxPixelScale[1] ) {
- result[1] = PlatformMaxPixelScale[1];
- } else {
- result[1] = reqPixelScale[1];
- }
- }
- if( null != DEBUG_PREFIX ) {
- System.err.println(DEBUG_PREFIX+".validateReqPixelScale: ["+reqPixelScale[0]+"x"+reqPixelScale[1]+" (req), "+
- PlatformMaxPixelScale[0]+"x"+PlatformMaxPixelScale[1]+" (max)] -> "+
- result[0]+"x"+result[1]+" (valid)");
- }
+ public static int scaleInv(final int a, final float pixelScale) {
+ return (int) ( a / pixelScale + 0.5f );
}
/**
- * Replaces {@link ScalableSurface#AUTOMAX_PIXELSCALE} with {@link #getPlatformMaxPixelScale(int[])},
- * for each component.
+ * Returns integer rounded product, i.e. {@code (int) ( a * pixelScale + 0.5f )}
*
- * @param pixelScale int[2] value array to be tested and replaced
+ * @param result the int[2] result, may be {@code a} for in-place operation
+ * @param a the int[2] values
+ * @param pixelScale the float[2] scale factors
+ * @return the result for chaining
*/
- public static void replaceAutoMaxWithPlatformMax(final int[] pixelScale) {
- if( ScalableSurface.AUTOMAX_PIXELSCALE == pixelScale[0] ) {
- pixelScale[0] = PlatformMaxPixelScale[0];
- }
- if( ScalableSurface.AUTOMAX_PIXELSCALE == pixelScale[1] ) {
- pixelScale[1] = PlatformMaxPixelScale[1];
- }
+ public static int[] scale(final int[] result, final int[] a, final float[] pixelScale) {
+ result[0] = (int) ( a[0] * pixelScale[0] + 0.5f );
+ result[1] = (int) ( a[1] * pixelScale[1] + 0.5f );
+ return result;
}
-
/**
- * Returns the maximum platform pixelScale
+ * Returns integer rounded product, i.e. {@code (int) ( a / pixelScale + 0.5f )}
+ *
+ * @param result the int[2] result, may be {@code a} for in-place operation
+ * @param a the int[2] values
+ * @param pixelScale the float[2] scale factors
+ * @return the result for chaining
*/
- public static int[] getPlatformMaxPixelScale(final int[] result) {
- System.arraycopy(PlatformMaxPixelScale, 0, result, 0, 2);
+ public static int[] scaleInv(final int[] result, final int[] a, final float[] pixelScale) {
+ result[0] = (int) ( a[0] / pixelScale[0] + 0.5f );
+ result[1] = (int) ( a[1] / pixelScale[1] + 0.5f );
return result;
}
/**
- * Returns true if platform pixelScale is uniform, i.e. same scale factor for x- and y-direction, otherwise false.
+ * Method constrains the given pixel-scale within ]0..{@code maxPixelScale}], as described below.
+ * <p>
+ * Method returns {@link ScalableSurface#IDENTITY_PIXELSCALE IDENTITY_PIXELSCALE} if:
+ * <ul>
+ * <li>{@code pixelScale} ~= {@link ScalableSurface#IDENTITY_PIXELSCALE IDENTITY_PIXELSCALE}</li>
+ * </ul>
+ * </p>
+ * <p>
+ * Method returns {@code maxPixelScale} if
+ * <ul>
+ * <li>{@code pixelScale} ~= {@link ScalableSurface#AUTOMAX_PIXELSCALE AUTOMAX_PIXELSCALE}</li>
+ * <li>{@code pixelScale} &gt; {@code maxPixelScale}</li>
+ * <li>{@code pixelScale} ~= {@code maxPixelScale}</li>
+ * </ul>
+ * </p>
+ * <p>
+ * Method returns {@code minPixelScale} if
+ * <ul>
+ * <li>{@code pixelScale} &lt; {@code minPixelScale}</li>
+ * <li>{@code pixelScale} ~= {@code minPixelScale}</li>
+ * </ul>
+ * </p>
+ * <p>
+ * Otherwise method returns the given {@code pixelScale}.
+ * </p>
+ * <p>
+ * <i>~=</i> denominates a delta &le; {@link FloatUtil#EPSILON}.
+ * </p>
+ * @param pixelScale pixel-scale to be constrained
+ * @param minPixelScale minimum pixel-scale
+ * @param maxPixelScale maximum pixel-scale
+ * @return the constrained pixel-scale
*/
- public static boolean isPlatformPixelScaleUniform() {
- return PlatformUniformPixelScale;
+ public static float clampPixelScale(final float pixelScale, final float minPixelScale, final float maxPixelScale) {
+ if( isZero(pixelScale-ScalableSurface.IDENTITY_PIXELSCALE) ) {
+ return ScalableSurface.IDENTITY_PIXELSCALE;
+ } else if( isZero(pixelScale-ScalableSurface.AUTOMAX_PIXELSCALE) ||
+ pixelScale > maxPixelScale ||
+ isZero(pixelScale-maxPixelScale)
+ )
+ {
+ return maxPixelScale;
+ } else if( pixelScale < minPixelScale || isZero(pixelScale-minPixelScale) )
+ {
+ return minPixelScale;
+ } else {
+ return pixelScale;
+ }
}
/**
- * Returns whether the platform supports pixelScale
+ * Method {@link #clampPixelScale(float, float, float) constrains} the given float[2] pixel-scale
+ * within ]0..{@code maxPixelScale}], as described in {@link #clampPixelScale(float, float, float)}.
+ *
+ * @param result float[2] storage for result, maybe same as <code>s</code> for in-place
+ * @param pixelScale float[2] pixelScale to be constrained
+ * @param minPixelScale float[2] minimum pixel-scale
+ * @param maxPixelScale float[2] maximum pixel-scale
+ * @return the constrained result for chaining
*/
- public static boolean isPlatformPixelScaleSupported() {
- return PlatformPixelScaleSupported;
+ public static float[] clampPixelScale(final float[] result, final float[] pixelScale,
+ final float[] minPixelScale, final float[] maxPixelScale) {
+ result[0] = clampPixelScale(pixelScale[0], minPixelScale[0], maxPixelScale[0]);
+ result[1] = clampPixelScale(pixelScale[1], minPixelScale[1], maxPixelScale[1]);
+ return result;
}
+ /**
+ * Method writes the given float[2] requested pixel-scale {@code reqPixelScale}
+ * into {@code result} within its constraints ]0..{@code maxPixelScale}], as described in {@link #clampPixelScale(float, float, float)}.
+ * <p>
+ * Method only differs from {@link #clampPixelScale(float[], float[], float[], float[])}
+ * by returning the whether the value has changed, i.e. different from the given {@code prePixelScale}.
+ * </p>
+ *
+ * @param result int[2] storage for result, maybe same as <code>prePixelScale</code> for in-place
+ * @param prePixelScale float[2] previous pixel-scale
+ * @param reqPixelScale float[2] requested pixel-scale, validated via {@link #validateReqPixelScale(float[], float[], String)}.
+ * @param minPixelScale float[2] minimum pixel-scale
+ * @param maxPixelScale float[2] maximum pixel-scale
+ * @param DEBUG_PREFIX if set, dumps debug info on stderr using this prefix
+ * @param newPixelScaleRaw new raw surface pixel-scale
+ * @return {@code true} if pixel-scale has changed, otherwise {@code false}.
+ */
+ public static boolean setNewPixelScale(final float[] result,
+ final float[] prePixelScale, final float[] reqPixelScale,
+ final float[] minPixelScale, final float[] maxPixelScale,
+ final String DEBUG_PREFIX) {
+ final float resultX = clampPixelScale(reqPixelScale[0], minPixelScale[0], maxPixelScale[0]);
+ final float resultY = clampPixelScale(reqPixelScale[1], minPixelScale[1], maxPixelScale[1]);
+ final boolean changed = resultX != prePixelScale[0] || resultY != prePixelScale[1];
+ if( null != DEBUG_PREFIX ) {
+ System.err.println(DEBUG_PREFIX+".setNewPixelScale: pre["+prePixelScale[0]+", "+prePixelScale[1]+"], req["+
+ reqPixelScale[0]+", "+reqPixelScale[1]+"], min["+
+ minPixelScale[0]+", "+minPixelScale[1]+"], max["+
+ maxPixelScale[0]+", "+maxPixelScale[1]+"] -> result["+
+ resultX+", "+resultY+"], changed "+changed);
+ }
+ result[0] = resultX;
+ result[1] = resultY;
+ return changed;
+ }
}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/WrappedSurface.java b/src/nativewindow/classes/jogamp/nativewindow/WrappedSurface.java
index d3439b53f..cfcca7d05 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/WrappedSurface.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/WrappedSurface.java
@@ -42,7 +42,7 @@ import com.jogamp.nativewindow.UpstreamSurfaceHookMutableSize;
* @see ProxySurface
*/
public class WrappedSurface extends ProxySurfaceImpl implements ScalableSurface {
- private final int[] hasPixelScale = new int[] { ScalableSurface.IDENTITY_PIXELSCALE, ScalableSurface.IDENTITY_PIXELSCALE };
+ private final float[] hasPixelScale = new float[] { ScalableSurface.IDENTITY_PIXELSCALE, ScalableSurface.IDENTITY_PIXELSCALE };
private long surfaceHandle;
/**
@@ -104,27 +104,23 @@ public class WrappedSurface extends ProxySurfaceImpl implements ScalableSurface
/**
* {@inheritDoc}
* <p>
- * {@link WrappedSurface}'s implementation uses the {@link #setSurfaceScale(int[]) given pixelScale} directly.
+ * {@link WrappedSurface}'s implementation uses the {@link #setSurfaceScale(float[]) given pixelScale} directly.
* </p>
*/
@Override
public final int[] convertToWindowUnits(final int[] pixelUnitsAndResult) {
- pixelUnitsAndResult[0] /= hasPixelScale[0];
- pixelUnitsAndResult[1] /= hasPixelScale[1];
- return pixelUnitsAndResult;
+ return SurfaceScaleUtils.scaleInv(pixelUnitsAndResult, pixelUnitsAndResult, hasPixelScale);
}
/**
* {@inheritDoc}
* <p>
- * {@link WrappedSurface}'s implementation uses the {@link #setSurfaceScale(int[]) given pixelScale} directly.
+ * {@link WrappedSurface}'s implementation uses the {@link #setSurfaceScale(float[]) given pixelScale} directly.
* </p>
*/
@Override
public final int[] convertToPixelUnits(final int[] windowUnitsAndResult) {
- windowUnitsAndResult[0] *= hasPixelScale[0];
- windowUnitsAndResult[1] *= hasPixelScale[1];
- return windowUnitsAndResult;
+ return SurfaceScaleUtils.scale(windowUnitsAndResult, windowUnitsAndResult, hasPixelScale);
}
/**
@@ -147,25 +143,32 @@ public class WrappedSurface extends ProxySurfaceImpl implements ScalableSurface
* </p>
*/
@Override
- public final void setSurfaceScale(final int[] pixelScale) {
- hasPixelScale[0] = pixelScale[0];
- hasPixelScale[1] = pixelScale[1];
+ public final boolean setSurfaceScale(final float[] pixelScale) {
+ final boolean changed = hasPixelScale[0] != pixelScale[0] || hasPixelScale[1] != pixelScale[1];
+ System.arraycopy(pixelScale, 0, hasPixelScale, 0, 2);
+ return changed;
}
@Override
- public final int[] getRequestedSurfaceScale(final int[] result) {
+ public final float[] getRequestedSurfaceScale(final float[] result) {
System.arraycopy(hasPixelScale, 0, result, 0, 2);
return result;
}
@Override
- public final int[] getCurrentSurfaceScale(final int[] result) {
+ public final float[] getCurrentSurfaceScale(final float[] result) {
System.arraycopy(hasPixelScale, 0, result, 0, 2);
return result;
}
@Override
- public final int[] getNativeSurfaceScale(final int[] result) {
+ public float[] getMinimumSurfaceScale(final float[] result) {
+ System.arraycopy(hasPixelScale, 0, result, 0, 2);
+ return result;
+ }
+
+ @Override
+ public final float[] getMaximumSurfaceScale(final float[] result) {
System.arraycopy(hasPixelScale, 0, result, 0, 2);
return result;
}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java
index 231a89c26..4fd2b0dca 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java
@@ -56,6 +56,7 @@ import javax.media.nativewindow.ToolkitLock;
import jogamp.common.os.PlatformPropsImpl;
import jogamp.nativewindow.Debug;
import jogamp.nativewindow.NWJNILibLoader;
+import jogamp.nativewindow.macosx.OSXUtil;
import com.jogamp.common.os.Platform;
import com.jogamp.common.util.PropertyAccess;
@@ -93,6 +94,7 @@ public class JAWTUtil {
private static final ToolkitLock jawtToolkitLock;
private static final Method getScaleFactorMethod;
+ private static final Method getCGDisplayIDMethodOnOSX;
private static class PrivilegedDataBlob1 {
PrivilegedDataBlob1() {
@@ -101,6 +103,7 @@ public class JAWTUtil {
Method sunToolkitAWTLockMethod;
Method sunToolkitAWTUnlockMethod;
Method getScaleFactorMethod;
+ Method getCGDisplayIDMethodOnOSX;
boolean ok;
}
@@ -321,6 +324,7 @@ public class JAWTUtil {
hasSunToolkitAWTLock = false;
// hasSunToolkitAWTLock = false;
getScaleFactorMethod = null;
+ getCGDisplayIDMethodOnOSX = null;
} else {
// Non-headless case
JAWTJNILibLoader.initSingleton(); // load libjawt.so
@@ -357,8 +361,13 @@ public class JAWTUtil {
}
try {
final GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
- d.getScaleFactorMethod = gd.getClass().getDeclaredMethod("getScaleFactor");
+ final Class<?> gdClass = gd.getClass();
+ d.getScaleFactorMethod = gdClass.getDeclaredMethod("getScaleFactor");
d.getScaleFactorMethod.setAccessible(true);
+ if( Platform.OSType.MACOS == PlatformPropsImpl.OS_TYPE ) {
+ d.getCGDisplayIDMethodOnOSX = gdClass.getDeclaredMethod("getCGDisplayID");
+ d.getCGDisplayIDMethodOnOSX.setAccessible(true);
+ }
} catch (final Throwable t) {}
return d;
}
@@ -366,6 +375,7 @@ public class JAWTUtil {
sunToolkitAWTLockMethod = pdb1.sunToolkitAWTLockMethod;
sunToolkitAWTUnlockMethod = pdb1.sunToolkitAWTUnlockMethod;
getScaleFactorMethod = pdb1.getScaleFactorMethod;
+ getCGDisplayIDMethodOnOSX = pdb1.getCGDisplayIDMethodOnOSX;
boolean _hasSunToolkitAWTLock = false;
if ( pdb1.ok ) {
@@ -545,20 +555,46 @@ public class JAWTUtil {
* Note: Currently only supported on OSX since 1.7.0_40 for HiDPI retina displays
* </p>
* @param device the {@link GraphicsDevice} instance used to query the pixel scale
- * @return the pixel scale factor
+ * @param minScale current and output min scale values
+ * @param maxScale current and output max scale values
+ * @return {@code true} if the given min and max scale values have changed, otherwise {@code false}.
*/
- public static final int getPixelScale(final GraphicsDevice device) {
+ public static final boolean getPixelScale(final GraphicsDevice device, final float[] minScale, final float[] maxScale) {
+ // Shall we allow ]0..1[ minimum scale?
+ boolean changed = minScale[0] != 1f || minScale[1] != 1f;
+ minScale[0] = 1f;
+ minScale[1] = 1f;
+ float sx = 1f;
+ float sy = 1f;
if( !SKIP_AWT_HIDPI ) {
+ if( null != getCGDisplayIDMethodOnOSX ) {
+ // OSX specific, preserving double type
+ try {
+ final Object res = getCGDisplayIDMethodOnOSX.invoke(device);
+ if (res instanceof Integer) {
+ final int displayID = ((Integer)res).intValue();
+ sx = (float) OSXUtil.GetPixelScaleByDisplayID(displayID);
+ sy = sx;
+ }
+ } catch (final Throwable t) {}
+ }
if( null != getScaleFactorMethod ) {
+ // Generic (?)
try {
final Object res = getScaleFactorMethod.invoke(device);
if (res instanceof Integer) {
- return ((Integer)res).intValue();
+ sx = ((Integer)res).floatValue();
+ } else if ( res instanceof Double) {
+ sx = ((Double)res).floatValue();
}
+ sy = sx;
} catch (final Throwable t) {}
}
}
- return 1;
+ changed = maxScale[0] != sx || maxScale[1] != sy;
+ maxScale[0] = sx;
+ maxScale[1] = sy;
+ return changed;
}
/**
@@ -574,20 +610,23 @@ public class JAWTUtil {
* Note: Currently only supported on OSX since 1.7.0_40 for HiDPI retina displays
* </p>
* @param gc the {@link GraphicsConfiguration} instance used to query the pixel scale
- * @return the pixel scale factor
+ * @param minScale current and output min scale values
+ * @param maxScale current and output max scale values
+ * @return {@code true} if the given min and max scale values have changed, otherwise {@code false}.
*/
- public static final int getPixelScale(final GraphicsConfiguration gc) {
+ public static final boolean getPixelScale(final GraphicsConfiguration gc, final float[] minScale, final float[] maxScale) {
final GraphicsDevice device = null != gc ? gc.getDevice() : null;
- final int ps;
+ boolean changed;
if( null == device ) {
- ps = 0;
+ changed = minScale[0] != 1f || minScale[1] != 1f || maxScale[0] != 1f || maxScale[1] != 1f;
+ minScale[0] = 1f;
+ minScale[1] = 1f;
+ maxScale[0] = 1f;
+ maxScale[1] = 1f;
} else {
- ps = JAWTUtil.getPixelScale(device);
- }
- if( DEBUG ) {
- System.err.println("JAWTUtil.updatePixelScale: Fetched "+ps);
+ changed = JAWTUtil.getPixelScale(device, minScale, maxScale);
}
- return ps;
+ return changed;
}
}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java
index fae8db52a..1c6c41262 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java
@@ -48,7 +48,6 @@ import java.security.PrivilegedAction;
import javax.media.nativewindow.AbstractGraphicsConfiguration;
import javax.media.nativewindow.Capabilities;
import javax.media.nativewindow.NativeSurface;
-import javax.media.nativewindow.NativeWindow;
import javax.media.nativewindow.NativeWindowException;
import javax.media.nativewindow.MutableSurface;
import javax.media.nativewindow.util.Point;
@@ -116,13 +115,10 @@ public class MacOSXJAWTWindow extends JAWTWindow implements MutableSurface {
}
@Override
- public void setSurfaceScale(final int[] pixelScale) {
+ public boolean setSurfaceScale(final float[] pixelScale) {
super.setSurfaceScale(pixelScale);
- if( 0 != getWindowHandle() ) { // locked at least once !
- final int hadPixelScaleX = getPixelScaleX();
- updatePixelScale();
-
- if( hadPixelScaleX != getPixelScaleX() && 0 != getAttachedSurfaceLayer() ) {
+ if( 0 != getWindowHandle() && setReqPixelScale() ) { // locked at least once _and_ updated pixel-scale
+ if( 0 != getAttachedSurfaceLayer() ) {
OSXUtil.RunOnMainThread(false, false, new Runnable() {
@Override
public void run() {
@@ -133,6 +129,9 @@ public class MacOSXJAWTWindow extends JAWTWindow implements MutableSurface {
}
});
}
+ return true;
+ } else {
+ return false;
}
}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java b/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java
index 9af74d9f5..7cd0439b7 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java
@@ -31,8 +31,6 @@ import javax.media.nativewindow.NativeWindowException;
import javax.media.nativewindow.NativeWindowFactory;
import javax.media.nativewindow.util.Insets;
import javax.media.nativewindow.util.Point;
-import javax.media.nativewindow.util.Rectangle;
-import javax.media.nativewindow.util.RectangleImmutable;
import com.jogamp.common.util.Function;
import com.jogamp.common.util.FunctionTask;
@@ -109,64 +107,14 @@ public class OSXUtil implements ToolkitProperties {
return (Insets) GetInsets0(windowOrView);
}
- /**
- * Returns the pixel-scale of the NSScreen, with the highest
- * {@link RectangleImmutable#coverage(RectangleImmutable) coverage} of the given rectangle in window units.
- * <p>
- * If no coverage is detected the pixel-scale of the first NSScreen is returned.
- * </p>
- * @param r arbitrary rectangle in window units
- * @param screenIndexOut storage returning the native screen index containing the given rectangle
- */
- public static double GetPixelScale(final RectangleImmutable r, final int[] screenIndexOut) {
- if( DEBUG ) {
- System.err.printf("GetPixelScale covering %s%n", r.toString());
- }
- final int screenCount;
- final RectangleImmutable[] screenBounds;
- final double[] pixelScales;
- {
- final double[] sd = GetScreenData0();
- if( 0 != sd.length % 5 ) {
- throw new InternalError("GetScreenData0 didn't return multiple of 5 but "+sd.length);
- }
- screenCount = sd.length / 5;
- screenBounds = new RectangleImmutable[screenCount];
- pixelScales = new double[screenCount] ;
- for(int i=0; i<screenCount; i++) {
- final int j = i*5;
- pixelScales[i] = sd[j+0];
- screenBounds[i] = new Rectangle((int)sd[j+1], (int)sd[j+2], (int)sd[j+3], (int)sd[j+4]);
- if( DEBUG ) {
- System.err.printf("GetPixelScale.Screen[%d]: scale %f, bounds[%f / %f %f x %f]%n",
- i, pixelScales[i], sd[j+1], sd[j+2], sd[j+3], sd[j+4]);
- }
- }
- }
- double pixelScale = pixelScales[0];
- screenIndexOut[0] = 0;
- float maxCoverage = Float.MIN_VALUE;
- for(int i=screenCount-1; i>=0; i--) {
- final RectangleImmutable sb = screenBounds[i];
- final float coverage = sb.coverage(r);
- if( coverage > maxCoverage ) {
- maxCoverage = coverage;
- screenIndexOut[0] = i;
- pixelScale = pixelScales[i];
- }
- }
- if( DEBUG ) {
- System.err.printf("GetPixelScale Result: screen %d, scale %f%n%n", screenIndexOut[0], pixelScale);
- }
- return pixelScale;
- }
-
- public static double GetPixelScale(final int screenIndex) {
+ public static double GetPixelScaleByScreenIdx(final int screenIndex) {
return GetPixelScale0(screenIndex);
}
-
+ public static double GetPixelScaleByDisplayID(final int displayID) {
+ return GetPixelScale1(displayID);
+ }
public static double GetPixelScale(final long windowOrView) {
- return GetPixelScale1(windowOrView);
+ return GetPixelScale2(windowOrView);
}
public static long CreateNSWindow(final int x, final int y, final int width, final int height) {
@@ -447,9 +395,9 @@ public class OSXUtil implements ToolkitProperties {
private static native boolean isNSWindow0(long object);
private static native Object GetLocationOnScreen0(long windowOrView, int src_x, int src_y);
private static native Object GetInsets0(long windowOrView);
- private static native double[] GetScreenData0();
private static native double GetPixelScale0(int screenIndex);
- private static native double GetPixelScale1(long windowOrView);
+ private static native double GetPixelScale1(int displayID);
+ private static native double GetPixelScale2(long windowOrView);
private static native long CreateNSWindow0(int x, int y, int width, int height);
private static native void DestroyNSWindow0(long nsWindow);
private static native long GetNSView0(long nsWindow);
diff --git a/src/nativewindow/native/macosx/OSXmisc.m b/src/nativewindow/native/macosx/OSXmisc.m
index 997bafba0..c86025ea8 100644
--- a/src/nativewindow/native/macosx/OSXmisc.m
+++ b/src/nativewindow/native/macosx/OSXmisc.m
@@ -138,12 +138,24 @@ Java_jogamp_nativewindow_macosx_OSXUtil_isNSWindow0(JNIEnv *env, jclass _unused,
}
static CGDirectDisplayID OSXUtil_getCGDirectDisplayIDByNSScreen(NSScreen *screen) {
- // Mind: typedef uint32_t CGDirectDisplayID; - however, we assume it's 64bit on 64bit ?!
+ // Mind: typedef uint32_t CGDirectDisplayID;
NSDictionary * dict = [screen deviceDescription];
NSNumber * val = (NSNumber *) [dict objectForKey: @"NSScreenNumber"];
// [NSNumber integerValue] returns NSInteger which is 32 or 64 bit native size
return (CGDirectDisplayID) [val integerValue];
}
+static NSScreen * OSXUtil_getNSScreenByCGDirectDisplayID(CGDirectDisplayID displayID) {
+ NSArray *screens = [NSScreen screens];
+ int i;
+ for(i=[screens count]-1; i>=0; i--) {
+ NSScreen * screen = (NSScreen *) [screens objectAtIndex: i];
+ CGDirectDisplayID dID = OSXUtil_getCGDirectDisplayIDByNSScreen(screen);
+ if( dID == displayID ) {
+ return screen;
+ }
+ }
+ return (NSScreen *) [screens objectAtIndex: 0];
+}
/*
* Class: Java_jogamp_nativewindow_macosx_OSXUtil
@@ -249,87 +261,54 @@ JNIEXPORT jobject JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_GetInsets0
return res;
}
-static CGDirectDisplayID 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"];
- // [NSNumber integerValue] returns NSInteger which is 32 or 64 bit native size
- return (CGDirectDisplayID) [val integerValue];
-}
-
/*
* Class: Java_jogamp_nativewindow_macosx_OSXUtil
- * Method: GetScreenData0
- * Signature: ()[F
+ * Method: GetPixelScale0
+ * Signature: (I)D
*/
-JNIEXPORT jdoubleArray JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_GetScreenData0
- (JNIEnv *env, jclass unused)
+JNIEXPORT jdouble JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_GetPixelScale0
+ (JNIEnv *env, jclass unused, jint screen_idx)
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
CGFloat pixelScale;
- CGDirectDisplayID display;
- NSRect dBounds;
NSScreen *screen;
NSArray *screens = [NSScreen screens];
- int sCount = [screens count];
- jdouble res[sCount*5];
- int i,j;
-
- for(i=0; i<sCount; i++) {
- j = i*5;
- screen = (NSScreen *) [screens objectAtIndex: i];
+ if( screen_idx<0 || screen_idx>=[screens count] ) {
+ screen = NULL;
+ pixelScale = 1.0;
+ } else {
+ screen = (NSScreen *) [screens objectAtIndex: screen_idx];
pixelScale = 1.0; // default
NS_DURING
// Available >= 10.7
pixelScale = [screen backingScaleFactor]; // HiDPI scaling
NS_HANDLER
NS_ENDHANDLER
- display = GetCGDirectDisplayIDByNSScreen(screen);
- dBounds = CGDisplayBounds (display); // origin top-left
- res[j+0] = (jdouble)pixelScale;
- res[j+1] = (jdouble)dBounds.origin.x;
- res[j+2] = (jdouble)dBounds.origin.y;
- res[j+3] = (jdouble)dBounds.size.width;
- res[j+4] = (jdouble)dBounds.size.height;
}
-
- jdoubleArray jniRes = (*env)->NewDoubleArray(env, sCount*5); // x,y,w,h,scale
- if (jniRes == NULL) {
- NativewindowCommon_throwNewRuntimeException(env, "Could not allocate double array of size %d", sCount*5);
- }
- (*env)->SetDoubleArrayRegion(env, jniRes, 0, sCount*5, res);
-
[pool release];
- return jniRes;
+ return (jdouble)pixelScale;
}
/*
* Class: Java_jogamp_nativewindow_macosx_OSXUtil
- * Method: GetPixelScale0
+ * Method: GetPixelScale1
* Signature: (I)D
*/
-JNIEXPORT jdouble JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_GetPixelScale0
- (JNIEnv *env, jclass unused, jint screen_idx)
+JNIEXPORT jdouble JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_GetPixelScale1
+ (JNIEnv *env, jclass unused, jint displayID)
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
CGFloat pixelScale;
- NSScreen *screen;
- NSArray *screens = [NSScreen screens];
- if( screen_idx<0 || screen_idx>=[screens count] ) {
- screen = NULL;
- pixelScale = 0.0;
- } else {
- screen = (NSScreen *) [screens objectAtIndex: screen_idx];
- pixelScale = 1.0; // default
+ NSScreen *screen = OSXUtil_getNSScreenByCGDirectDisplayID((CGDirectDisplayID)displayID);
+ pixelScale = 1.0; // default
NS_DURING
- // Available >= 10.7
- pixelScale = [screen backingScaleFactor]; // HiDPI scaling
+ // Available >= 10.7
+ pixelScale = [screen backingScaleFactor]; // HiDPI scaling
NS_HANDLER
NS_ENDHANDLER
- }
[pool release];
return (jdouble)pixelScale;
@@ -340,7 +319,7 @@ NS_ENDHANDLER
* Method: GetPixelScale1
* Signature: (J)D
*/
-JNIEXPORT jdouble JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_GetPixelScale1
+JNIEXPORT jdouble JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_GetPixelScale2
(JNIEnv *env, jclass unused, jlong winOrView)
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];