mirror of
https://github.com/glfw/glfw.git
synced 2024-11-22 10:05:10 +00:00
Cocoa: Monitor name cleanup
Only retrieve the display info dictionary once. Remove non-standard function name.
This commit is contained in:
parent
94b8486d4b
commit
d19a21bd01
@ -116,6 +116,8 @@ information on what to include when reporting a bug.
|
|||||||
- [Cocoa] Added support for Vulkan window surface creation via MoltenVK (#870)
|
- [Cocoa] Added support for Vulkan window surface creation via MoltenVK (#870)
|
||||||
- [Cocoa] Bugfix: Disabling window aspect ratio would assert (#852)
|
- [Cocoa] Bugfix: Disabling window aspect ratio would assert (#852)
|
||||||
- [Cocoa] Bugfix: Window creation failed to set first responder (#876,#883)
|
- [Cocoa] Bugfix: Window creation failed to set first responder (#876,#883)
|
||||||
|
- [Cocoa] Bugfix: Removed use of deprecated `CGDisplayIOServicePort` function
|
||||||
|
(#165,#192,#508,#511)
|
||||||
- [EGL] Added support for `EGL_KHR_get_all_proc_addresses` (#871)
|
- [EGL] Added support for `EGL_KHR_get_all_proc_addresses` (#871)
|
||||||
|
|
||||||
|
|
||||||
|
@ -36,108 +36,82 @@
|
|||||||
#include <ApplicationServices/ApplicationServices.h>
|
#include <ApplicationServices/ApplicationServices.h>
|
||||||
|
|
||||||
|
|
||||||
// Returns the io_service_t corresponding to a CG display ID, or 0 on failure.
|
// Get the name of the specified display, or NULL
|
||||||
// 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 char* getDisplayName(CGDirectDisplayID displayID)
|
static char* getDisplayName(CGDirectDisplayID displayID)
|
||||||
{
|
{
|
||||||
char* name;
|
io_iterator_t it;
|
||||||
CFDictionaryRef info, names;
|
io_service_t service;
|
||||||
CFStringRef value;
|
CFDictionaryRef info;
|
||||||
CFIndex size;
|
|
||||||
|
|
||||||
io_service_t serv = IOServicePortFromCGDisplayID(displayID);
|
if (IOServiceGetMatchingServices(kIOMasterPortDefault,
|
||||||
if (!serv)
|
IOServiceMatching("IODisplayConnect"),
|
||||||
|
&it) != 0)
|
||||||
{
|
{
|
||||||
return strdup("Unknown");
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Cocoa: Failed to get display service port iterator");
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
info = IODisplayCreateInfoDictionary(serv,
|
while ((service = IOIteratorNext(it)) != 0)
|
||||||
kIODisplayOnlyPreferredName);
|
{
|
||||||
|
info = IODisplayCreateInfoDictionary(service, kIODisplayOnlyPreferredName);
|
||||||
|
|
||||||
IOObjectRelease(serv);
|
CFNumberRef vendorIDRef =
|
||||||
|
CFDictionaryGetValue(info, CFSTR(kDisplayVendorID));
|
||||||
|
CFNumberRef productIDRef =
|
||||||
|
CFDictionaryGetValue(info, CFSTR(kDisplayProductID));
|
||||||
|
if (!vendorIDRef || !productIDRef)
|
||||||
|
{
|
||||||
|
CFRelease(info);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
names = CFDictionaryGetValue(info, CFSTR(kDisplayProductName));
|
unsigned int vendorID, productID;
|
||||||
|
CFNumberGetValue(vendorIDRef, kCFNumberIntType, &vendorID);
|
||||||
|
CFNumberGetValue(productIDRef, kCFNumberIntType, &productID);
|
||||||
|
|
||||||
|
if (CGDisplayVendorNumber(displayID) == vendorID &&
|
||||||
|
CGDisplayModelNumber(displayID) == productID)
|
||||||
|
{
|
||||||
|
// Info dictionary is used and freed below
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
CFRelease(info);
|
||||||
|
}
|
||||||
|
|
||||||
|
IOObjectRelease(it);
|
||||||
|
|
||||||
|
if (!service)
|
||||||
|
{
|
||||||
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
|
"Cocoa: Failed to find service port for display");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
CFDictionaryRef names =
|
||||||
|
CFDictionaryGetValue(info, CFSTR(kDisplayProductName));
|
||||||
|
|
||||||
|
CFStringRef nameRef;
|
||||||
|
|
||||||
if (!names || !CFDictionaryGetValueIfPresent(names, CFSTR("en_US"),
|
if (!names || !CFDictionaryGetValueIfPresent(names, CFSTR("en_US"),
|
||||||
(const void**) &value))
|
(const void**) &nameRef))
|
||||||
{
|
{
|
||||||
// This may happen if a desktop Mac is running headless
|
// This may happen if a desktop Mac is running headless
|
||||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||||
"Cocoa: Failed to retrieve display name");
|
"Cocoa: Failed to retrieve display name");
|
||||||
|
|
||||||
CFRelease(info);
|
CFRelease(info);
|
||||||
return strdup("Unknown");
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
size = CFStringGetMaximumSizeForEncoding(CFStringGetLength(value),
|
const CFIndex size =
|
||||||
kCFStringEncodingUTF8);
|
CFStringGetMaximumSizeForEncoding(CFStringGetLength(nameRef),
|
||||||
name = calloc(size + 1, 1);
|
kCFStringEncodingUTF8);
|
||||||
CFStringGetCString(value, name, size, kCFStringEncodingUTF8);
|
char* name = calloc(size + 1, 1);
|
||||||
|
CFStringGetCString(nameRef, name, size, kCFStringEncodingUTF8);
|
||||||
|
|
||||||
CFRelease(info);
|
CFRelease(info);
|
||||||
|
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -332,6 +306,8 @@ _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)
|
||||||
|
name = strdup("Unknown");
|
||||||
|
|
||||||
monitor = _glfwAllocMonitor(name, size.width, size.height);
|
monitor = _glfwAllocMonitor(name, size.width, size.height);
|
||||||
monitor->ns.displayID = displays[i];
|
monitor->ns.displayID = displays[i];
|
||||||
|
Loading…
Reference in New Issue
Block a user