Skip to content

Commit

Permalink
Replace CGDisplayIOServicePort with a workaround implementation
Browse files Browse the repository at this point in the history
This could be cleaned up and refined a bit by comparing more display
attributes when available, but it gets the job done.
  • Loading branch information
mhenr18 committed Dec 13, 2013
1 parent cf458fa commit 8101d7a
Showing 1 changed file with 82 additions and 11 deletions.
93 changes: 82 additions & 11 deletions src/cocoa_monitor.m
Expand Up @@ -36,6 +36,68 @@
#include <CoreVideo/CVDisplayLink.h>


// Returns the io_service_t corresponding to a CG display ID, or 0 on failure.
// The io_service_t should be released with IOObjectRelease when not needed.
//
static io_service_t IOServicePortFromCGDisplayID(CGDirectDisplayID displayID)
{
io_iterator_t iter;
io_service_t serv, servicePort = 0;

CFMutableDictionaryRef matching = IOServiceMatching("IODisplayConnect");

// releases matching for us
kern_return_t err = IOServiceGetMatchingServices(kIOMasterPortDefault,
matching,
&iter);
if (err)
{
return 0;
}

while ((serv = IOIteratorNext(iter)) != 0)
{
CFDictionaryRef info;
CFIndex vendorID, productID;
CFNumberRef vendorIDRef, productIDRef;
Boolean success;

info = IODisplayCreateInfoDictionary(serv,
kIODisplayOnlyPreferredName);

vendorIDRef = CFDictionaryGetValue(info,
CFSTR(kDisplayVendorID));
productIDRef = CFDictionaryGetValue(info,
CFSTR(kDisplayProductID));

success = CFNumberGetValue(vendorIDRef, kCFNumberCFIndexType,
&vendorID);
success &= CFNumberGetValue(productIDRef, kCFNumberCFIndexType,
&productID);

if (!success)
{
CFRelease(info);
continue;
}

if (CGDisplayVendorNumber(displayID) != vendorID ||
CGDisplayModelNumber(displayID) != productID)
{
CFRelease(info);
continue;
}

// we're a match
servicePort = serv;
CFRelease(info);
break;
}

IOObjectRelease(iter);
return servicePort;
}

// Get the name of the specified display
//
static const char* getDisplayName(CGDirectDisplayID displayID)
Expand All @@ -44,30 +106,39 @@
CFDictionaryRef info, names;
CFStringRef value;
CFIndex size;

info = IODisplayCreateInfoDictionary(CGDisplayIOServicePort(displayID),
kIODisplayOnlyPreferredName);

io_service_t serv = IOServicePortFromCGDisplayID(displayID);
if (!serv)
{
return strdup("Unknown");
}

info = IODisplayCreateInfoDictionary(serv,
kIODisplayOnlyPreferredName);

IOObjectRelease(serv);

names = CFDictionaryGetValue(info, CFSTR(kDisplayProductName));

if (!names || !CFDictionaryGetValueIfPresent(names, CFSTR("en_US"),
(const void**) &value))
(const void**) &value))
{
_glfwInputError(GLFW_PLATFORM_ERROR, "Failed to retrieve display name");


CFRelease(info);
return strdup("Unknown");
}

size = CFStringGetMaximumSizeForEncoding(CFStringGetLength(value),
kCFStringEncodingUTF8);
kCFStringEncodingUTF8);
name = calloc(size + 1, sizeof(char));
CFStringGetCString(value, name, size, kCFStringEncodingUTF8);

CFRelease(info);

return name;
}


// Check whether the display mode should be included in enumeration
//
static GLboolean modeIsGood(CGDisplayModeRef mode)
Expand Down

0 comments on commit 8101d7a

Please sign in to comment.