Beispiel #1
0
static Bool
QuartzRandRSetCGMode(CGDirectDisplayID screenId,
                     QuartzModeInfoPtr pMode)
{
    CGDisplayModeRef modeRef = (CGDisplayModeRef)pMode->ref;
    if (!modeRef)
        return FALSE;

    return (CGDisplaySetDisplayMode(screenId, modeRef,
                                    NULL) == kCGErrorSuccess);
}
bool DisplayManagerOSX::setDisplayMode(int display, int mode)
{
  if (!isValidDisplayMode(display, mode) || !m_osxDisplayModes[display])
    return false;
  
  CGDisplayModeRef displayMode =
  (CGDisplayModeRef)CFArrayGetValueAtIndex(m_osxDisplayModes[display], mode);

  CGError err = CGDisplaySetDisplayMode(m_osxDisplays[display], displayMode, nullptr);
  if (err)
  {
    QLOG_ERROR() << "CGDisplaySetDisplayMode() returned failure:" << err;
    return false;
  }

  // HACK : on OSX, switching display mode can leave dock in a state where mouse cursor
  // will not hide on top of hidden dock, so we reset it state to fix this
  OSXUtils::SetMenuBarVisible(true);
  OSXUtils::SetMenuBarVisible(false);

  return true;
}
Beispiel #3
0
//-------------------------------------------------------------------------------------------------//
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);
}
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;
		}
	}
}