예제 #1
0
void TorcQMLDisplayOSX::RefreshScreenModes(void)
{
    if (!m_window)
        return;

    // release existing modes
    if (m_displayModes)
        CFRelease(m_displayModes);
    m_displayModes = NULL;
    m_modes.clear();

    // retrieve new list of modes
    CGDirectDisplayID display = GetOSXDisplay(m_window->winId());
    if (!display)
        return;

    CGDisplayModeRef current = CGDisplayCopyDisplayMode(display);
    m_displayModes = CGDisplayCopyAllDisplayModes(display, NULL);

    if (m_displayModes)
    {
        for (int i = 0; i < CFArrayGetCount(m_displayModes); ++i)
        {
            CGDisplayModeRef mode = (CGDisplayModeRef)CFArrayGetValueAtIndex(m_displayModes, i);
            int modewidth         = CGDisplayModeGetWidth(mode);
            int modeheight        = CGDisplayModeGetHeight(mode);
            double moderate       = CGDisplayModeGetRefreshRate(mode);
            // internal OSX displays have 'flexible' refresh rates, with a max of 60Hz - but report 0hz
            if (moderate < 0.1f)
                moderate = 60.0f;
            int32_t flags         = CGDisplayModeGetIOFlags(mode);
            bool interlaced       = flags & kDisplayModeInterlacedFlag;
            CFStringRef fmt       = CGDisplayModeCopyPixelEncoding(mode);
            int depth             = DepthFromStringRef(fmt);
            CFRelease(fmt);

            bool ignore = modewidth  != screenPixelSize.width() ||
                          modeheight != screenPixelSize.height() ||
                          (flags & kDisplayModeNotGraphicsQualityFlag) ||
                         !(flags & kDisplayModeSafetyFlags) ||
                          depth < 32 || moderate < 10.0f || moderate > 121.0f;

            LOG(VB_GENERAL, LOG_INFO, QString("Mode %1x%2@%3Hz %4bpp%5%6%7")
                .arg(modewidth).arg(modeheight).arg(moderate).arg(depth)
                .arg(interlaced ? QString(" Interlaced") : "")
                .arg(ignore ? QString(" Ignoring") : "")
                .arg(mode == current ? QString(" CURRENT"): ""));

            if (!ignore)
            {
                if (mode == current)
                {
                    setScreenInterlaced(interlaced);
                    setScreenRefreshRate(moderate);
                }
                m_modes.append(TorcDisplayMode(modewidth, modeheight, depth, moderate, interlaced, i));
            }
        }
    }
}
예제 #2
0
// Search for available resolutions - TODO: Move to Common?
static wxArrayString GetListOfResolutions()
{
	wxArrayString retlist;
	retlist.Add(_("Auto"));
#ifdef _WIN32
	DWORD iModeNum = 0;
	DEVMODE dmi;
	ZeroMemory(&dmi, sizeof(dmi));
	dmi.dmSize = sizeof(dmi);
	std::vector<std::string> resos;

	while (EnumDisplaySettings(nullptr, iModeNum++, &dmi) != 0)
	{
		char res[100];
		sprintf(res, "%dx%d", dmi.dmPelsWidth, dmi.dmPelsHeight);
		std::string strRes(res);
		// Only add unique resolutions
		if (std::find(resos.begin(), resos.end(), strRes) == resos.end())
		{
			resos.push_back(strRes);
			retlist.Add(StrToWxStr(res));
		}
		ZeroMemory(&dmi, sizeof(dmi));
	}
#elif defined(HAVE_XRANDR) && HAVE_XRANDR
	std::vector<std::string> resos;
	main_frame->m_XRRConfig->AddResolutions(resos);
	for (auto res : resos)
		retlist.Add(StrToWxStr(res));
#elif defined(__APPLE__)
	CFArrayRef modes = CGDisplayCopyAllDisplayModes(CGMainDisplayID(), nullptr);
	for (CFIndex i = 0; i < CFArrayGetCount(modes); i++)
	{
		std::stringstream res;
		CGDisplayModeRef mode;
		CFStringRef encoding;
		size_t w, h;
		bool is32;

		mode = (CGDisplayModeRef)CFArrayGetValueAtIndex(modes, i);
		w = CGDisplayModeGetWidth(mode);
		h = CGDisplayModeGetHeight(mode);
		encoding = CGDisplayModeCopyPixelEncoding(mode);
		is32 = CFEqual(encoding, CFSTR(IO32BitDirectPixels));
		CFRelease(encoding);

		if (!is32)
			continue;
		if (CGDisplayModeGetIOFlags(mode) & kDisplayModeStretchedFlag)
			continue;

		res << w << "x" << h;

		retlist.Add(res.str());
	}
	CFRelease(modes);
#endif
	return retlist;
}
예제 #3
0
unsigned int configureDisplay(CGDirectDisplayID display, struct config *config, int displayNum) {
    unsigned int returncode = 1;
    CFArrayRef allModes = CGDisplayCopyAllDisplayModes(display, NULL);
    if (allModes == NULL) {
        NSLog(CFSTR("Error: failed trying to look up modes for display %u"), displayNum);
    }

    CGDisplayModeRef newMode = NULL;
    CGDisplayModeRef possibleMode;
    size_t pw; // possible width.
    size_t ph; // possible height.
    size_t pd; // possible depth.
    double pr; // possible refresh rate
    int looking = 1; // used to decide whether to continue looking for modes.
    int i;
    for (i = 0 ; i < CFArrayGetCount(allModes) && looking; i++) {
        possibleMode = (CGDisplayModeRef)CFArrayGetValueAtIndex(allModes, i);
        pw = CGDisplayModeGetWidth(possibleMode);
        ph = CGDisplayModeGetHeight(possibleMode);
        pd = bitDepth(possibleMode);
        pr = CGDisplayModeGetRefreshRate(possibleMode);
        if (pw == config->w &&
            ph == config->h &&
            pd == config->d &&
            pr == config->r) {
            looking = 0; // Stop looking for more modes!
            newMode = possibleMode;
        }
    }
    CFRelease(allModes);
    if (newMode != NULL) {
        NSLog(CFSTR("set mode on display %u to %ux%ux%u@%.0f"), displayNum, pw, ph, pd, pr);
        setDisplayToMode(display,newMode);
    } else {
        NSLog(CFSTR("Error: mode %ux%ux%u@%f not available on display %u"), 
                config->w, config->h, config->d, config->r, displayNum);
        returncode = 0;
    }
    return returncode;
}
예제 #4
0
CGDisplayModeRef convertSFModeToCGMode(VideoMode sfmode)
{
    // Starting with 10.6 we should query the display all the modes and
    // search for the best one.
    
    // Will return NULL if sfmode is not in VideoMode::GetFullscreenModes.
    CGDisplayModeRef cgbestMode = NULL;
    
    // Retrieve all modes available for main screen only.
    CFArrayRef cgmodes = CGDisplayCopyAllDisplayModes(CGMainDisplayID(), NULL);
    
    if (cgmodes == NULL) { // Should not happen but anyway...
        sf::err() << "Couldn't get VideoMode for main display.";
        return NULL;
    }
    
    // Loop on each mode and convert it into a sf::VideoMode object.
    CFIndex const modesCount = CFArrayGetCount(cgmodes);
    for (CFIndex i = 0; i < modesCount; i++) {
        CGDisplayModeRef cgmode = (CGDisplayModeRef)CFArrayGetValueAtIndex(cgmodes, i);
        
        VideoMode mode = convertCGModeToSFMode(cgmode);
        
        if (mode == sfmode) {
            cgbestMode = cgmode;
        }
    }
    
    // Clean up memory.
    CFRelease(cgmodes);
    
    if (cgbestMode == NULL) {
        sf::err()
        << "Couldn't convert the given sf:VideoMode into a CGDisplayMode."
        << std::endl;
    }
    
    return cgbestMode;
}
예제 #5
0
std::vector<VideoMode> VideoModeImpl::getFullscreenModes()
{
    std::vector<VideoMode> modes;

    // Retrieve all modes available for main screen only.
    CFArrayRef cgmodes = CGDisplayCopyAllDisplayModes(CGMainDisplayID(), NULL);

    if (cgmodes == NULL)
    {
        sf::err() << "Couldn't get VideoMode for main display." << std::endl;
        return modes;
    }

    VideoMode desktop = getDesktopMode();

    // Loop on each mode and convert it into a sf::VideoMode object.
    const CFIndex modesCount = CFArrayGetCount(cgmodes);
    for (CFIndex i = 0; i < modesCount; i++)
    {
        CGDisplayModeRef cgmode = (CGDisplayModeRef)CFArrayGetValueAtIndex(cgmodes, i);

        VideoMode mode = convertCGModeToSFMode(cgmode);

        // Skip if bigger than desktop as we currently don't perform hard resolution switch
        if ((mode.width > desktop.width) || (mode.height > desktop.height))
            continue;

        // If not yet listed we add it to our modes array.
        if (std::find(modes.begin(), modes.end(), mode) == modes.end())
            modes.push_back(mode);
    }

    // Clean up memory.
    CFRelease(cgmodes);

    return modes;
}
예제 #6
0
double UIDisplay::GetRefreshRatePriv(void)
{
    CocoaAutoReleasePool pool;

    double rate = 0.0f;
    CGDirectDisplayID disp = GetOSXDisplay(m_widget->winId());
    if (!disp)
    {
        LOG(VB_GENERAL, LOG_WARNING, "Failed to get OS X display");
        return rate;
    }

    CGDisplayModeRef current = CGDisplayCopyDisplayMode(disp);
    if (current)
    {
        rate = CGDisplayModeGetRefreshRate(current);
        if (qFuzzyCompare((double)1.0f, rate + 1.0f))
            m_variableRefreshRate = true;
    }
    else
    {
        LOG(VB_GENERAL, LOG_WARNING, "Failed to get current display mode");
        return rate;
    }

    if (m_variableRefreshRate)
    {
        CGDisplayModeRelease(current);
        return rate;
    }

    // if we've run this already, release the modes
    m_modes.clear();
    m_originalModeIndex = -1;
    if (gDisplayModes)
        CFRelease(gDisplayModes);

    gDisplayModes = CGDisplayCopyAllDisplayModes(disp, NULL);
    if (gDisplayModes)
    {
        for (int i = 0; i < CFArrayGetCount(gDisplayModes); ++i)
        {
            CGDisplayModeRef mode = (CGDisplayModeRef)CFArrayGetValueAtIndex(gDisplayModes, i);
            int modewidth         = CGDisplayModeGetWidth(mode);
            int modeheight        = CGDisplayModeGetHeight(mode);
            double moderate       = CGDisplayModeGetRefreshRate(mode);
            int32_t flags         = CGDisplayModeGetIOFlags(mode);
            bool interlaced       = flags & kDisplayModeInterlacedFlag;
            CFStringRef fmt       = CGDisplayModeCopyPixelEncoding(mode);
            int depth             = DepthFromStringRef(fmt);
            CFRelease(fmt);

            bool ignore = modewidth  != m_pixelSize.width() ||
                          modeheight != m_pixelSize.height() ||
                          (flags & kDisplayModeNotGraphicsQualityFlag) ||
                         !(flags & kDisplayModeSafetyFlags) ||
                          depth < 32 || moderate < 10.0f || moderate > 121.0f;

            LOG(VB_GUI, LOG_INFO, QString("Mode %1x%2@%3Hz %4bpp%5%6%7")
                .arg(modewidth).arg(modeheight).arg(moderate).arg(depth)
                .arg(interlaced ? QString(" Interlaced") : "")
                .arg(ignore ? QString(" Ignoring") : "")
                .arg(mode == current ? QString(" CURRENT"): ""));

            if (!ignore)
            {
                m_modes.append(UIDisplayMode(modewidth, modeheight, depth, moderate, interlaced, i));
                if (mode == current)
                    m_originalModeIndex = m_modes.size() - 1;
            }
        }
    }

    CGDisplayModeRelease(current);
    return rate;
}
예제 #7
0
unsigned int listAvailableModes(CGDirectDisplayID display, int displayNum) {
    unsigned int returncode = 1;
    int i;
    CFArrayRef allModes = CGDisplayCopyAllDisplayModes(display, NULL);
    if (allModes == NULL) {
        returncode = 0;
    }
#ifndef LIST_DEBUG
    printf("Available Modes on Display %d\n", displayNum);

#endif
    CGDisplayModeRef mode;
    for (i = 0; i < CFArrayGetCount(allModes) && returncode; i++) {
        mode = (CGDisplayModeRef) CFArrayGetValueAtIndex(allModes, i);
        // This formatting is functional but it ought to be done less poorly.
#ifndef LIST_DEBUG
        if (i % MODES_PER_LINE == 0) {
            printf("  ");
        } else {
            printf("\t");
        }
        char modestr [50];
        sprintf(modestr, "%lux%lux%lu@%.0f",
               CGDisplayModeGetWidth(mode),
               CGDisplayModeGetHeight(mode),
               bitDepth(mode),
               CGDisplayModeGetRefreshRate(mode));
        printf("%-20s ", modestr);
        if (i % MODES_PER_LINE == MODES_PER_LINE - 1) {
            printf("\n");
        }
#else
        uint32_t ioflags = CGDisplayModeGetIOFlags(mode);
        printf("display: %d %4lux%4lux%2lu@%.0f usable:%u ioflags:%4x valid:%u safe:%u default:%u",
                displayNum,
                CGDisplayModeGetWidth(mode),
                CGDisplayModeGetHeight(mode),
                bitDepth(mode),
                CGDisplayModeGetRefreshRate(mode),
                CGDisplayModeIsUsableForDesktopGUI(mode),
                ioflags,
                ioflags & kDisplayModeValidFlag ?1:0,
                ioflags & kDisplayModeSafeFlag ?1:0,
                ioflags & kDisplayModeDefaultFlag ?1:0 );
        printf(" safety:%u alwaysshow:%u nevershow:%u notresize:%u requirepan:%u int:%u simul:%u",
                ioflags & kDisplayModeSafetyFlags ?1:0,
                ioflags & kDisplayModeAlwaysShowFlag ?1:0,
                ioflags & kDisplayModeNeverShowFlag ?1:0,
                ioflags & kDisplayModeNotResizeFlag ?1:0,
                ioflags & kDisplayModeRequiresPanFlag ?1:0,
                ioflags & kDisplayModeInterlacedFlag ?1:0,
                ioflags & kDisplayModeSimulscanFlag ?1:0 );
        printf(" builtin:%u notpreset:%u stretched:%u notgfxqual:%u valagnstdisp:%u tv:%u vldmirror:%u\n",
                ioflags & kDisplayModeBuiltInFlag ?1:0,
                ioflags & kDisplayModeNotPresetFlag ?1:0,
                ioflags & kDisplayModeStretchedFlag ?1:0,
                ioflags & kDisplayModeNotGraphicsQualityFlag ?1:0,
                ioflags & kDisplayModeValidateAgainstDisplay ?1:0,
                ioflags & kDisplayModeTelevisionFlag ?1:0,
                ioflags & kDisplayModeValidForMirroringFlag ?1:0 );
#endif
    }
    CFRelease(allModes);
    return returncode;
}
bool DisplayManagerOSX::initialize()
{
  int totalModes = 0;

  m_displays.clear();

  for (int i = 0; i < m_osxDisplayModes.size(); i++)
  {
    if (m_osxDisplayModes[i])
      CFRelease(m_osxDisplayModes[i]);
  }
  m_osxDisplayModes.clear();

  CGError err = CGGetActiveDisplayList(MAX_DISPLAYS, m_osxDisplays, &m_osxnumDisplays);
  if (err)
  {
    m_osxnumDisplays = 0;
    QLOG_ERROR() << "CGGetActiveDisplayList returned failure:" << err;
    return false;
  }

  for (int displayid = 0; displayid < m_osxnumDisplays; displayid++)
  {
    // add the display to the list
    DMDisplayPtr display = DMDisplayPtr(new DMDisplay);
    display->m_id = displayid;
    display->m_name = QString("Display %1").arg(displayid);
    m_displays[display->m_id] = display;

    m_osxDisplayModes[displayid] = CGDisplayCopyAllDisplayModes(m_osxDisplays[displayid], nullptr);
    if (!m_osxDisplayModes[displayid])
      continue;

    int numModes = (int)CFArrayGetCount(m_osxDisplayModes[displayid]);

    for (int modeid = 0; modeid < numModes; modeid++)
    {
      totalModes++;
      
      // add the videomode to the display
      DMVideoModePtr mode = DMVideoModePtr(new DMVideoMode);
      mode->m_id = modeid;
      display->m_videoModes[modeid] = mode;

      // grab videomode info
      CGDisplayModeRef displayMode =
      (CGDisplayModeRef)CFArrayGetValueAtIndex(m_osxDisplayModes[displayid], modeid);

      mode->m_height = CGDisplayModeGetHeight(displayMode);
      mode->m_width = CGDisplayModeGetWidth(displayMode);
      mode->m_refreshRate = CGDisplayModeGetRefreshRate(displayMode);

      CFStringRef pixEnc = CGDisplayModeCopyPixelEncoding(displayMode);

      if (CFStringCompare(pixEnc, CFSTR(IO32BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo)
        mode->m_bitsPerPixel = 32;
      else if (CFStringCompare(pixEnc, CFSTR(IO16BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo)
        mode->m_bitsPerPixel = 16;
      else if (CFStringCompare(pixEnc, CFSTR(IO8BitIndexedPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo)
        mode->m_bitsPerPixel = 8;

      CFRelease(pixEnc);

      mode->m_interlaced = (CGDisplayModeGetIOFlags(displayMode) & kDisplayModeInterlacedFlag) > 0;

      if (mode->m_refreshRate == 0)
        mode->m_refreshRate = 60;
    }
  }

  if (totalModes == 0)
    return false;
  else
    return DisplayManager::initialize();
}
예제 #9
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);
}
예제 #10
0
/***********************************************************************
 *              copy_display_modes
 *
 * Wrapper around CGDisplayCopyAllDisplayModes() to include additional
 * modes on Retina-capable systems, but filter those which would confuse
 * Windows apps (basically duplicates at different DPIs).
 *
 * For example, some Retina Macs support a 1920x1200 mode, but it's not
 * returned from CGDisplayCopyAllDisplayModes() without special options.
 * This is especially bad if that's the user's default mode, since then
 * no "available" mode matches the initial settings.
 */
static CFArrayRef copy_display_modes(CGDirectDisplayID display)
{
    CFArrayRef modes = NULL;

#if defined(MAC_OS_X_VERSION_10_8) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_8
    if (&kCGDisplayShowDuplicateLowResolutionModes != NULL &&
            CGDisplayModeGetPixelWidth != NULL && CGDisplayModeGetPixelHeight != NULL)
    {
        CFDictionaryRef options;
        struct display_mode_descriptor* desc;
        CFMutableDictionaryRef modes_by_size;
        CFIndex i, count;
        CGDisplayModeRef* mode_array;

        options = CFDictionaryCreate(NULL, (const void**)&kCGDisplayShowDuplicateLowResolutionModes,
                                     (const void**)&kCFBooleanTrue, 1, &kCFTypeDictionaryKeyCallBacks,
                                     &kCFTypeDictionaryValueCallBacks);

        modes = CGDisplayCopyAllDisplayModes(display, options);
        if (options)
            CFRelease(options);
        if (!modes)
            return NULL;

        desc = create_original_display_mode_descriptor(display);

        modes_by_size = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
        count = CFArrayGetCount(modes);
        for (i = 0; i < count; i++)
        {
            BOOL better = TRUE;
            CGDisplayModeRef new_mode = (CGDisplayModeRef)CFArrayGetValueAtIndex(modes, i);
            BOOL new_is_original = display_mode_matches_descriptor(new_mode, desc);
            CFDictionaryRef key = create_mode_dict(new_mode);

            /* If a given mode is the user's default, then always list it in preference to any similar
               modes that may exist. */
            if (new_is_original)
                better = TRUE;
            else
            {
                CFStringRef pixel_encoding = CGDisplayModeCopyPixelEncoding(new_mode);
                CGDisplayModeRef old_mode;

                if (pixel_encoding)
                {
                    BOOL bpp30 = CFEqual(pixel_encoding, CFSTR(kIO30BitDirectPixels));
                    CFRelease(pixel_encoding);
                    if (bpp30)
                    {
                        /* This is an odd pixel encoding.  It seems it's only returned
                           when using kCGDisplayShowDuplicateLowResolutionModes.  It's
                           32bpp in terms of the actual raster layout, but it's 10
                           bits per component.  I think that no Windows program is
                           likely to need it and they will probably be confused by it.
                           Skip it. */
                        CFRelease(key);
                        continue;
                    }
                }

                old_mode = (CGDisplayModeRef)CFDictionaryGetValue(modes_by_size, key);
                if (old_mode)
                {
                    BOOL old_is_original = display_mode_matches_descriptor(old_mode, desc);

                    if (old_is_original)
                        better = FALSE;
                    else
                    {
                        /* Otherwise, prefer a mode whose pixel size equals its point size over one which
                           is scaled. */
                        size_t width_points = CGDisplayModeGetWidth(new_mode);
                        size_t height_points = CGDisplayModeGetHeight(new_mode);
                        size_t new_width_pixels = CGDisplayModeGetPixelWidth(new_mode);
                        size_t new_height_pixels = CGDisplayModeGetPixelHeight(new_mode);
                        size_t old_width_pixels = CGDisplayModeGetPixelWidth(old_mode);
                        size_t old_height_pixels = CGDisplayModeGetPixelHeight(old_mode);
                        BOOL new_size_same = (new_width_pixels == width_points && new_height_pixels == height_points);
                        BOOL old_size_same = (old_width_pixels == width_points && old_height_pixels == height_points);

                        if (new_size_same && !old_size_same)
                            better = TRUE;
                        else if (!new_size_same && old_size_same)
                            better = FALSE;
                        else
                        {
                            /* Otherwise, prefer the mode with the smaller pixel size. */
                            if (old_width_pixels < new_width_pixels || old_height_pixels < new_height_pixels)
                                better = FALSE;
                        }
                    }
                }
            }

            if (better)
                CFDictionarySetValue(modes_by_size, key, new_mode);

            CFRelease(key);
        }

        free_display_mode_descriptor(desc);
        CFRelease(modes);

        count = CFDictionaryGetCount(modes_by_size);
        mode_array = HeapAlloc(GetProcessHeap(), 0, count * sizeof(mode_array[0]));
        CFDictionaryGetKeysAndValues(modes_by_size, NULL, (const void **)mode_array);
        modes = CFArrayCreate(NULL, (const void **)mode_array, count, &kCFTypeArrayCallBacks);
        HeapFree(GetProcessHeap(), 0, mode_array);
        CFRelease(modes_by_size);
    }
    else
#endif
        modes = CGDisplayCopyAllDisplayModes(display, NULL);

    return modes;
}
bool macosxAppendAvailableScreenResolutions(QList<QSize> &resolutions, QSize minSize, QPoint screenPoint)
{
	CGDirectDisplayID display = displayAtPoint(screenPoint);
	if (display == kCGNullDirectDisplay)
	{
		return false;
	}

#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1060
	bool modern = (CGDisplayCopyAllDisplayModes != NULL); // where 'modern' means >= 10.6
#endif

	CFArrayRef displayModes;
#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1060
	if (modern)
	{
		displayModes = CGDisplayCopyAllDisplayModes(display, NULL);
	}
	else
#endif
	{
		displayModes = CGDisplayAvailableModes(display);
	}

#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1060
	CFStringRef currentPixelEncoding = NULL;
#endif
	double currentRefreshRate;
	int curBPP, curBPS, curSPP;

#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1060
	if (modern)
	{
		CGDisplayModeRef currentDisplayMode = CGDisplayCopyDisplayMode(display);
		currentRefreshRate = CGDisplayModeGetRefreshRate(currentDisplayMode);
		currentPixelEncoding = CGDisplayModeCopyPixelEncoding(currentDisplayMode);
		CFRelease(currentDisplayMode);
	}
	else
#endif
	{
		CFDictionaryRef currentDisplayMode = CGDisplayCurrentMode(display);
		dictget(currentDisplayMode, Double, kCGDisplayRefreshRate, &currentRefreshRate);
		dictget(currentDisplayMode, Int, kCGDisplayBitsPerPixel, &curBPP);
		dictget(currentDisplayMode, Int, kCGDisplayBitsPerSample, &curBPS);
		dictget(currentDisplayMode, Int, kCGDisplaySamplesPerPixel, &curSPP);
	}

	for (CFIndex j = 0, c = CFArrayGetCount(displayModes); j < c; j++)
	{
		int width, height;
		double refreshRate;
		bool pixelEncodingsEqual;

#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1060
		if (modern)
		{
			CGDisplayModeRef displayMode = (CGDisplayModeRef)CFArrayGetValueAtIndex(displayModes, j);
			width = (int)CGDisplayModeGetWidth(displayMode);
			height = (int)CGDisplayModeGetHeight(displayMode);
			refreshRate = CGDisplayModeGetRefreshRate(displayMode);
			CFStringRef pixelEncoding = CGDisplayModeCopyPixelEncoding(displayMode);
			pixelEncodingsEqual = (CFStringCompare(pixelEncoding, currentPixelEncoding, 0) == kCFCompareEqualTo);
			CFRelease(pixelEncoding);
		}
		else
#endif
		{
			CFDictionaryRef displayMode = (CFDictionaryRef)CFArrayGetValueAtIndex(displayModes, j);
			dictget(displayMode, Int, kCGDisplayWidth, &width);
			dictget(displayMode, Int, kCGDisplayHeight, &height);
			dictget(displayMode, Double, kCGDisplayRefreshRate, &refreshRate);
			int bpp, bps, spp;
			dictget(displayMode, Int, kCGDisplayBitsPerPixel, &bpp);
			dictget(displayMode, Int, kCGDisplayBitsPerSample, &bps);
			dictget(displayMode, Int, kCGDisplaySamplesPerPixel, &spp);
			pixelEncodingsEqual = (bpp == curBPP && bps == curBPS && spp == curSPP);
		}

		QSize res(width, height);
		if (!resolutions.contains(res)
		    && width >= minSize.width() && height >= minSize.height()
		    && refreshRate == currentRefreshRate && pixelEncodingsEqual)
		{
			resolutions += res;
		}
	}

#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1060
	if (modern)
	{
		CFRelease(currentPixelEncoding);
		CFRelease(displayModes);
	}
#endif

	return true;
}
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;
		}
	}
}
예제 #13
0
static Bool
QuartzRandREnumerateModes(ScreenPtr pScreen,
                          QuartzModeCallback callback,
                          void *data)
{
    Bool retval = FALSE;
    QuartzScreenPtr pQuartzScreen = QUARTZ_PRIV(pScreen);

    /* Just an 800x600 fallback if we have no attached heads */
    if (pQuartzScreen->displayIDs) {
        CGDisplayModeRef curModeRef, modeRef;
        CFStringRef curPixelEnc, pixelEnc;
        CFComparisonResult pixelEncEqual;
        CFArrayRef modes;
        QuartzModeInfo modeInfo;
        int i;
        CGDirectDisplayID screenId = pQuartzScreen->displayIDs[0];

        curModeRef = CGDisplayCopyDisplayMode(screenId);
        if (!curModeRef)
            return FALSE;
        curPixelEnc = CGDisplayModeCopyPixelEncoding(curModeRef);
        CGDisplayModeRelease(curModeRef);

        modes = CGDisplayCopyAllDisplayModes(screenId, NULL);
        if (!modes) {
            CFRelease(curPixelEnc);
            return FALSE;
        }
        for (i = 0; i < CFArrayGetCount(modes); i++) {
            int cb;
            modeRef = (CGDisplayModeRef)CFArrayGetValueAtIndex(modes, i);

            /* Skip modes that are not usable on the current display or have a
               different pixel encoding than the current mode. */
            if ((CGDisplayModeGetIOFlags(modeRef) &
                 kDisplayModeUsableFlags) !=
                kDisplayModeUsableFlags)
                continue;
            pixelEnc = CGDisplayModeCopyPixelEncoding(modeRef);
            pixelEncEqual = CFStringCompare(pixelEnc, curPixelEnc, 0);
            CFRelease(pixelEnc);
            if (pixelEncEqual != kCFCompareEqualTo)
                continue;

            QuartzRandRGetModeInfo(modeRef, &modeInfo);
            modeInfo.ref = modeRef;
            cb = callback(pScreen, &modeInfo, data);
            if (cb == CALLBACK_CONTINUE) {
                retval = TRUE;
            }
            else if (cb == CALLBACK_SUCCESS) {
                CFRelease(modes);
                CFRelease(curPixelEnc);
                return TRUE;
            }
            else if (cb == CALLBACK_ERROR) {
                CFRelease(modes);
                CFRelease(curPixelEnc);
                return FALSE;
            }
        }

        CFRelease(modes);
        CFRelease(curPixelEnc);
    }

    switch (callback(pScreen, &pQuartzScreen->rootlessMode, data)) {
    case CALLBACK_SUCCESS:
        return TRUE;

    case CALLBACK_ERROR:
        return FALSE;

    case CALLBACK_CONTINUE:
        retval = TRUE;

    default:
        break;
    }

    switch (callback(pScreen, &pQuartzScreen->fullscreenMode, data)) {
    case CALLBACK_SUCCESS:
        return TRUE;

    case CALLBACK_ERROR:
        return FALSE;

    case CALLBACK_CONTINUE:
        retval = TRUE;

    default:
        break;
    }

    return retval;
}
예제 #14
0
////////////////////////////////////////////////////////////
/// Note : 
///     Starting with 10.6, CGDisplayModeRef and CGDisplayCopyAllDisplayModes
///     should be used instead of CFDictionaryRef and CGDisplayAvailableModes.
///
////////////////////////////////////////////////////////////
std::vector<VideoMode> VideoModeImpl::getFullscreenModes()
{
#if MAC_OS_X_VERSION_MAX_ALLOWED < 1060
    
    std::vector<VideoMode> modes;
    
    // Retrieve array of dictionaries representing display modes.
    CFArrayRef displayModes = CGDisplayAvailableModes(CGMainDisplayID());
    
    if (displayModes == NULL) {
        sf::err() << "Couldn't get VideoMode for main display.";
        return modes;
    }
    
    // Loop on each mode and convert it into a sf::VideoMode object.
    CFIndex const modesCount = CFArrayGetCount(displayModes);
    for (CFIndex i = 0; i < modesCount; i++) {
        CFDictionaryRef dictionary = (CFDictionaryRef)CFArrayGetValueAtIndex(displayModes, i);
        
        VideoMode mode = convertCGModeToSFMode(dictionary);
        
        // If not yet listed we add it to our modes array.
        if (std::find(modes.begin(), modes.end(), mode) == modes.end()) {
            modes.push_back(mode);
        }
    }
    
    return modes;
    
#else // MAC_OS_X_VERSION_MAX_ALLOWED >= 1060
    
    std::vector<VideoMode> modes;
    
    // Retrieve all modes available for main screen only.
    CFArrayRef cgmodes = CGDisplayCopyAllDisplayModes(CGMainDisplayID(), NULL);
    
    if (cgmodes == NULL) {
        sf::err() << "Couldn't get VideoMode for main display.";
        return modes;
    }
    
    // Loop on each mode and convert it into a sf::VideoMode object.
    CFIndex const modesCount = CFArrayGetCount(cgmodes);
    for (CFIndex i = 0; i < modesCount; i++) {
        CGDisplayModeRef cgmode = (CGDisplayModeRef)CFArrayGetValueAtIndex(cgmodes, i);
        
        VideoMode mode = convertCGModeToSFMode(cgmode);
        
        // If not yet listed we add it to our modes array.
        if (std::find(modes.begin(), modes.end(), mode) == modes.end()) {
            modes.push_back(mode);
        }
    }
    
    // Clean up memory.
    CFRelease(cgmodes);
    
    return modes;
    
#endif
}
예제 #15
0
unsigned int listAvailableModes(CGDirectDisplayID display, int displayNum) {
    unsigned int returncode = 1;
    int numModes = 0;
    int i;

    CFArrayRef allModes = CGDisplayCopyAllDisplayModes(display, NULL);
    if (allModes == NULL) {
        returncode = 0;
    }

    numModes = CFArrayGetCount(allModes);

    // sort the array of display modes
    CFMutableArrayRef allModesSorted =  CFArrayCreateMutableCopy(
                                          kCFAllocatorDefault,
                                          numModes,
                                          allModes
                                        );

    CFArraySortValues(
        allModesSorted,
        CFRangeMake(0, CFArrayGetCount(allModesSorted)),
        (CFComparatorFunction) _compareCFDisplayModes,
        NULL
    ); 

#ifndef LIST_DEBUG
    if(displayNum != 0)
        printf("\n\n");
    printf("Available Modes on Display %d\n", displayNum);
#endif

    CGDisplayModeRef mode;

    int modesPerColumn = numModes / MODES_PER_LINE;

    for (i = 0; (i < numModes) && returncode; i++) {
        int rowNumber = (i / MODES_PER_LINE);
        int idxDisplayMode = (i % MODES_PER_LINE) * modesPerColumn + rowNumber;

        // if there are an even number of display modes to display,
        // the last mode must have it's index decremented by 1
        idxDisplayMode = MIN(idxDisplayMode, numModes - 1);

        mode = (CGDisplayModeRef) CFArrayGetValueAtIndex(allModesSorted, idxDisplayMode);

        // This formatting is functional but it ought to be done less poorly.
#ifndef LIST_DEBUG
        if (i % MODES_PER_LINE == 0) {
            printf("  ");
        } else {
            printf("\t");
        }

        char modestr [50];
        sprintf(modestr, "%4lux%4lux%lu@%.0f",
               CGDisplayModeGetWidth(mode),
               CGDisplayModeGetHeight(mode),
               bitDepth(mode),
               CGDisplayModeGetRefreshRate(mode));
        printf("%-20s ", modestr);

        if(i % MODES_PER_LINE == MODES_PER_LINE - 1)
            printf("\n");
#else
        uint32_t ioflags = CGDisplayModeGetIOFlags(mode);
        printf("display: %d %4lux%4lux%2lu@%.0f usable:%u ioflags:%4x valid:%u safe:%u default:%u",
                displayNum,
                CGDisplayModeGetWidth(mode),
                CGDisplayModeGetHeight(mode),
                bitDepth(mode),
                CGDisplayModeGetRefreshRate(mode),
                CGDisplayModeIsUsableForDesktopGUI(mode),
                ioflags,
                ioflags & kDisplayModeValidFlag ?1:0,
                ioflags & kDisplayModeSafeFlag ?1:0,
                ioflags & kDisplayModeDefaultFlag ?1:0 );
        printf(" safety:%u alwaysshow:%u nevershow:%u notresize:%u requirepan:%u int:%u simul:%u",
                ioflags & kDisplayModeSafetyFlags ?1:0,
                ioflags & kDisplayModeAlwaysShowFlag ?1:0,
                ioflags & kDisplayModeNeverShowFlag ?1:0,
                ioflags & kDisplayModeNotResizeFlag ?1:0,
                ioflags & kDisplayModeRequiresPanFlag ?1:0,
                ioflags & kDisplayModeInterlacedFlag ?1:0,
                ioflags & kDisplayModeSimulscanFlag ?1:0 );
        printf(" builtin:%u notpreset:%u stretched:%u notgfxqual:%u valagnstdisp:%u tv:%u vldmirror:%u\n",
                ioflags & kDisplayModeBuiltInFlag ?1:0,
                ioflags & kDisplayModeNotPresetFlag ?1:0,
                ioflags & kDisplayModeStretchedFlag ?1:0,
                ioflags & kDisplayModeNotGraphicsQualityFlag ?1:0,
                ioflags & kDisplayModeValidateAgainstDisplay ?1:0,
                ioflags & kDisplayModeTelevisionFlag ?1:0,
                ioflags & kDisplayModeValidForMirroringFlag ?1:0 );
#endif
    }

    CFRelease(allModes);
    CFRelease(allModesSorted);

    return returncode;
}