The proposed fix broke for multiple displays of the same model.
This commit is contained in:
Camilla Berglund 2014-03-19 23:24:48 +01:00
parent 7ebd10a868
commit aaac715060
1 changed files with 21 additions and 63 deletions

View File

@ -36,72 +36,37 @@
#include <CoreVideo/CVDisplayLink.h> #include <CoreVideo/CVDisplayLink.h>
// Returns the name of the specified display // Get the name of the specified display
// //
static char* getDisplayName(CGDirectDisplayID displayID) static char* getDisplayName(CGDirectDisplayID displayID)
{ {
io_iterator_t iter; char* name;
io_service_t service; CFDictionaryRef info, names;
char* result = NULL; CFStringRef value;
CFIndex size;
const uint32_t modelNumber = CGDisplayModelNumber(displayID); info = IODisplayCreateInfoDictionary(CGDisplayIOServicePort(displayID),
const uint32_t vendorNumber = CGDisplayVendorNumber(displayID); kIODisplayOnlyPreferredName);
names = CFDictionaryGetValue(info, CFSTR(kDisplayProductName));
if (modelNumber == kDisplayProductIDGeneric || modelNumber == 0xffffffff || if (!names || !CFDictionaryGetValueIfPresent(names, CFSTR("en_US"),
vendorNumber == kDisplayVendorIDUnknown || vendorNumber == 0xffffffff) (const void**) &value))
{ {
return NULL; // This may happen if a desktop Mac is running headless
} _glfwInputError(GLFW_PLATFORM_ERROR, "Failed to retrieve display name");
CFMutableDictionaryRef matching = IOServiceMatching("IODisplayConnect");
if (IOServiceGetMatchingServices(kIOMasterPortDefault, matching, &iter) != 0)
return NULL;
while ((service = IOIteratorNext(iter)) != 0)
{
CFIndex size, vendorID, productID;
CFDictionaryRef info, names;
CFStringRef name;
info = IODisplayCreateInfoDictionary(service, kIODisplayOnlyPreferredName);
CFNumberGetValue(CFDictionaryGetValue(info, CFSTR(kDisplayVendorID)),
kCFNumberCFIndexType, &vendorID);
CFNumberGetValue(CFDictionaryGetValue(info, CFSTR(kDisplayProductID)),
kCFNumberCFIndexType, &productID);
if (vendorNumber != vendorID || modelNumber != productID)
{
CFRelease(info);
continue;
}
names = CFDictionaryGetValue(info, CFSTR(kDisplayProductName));
if (!names)
{
// This may happen if a desktop Mac is running headless
CFRelease(info);
continue;
}
if (!CFDictionaryGetValueIfPresent(names, CFSTR("en_US"),
(const void**) &name))
{
CFRelease(info);
continue;
}
size = CFStringGetMaximumSizeForEncoding(CFStringGetLength(name),
kCFStringEncodingUTF8);
result = calloc(size + 1, sizeof(char));
CFStringGetCString(name, result, size, kCFStringEncodingUTF8);
CFRelease(info); CFRelease(info);
return strdup("Unknown");
} }
IOObjectRelease(iter); size = CFStringGetMaximumSizeForEncoding(CFStringGetLength(value),
return result; 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 // Check whether the display mode should be included in enumeration
@ -298,13 +263,6 @@ _GLFWmonitor** _glfwPlatformGetMonitors(int* count)
const CGSize size = CGDisplayScreenSize(displays[i]); const CGSize size = CGDisplayScreenSize(displays[i]);
char* name = getDisplayName(displays[i]); char* name = getDisplayName(displays[i]);
if (!name)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Cocoa: Failed to retrieve display name");
name = strdup("Unknown");
}
monitors[found] = _glfwAllocMonitor(name, size.width, size.height); monitors[found] = _glfwAllocMonitor(name, size.width, size.height);
monitors[found]->ns.displayID = displays[i]; monitors[found]->ns.displayID = displays[i];