Cocoa: Replace deprecated CGDisplayIOServicePort

This replaces CGDisplayIOServicePort with manually finding a service
port with matching vendor and product IDs.  This may technically not be
the one corresponding to the display ID, but it is only used to retrieve
the human-readable make/model string.

This could be cleaned up and refined a bit by comparing more display
attributes when available, but it gets the job done.

Fixes #165.
Closes #192.
Closes #508.
Closes #511.
This commit is contained in:
Matthew Henry 2013-12-14 01:03:39 +10:00 committed by Camilla Berglund
parent cce430fbfa
commit 94b8486d4b

View File

@ -36,6 +36,68 @@
#include <ApplicationServices/ApplicationServices.h> #include <ApplicationServices/ApplicationServices.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 // Get the name of the specified display
// //
static char* getDisplayName(CGDirectDisplayID displayID) static char* getDisplayName(CGDirectDisplayID displayID)
@ -45,10 +107,17 @@ static char* getDisplayName(CGDirectDisplayID displayID)
CFStringRef value; CFStringRef value;
CFIndex size; CFIndex size;
// NOTE: This uses a deprecated function because Apple has io_service_t serv = IOServicePortFromCGDisplayID(displayID);
// (as of January 2015) not provided any alternative if (!serv)
info = IODisplayCreateInfoDictionary(CGDisplayIOServicePort(displayID), {
return strdup("Unknown");
}
info = IODisplayCreateInfoDictionary(serv,
kIODisplayOnlyPreferredName); kIODisplayOnlyPreferredName);
IOObjectRelease(serv);
names = CFDictionaryGetValue(info, CFSTR(kDisplayProductName)); names = CFDictionaryGetValue(info, CFSTR(kDisplayProductName));
if (!names || !CFDictionaryGetValueIfPresent(names, CFSTR("en_US"), if (!names || !CFDictionaryGetValueIfPresent(names, CFSTR("en_US"),