bool DisplayResOSX::SwitchToVideoMode(int width, int height, double refreshrate) { CGDirectDisplayID d = GetOSXDisplay(MythDisplay::GetWindowID()); CFDictionaryRef dispMode = NULL; boolean_t match = 0; // find mode that matches the desired size if (refreshrate) dispMode = CGDisplayBestModeForParametersAndRefreshRate( d, 32, width, height, (CGRefreshRate)((short)refreshrate), &match); if (!match) dispMode = CGDisplayBestModeForParameters(d, 32, width, height, &match); if (!match) dispMode = CGDisplayBestModeForParameters(d, 16, width, height, &match); if (!match) return false; // switch mode and return success CGDisplayCapture(d); CGDisplayConfigRef cfg; CGBeginDisplayConfiguration(&cfg); CGConfigureDisplayFadeEffect(cfg, 0.3f, 0.5f, 0, 0, 0); CGConfigureDisplayMode(cfg, d, dispMode); CGError err = CGCompleteDisplayConfiguration(cfg, kCGConfigureForAppOnly); CGDisplayRelease(d); return (err == kCGErrorSuccess); }
CFDictionaryRef convertSFModeToCGMode(VideoMode sfmode) { // If sfmode is in VideoMode::GetFullscreenModes // then this should be an exact match (see NULL parameter doc). return CGDisplayBestModeForParameters(CGMainDisplayID(), sfmode.BitsPerPixel, sfmode.width, sfmode.height, NULL); }
static GXDISPLAYMODEHANDLE RLXAPI SearchDisplayMode(int lx, int ly, int bpp) { gl_lx = lx; gl_ly = ly; gl_bpp = bpp == -1 ? (*(*GetMainDevice())->gdPMap)->pixelSize : bpp; if ((g_pRLX->Video.Config & RLXVIDEO_Windowed)==0) { boolean_t ret; g_cgDisplayMode = CGDisplayBestModeForParameters(g_cgDisplayID, bpp, lx, ly, &ret); return ModeHandleToDictRef(g_cgDisplayMode); } return 1; }
static void modewhacker( CGDirectDisplayID dspy ) { int i; CFDictionaryRef mode; CFDictionaryRef originalMode; boolean_t exactMatch; CGDisplayErr err; originalMode = CGDisplayCurrentMode( dspy ); if ( originalMode == NULL ) { printf( "Display is invalid\n" ); return; } for ( i = 0; i < (sizeof myModeList / sizeof myModeList[0]); ++i ) { printf( "Display 0x%x: Looking for %ld x %ld, %ld Bits Per Pixel\n", (unsigned int)dspy, myModeList[i].width, myModeList[i].height, myModeList[i].bitsPerPixel ); mode = CGDisplayBestModeForParameters(dspy, myModeList[i].bitsPerPixel, myModeList[i].width, myModeList[i].height, &exactMatch); if ( exactMatch ) printf( "Found an exact match, switching modes:\n" ); else printf( "Found a mode, switching modes:\n" ); printDesc( mode ); sleep( 1 ); // Short pause, then switch err = CGDisplaySwitchToMode(dspy, mode); if ( err != CGDisplayNoErr ) { printf( "Oops! Mode switch failed?!?? (%d)\n", err ); break; } printf( "Pausing for 5 seconds...\n" ); sleep( 5 ); } err = CGDisplaySwitchToMode(dspy, originalMode); if ( err != CGDisplayNoErr ) printf( "Oops! Mode restore failed?!?? (%d)\n", err ); }
//-------------------------------------------------------------------------------------------------// void OSXWindow::createCGLFullscreen(unsigned int width, unsigned int height, unsigned int depth, unsigned int fsaa, CGLContextObj sharedContext) { // Find the best match to what was requested boolean_t exactMatch = 0; int reqWidth, reqHeight, reqDepth; #if defined(MAC_OS_X_VERSION_10_6) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 // Get a copy of the current display mode CGDisplayModeRef displayMode = CGDisplayCopyDisplayMode(kCGDirectMainDisplay); // Loop through all display modes to determine the closest match. // CGDisplayBestModeForParameters is deprecated on 10.6 so we will emulate it's behavior // Try to find a mode with the requested depth and equal or greater dimensions first. // If no match is found, try to find a mode with greater depth and same or greater dimensions. // If still no match is found, just use the current mode. CFArrayRef allModes = CGDisplayCopyAllDisplayModes(kCGDirectMainDisplay, NULL); for(int i = 0; i < CFArrayGetCount(allModes); i++) { CGDisplayModeRef mode = (CGDisplayModeRef)CFArrayGetValueAtIndex(allModes, i); String modeString = StringConverter::toString(CGDisplayModeGetWidth(mode)) + String(" x ") + StringConverter::toString(CGDisplayModeGetHeight(mode)) + String(" @ ") + StringConverter::toString(bitDepthFromDisplayMode(mode)) + "bpp."; LogManager::getSingleton().logMessage(modeString); if(bitDepthFromDisplayMode(mode) != depth) continue; if((CGDisplayModeGetWidth(mode) >= width) && (CGDisplayModeGetHeight(mode) >= height)) { displayMode = mode; exactMatch = 1; break; } } // No depth match was found if(!exactMatch) { for(int i = 0; i < CFArrayGetCount(allModes); i++) { CGDisplayModeRef mode = (CGDisplayModeRef)CFArrayGetValueAtIndex(allModes, i); if(bitDepthFromDisplayMode(mode) >= depth) continue; if((CGDisplayModeGetWidth(mode) >= width) && (CGDisplayModeGetHeight(mode) >= height)) { displayMode = mode; exactMatch = 1; break; } } } reqWidth = CGDisplayModeGetWidth(displayMode); reqHeight = CGDisplayModeGetHeight(displayMode); reqDepth = bitDepthFromDisplayMode(displayMode); #else CFDictionaryRef displayMode = CGDisplayBestModeForParameters(kCGDirectMainDisplay, depth, width, height, &exactMatch); const void *value = NULL; value = CFDictionaryGetValue(displayMode, kCGDisplayWidth); CFNumberGetValue((CFNumberRef)value, kCFNumberSInt32Type, &reqWidth); value = CFDictionaryGetValue(displayMode, kCGDisplayHeight); CFNumberGetValue((CFNumberRef)value, kCFNumberSInt32Type, &reqHeight); value = CFDictionaryGetValue(displayMode, kCGDisplayBitsPerPixel); CFNumberGetValue((CFNumberRef)value, kCFNumberSInt32Type, &reqDepth); #endif if(!exactMatch) { // TODO: Report the size difference // That mode is not available, using the closest match String request = StringConverter::toString(width) + String(" x ") + StringConverter::toString(height) + String(" @ ") + StringConverter::toString(depth) + "bpp. "; String received = StringConverter::toString(reqWidth) + String(" x ") + StringConverter::toString(reqHeight) + String(" @ ") + StringConverter::toString(reqDepth) + "bpp. "; LogManager::getSingleton().logMessage(String("RenderSystem Warning: You requested a fullscreen mode of ") + request + String(" This mode is not available and you will receive the closest match. The best display mode for the parameters requested is: ") + received); } // Do the fancy display fading CGDisplayFadeReservationToken reservationToken; CGAcquireDisplayFadeReservation(kCGMaxDisplayReservationInterval, &reservationToken); CGDisplayFade(reservationToken, 0.5, kCGDisplayBlendNormal, kCGDisplayBlendSolidColor, 0.0, 0.0, 0.0, true); // Grab the main display and save it for later. // You could render to any display, but picking what display // to render to could be interesting. CGDisplayCapture(kCGDirectMainDisplay); // Switch to the correct resolution #if defined(MAC_OS_X_VERSION_10_6) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 CGDisplaySetDisplayMode(kCGDirectMainDisplay, displayMode, NULL); #else CGDisplaySwitchToMode(kCGDirectMainDisplay, displayMode); #endif // Get a pixel format that best matches what we are looking for CGLPixelFormatAttribute attribs[] = { kCGLPFADoubleBuffer, kCGLPFAAlphaSize, (CGLPixelFormatAttribute)8, kCGLPFADepthSize, (CGLPixelFormatAttribute)reqDepth, kCGLPFAStencilSize, (CGLPixelFormatAttribute)8, kCGLPFASampleBuffers, (CGLPixelFormatAttribute)0, kCGLPFASamples, (CGLPixelFormatAttribute)0, kCGLPFAFullScreen, kCGLPFASingleRenderer, kCGLPFAAccelerated, kCGLPFADisplayMask, (CGLPixelFormatAttribute)CGDisplayIDToOpenGLDisplayMask(kCGDirectMainDisplay), (CGLPixelFormatAttribute)0 }; // Set up FSAA if it was requested if(fsaa > 1) { // turn on kCGLPFASampleBuffers attribs[8] = (CGLPixelFormatAttribute)1; // set the samples for kCGLPFASamples attribs[10] = (CGLPixelFormatAttribute)fsaa; } CGLError err; CGLPixelFormatObj pixelFormatObj; #if (MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_4) GLint numPixelFormats = 0; err = CGLChoosePixelFormat(attribs, &pixelFormatObj, &numPixelFormats); #else long numPixelFormats = 0; err = CGLChoosePixelFormat(attribs, &pixelFormatObj, &numPixelFormats); #endif if(err != 0) { CGReleaseAllDisplays(); OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, String("CGL Error: " + String(CGLErrorString(err))), "OSXWindow::createCGLFullscreen"); } // Create the CGLcontext from our pixel format, share it with the sharedContext passed in err = CGLCreateContext(pixelFormatObj, sharedContext, &mCGLContext); if(err != 0) { CGReleaseAllDisplays(); OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, String("CGL Error: " + String(CGLErrorString(err))), "OSXWindow::createCGLFullscreen"); } // Once we have the context we can destroy the pixel format // In order to share contexts you must keep a pointer to the context object around // Our context class will now manage the life of the pixelFormatObj //CGLDestroyPixelFormat(pixelFormatObj); // Set the context to full screen #if defined(MAC_OS_X_VERSION_10_6) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 CGLSetFullScreenOnDisplay(mCGLContext, CGDisplayIDToOpenGLDisplayMask(kCGDirectMainDisplay)); #else CGLSetFullScreen(mCGLContext); #endif // Set the context as current CGLSetCurrentContext(mCGLContext); // This synchronizes CGL with the vertical retrace // Apple docs suggest that OpenGL blocks rendering calls when waiting for // a vertical retrace anyhow. #if (MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_4) GLint swapInterval = 1; CGLSetParameter(mCGLContext, kCGLCPSwapInterval, &swapInterval); #else long swapInterval = 1; CGLSetParameter(mCGLContext, kCGLCPSwapInterval, &swapInterval); #endif // Give a copy of our context to the rendersystem mContext = new OSXCGLContext(mCGLContext, pixelFormatObj); // Let everyone know we are fullscreen now mIsFullScreen = true; // Set some other variables. Just in case we got a different value from CGDisplayBestModeForParameters than we requested mWidth = reqWidth; mHeight = reqHeight; mColourDepth = reqDepth; CGDisplayFade(reservationToken, 2.0, kCGDisplayBlendSolidColor, kCGDisplayBlendNormal, 0.0, 0.0, 0.0, false); CGReleaseDisplayFadeReservation(reservationToken); }
void changeResolution(int x, int y) { CGDirectDisplayID main = CGMainDisplayID(); CFDictionaryRef mode = CGDisplayBestModeForParameters(main, CGDisplayBitsPerPixel(main), x, y, NULL); CGDisplaySwitchToMode(main, mode); }
bool macosxSetScreenResolution(QSize resolution, QPoint screenPoint) { CGDirectDisplayID display = displayAtPoint(screenPoint); if (display == kCGNullDirectDisplay) { return false; } #if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1060 if (CGDisplayCopyAllDisplayModes != NULL) { bool ok = false; CGDisplayModeRef currentMainDisplayMode = CGDisplayCopyDisplayMode(display); CFStringRef currentPixelEncoding = CGDisplayModeCopyPixelEncoding(currentMainDisplayMode); CFArrayRef displayModes = CGDisplayCopyAllDisplayModes(display, NULL); for (CFIndex i = 0, c = CFArrayGetCount(displayModes); i < c; i++) { bool isEqual = false; CGDisplayModeRef mode = (CGDisplayModeRef)CFArrayGetValueAtIndex(displayModes, i); CFStringRef pixelEncoding = CGDisplayModeCopyPixelEncoding(mode); if (CFStringCompare(pixelEncoding, currentPixelEncoding, 0) == kCFCompareEqualTo && CGDisplayModeGetWidth(mode) == (size_t)resolution.width() && CGDisplayModeGetHeight(mode) == (size_t)resolution.height()) { isEqual = true; } CFRelease(pixelEncoding); if (isEqual) { CGDisplaySetDisplayMode(display, mode, NULL); ok = true; break; } } CFRelease(currentPixelEncoding); CFRelease(displayModes); return ok; } else #endif { CFDictionaryRef currentMainDisplayMode = CGDisplayCurrentMode(display); int bpp; dictget(currentMainDisplayMode, Int, kCGDisplayBitsPerPixel, &bpp); boolean_t exactMatch = false; CFDictionaryRef bestMode = CGDisplayBestModeForParameters(display, bpp, resolution.width(), resolution.height(), &exactMatch); if (bestMode != NULL) { if (!exactMatch) { qWarning("No optimal display mode for requested parameters."); } CGDisplaySwitchToMode(display, bestMode); return true; } else { qWarning("Bad resolution change: Invalid display."); return false; } } }
static AGLContext createContext(WindowRef window) { AGLPixelFormat pf; AGLContext ctx; GDHandle gdh; CFDictionaryRef refMode; GLenum error; CGDirectDisplayID mainDisplay = CGMainDisplayID(); GLint attrs[] = { AGL_RGBA, AGL_DOUBLEBUFFER, AGL_RED_SIZE, 4, AGL_GREEN_SIZE, 4, AGL_BLUE_SIZE, 4, AGL_DEPTH_SIZE, 16, AGL_NONE }; GLint fullscreen_attrs[] = { AGL_FULLSCREEN, AGL_RGBA, AGL_DOUBLEBUFFER, AGL_RED_SIZE, 4, AGL_GREEN_SIZE, 4, AGL_BLUE_SIZE, 4, AGL_DEPTH_SIZE, 16, AGL_NONE }; g_Window.double_buffered = true; if (!g_Window.fs) { pf = aglChoosePixelFormat(NULL, 0, attrs); } else { CGDisplayCapture(mainDisplay); refMode = CGDisplayBestModeForParameters(mainDisplay, 32, g_Window.width, g_Window.height, NULL); CGDisplaySwitchToMode(mainDisplay, refMode); DMGetGDeviceByDisplayID(mainDisplay, &gdh, false); pf = aglChoosePixelFormat(&gdh, 1, fullscreen_attrs); error = aglGetError(); if (error != AGL_NO_ERROR) { printf("%s\n", aglErrorString(error)); return 0; } } if (!pf) { printf("Error choosing pixel format\n"); return 0; } ctx = aglCreateContext(pf, 0); if (!ctx) { printf("%s\n", aglErrorString(aglGetError())); return 0; } aglDestroyPixelFormat(pf); aglSetCurrentContext(ctx); if (g_Window.fs) { aglSetFullScreen(ctx, g_Window.width, g_Window.height, 0, 0); } else { aglSetWindowRef(ctx, window); } return ctx; }