Beispiel #1
0
CFComparisonResult _compareCFDisplayModes (CGDisplayModeRef *mode1Ptr, CGDisplayModeRef *mode2Ptr, void *context)
{
    CGDisplayModeRef mode1 = (CGDisplayModeRef)mode1Ptr;
    CGDisplayModeRef mode2 = (CGDisplayModeRef)mode2Ptr;

    size_t width1 = CGDisplayModeGetWidth(mode1);
    size_t width2 = CGDisplayModeGetWidth(mode2);
    
    if(width1 == width2) {
        size_t height1 = CGDisplayModeGetWidth(mode1);
        size_t height2 = CGDisplayModeGetWidth(mode2);
        
        if(height1 == height2) {
            size_t refreshRate1 = CGDisplayModeGetRefreshRate(mode1);
            size_t refreshRate2 = CGDisplayModeGetRefreshRate(mode2);
            
            if(refreshRate1 == refreshRate2) {
                long bitDepth1 = bitDepth(mode1);
                long bitDepth2 = bitDepth(mode2);
                
                if(bitDepth1 == bitDepth2)
                    return kCFCompareEqualTo;
                else
                    return (bitDepth1 < bitDepth2) ? kCFCompareLessThan : kCFCompareGreaterThan;
            }
            else 
                return (refreshRate1 < refreshRate2) ? kCFCompareLessThan : kCFCompareGreaterThan;
        }
        else 
            return (height1 < height2) ? kCFCompareLessThan : kCFCompareGreaterThan;
    }
    else 
        return (width1 < width2) ? kCFCompareLessThan : kCFCompareGreaterThan;
}
Beispiel #2
0
/***********************************************************************
 *              macdrv_displays_changed
 *
 * Handler for DISPLAYS_CHANGED events.
 */
void macdrv_displays_changed(const macdrv_event *event)
{
    HWND hwnd = GetDesktopWindow();

    /* A system display change will get delivered to all GUI-attached threads,
       so the desktop-window-owning thread will get it and all others should
       ignore it.  A synthesized display change event due to activation
       will only get delivered to the activated process.  So, it needs to
       process it (by sending it to the desktop window). */
    if (event->displays_changed.activating ||
        GetWindowThreadProcessId(hwnd, NULL) == GetCurrentThreadId())
    {
        CGDirectDisplayID mainDisplay = CGMainDisplayID();
        CGDisplayModeRef mode = CGDisplayCopyDisplayMode(mainDisplay);
        size_t width = CGDisplayModeGetWidth(mode);
        size_t height = CGDisplayModeGetHeight(mode);
        int mode_bpp = display_mode_bits_per_pixel(mode);
        struct display_mode_descriptor* desc = create_original_display_mode_descriptor(mainDisplay);
        BOOL is_original = display_mode_matches_descriptor(mode, desc);

        free_display_mode_descriptor(desc);
        CGDisplayModeRelease(mode);

        if (is_original && retina_enabled)
        {
            width *= 2;
            height *= 2;
        }

        SendMessageW(hwnd, WM_MACDRV_UPDATE_DESKTOP_RECT, mode_bpp,
                     MAKELPARAM(width, height));
    }
}
Beispiel #3
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));
            }
        }
    }
}
Beispiel #4
0
static BOOL display_mode_matches_descriptor(CGDisplayModeRef mode, const struct display_mode_descriptor* desc)
{
    DWORD mode_io_flags;
    double mode_refresh;
    CFStringRef mode_pixel_encoding;

    if (!desc)
        return FALSE;

    if (CGDisplayModeGetWidth(mode) != desc->width ||
            CGDisplayModeGetHeight(mode) != desc->height)
        return FALSE;

    mode_io_flags = CGDisplayModeGetIOFlags(mode);
    if ((desc->io_flags ^ mode_io_flags) & (kDisplayModeValidFlag | kDisplayModeSafeFlag | kDisplayModeStretchedFlag |
                                            kDisplayModeInterlacedFlag | kDisplayModeTelevisionFlag))
        return FALSE;

    mode_refresh = CGDisplayModeGetRefreshRate(mode);
    if (!mode_refresh)
        mode_refresh = 60;
    if (fabs(desc->refresh - mode_refresh) > 0.1)
        return FALSE;

#if defined(MAC_OS_X_VERSION_10_8) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_8
    if (CGDisplayModeGetPixelWidth != NULL && CGDisplayModeGetPixelHeight != NULL)
    {
        if (CGDisplayModeGetPixelWidth(mode) != desc->pixel_width ||
                CGDisplayModeGetPixelHeight(mode) != desc->pixel_height)
            return FALSE;
    }
    else
#endif
        if (CGDisplayModeGetWidth(mode) != desc->pixel_width ||
                CGDisplayModeGetHeight(mode) != desc->pixel_height)
            return FALSE;

    mode_pixel_encoding = CGDisplayModeCopyPixelEncoding(mode);
    if (!CFEqual(mode_pixel_encoding, desc->pixel_encoding))
    {
        CFRelease(mode_pixel_encoding);
        return FALSE;
    }
    CFRelease(mode_pixel_encoding);

    return TRUE;
}
// 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;
}
Beispiel #6
0
static void
QuartzRandRGetModeInfo(CGDisplayModeRef modeRef,
                       QuartzModeInfoPtr pMode)
{
    pMode->width = CGDisplayModeGetWidth(modeRef);
    pMode->height = CGDisplayModeGetHeight(modeRef);
    pMode->refresh = (int)(CGDisplayModeGetRefreshRate(modeRef) + 0.5);
    if (pMode->refresh == 0)
        pMode->refresh = DEFAULT_REFRESH;
    pMode->ref = NULL;
    pMode->pSize = NULL;
}
Beispiel #7
0
/**********************************************************************
 *              device_init
 *
 * Perform initializations needed upon creation of the first device.
 */
static void device_init(void)
{
    CGDirectDisplayID mainDisplay = CGMainDisplayID();
    CGSize size_mm = CGDisplayScreenSize(mainDisplay);
    CGDisplayModeRef mode = CGDisplayCopyDisplayMode(mainDisplay);

    check_retina_status();

    /* Initialize device caps */
    horz_size = size_mm.width;
    vert_size = size_mm.height;

    bits_per_pixel = 32;
    if (mode)
    {
        CFStringRef pixelEncoding = CGDisplayModeCopyPixelEncoding(mode);

        horz_res = CGDisplayModeGetWidth(mode);
        vert_res = CGDisplayModeGetHeight(mode);

        if (pixelEncoding)
        {
            if (CFEqual(pixelEncoding, CFSTR(IO32BitDirectPixels)))
                bits_per_pixel = 32;
            else if (CFEqual(pixelEncoding, CFSTR(IO16BitDirectPixels)))
                bits_per_pixel = 16;
            else if (CFEqual(pixelEncoding, CFSTR(IO8BitIndexedPixels)))
                bits_per_pixel = 8;
            CFRelease(pixelEncoding);
        }

        CGDisplayModeRelease(mode);
    }
    else
    {
        horz_res = CGDisplayPixelsWide(mainDisplay);
        vert_res = CGDisplayPixelsHigh(mainDisplay);
    }

    if (retina_on)
    {
        horz_res *= 2;
        vert_res *= 2;
    }

    compute_desktop_rect();
    desktop_horz_res = desktop_rect.size.width;
    desktop_vert_res = desktop_rect.size.height;

    device_data_valid = TRUE;
}
Beispiel #8
0
static CFDictionaryRef create_mode_dict(CGDisplayModeRef display_mode, BOOL is_original)
{
    CFDictionaryRef ret;
    SInt32 io_flags = CGDisplayModeGetIOFlags(display_mode);
    SInt64 width = CGDisplayModeGetWidth(display_mode);
    SInt64 height = CGDisplayModeGetHeight(display_mode);
    double refresh_rate = CGDisplayModeGetRefreshRate(display_mode);
    CFStringRef pixel_encoding = CGDisplayModeCopyPixelEncoding(display_mode);
    CFNumberRef cf_io_flags, cf_width, cf_height, cf_refresh;

    if (retina_enabled && is_original)
    {
        width *= 2;
        height *= 2;
    }

    io_flags &= kDisplayModeValidFlag | kDisplayModeSafeFlag | kDisplayModeInterlacedFlag |
                kDisplayModeStretchedFlag | kDisplayModeTelevisionFlag;
    cf_io_flags = CFNumberCreate(NULL, kCFNumberSInt32Type, &io_flags);
    cf_width = CFNumberCreate(NULL, kCFNumberSInt64Type, &width);
    cf_height = CFNumberCreate(NULL, kCFNumberSInt64Type, &height);
    cf_refresh = CFNumberCreate(NULL, kCFNumberDoubleType, &refresh_rate);

    {
        static const CFStringRef keys[] = {
            CFSTR("io_flags"),
            CFSTR("width"),
            CFSTR("height"),
            CFSTR("pixel_encoding"),
            CFSTR("refresh_rate"),
        };
        const void* values[sizeof(keys) / sizeof(keys[0])] = {
            cf_io_flags,
            cf_width,
            cf_height,
            pixel_encoding,
            cf_refresh,
        };

        ret = CFDictionaryCreate(NULL, (const void**)keys, (const void**)values, sizeof(keys) / sizeof(keys[0]),
                                 &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
    }

    CFRelease(pixel_encoding);
    CFRelease(cf_io_flags);
    CFRelease(cf_width);
    CFRelease(cf_height);
    CFRelease(cf_refresh);

    return ret;
}
Beispiel #9
0
unsigned int listCurrentMode(CGDirectDisplayID display, int displayNum) {
    unsigned int returncode = 1;
    CGDisplayModeRef currentMode = CGDisplayCopyDisplayMode(display);
    if (currentMode == NULL) {
        NSLog(CFSTR("%s"), "Error: unable to copy current display mode");
        returncode = 0;
    }
    NSLog(CFSTR("Display %d: %ux%ux%u@%.0f"),
           displayNum,
           CGDisplayModeGetWidth(currentMode),
           CGDisplayModeGetHeight(currentMode),
           bitDepth(currentMode),
           CGDisplayModeGetRefreshRate(currentMode));
    CGDisplayModeRelease(currentMode);
    return returncode;
}
Beispiel #10
0
int fs_ml_video_mode_get_current(fs_ml_video_mode *mode) {
    mode->width = 0;
    mode->height = 0;
    mode->fps = 0;
    mode->bpp = 0;
    mode->flags = 0;

#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1060
    // CGDisplayCurrentMode is deprecated in Mac OS X 10.6, so we use
    // the new API here
    CGDirectDisplayID currentDisplay = CGDisplayPrimaryDisplay(
            kCGDirectMainDisplay);
    CGDisplayModeRef currentMode = CGDisplayCopyDisplayMode(
            currentDisplay);
    mode->width = CGDisplayModeGetWidth(currentMode);
    mode->height = CGDisplayModeGetHeight(currentMode);
    mode->fps = CGDisplayModeGetRefreshRate(currentMode);
    CGDisplayModeRelease(currentMode);
#else
    CFNumberRef number;
    long refresh, width, height;
    CFDictionaryRef currentMode = CGDisplayCurrentMode(kCGDirectMainDisplay);
    number = CFDictionaryGetValue(currentMode, kCGDisplayWidth);
    CFNumberGetValue(number, kCFNumberLongType, &width);
    number = CFDictionaryGetValue(currentMode, kCGDisplayHeight);
    CFNumberGetValue(number, kCFNumberLongType, &height);
    number = CFDictionaryGetValue(currentMode, kCGDisplayRefreshRate);
    CFNumberGetValue(number, kCFNumberLongType, &refresh);
    mode->width = width;
    mode->height = height;
    mode->fps = refresh;
#endif

    //fs_log("WARNING: assuming 60 Hz refresh rate on Mac OS X\n");
    //mode->fps = 60;

    if (mode->fps == 0) {
        fs_log("WARNING: refresh rate was not detected\n");
        fs_log("full video sync will not be enabled automatically, but can "
                "be forced\n");
    }

    return 0;
}
Beispiel #11
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;
}
Beispiel #12
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 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();
}
Beispiel #14
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);
}
Beispiel #15
0
VideoMode convertCGModeToSFMode(CGDisplayModeRef cgmode)
{
    return VideoMode(CGDisplayModeGetWidth(cgmode),
                     CGDisplayModeGetHeight(cgmode),
                     modeBitsPerPixel(cgmode));
}
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;
		}
	}
}
Beispiel #17
0
/**********************************************************************
 *              device_init
 *
 * Perform initializations needed upon creation of the first device.
 */
static void device_init(void)
{
    CGDirectDisplayID mainDisplay = CGMainDisplayID();
    CGSize size_mm = CGDisplayScreenSize(mainDisplay);
    CGDisplayModeRef mode = CGDisplayCopyDisplayMode(mainDisplay);
    CGDirectPaletteRef palette;

    /* Initialize device caps */
    log_pixels_x = log_pixels_y = get_dpi();
    if (!log_pixels_x)
    {
        size_t width = CGDisplayPixelsWide(mainDisplay);
        size_t height = CGDisplayPixelsHigh(mainDisplay);
        log_pixels_x = MulDiv(width, 254, size_mm.width * 10);
        log_pixels_y = MulDiv(height, 254, size_mm.height * 10);
    }

    horz_size = size_mm.width;
    vert_size = size_mm.height;

    bits_per_pixel = 32;
    if (mode)
    {
        CFStringRef pixelEncoding = CGDisplayModeCopyPixelEncoding(mode);

        horz_res = CGDisplayModeGetWidth(mode);
        vert_res = CGDisplayModeGetHeight(mode);

        if (pixelEncoding)
        {
            if (CFEqual(pixelEncoding, CFSTR(IO32BitDirectPixels)))
                bits_per_pixel = 32;
            else if (CFEqual(pixelEncoding, CFSTR(IO16BitDirectPixels)))
                bits_per_pixel = 16;
            else if (CFEqual(pixelEncoding, CFSTR(IO8BitIndexedPixels)))
                bits_per_pixel = 8;
            CFRelease(pixelEncoding);
        }

        CGDisplayModeRelease(mode);
    }
    else
    {
        horz_res = CGDisplayPixelsWide(mainDisplay);
        vert_res = CGDisplayPixelsHigh(mainDisplay);
    }

    macdrv_get_desktop_rect();
    desktop_horz_res = desktop_rect.size.width;
    desktop_vert_res = desktop_rect.size.height;

    palette = CGPaletteCreateWithDisplay(mainDisplay);
    if (palette)
    {
        palette_size = CGPaletteGetNumberOfSamples(palette);
        CGPaletteRelease(palette);
    }
    else
        palette_size = 0;

    device_data_valid = TRUE;
}
Beispiel #18
0
/***********************************************************************
 *              EnumDisplaySettingsEx  (MACDRV.@)
 *
 */
BOOL CDECL macdrv_EnumDisplaySettingsEx(LPCWSTR devname, DWORD mode,
                                        LPDEVMODEW devmode, DWORD flags)
{
    static const WCHAR dev_name[CCHDEVICENAME] =
    { 'W','i','n','e',' ','M','a','c',' ','d','r','i','v','e','r',0 };
    struct macdrv_display *displays = NULL;
    int num_displays;
    CGDisplayModeRef display_mode;
    int display_mode_bpp;
    BOOL synthesized = FALSE;
    double rotation;
    uint32_t io_flags;

    TRACE("%s, %u, %p + %hu, %08x\n", debugstr_w(devname), mode, devmode, devmode->dmSize, flags);

    init_original_display_mode();

    memcpy(devmode->dmDeviceName, dev_name, sizeof(dev_name));
    devmode->dmSpecVersion = DM_SPECVERSION;
    devmode->dmDriverVersion = DM_SPECVERSION;
    devmode->dmSize = FIELD_OFFSET(DEVMODEW, dmICMMethod);
    devmode->dmDriverExtra = 0;
    memset(&devmode->dmFields, 0, devmode->dmSize - FIELD_OFFSET(DEVMODEW, dmFields));

    if (mode == ENUM_REGISTRY_SETTINGS)
    {
        TRACE("mode %d (registry) -- getting default mode\n", mode);
        return read_registry_settings(devmode);
    }

    if (macdrv_get_displays(&displays, &num_displays))
        goto failed;

    if (mode == ENUM_CURRENT_SETTINGS)
    {
        TRACE("mode %d (current) -- getting current mode\n", mode);
        display_mode = CGDisplayCopyDisplayMode(displays[0].displayID);
        display_mode_bpp = display_mode_bits_per_pixel(display_mode);
    }
    else
    {
        DWORD count, i;

        EnterCriticalSection(&modes_section);

        if (mode == 0 || !modes)
        {
            if (modes) CFRelease(modes);
            modes = copy_display_modes(displays[0].displayID);
            modes_has_8bpp = modes_has_16bpp = FALSE;

            if (modes)
            {
                count = CFArrayGetCount(modes);
                for (i = 0; i < count && !(modes_has_8bpp && modes_has_16bpp); i++)
                {
                    CGDisplayModeRef mode = (CGDisplayModeRef)CFArrayGetValueAtIndex(modes, i);
                    int bpp = display_mode_bits_per_pixel(mode);
                    if (bpp == 8)
                        modes_has_8bpp = TRUE;
                    else if (bpp == 16)
                        modes_has_16bpp = TRUE;
                }
            }
        }

        display_mode = NULL;
        if (modes)
        {
            int default_bpp = get_default_bpp();
            DWORD seen_modes = 0;

            count = CFArrayGetCount(modes);
            for (i = 0; i < count; i++)
            {
                CGDisplayModeRef candidate = (CGDisplayModeRef)CFArrayGetValueAtIndex(modes, i);

                io_flags = CGDisplayModeGetIOFlags(candidate);
                if (!(flags & EDS_RAWMODE) &&
                        (!(io_flags & kDisplayModeValidFlag) || !(io_flags & kDisplayModeSafeFlag)))
                    continue;

                seen_modes++;
                if (seen_modes > mode)
                {
                    display_mode = (CGDisplayModeRef)CFRetain(candidate);
                    display_mode_bpp = display_mode_bits_per_pixel(display_mode);
                    break;
                }

                /* We only synthesize modes from those having the default bpp. */
                if (display_mode_bits_per_pixel(candidate) != default_bpp)
                    continue;

                if (!modes_has_8bpp)
                {
                    seen_modes++;
                    if (seen_modes > mode)
                    {
                        display_mode = (CGDisplayModeRef)CFRetain(candidate);
                        display_mode_bpp = 8;
                        synthesized = TRUE;
                        break;
                    }
                }

                if (!modes_has_16bpp)
                {
                    seen_modes++;
                    if (seen_modes > mode)
                    {
                        display_mode = (CGDisplayModeRef)CFRetain(candidate);
                        display_mode_bpp = 16;
                        synthesized = TRUE;
                        break;
                    }
                }
            }
        }

        LeaveCriticalSection(&modes_section);
    }

    if (!display_mode)
        goto failed;

    /* We currently only report modes for the primary display, so it's at (0, 0). */
    devmode->dmPosition.x = 0;
    devmode->dmPosition.y = 0;
    devmode->dmFields |= DM_POSITION;

    rotation = CGDisplayRotation(displays[0].displayID);
    devmode->dmDisplayOrientation = ((int)((rotation / 90) + 0.5)) % 4;
    devmode->dmFields |= DM_DISPLAYORIENTATION;

    io_flags = CGDisplayModeGetIOFlags(display_mode);
    if (io_flags & kDisplayModeStretchedFlag)
        devmode->dmDisplayFixedOutput = DMDFO_STRETCH;
    else
        devmode->dmDisplayFixedOutput = DMDFO_CENTER;
    devmode->dmFields |= DM_DISPLAYFIXEDOUTPUT;

    devmode->dmBitsPerPel = display_mode_bpp;
    if (devmode->dmBitsPerPel)
        devmode->dmFields |= DM_BITSPERPEL;

    devmode->dmPelsWidth = CGDisplayModeGetWidth(display_mode);
    devmode->dmPelsHeight = CGDisplayModeGetHeight(display_mode);
    devmode->dmFields |= DM_PELSWIDTH | DM_PELSHEIGHT;

    devmode->dmDisplayFlags = 0;
    if (io_flags & kDisplayModeInterlacedFlag)
        devmode->dmDisplayFlags |= DM_INTERLACED;
    devmode->dmFields |= DM_DISPLAYFLAGS;

    devmode->dmDisplayFrequency = CGDisplayModeGetRefreshRate(display_mode);
    if (!devmode->dmDisplayFrequency)
        devmode->dmDisplayFrequency = 60;
    devmode->dmFields |= DM_DISPLAYFREQUENCY;

    CFRelease(display_mode);
    macdrv_free_displays(displays);

    TRACE("mode %d -- %dx%dx%dbpp @%d Hz", mode,
          devmode->dmPelsWidth, devmode->dmPelsHeight, devmode->dmBitsPerPel,
          devmode->dmDisplayFrequency);
    if (devmode->dmDisplayOrientation)
        TRACE(" rotated %u degrees", devmode->dmDisplayOrientation * 90);
    if (devmode->dmDisplayFixedOutput == DMDFO_STRETCH)
        TRACE(" stretched");
    if (devmode->dmDisplayFlags & DM_INTERLACED)
        TRACE(" interlaced");
    if (synthesized)
        TRACE(" (synthesized)");
    TRACE("\n");

    return TRUE;

failed:
    TRACE("mode %d -- not present\n", mode);
    if (displays) macdrv_free_displays(displays);
    SetLastError(ERROR_NO_MORE_FILES);
    return FALSE;
}
Beispiel #19
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;
}
Beispiel #20
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 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;
}
Beispiel #22
0
static BOOL write_display_settings(HKEY parent_hkey, CGDirectDisplayID displayID)
{
    BOOL ret = FALSE;
    char display_key_name[19];
    HKEY display_hkey;
    CGDisplayModeRef display_mode;
    DWORD val;
    CFStringRef pixel_encoding;
    size_t len;
    WCHAR* buf = NULL;

    snprintf(display_key_name, sizeof(display_key_name), "Display 0x%08x", CGDisplayUnitNumber(displayID));
    /* @@ Wine registry key: HKLM\Software\Wine\Mac Driver\Initial Display Mode\Display 0xnnnnnnnn */
    if (RegCreateKeyExA(parent_hkey, display_key_name, 0, NULL,
                        REG_OPTION_VOLATILE, KEY_WRITE, NULL, &display_hkey, NULL))
        return FALSE;

    display_mode = CGDisplayCopyDisplayMode(displayID);
    if (!display_mode)
        goto fail;

    val = CGDisplayModeGetWidth(display_mode);
    if (RegSetValueExA(display_hkey, "Width", 0, REG_DWORD, (const BYTE*)&val, sizeof(val)))
        goto fail;
    val = CGDisplayModeGetHeight(display_mode);
    if (RegSetValueExA(display_hkey, "Height", 0, REG_DWORD, (const BYTE*)&val, sizeof(val)))
        goto fail;
    val = CGDisplayModeGetRefreshRate(display_mode) * 100;
    if (RegSetValueExA(display_hkey, "RefreshRateTimes100", 0, REG_DWORD, (const BYTE*)&val, sizeof(val)))
        goto fail;
    val = CGDisplayModeGetIOFlags(display_mode);
    if (RegSetValueExA(display_hkey, "IOFlags", 0, REG_DWORD, (const BYTE*)&val, sizeof(val)))
        goto fail;

#if defined(MAC_OS_X_VERSION_10_8) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_8
    if (CGDisplayModeGetPixelWidth != NULL && CGDisplayModeGetPixelHeight != NULL)
    {
        val = CGDisplayModeGetPixelWidth(display_mode);
        if (RegSetValueExA(display_hkey, "PixelWidth", 0, REG_DWORD, (const BYTE*)&val, sizeof(val)))
            goto fail;
        val = CGDisplayModeGetPixelHeight(display_mode);
        if (RegSetValueExA(display_hkey, "PixelHeight", 0, REG_DWORD, (const BYTE*)&val, sizeof(val)))
            goto fail;
    }
#endif

    pixel_encoding = CGDisplayModeCopyPixelEncoding(display_mode);
    len = CFStringGetLength(pixel_encoding);
    buf = HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR));
    CFStringGetCharacters(pixel_encoding, CFRangeMake(0, len), (UniChar*)buf);
    buf[len] = 0;
    CFRelease(pixel_encoding);
    if (RegSetValueExW(display_hkey, pixelencodingW, 0, REG_SZ, (const BYTE*)buf, (len + 1) * sizeof(WCHAR)))
        goto fail;

    ret = TRUE;

fail:
    HeapFree(GetProcessHeap(), 0, buf);
    if (display_mode) CGDisplayModeRelease(display_mode);
    RegCloseKey(display_hkey);
    if (!ret)
        RegDeleteKeyA(parent_hkey, display_key_name);
    return ret;
}
Beispiel #23
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;
}
Beispiel #24
0
/***********************************************************************
 *              ChangeDisplaySettingsEx  (MACDRV.@)
 *
 */
LONG CDECL macdrv_ChangeDisplaySettingsEx(LPCWSTR devname, LPDEVMODEW devmode,
        HWND hwnd, DWORD flags, LPVOID lpvoid)
{
    LONG ret = DISP_CHANGE_BADMODE;
    int bpp;
    DEVMODEW dm;
    BOOL def_mode = TRUE;
    struct macdrv_display *displays;
    int num_displays;
    CFArrayRef display_modes;
    CFIndex count, i, safe, best;
    CGDisplayModeRef best_display_mode;
    uint32_t best_io_flags;

    TRACE("%s %p %p 0x%08x %p\n", debugstr_w(devname), devmode, hwnd, flags, lpvoid);

    init_original_display_mode();

    if (devmode)
    {
        /* this is the minimal dmSize that XP accepts */
        if (devmode->dmSize < FIELD_OFFSET(DEVMODEW, dmFields))
            return DISP_CHANGE_FAILED;

        if (devmode->dmSize >= FIELD_OFFSET(DEVMODEW, dmFields) + sizeof(devmode->dmFields))
        {
            if (((devmode->dmFields & DM_BITSPERPEL) && devmode->dmBitsPerPel) ||
                    ((devmode->dmFields & DM_PELSWIDTH) && devmode->dmPelsWidth) ||
                    ((devmode->dmFields & DM_PELSHEIGHT) && devmode->dmPelsHeight) ||
                    ((devmode->dmFields & DM_DISPLAYFREQUENCY) && devmode->dmDisplayFrequency))
                def_mode = FALSE;
        }
    }

    if (def_mode)
    {
        if (!macdrv_EnumDisplaySettingsEx(devname, ENUM_REGISTRY_SETTINGS, &dm, 0))
        {
            ERR("Default mode not found!\n");
            return DISP_CHANGE_BADMODE;
        }

        TRACE("Return to original display mode\n");
        devmode = &dm;
    }

    if ((devmode->dmFields & (DM_PELSWIDTH | DM_PELSHEIGHT)) != (DM_PELSWIDTH | DM_PELSHEIGHT))
    {
        WARN("devmode doesn't specify the resolution: %04x\n", devmode->dmFields);
        return DISP_CHANGE_BADMODE;
    }

    if (macdrv_get_displays(&displays, &num_displays))
        return DISP_CHANGE_FAILED;

    display_modes = copy_display_modes(displays[0].displayID);
    if (!display_modes)
    {
        macdrv_free_displays(displays);
        return DISP_CHANGE_FAILED;
    }

    bpp = get_default_bpp();
    if ((devmode->dmFields & DM_BITSPERPEL) && devmode->dmBitsPerPel != bpp)
        TRACE("using default %d bpp instead of caller's request %d bpp\n", bpp, devmode->dmBitsPerPel);

    TRACE("looking for %dx%dx%dbpp @%d Hz",
          (devmode->dmFields & DM_PELSWIDTH ? devmode->dmPelsWidth : 0),
          (devmode->dmFields & DM_PELSHEIGHT ? devmode->dmPelsHeight : 0),
          bpp,
          (devmode->dmFields & DM_DISPLAYFREQUENCY ? devmode->dmDisplayFrequency : 0));
    if (devmode->dmFields & DM_DISPLAYFIXEDOUTPUT)
        TRACE(" %sstretched", devmode->dmDisplayFixedOutput == DMDFO_STRETCH ? "" : "un");
    if (devmode->dmFields & DM_DISPLAYFLAGS)
        TRACE(" %sinterlaced", devmode->dmDisplayFlags & DM_INTERLACED ? "" : "non-");
    TRACE("\n");

    safe = -1;
    best_display_mode = NULL;
    count = CFArrayGetCount(display_modes);
    for (i = 0; i < count; i++)
    {
        CGDisplayModeRef display_mode = (CGDisplayModeRef)CFArrayGetValueAtIndex(display_modes, i);
        uint32_t io_flags = CGDisplayModeGetIOFlags(display_mode);
        int mode_bpp = display_mode_bits_per_pixel(display_mode);
        size_t width = CGDisplayModeGetWidth(display_mode);
        size_t height = CGDisplayModeGetHeight(display_mode);

        if (!(io_flags & kDisplayModeValidFlag) || !(io_flags & kDisplayModeSafeFlag))
            continue;

        safe++;

        if (bpp != mode_bpp)
            continue;

        if (devmode->dmFields & DM_PELSWIDTH)
        {
            if (devmode->dmPelsWidth != width)
                continue;
        }
        if (devmode->dmFields & DM_PELSHEIGHT)
        {
            if (devmode->dmPelsHeight != height)
                continue;
        }
        if ((devmode->dmFields & DM_DISPLAYFREQUENCY) && devmode->dmDisplayFrequency != 0)
        {
            double refresh_rate = CGDisplayModeGetRefreshRate(display_mode);
            if (!refresh_rate)
                refresh_rate = 60;
            if (devmode->dmDisplayFrequency != (DWORD)refresh_rate)
                continue;
        }
        if (devmode->dmFields & DM_DISPLAYFLAGS)
        {
            if (!(devmode->dmDisplayFlags & DM_INTERLACED) != !(io_flags & kDisplayModeInterlacedFlag))
                continue;
        }
        else if (best_display_mode)
        {
            if (io_flags & kDisplayModeInterlacedFlag && !(best_io_flags & kDisplayModeInterlacedFlag))
                continue;
            else if (!(io_flags & kDisplayModeInterlacedFlag) && best_io_flags & kDisplayModeInterlacedFlag)
                goto better;
        }
        if (devmode->dmFields & DM_DISPLAYFIXEDOUTPUT)
        {
            if (!(devmode->dmDisplayFixedOutput == DMDFO_STRETCH) != !(io_flags & kDisplayModeStretchedFlag))
                continue;
        }
        else if (best_display_mode)
        {
            if (io_flags & kDisplayModeStretchedFlag && !(best_io_flags & kDisplayModeStretchedFlag))
                continue;
            else if (!(io_flags & kDisplayModeStretchedFlag) && best_io_flags & kDisplayModeStretchedFlag)
                goto better;
        }

        if (best_display_mode)
            continue;

better:
        best_display_mode = display_mode;
        best = safe;
        best_io_flags = io_flags;
    }

    if (best_display_mode)
    {
        /* we have a valid mode */
        TRACE("Requested display settings match mode %ld\n", best);

        if ((flags & CDS_UPDATEREGISTRY) && !write_registry_settings(devmode))
        {
            WARN("Failed to update registry\n");
            ret = DISP_CHANGE_NOTUPDATED;
        }
        else if (flags & (CDS_TEST | CDS_NORESET))
            ret = DISP_CHANGE_SUCCESSFUL;
        else if (macdrv_set_display_mode(&displays[0], best_display_mode))
        {
            int mode_bpp = display_mode_bits_per_pixel(best_display_mode);
            size_t width = CGDisplayModeGetWidth(best_display_mode);
            size_t height = CGDisplayModeGetHeight(best_display_mode);

            SendMessageW(GetDesktopWindow(), WM_MACDRV_UPDATE_DESKTOP_RECT, mode_bpp,
                         MAKELPARAM(width, height));
            ret = DISP_CHANGE_SUCCESSFUL;
        }
        else
        {
            WARN("Failed to set display mode\n");
            ret = DISP_CHANGE_FAILED;
        }
    }
    else
    {
        /* no valid modes found */
        ERR("No matching mode found %ux%ux%d @%u!\n", devmode->dmPelsWidth, devmode->dmPelsHeight,
            bpp, devmode->dmDisplayFrequency);
    }

    CFRelease(display_modes);
    macdrv_free_displays(displays);

    return ret;
}