51 /* 52 * Find the best possible match in the list of display modes that we can switch to based on 53 * the provided parameters. 54 */ 55 static CGDisplayModeRef getBestModeForParameters(CFArrayRef allModes, int w, int h, int bpp, int refrate) { 56 CGDisplayModeRef bestGuess = NULL; 57 CFIndex numModes = CFArrayGetCount(allModes), n; 58 int thisBpp = 0; 59 for(n = 0; n < numModes; n++ ) { 60 CGDisplayModeRef cRef = (CGDisplayModeRef) CFArrayGetValueAtIndex(allModes, n); 61 if(cRef == NULL) { 62 continue; 63 } 64 CFStringRef modeString = CGDisplayModeCopyPixelEncoding(cRef); 65 thisBpp = getBPPFromModeString(modeString); 66 CFRelease(modeString); 67 if (thisBpp != bpp || (int)CGDisplayModeGetHeight(cRef) != h || (int)CGDisplayModeGetWidth(cRef) != w) { 68 // One of the key parameters does not match 69 continue; 70 } 71 // Refresh rate might be 0 in display mode and we ask for specific display rate 72 // but if we do not find exact match then 0 refresh rate might be just Ok 73 if (CGDisplayModeGetRefreshRate(cRef) == refrate) { 74 // Exact match 75 return cRef; 76 } 77 if (CGDisplayModeGetRefreshRate(cRef) == 0) { 78 // Not exactly what was asked for, but may fit our needs if we don't find an exact match 79 bestGuess = cRef; 80 } 81 } 82 return bestGuess; 83 } 84 85 /* 86 * Create a new java.awt.DisplayMode instance based on provided CGDisplayModeRef 87 */ 88 static jobject createJavaDisplayMode(CGDisplayModeRef mode, JNIEnv *env, jint displayID) { 89 jobject ret = NULL; 90 jint h, w, bpp, refrate; 148 */ 149 JNIEXPORT void JNICALL 150 Java_sun_awt_CGraphicsDevice_nativeSetDisplayMode 151 (JNIEnv *env, jclass class, jint displayID, jint w, jint h, jint bpp, jint refrate) 152 { 153 JNF_COCOA_ENTER(env); 154 CFArrayRef allModes = CGDisplayCopyAllDisplayModes(displayID, NULL); 155 CGDisplayModeRef closestMatch = getBestModeForParameters(allModes, (int)w, (int)h, (int)bpp, (int)refrate); 156 if (closestMatch != NULL) { 157 [JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){ 158 CGDisplayConfigRef config; 159 CGError retCode = CGBeginDisplayConfiguration(&config); 160 if (retCode == kCGErrorSuccess) { 161 CGConfigureDisplayWithDisplayMode(config, displayID, closestMatch, NULL); 162 CGCompleteDisplayConfiguration(config, kCGConfigureForAppOnly); 163 if (config != NULL) { 164 CFRelease(config); 165 } 166 } 167 }]; 168 } 169 CFRelease(allModes); 170 JNF_COCOA_EXIT(env); 171 } 172 173 /* 174 * Class: sun_awt_CGraphicsDevice 175 * Method: nativeGetDisplayMode 176 * Signature: (I)Ljava/awt/DisplayMode 177 */ 178 JNIEXPORT jobject JNICALL 179 Java_sun_awt_CGraphicsDevice_nativeGetDisplayMode 180 (JNIEnv *env, jclass class, jint displayID) 181 { 182 jobject ret = NULL; 183 CGDisplayModeRef currentMode = CGDisplayCopyDisplayMode(displayID); 184 ret = createJavaDisplayMode(currentMode, env, displayID); 185 CGDisplayModeRelease(currentMode); 186 return ret; 187 } 188 | 51 /* 52 * Find the best possible match in the list of display modes that we can switch to based on 53 * the provided parameters. 54 */ 55 static CGDisplayModeRef getBestModeForParameters(CFArrayRef allModes, int w, int h, int bpp, int refrate) { 56 CGDisplayModeRef bestGuess = NULL; 57 CFIndex numModes = CFArrayGetCount(allModes), n; 58 int thisBpp = 0; 59 for(n = 0; n < numModes; n++ ) { 60 CGDisplayModeRef cRef = (CGDisplayModeRef) CFArrayGetValueAtIndex(allModes, n); 61 if(cRef == NULL) { 62 continue; 63 } 64 CFStringRef modeString = CGDisplayModeCopyPixelEncoding(cRef); 65 thisBpp = getBPPFromModeString(modeString); 66 CFRelease(modeString); 67 if (thisBpp != bpp || (int)CGDisplayModeGetHeight(cRef) != h || (int)CGDisplayModeGetWidth(cRef) != w) { 68 // One of the key parameters does not match 69 continue; 70 } 71 72 if (refrate == 0) { // REFRESH_RATE_UNKNOWN 73 return cRef; 74 } 75 76 // Refresh rate might be 0 in display mode and we ask for specific display rate 77 // but if we do not find exact match then 0 refresh rate might be just Ok 78 if (CGDisplayModeGetRefreshRate(cRef) == refrate) { 79 // Exact match 80 return cRef; 81 } 82 if (CGDisplayModeGetRefreshRate(cRef) == 0) { 83 // Not exactly what was asked for, but may fit our needs if we don't find an exact match 84 bestGuess = cRef; 85 } 86 } 87 return bestGuess; 88 } 89 90 /* 91 * Create a new java.awt.DisplayMode instance based on provided CGDisplayModeRef 92 */ 93 static jobject createJavaDisplayMode(CGDisplayModeRef mode, JNIEnv *env, jint displayID) { 94 jobject ret = NULL; 95 jint h, w, bpp, refrate; 153 */ 154 JNIEXPORT void JNICALL 155 Java_sun_awt_CGraphicsDevice_nativeSetDisplayMode 156 (JNIEnv *env, jclass class, jint displayID, jint w, jint h, jint bpp, jint refrate) 157 { 158 JNF_COCOA_ENTER(env); 159 CFArrayRef allModes = CGDisplayCopyAllDisplayModes(displayID, NULL); 160 CGDisplayModeRef closestMatch = getBestModeForParameters(allModes, (int)w, (int)h, (int)bpp, (int)refrate); 161 if (closestMatch != NULL) { 162 [JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){ 163 CGDisplayConfigRef config; 164 CGError retCode = CGBeginDisplayConfiguration(&config); 165 if (retCode == kCGErrorSuccess) { 166 CGConfigureDisplayWithDisplayMode(config, displayID, closestMatch, NULL); 167 CGCompleteDisplayConfiguration(config, kCGConfigureForAppOnly); 168 if (config != NULL) { 169 CFRelease(config); 170 } 171 } 172 }]; 173 } else { 174 [JNFException raise:env as:kIllegalArgumentException reason:"Invalid display mode"]; 175 } 176 177 CFRelease(allModes); 178 JNF_COCOA_EXIT(env); 179 } 180 181 /* 182 * Class: sun_awt_CGraphicsDevice 183 * Method: nativeGetDisplayMode 184 * Signature: (I)Ljava/awt/DisplayMode 185 */ 186 JNIEXPORT jobject JNICALL 187 Java_sun_awt_CGraphicsDevice_nativeGetDisplayMode 188 (JNIEnv *env, jclass class, jint displayID) 189 { 190 jobject ret = NULL; 191 CGDisplayModeRef currentMode = CGDisplayCopyDisplayMode(displayID); 192 ret = createJavaDisplayMode(currentMode, env, displayID); 193 CGDisplayModeRelease(currentMode); 194 return ret; 195 } 196 |