From a2942450dcebe6177aa05b4e8e1c0a7c5d569e50 Mon Sep 17 00:00:00 2001 From: Naresh R Date: Sat, 6 Jun 2020 17:12:23 +0530 Subject: [PATCH 1/2] Avoid de-reference in _compareCFDisplayModes Currently, the _compareCFDisplayModes method uses CGDisplayModeRef* as the first and second parameters, in alignment with the CFComparatorFunction type alias declaration expecting an UnsafeRawPointer. But CGDisplayModeRef is already a pointer to CGDisplayMode and doesn't need a reference again to work as a comparator. Doing so also introduces extra referencing and dereferencing that can be avoided. Update the method signature to pass CGDisplayModeRef directly. --- cg_utils.c | 5 +---- cg_utils.h | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/cg_utils.c b/cg_utils.c index 4fef025..899022c 100644 --- a/cg_utils.c +++ b/cg_utils.c @@ -136,11 +136,8 @@ unsigned int parseStringConfig(const char *string, struct config *out) { return rc; } -CFComparisonResult _compareCFDisplayModes (CGDisplayModeRef *mode1Ptr, CGDisplayModeRef *mode2Ptr, void *context) +CFComparisonResult _compareCFDisplayModes (CGDisplayModeRef mode1, CGDisplayModeRef mode2, void *context) { - CGDisplayModeRef mode1 = (CGDisplayModeRef)mode1Ptr; - CGDisplayModeRef mode2 = (CGDisplayModeRef)mode2Ptr; - size_t width1 = CGDisplayModeGetWidth(mode1); size_t width2 = CGDisplayModeGetWidth(mode2); diff --git a/cg_utils.h b/cg_utils.h index d050961..6a42fc8 100644 --- a/cg_utils.h +++ b/cg_utils.h @@ -42,6 +42,6 @@ unsigned int configureDisplay(CGDirectDisplayID display, int displayNum); unsigned int parseStringConfig(const char *string, struct config *out); size_t bitDepth(CGDisplayModeRef mode); -CFComparisonResult _compareCFDisplayModes (CGDisplayModeRef *mode1Ptr, CGDisplayModeRef *mode2Ptr, void *context); +CFComparisonResult _compareCFDisplayModes (CGDisplayModeRef mode1, CGDisplayModeRef mode2, void *context); #endif \ No newline at end of file From cc16458aa083e7bdcc61057a5607da5a67a6b679 Mon Sep 17 00:00:00 2001 From: Naresh R Date: Sat, 6 Jun 2020 17:28:52 +0530 Subject: [PATCH 2/2] Fetch max supported mode for each monitor Newer versions of MacOS use a scaling factor (like 2x, which is the default for newer MacBooks), leading to the default mode being half the native resolution of the display. In such cases, it would be desirable to fetch the maximum resolution supported by the display (native resolution). Add a getMax option to fetch this information. --- main.c | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/main.c b/main.c index c4cecc6..58060d2 100644 --- a/main.c +++ b/main.c @@ -30,6 +30,7 @@ unsigned int listAvailableModes(CGDirectDisplayID display, int displayNum); unsigned int listCurrentMode(CGDirectDisplayID display, int displayNum); +unsigned int listMaxSupported(CGDirectDisplayID display, int displayNum); int main(int argc, const char *argv[]) { // http://developer.apple.com/library/IOs/#documentation/CoreFoundation/Conceptual/CFStrings/Articles/MutableStrings.html @@ -77,6 +78,10 @@ int main(int argc, const char *argv[]) { if (!listCurrentMode(activeDisplays[d], d)) { exitcode++; } + } else if (strcmp(argv[1], "getMax") == 0) { + if (!listMaxSupported(activeDisplays[d], d)) { + exitcode++; + } } else if (strcmp(argv[1], "list") == 0) { if (!listAvailableModes(activeDisplays[d], d)) { exitcode++; @@ -131,6 +136,42 @@ unsigned int listCurrentMode(CGDirectDisplayID display, int displayNum) { return returncode; } +unsigned int listMaxSupported(CGDirectDisplayID display, int displayNum) { + unsigned int returncode = 1; + CGDisplayModeRef maxSupportedMode = CGDisplayCopyDisplayMode(display); + + CFStringRef keys[1] = { kCGDisplayShowDuplicateLowResolutionModes }; + CFBooleanRef values[1] = { kCFBooleanTrue }; + CFDictionaryRef options = CFDictionaryCreate( + kCFAllocatorDefault, (const void**) keys, (const void**) values, 1, + &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + CFArrayRef allModes = CGDisplayCopyAllDisplayModes(display, options); + if (allModes == NULL) { + NSLog(CFSTR("Error: failed trying to look up modes for display %u"), displayNum); + } + + CFIndex displayModeCount = CFArrayGetCount(allModes); + for (int i = 0; i < displayModeCount; ++i) { + CGDisplayModeRef mode = (CGDisplayModeRef)CFArrayGetValueAtIndex(allModes, i); + CFComparisonResult result = _compareCFDisplayModes(mode, maxSupportedMode, NULL); + if (result == kCFCompareGreaterThan) { + maxSupportedMode = CGDisplayModeRetain(mode); + } + } + + NSLog(CFSTR("Display %d: %ux%ux%u@%.0f"), + displayNum, + CGDisplayModeGetWidth(maxSupportedMode), + CGDisplayModeGetHeight(maxSupportedMode), + bitDepth(maxSupportedMode), + CGDisplayModeGetRefreshRate(maxSupportedMode)); + + CFRelease(allModes); + CFRelease(options); + CGDisplayModeRelease(maxSupportedMode); + return returncode; +} + unsigned int listAvailableModes(CGDirectDisplayID display, int displayNum) { unsigned int returncode = 1; int numModes = 0;