mirror of
https://github.com/openjdk/jdk.git
synced 2026-03-06 14:10:36 +00:00
7124247: [macosx] Implement GraphicsDevice.setDisplayMode()
Reviewed-by: anthony, swingler
This commit is contained in:
parent
980d62fd25
commit
4eb87c577e
@ -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.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);
|
||||
}
|
||||
|
||||
@ -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
|
||||
@ -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;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user