We used to have a cool function that would give us the best match for a given resolution, it’s deprecated so let’s work around it. Again Apple failed to provide a documented example so here is one:
struct screenMode { size_t width; size_t height; size_t bitsPerPixel; }; - (size_t) displayBitsPerPixelForMode: (CGDisplayModeRef) mode { 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; return depth; } - (CGDisplayModeRef) bestMatchForMode: (struct screenMode) screenMode { bool exactMatch = false; // 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); if([self displayBitsPerPixelForMode: mode] != screenMode.bitsPerPixel) continue; if((CGDisplayModeGetWidth(mode) >= screenMode.width) && (CGDisplayModeGetHeight(mode) >= screenMode.height)) { displayMode = mode; exactMatch = true; break; } } // No depth match was found if(!exactMatch) { for(int i = 0; i < CFArrayGetCount(allModes); i++) { CGDisplayModeRef mode = (CGDisplayModeRef)CFArrayGetValueAtIndex(allModes, i); if([self displayBitsPerPixelForMode: mode] >= screenMode.bitsPerPixel) continue; if((CGDisplayModeGetWidth(mode) >= screenMode.width) && (CGDisplayModeGetHeight(mode) >= screenMode.height)) { displayMode = mode; break; } } } return displayMode; }
Now, now Apple, this was a lot easier before
Your code is leaking the return value from CGDisplayCopyDisplayMode()
You’re absolutely right, i call this code only on startup so i hadn’t noticed since there were more significant parts to fix.
Thanks for the pointer!
[…] Taming Snow Leopard: CGDisplayBestModeForParameters deprecation January 2010 2 comments […]