aboutsummaryrefslogtreecommitdiffstats
path: root/src/nativewindow
diff options
context:
space:
mode:
Diffstat (limited to 'src/nativewindow')
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java55
-rw-r--r--src/nativewindow/native/macosx/OSXmisc.m56
2 files changed, 111 insertions, 0 deletions
diff --git a/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java b/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java
index cf163bd82..9af74d9f5 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java
@@ -31,6 +31,8 @@ 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;
@@ -107,6 +109,58 @@ 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) {
return GetPixelScale0(screenIndex);
}
@@ -393,6 +447,7 @@ 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 long CreateNSWindow0(int x, int y, int width, int height);
diff --git a/src/nativewindow/native/macosx/OSXmisc.m b/src/nativewindow/native/macosx/OSXmisc.m
index 127b329d1..997bafba0 100644
--- a/src/nativewindow/native/macosx/OSXmisc.m
+++ b/src/nativewindow/native/macosx/OSXmisc.m
@@ -249,6 +249,62 @@ 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
+ */
+JNIEXPORT jdoubleArray JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_GetScreenData0
+ (JNIEnv *env, jclass unused)
+{
+ 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];
+ 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;
+}
+
/*
* Class: Java_jogamp_nativewindow_macosx_OSXUtil
* Method: GetPixelScale0