提交 a91c078e 编写于 作者: K kizune

7124247: [macosx] Implement GraphicsDevice.setDisplayMode()

Reviewed-by: anthony, swingler
上级 952a919f
/*
* 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.GraphicsConfiguration;
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 @@ public class CGraphicsDevice extends GraphicsDevice {
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);
}
/*
* 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
......@@ -25,6 +25,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
......@@ -62,3 +140,85 @@ Java_sun_awt_CGraphicsDevice_nativeGetYResolution
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;
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册