Cleanup of CGDisplayIOServicePort replacement.
This commit is contained in:
parent
bebae14223
commit
43095307da
@ -123,6 +123,7 @@ skills.
|
||||
- Marcus Geelnard
|
||||
- Stefan Gustavson
|
||||
- Sylvain Hellegouarch
|
||||
- Matthew Henry
|
||||
- heromyth
|
||||
- Paul Holden
|
||||
- Toni Jovanoski
|
||||
|
@ -36,110 +36,74 @@
|
||||
#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.
|
||||
// Returns the name of the specified display
|
||||
//
|
||||
static io_service_t IOServicePortFromCGDisplayID(CGDirectDisplayID displayID)
|
||||
static char* getDisplayName(CGDirectDisplayID displayID)
|
||||
{
|
||||
io_iterator_t iter;
|
||||
io_service_t serv, servicePort = 0;
|
||||
|
||||
io_service_t service;
|
||||
char* result = NULL;
|
||||
|
||||
const uint32_t modelNumber = CGDisplayModelNumber(displayID);
|
||||
const uint32_t vendorNumber = CGDisplayVendorNumber(displayID);
|
||||
|
||||
if (modelNumber == kDisplayProductIDGeneric || modelNumber == 0xffffffff ||
|
||||
vendorNumber == kDisplayVendorIDUnknown || vendorNumber == 0xffffffff)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
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)
|
||||
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;
|
||||
}
|
||||
|
||||
if (CGDisplayVendorNumber(displayID) != vendorID ||
|
||||
CGDisplayModelNumber(displayID) != productID)
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// we're a match
|
||||
servicePort = serv;
|
||||
|
||||
size = CFStringGetMaximumSizeForEncoding(CFStringGetLength(name),
|
||||
kCFStringEncodingUTF8);
|
||||
result = calloc(size + 1, sizeof(char));
|
||||
CFStringGetCString(name, result, size, kCFStringEncodingUTF8);
|
||||
|
||||
CFRelease(info);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
IOObjectRelease(iter);
|
||||
return servicePort;
|
||||
return result;
|
||||
}
|
||||
|
||||
// Get the name of the specified display
|
||||
//
|
||||
static const char* getDisplayName(CGDirectDisplayID displayID)
|
||||
{
|
||||
char* name;
|
||||
CFDictionaryRef info, names;
|
||||
CFStringRef value;
|
||||
CFIndex size;
|
||||
|
||||
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))
|
||||
{
|
||||
// This may happen if a desktop Mac is running headless
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "Failed to retrieve display name");
|
||||
CFRelease(info);
|
||||
return strdup("Unknown");
|
||||
}
|
||||
|
||||
size = CFStringGetMaximumSizeForEncoding(CFStringGetLength(value),
|
||||
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)
|
||||
@ -332,10 +296,16 @@ _GLFWmonitor** _glfwPlatformGetMonitors(int* count)
|
||||
{
|
||||
int j;
|
||||
const CGSize size = CGDisplayScreenSize(displays[i]);
|
||||
char* name = getDisplayName(displays[i]);
|
||||
|
||||
monitors[found] = _glfwAllocMonitor(getDisplayName(displays[i]),
|
||||
size.width, size.height);
|
||||
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]->ns.displayID = displays[i];
|
||||
|
||||
for (j = 0; j < [screens count]; j++)
|
||||
|
Loading…
Reference in New Issue
Block a user