diff options
Diffstat (limited to 'src/nativewindow')
-rw-r--r-- | src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java | 55 | ||||
-rw-r--r-- | src/nativewindow/native/macosx/OSXmisc.m | 56 |
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 |