예제 #1
0
size_t modeBitsPerPixel(CGDisplayModeRef mode)
{
    size_t bpp = 0; // no match
    
    // Compare encoding.
    CFStringRef pixEnc = CGDisplayModeCopyPixelEncoding(mode);
    if(CFStringCompare(pixEnc, CFSTR(IO32BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
        
        bpp = 32;
        
    } else if(CFStringCompare(pixEnc, CFSTR(IO16BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
        
        bpp = 16;
        
    } else if(CFStringCompare(pixEnc, CFSTR(IO8BitIndexedPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
        
        bpp = 8;
        
    }
    
    // Clean up memory.
    CFRelease(pixEnc);
    
    return bpp;
}
예제 #2
0
// Returns depth of screen
int wxDisplayDepth()
{
    int theDepth = 0;
    
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1060
    if ( UMAGetSystemVersion() >= 0x1060 ) 
    {
        CGDisplayModeRef currentMode = CGDisplayCopyDisplayMode(kCGDirectMainDisplay);
        CFStringRef encoding = CGDisplayModeCopyPixelEncoding(currentMode);
        
        if(CFStringCompare(encoding, CFSTR(IO32BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo)
            theDepth = 32;
        else if(CFStringCompare(encoding, CFSTR(IO16BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo)
            theDepth = 16;
        else if(CFStringCompare(encoding, CFSTR(IO8BitIndexedPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo)
            theDepth = 8;
        else
            theDepth = 32; // some reasonable default

        CFRelease(encoding);
        CGDisplayModeRelease(currentMode);
    }
    else
#endif
    {
#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
        theDepth = (int) CGDisplayBitsPerPixel(CGMainDisplayID());
#endif
    }
    return theDepth;
}
예제 #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));
            }
        }
    }
}
예제 #4
0
static int display_mode_bits_per_pixel(CGDisplayModeRef display_mode)
{
    CFStringRef pixel_encoding;
    int bits_per_pixel = 0;

    pixel_encoding = CGDisplayModeCopyPixelEncoding(display_mode);
    if (pixel_encoding)
    {
        if (CFEqual(pixel_encoding, CFSTR(kIO32BitFloatPixels)))
            bits_per_pixel = 128;
        else if (CFEqual(pixel_encoding, CFSTR(kIO16BitFloatPixels)))
            bits_per_pixel = 64;
        else if (CFEqual(pixel_encoding, CFSTR(kIO64BitDirectPixels)))
            bits_per_pixel = 64;
        else if (CFEqual(pixel_encoding, CFSTR(kIO30BitDirectPixels)))
            bits_per_pixel = 30;
        else if (CFEqual(pixel_encoding, CFSTR(IO32BitDirectPixels)))
            bits_per_pixel = 32;
        else if (CFEqual(pixel_encoding, CFSTR(IO16BitDirectPixels)))
            bits_per_pixel = 16;
        else if (CFEqual(pixel_encoding, CFSTR(IO8BitIndexedPixels)))
            bits_per_pixel = 8;
        else if (CFEqual(pixel_encoding, CFSTR(IO4BitIndexedPixels)))
            bits_per_pixel = 4;
        else if (CFEqual(pixel_encoding, CFSTR(IO2BitIndexedPixels)))
            bits_per_pixel = 2;
        else if (CFEqual(pixel_encoding, CFSTR(IO1BitIndexedPixels)))
            bits_per_pixel = 1;

        CFRelease(pixel_encoding);
    }

    return bits_per_pixel;
}
예제 #5
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;
}
예제 #6
0
파일: osx.cpp 프로젝트: TiriliPiitPiit/0ad
Status GetVideoMode(int* xres, int* yres, int* bpp, int* freq)
{
#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
	CGDisplayModeRef currentMode = CGDisplayCopyDisplayMode(kCGDirectMainDisplay);
#else
	CFDictionaryRef currentMode = CGDisplayCurrentMode(kCGDirectMainDisplay);
#endif

	if(xres)
		*xres = (int)CGDisplayPixelsWide(kCGDirectMainDisplay);

	if(yres)
		*yres = (int)CGDisplayPixelsHigh(kCGDirectMainDisplay);

	if(bpp)
	{
#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
		// CGDisplayBitsPerPixel was deprecated in OS X 10.6
		CFStringRef pixelEncoding = CGDisplayModeCopyPixelEncoding(currentMode);
		if (CFStringCompare(pixelEncoding, CFSTR(IO32BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo)
			*bpp = 32;
		else if (CFStringCompare(pixelEncoding, CFSTR(IO16BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo)
			*bpp = 16;
		else if (CFStringCompare(pixelEncoding, CFSTR(IO8BitIndexedPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo)
			*bpp = 8;
		else	// error
			*bpp = 0;

		// We're responsible for this
		CFRelease(pixelEncoding);
#else
		CFNumberRef num = (CFNumberRef)CFDictionaryGetValue(currentMode, kCGDisplayBitsPerPixel);
		CFNumberGetValue(num, kCFNumberIntType, bpp);
#endif
	}

	if(freq)
	{
#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
		*freq = (int)CGDisplayModeGetRefreshRate(currentMode);
#else
		CFNumberRef num = (CFNumberRef)CFDictionaryGetValue(currentMode, kCGDisplayRefreshRate);
		CFNumberGetValue(num, kCFNumberIntType, freq);
#endif
	}

#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
	// We're responsible for this
	CGDisplayModeRelease(currentMode);
#endif

	return INFO::OK;
}
예제 #7
0
uint32 OSXWindow::bitDepthFromDisplayMode(CGDisplayModeRef mode)
{
    uint32 depth = 0;
    CFStringRef pixEnc = CGDisplayModeCopyPixelEncoding(mode);
    if(CFStringCompare(pixEnc, CFSTR(IO32BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo)
        depth = 32;
    else if(CFStringCompare(pixEnc, CFSTR(IO16BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo)
        depth = 16;
    else if(CFStringCompare(pixEnc, CFSTR(IO8BitIndexedPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo)
        depth = 8;
    
    return depth;
}
예제 #8
0
파일: display.c 프로젝트: AmesianX/wine
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;
}
예제 #9
0
파일: gdi.c 프로젝트: AndreRH/wine
/**********************************************************************
 *              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;
}
예제 #10
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;
}
예제 #11
0
// Returns depth of screen
int wxDisplayDepth()
{
    int theDepth = 0;
    
    CGDisplayModeRef currentMode = CGDisplayCopyDisplayMode(kCGDirectMainDisplay);
    CFStringRef encoding = CGDisplayModeCopyPixelEncoding(currentMode);
    
    if(CFStringCompare(encoding, CFSTR(IO32BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo)
        theDepth = 32;
    else if(CFStringCompare(encoding, CFSTR(IO16BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo)
        theDepth = 16;
    else if(CFStringCompare(encoding, CFSTR(IO8BitIndexedPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo)
        theDepth = 8;
    else
        theDepth = 32; // some reasonable default

    CFRelease(encoding);
    CGDisplayModeRelease(currentMode);

    return theDepth;
}
예제 #12
0
size_t bitDepth(CGDisplayModeRef mode) {
    size_t depth = 0;
	CFStringRef pixelEncoding = CGDisplayModeCopyPixelEncoding(mode);
    // my numerical representation for kIO16BitFloatPixels and kIO32bitFloatPixels
    // are made up and possibly non-sensical
    if (kCFCompareEqualTo == CFStringCompare(pixelEncoding, CFSTR(kIO32BitFloatPixels), kCFCompareCaseInsensitive)) {
        depth = 96;
    } else if (kCFCompareEqualTo == CFStringCompare(pixelEncoding, CFSTR(kIO64BitDirectPixels), kCFCompareCaseInsensitive)) {
        depth = 64;
    } else if (kCFCompareEqualTo == CFStringCompare(pixelEncoding, CFSTR(kIO16BitFloatPixels), kCFCompareCaseInsensitive)) {
        depth = 48;
    } else if (kCFCompareEqualTo == CFStringCompare(pixelEncoding, CFSTR(IO32BitDirectPixels), kCFCompareCaseInsensitive)) {
        depth = 32;
    } else if (kCFCompareEqualTo == CFStringCompare(pixelEncoding, CFSTR(kIO30BitDirectPixels), kCFCompareCaseInsensitive)) {
        depth = 30;
    } else if (kCFCompareEqualTo == CFStringCompare(pixelEncoding, CFSTR(IO16BitDirectPixels), kCFCompareCaseInsensitive)) {
        depth = 16;
    } else if (kCFCompareEqualTo == CFStringCompare(pixelEncoding, CFSTR(IO8BitIndexedPixels), kCFCompareCaseInsensitive)) {
        depth = 8;
    }
    CFRelease(pixelEncoding);
    return depth;
}
예제 #13
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;
}
/*
 * xprAddScreen
 *  Init the framebuffer and record pixmap parameters for the screen.
 */
static Bool
xprAddScreen(int index, ScreenPtr pScreen)
{
    DarwinFramebufferPtr dfb = SCREEN_PRIV(pScreen);
    int depth = darwinDesiredDepth;

    DEBUG_LOG("index=%d depth=%d\n", index, depth);
    
    if(depth == -1) {
#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
        depth = CGDisplaySamplesPerPixel(kCGDirectMainDisplay) * CGDisplayBitsPerSample(kCGDirectMainDisplay);
#else
        CGDisplayModeRef modeRef;
        CFStringRef encStrRef;
        
        modeRef = CGDisplayCopyDisplayMode(kCGDirectMainDisplay);
        if(!modeRef)
            goto have_depth;

        encStrRef = CGDisplayModeCopyPixelEncoding(modeRef);
        CFRelease(modeRef);
        if(!encStrRef)
            goto have_depth;
        
        if(CFStringCompare(encStrRef, CFSTR(IO32BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
            depth = 24;
        } else if(CFStringCompare(encStrRef, CFSTR(IO16BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
            depth = 15;
        } else if(CFStringCompare(encStrRef, CFSTR(IO8BitIndexedPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
            depth = 8;
        }

        CFRelease(encStrRef);
#endif
    }
    
have_depth:
    switch(depth) {
        case 8: // pseudo-working
            dfb->visuals = PseudoColorMask;
            dfb->preferredCVC = PseudoColor;
            dfb->depth = 8;
            dfb->bitsPerRGB = 8;
            dfb->bitsPerPixel = 8;
            dfb->redMask = 0;
            dfb->greenMask = 0;
            dfb->blueMask = 0;
            break;
        case 15:
            dfb->visuals = TrueColorMask; //LARGE_VISUALS;
            dfb->preferredCVC = TrueColor;
            dfb->depth = 15;
            dfb->bitsPerRGB = 5;
            dfb->bitsPerPixel = 16;
            dfb->redMask   = RM_ARGB(0,5,5,5);
            dfb->greenMask = GM_ARGB(0,5,5,5);
            dfb->blueMask  = BM_ARGB(0,5,5,5);
            break;
//        case 24:
        default:
            if(depth != 24)
                ErrorF("Unsupported color depth requested.  Defaulting to 24bit. (depth=%d darwinDesiredDepth=%d)\n", depth, darwinDesiredDepth);
            dfb->visuals = TrueColorMask; //LARGE_VISUALS;
            dfb->preferredCVC = TrueColor;
            dfb->depth = 24;
            dfb->bitsPerRGB = 8;
            dfb->bitsPerPixel = 32;
            dfb->redMask   = RM_ARGB(0,8,8,8);
            dfb->greenMask = GM_ARGB(0,8,8,8);
            dfb->blueMask  = BM_ARGB(0,8,8,8);
            break;
    }

    if (noPseudoramiXExtension)
    {
        CGDirectDisplayID dpy;
        CGRect frame;

        ErrorF("Warning: noPseudoramiXExtension!\n");
        
        dpy = displayAtIndex(index);
        QuartzCopyDisplayIDs(pScreen, 1, &dpy);

        frame = displayScreenBounds(dpy);

        dfb->x = frame.origin.x;
        dfb->y = frame.origin.y;
        dfb->width =  frame.size.width;
        dfb->height = frame.size.height;
    }
    else
    {
        xprAddPseudoramiXScreens(&dfb->x, &dfb->y, &dfb->width, &dfb->height, pScreen);
    }

    /* Passing zero width (pitch) makes miCreateScreenResources set the
       screen pixmap to the framebuffer pointer, i.e. NULL. The generic
       rootless code takes care of making this work. */
    dfb->pitch = 0;
    dfb->framebuffer = NULL;

    DRIScreenInit(pScreen);

    return TRUE;
}
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();
}
예제 #16
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;
}
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;
		}
	}
}
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;
}
예제 #19
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;
}
예제 #20
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;
}
예제 #21
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;
}
예제 #22
0
MMBitmapRef copyMMBitmapFromDisplayInRect(MMRect rect)
{
#if defined(IS_MACOSX)

	size_t bytewidth;
	uint8_t bitsPerPixel, bytesPerPixel;
	uint8_t *buffer;

	CGDirectDisplayID displayID = CGMainDisplayID();

	//Replacement for CGDisplayBitsPerPixel. 
	CGDisplayModeRef mode = CGDisplayCopyDisplayMode(displayID);
	size_t depth = 0;
	
	CFStringRef pixEnc = CGDisplayModeCopyPixelEncoding(mode);
	if(CFStringCompare(pixEnc, CFSTR(IO32BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo)
		depth = 32;
	else if(CFStringCompare(pixEnc, CFSTR(IO16BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo)
		depth = 16;
	else if(CFStringCompare(pixEnc, CFSTR(IO8BitIndexedPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo)
		depth = 8;

	bitsPerPixel = (uint8_t) depth; 
	bytesPerPixel = bitsPerPixel / 8;
	/* Align width to padding. */
	bytewidth = ADD_PADDING(rect.size.width * bytesPerPixel);

	/* Convert Quartz point to postscript point. */
	rect.origin.y = CGDisplayPixelsHigh(displayID) - rect.origin.y - rect.size.height;

	CGImageRef image = CGDisplayCreateImageForRect(displayID, CGRectMake(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height));

    // Request access to the raw pixel data via the image's DataProvider.
    CGDataProviderRef provider = CGImageGetDataProvider(image);
    CFDataRef data = CGDataProviderCopyData(provider);

    size_t width, height;    
    width = CGImageGetWidth(image);
    height = CGImageGetHeight(image); 
    size_t bpp = CGImageGetBitsPerPixel(image) / 8;

    uint8 *pixels = malloc(width * height * bpp);
    memcpy(pixels, CFDataGetBytePtr(data), width * height * bpp);
    CFRelease(data); 
   	CGImageRelease(image); 

	return createMMBitmap(pixels, rect.size.width, rect.size.height, bytewidth,
	                      bitsPerPixel, bytesPerPixel);
#elif defined(USE_X11)
	MMBitmapRef bitmap;

	Display *display = XOpenDisplay(NULL);
	XImage *image = XGetImage(display,
	                          XDefaultRootWindow(display),
	                          (int)rect.origin.x,
	                          (int)rect.origin.y,
	                          (unsigned int)rect.size.width,
	                          (unsigned int)rect.size.height,
	                          AllPlanes, ZPixmap);
	XCloseDisplay(display);
	if (image == NULL) return NULL;

	bitmap = createMMBitmap((uint8_t *)image->data,
	                        rect.size.width,
	                        rect.size.height,
	                        (size_t)image->bytes_per_line,
	                        (uint8_t)image->bits_per_pixel,
	                        (uint8_t)image->bits_per_pixel / 8);
	image->data = NULL; /* Steal ownership of bitmap data so we don't have to
	                     * copy it. */
	XDestroyImage(image);

	return bitmap;
#elif defined(IS_WINDOWS)
	MMBitmapRef bitmap;
	void *data;
	HDC screen = NULL, screenMem = NULL;
	HBITMAP dib;
	BITMAPINFO bi;

	/* Initialize bitmap info. */
	bi.bmiHeader.biSize = sizeof(bi.bmiHeader);
   	bi.bmiHeader.biWidth = (long)rect.size.width;
   	bi.bmiHeader.biHeight = -(long)rect.size.height; /* Non-cartesian, please */
   	bi.bmiHeader.biPlanes = 1;
   	bi.bmiHeader.biBitCount = 32;
   	bi.bmiHeader.biCompression = BI_RGB;
   	bi.bmiHeader.biSizeImage = (DWORD)(4 * rect.size.width * rect.size.height);
	bi.bmiHeader.biXPelsPerMeter = 0;
	bi.bmiHeader.biYPelsPerMeter = 0;
	bi.bmiHeader.biClrUsed = 0;
	bi.bmiHeader.biClrImportant = 0;

	screen = GetDC(NULL); /* Get entire screen */
	if (screen == NULL) return NULL;

	/* Get screen data in display device context. */
   	dib = CreateDIBSection(screen, &bi, DIB_RGB_COLORS, &data, NULL, 0);

	/* Copy the data into a bitmap struct. */
	if ((screenMem = CreateCompatibleDC(screen)) == NULL ||
	    SelectObject(screenMem, dib) == NULL ||
	    !BitBlt(screenMem, 
	            (int)rect.origin.x, 
	            (int)rect.origin.y, 
	            (int)rect.size.width,
	            (int)rect.size.height, screen, 0, 0, SRCCOPY)) {
		/* Error copying data. */
		ReleaseDC(NULL, screen);
		DeleteObject(dib);
		if (screenMem != NULL) DeleteDC(screenMem);

		return NULL;
	}

	bitmap = createMMBitmap(NULL,
	                        rect.size.width,
	                        rect.size.height,
	                        4 * rect.size.width,
	                        (uint8_t)bi.bmiHeader.biBitCount, 
	                        4);

	/* Copy the data to our pixel buffer. */
	if (bitmap != NULL) {
		bitmap->imageBuffer = malloc(bitmap->bytewidth * bitmap->height);
		memcpy(bitmap->imageBuffer, data, bitmap->bytewidth * bitmap->height);
	}

	ReleaseDC(NULL, screen);
	DeleteObject(dib);
	DeleteDC(screenMem);

	return bitmap;
#endif
}