--- a/jdk/src/macosx/classes/sun/awt/CGraphicsDevice.java Thu Jun 07 10:22:10 2012 +0800
+++ b/jdk/src/macosx/classes/sun/awt/CGraphicsDevice.java Thu Jun 07 20:04:56 2012 +0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -29,6 +29,7 @@
import java.awt.GraphicsDevice;
import java.awt.Window;
import java.awt.AWTPermission;
+import java.awt.DisplayMode;
import sun.java2d.opengl.CGLGraphicsConfig;
@@ -178,4 +179,33 @@
peer.exitFullScreenMode();
}
}
+
+ @Override
+ public boolean isDisplayChangeSupported() {
+ return true;
+ }
+
+ @Override
+ public void setDisplayMode(DisplayMode dm) {
+ nativeSetDisplayMode(displayID, dm.getWidth(), dm.getHeight(), dm.getBitDepth(), dm.getRefreshRate());
+ if (isFullScreenSupported() && getFullScreenWindow() != null) {
+ getFullScreenWindow().setSize(dm.getWidth(), dm.getHeight());
+ }
+ }
+
+ @Override
+ public DisplayMode getDisplayMode() {
+ return nativeGetDisplayMode(displayID);
+ }
+
+ @Override
+ public DisplayMode[] getDisplayModes() {
+ return nativeGetDisplayModes(displayID);
+ }
+
+ private native void nativeSetDisplayMode(int displayID, int w, int h, int bpp, int refrate);
+
+ private native DisplayMode nativeGetDisplayMode(int displayID);
+
+ private native DisplayMode[] nativeGetDisplayModes(int displayID);
}
--- a/jdk/src/macosx/native/sun/awt/CGraphicsDevice.m Thu Jun 07 10:22:10 2012 +0800
+++ b/jdk/src/macosx/native/sun/awt/CGraphicsDevice.m Thu Jun 07 20:04:56 2012 +0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,84 @@
#include "LWCToolkit.h"
/*
+ * Convert the mode string to the more convinient bits per pixel value
+ */
+static int getBPPFromModeString(CFStringRef mode)
+{
+ if ((CFStringCompare(mode, CFSTR(kIO30BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo)) {
+ // This is a strange mode, where we using 10 bits per RGB component and pack it into 32 bits
+ // Java is not ready to work with this mode but we have to specify it as supported
+ return 30;
+ }
+ else if (CFStringCompare(mode, CFSTR(IO32BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
+ return 32;
+ }
+ else if (CFStringCompare(mode, CFSTR(IO16BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
+ return 16;
+ }
+ else if (CFStringCompare(mode, CFSTR(IO8BitIndexedPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
+ return 8;
+ }
+
+ return 0;
+}
+
+/*
+ * Find the best possible match in the list of display modes that we can switch to based on
+ * the provided parameters.
+ */
+static CGDisplayModeRef getBestModeForParameters(CFArrayRef allModes, int w, int h, int bpp, int refrate) {
+ CGDisplayModeRef bestGuess = NULL;
+ CFIndex numModes = CFArrayGetCount(allModes), n;
+ int thisBpp = 0;
+ for(n = 0; n < numModes; n++ ) {
+ CGDisplayModeRef cRef = (CGDisplayModeRef) CFArrayGetValueAtIndex(allModes, n);
+ if(cRef == NULL) {
+ continue;
+ }
+ CFStringRef modeString = CGDisplayModeCopyPixelEncoding(cRef);
+ thisBpp = getBPPFromModeString(modeString);
+ CFRelease(modeString);
+ if (thisBpp != bpp || (int)CGDisplayModeGetHeight(cRef) != h || (int)CGDisplayModeGetWidth(cRef) != w) {
+ // One of the key parameters does not match
+ continue;
+ }
+ // Refresh rate might be 0 in display mode and we ask for specific display rate
+ // but if we do not find exact match then 0 refresh rate might be just Ok
+ if (CGDisplayModeGetRefreshRate(cRef) == refrate) {
+ // Exact match
+ return cRef;
+ }
+ if (CGDisplayModeGetRefreshRate(cRef) == 0) {
+ // Not exactly what was asked for, but may fit our needs if we don't find an exact match
+ bestGuess = cRef;
+ }
+ }
+ return bestGuess;
+}
+
+/*
+ * Create a new java.awt.DisplayMode instance based on provided CGDisplayModeRef
+ */
+static jobject createJavaDisplayMode(CGDisplayModeRef mode, JNIEnv *env, jint displayID) {
+ jobject ret = NULL;
+ jint h, w, bpp, refrate;
+ JNF_COCOA_ENTER(env);
+ CFStringRef currentBPP = CGDisplayModeCopyPixelEncoding(mode);
+ bpp = getBPPFromModeString(currentBPP);
+ refrate = CGDisplayModeGetRefreshRate(mode);
+ h = CGDisplayPixelsHigh(displayID);
+ w = CGDisplayPixelsWide(displayID);
+ CFRelease(currentBPP);
+ static JNF_CLASS_CACHE(jc_DisplayMode, "java/awt/DisplayMode");
+ static JNF_CTOR_CACHE(jc_DisplayMode_ctor, jc_DisplayMode, "(IIII)V");
+ ret = JNFNewObject(env, jc_DisplayMode_ctor, w, h, bpp, refrate);
+ JNF_COCOA_EXIT(env);
+ return ret;
+}
+
+
+/*
* Class: sun_awt_CGraphicsDevice
* Method: nativeGetXResolution
* Signature: (I)D
@@ -62,3 +140,85 @@
jfloat dpi = rect.size.height / inches;
return dpi;
}
+
+/*
+ * Class: sun_awt_CGraphicsDevice
+ * Method: nativeSetDisplayMode
+ * Signature: (IIIII)V
+ */
+JNIEXPORT void JNICALL
+Java_sun_awt_CGraphicsDevice_nativeSetDisplayMode
+(JNIEnv *env, jclass class, jint displayID, jint w, jint h, jint bpp, jint refrate)
+{
+ JNF_COCOA_ENTER(env);
+ CFArrayRef allModes = CGDisplayCopyAllDisplayModes(displayID, NULL);
+ CGDisplayModeRef closestMatch = getBestModeForParameters(allModes, (int)w, (int)h, (int)bpp, (int)refrate);
+ if (closestMatch != NULL) {
+ CGDisplayConfigRef config;
+ CGError retCode = CGBeginDisplayConfiguration(&config);
+ if (retCode == kCGErrorSuccess) {
+ CGConfigureDisplayWithDisplayMode(config, displayID, closestMatch, NULL);
+ CGCompleteDisplayConfiguration(config, kCGConfigureForAppOnly);
+ CFRelease(config);
+ }
+ }
+ CFRelease(allModes);
+ JNF_COCOA_EXIT(env);
+}
+
+/*
+ * Class: sun_awt_CGraphicsDevice
+ * Method: nativeGetDisplayMode
+ * Signature: (I)Ljava/awt/DisplayMode
+ */
+JNIEXPORT jobject JNICALL
+Java_sun_awt_CGraphicsDevice_nativeGetDisplayMode
+(JNIEnv *env, jclass class, jint displayID)
+{
+ jobject ret = NULL;
+ CGDisplayModeRef currentMode = CGDisplayCopyDisplayMode(displayID);
+ ret = createJavaDisplayMode(currentMode, env, displayID);
+ CGDisplayModeRelease(currentMode);
+ return ret;
+}
+
+/*
+ * Class: sun_awt_CGraphicsDevice
+ * Method: nativeGetDisplayMode
+ * Signature: (I)[Ljava/awt/DisplayModes
+ */
+JNIEXPORT jobjectArray JNICALL
+Java_sun_awt_CGraphicsDevice_nativeGetDisplayModes
+(JNIEnv *env, jclass class, jint displayID)
+{
+ jobjectArray jreturnArray = NULL;
+ JNF_COCOA_ENTER(env);
+ CFArrayRef allModes = CGDisplayCopyAllDisplayModes(displayID, NULL);
+ CFIndex numModes = CFArrayGetCount(allModes);
+ static JNF_CLASS_CACHE(jc_DisplayMode, "java/awt/DisplayMode");
+
+ jreturnArray = JNFNewObjectArray(env, &jc_DisplayMode, (jsize) numModes);
+ if (!jreturnArray) {
+ NSLog(@"CGraphicsDevice can't create java array of DisplayMode objects");
+ return nil;
+ }
+
+ CFIndex n;
+ for (n=0; n < numModes; n++) {
+ CGDisplayModeRef cRef = (CGDisplayModeRef) CFArrayGetValueAtIndex(allModes, n);
+ if (cRef != NULL) {
+ jobject oneMode = createJavaDisplayMode(cRef, env, displayID);
+ (*env)->SetObjectArrayElement(env, jreturnArray, n, oneMode);
+ if ((*env)->ExceptionOccurred(env)) {
+ (*env)->ExceptionDescribe(env);
+ (*env)->ExceptionClear(env);
+ continue;
+ }
+ (*env)->DeleteLocalRef(env, oneMode);
+ }
+ }
+ CFRelease(allModes);
+ JNF_COCOA_EXIT(env);
+
+ return jreturnArray;
+}