DMGetNameByAVID deprecated in 10.4
I've been using it for a long time to get the name of the connected monitors. In Displays.h it says it's been deprecated in 10.4. I can't seem to find a replacement. Does anybody know what to use instead?
Since Apple seems to be tossing Display Manager in the circular file and I still haven't found a way to get the proper name ( e.g. "Apple Display" or "Studio Display 21", etc. ) of any connected displays I'll try to get by without it. I'll iterate over them as they are returned from CGGetActiveDisplayList and just label them in order as "Main Display", "Display 2", "Display 3", and so on, since CGDirectDisplay.h says the first one returned in the array is the main display. Not perfect, but I guess it'll have to suffice unless someone has a better idea...
You can get the information you want from the IOKit. I haven't quite figured it out yet, but I'll take a closer look when I get home. The function you need (IODisplayCreateInfoDictionary) is declared in /System/Library/Frameworks/IOKit.framework/Headers/graphics/IOGraphicsLib.h
OK, here's a little program that'll loop through your framebuffers and print the names of the displays attached to each:
The question now is, how to associate this information with a CGDirectDisplayID?
Code:
#include <stdio.h>
#include <stdlib.h>
#include <IOKit/IOKitLib.h>
#include <IOKit/graphics/IOGraphicsLib.h>
#define QUIT_IF(condition) \
if (condition) \
{ \
printf("%s on line %d of %s\n", #condition, __LINE__, __FILE__); \
exit(EXIT_FAILURE); \
}
#define QUIT_ON_IOERROR(x) QUIT_IF((x) != kIOReturnSuccess)
#define QUIT_ON_NULL(x) QUIT_IF((x) == NULL)
int main(int argc, const char *argv[])
{
kern_return_t result;
CFMutableDictionaryRef matching_dictionary;
matching_dictionary = IOServiceMatching(IOFRAMEBUFFER_CONFORMSTO);
QUIT_ON_NULL(matching_dictionary);
io_iterator_t iterator;
result = IOServiceGetMatchingServices(
kIOMasterPortDefault,
matching_dictionary,
&iterator);
QUIT_ON_IOERROR(result);
io_service_t service;
service = (io_service_t)IOIteratorNext(iterator);
while (service != 0)
{
CFDictionaryRef display_dictionary;
display_dictionary = IODisplayCreateInfoDictionary(
service,
kIODisplayOnlyPreferredName);
QUIT_ON_NULL(display_dictionary);
//CFShow(display_dictionary);
CFDictionaryRef product_names_dictionary;
product_names_dictionary = CFDictionaryGetValue(
display_dictionary,
CFSTR(kDisplayProductName));
if (product_names_dictionary != NULL)
{
QUIT_IF(CFDictionaryGetCount(product_names_dictionary) != 1);
CFStringRef product_name;
CFDictionaryGetKeysAndValues(
product_names_dictionary,
NULL,
(const void**)&product_name);
QUIT_ON_NULL(product_name);
CFShow(product_name);
}
service = (io_service_t)IOIteratorNext(iterator);
}
IOObjectRelease(iterator);
}The question now is, how to associate this information with a CGDirectDisplayID?
... and I can't find any way to. Maybe, just maybe, by messing with undocumented CGS APIs there might be a way, but I can't find one. Fat lot of use that is
How about CGDisplayIOServicePort? I've never used the IOKit before, but that function does take a DisplayID and returns a io_service_t
Could be helpful,
Adam Zegelin
Could be helpful,
Adam Zegelin
YES! Much thanks to both of you!
I haven't written it for multiple displays or error conditions (give me a break, I just woke up and wanted to try it out), but I can plug in CGDirectDisplayID's all day so that won't be a problem. Looks like this case is closed.
Code:
- (void)printMainDisplayName
{
CFDictionaryRef display_dictionary, product_names_dictionary;
io_service_t service;
CFStringRef product_name;
service = CGDisplayIOServicePort(kCGDirectMainDisplay);
display_dictionary = IODisplayCreateInfoDictionary(service, kIODisplayOnlyPreferredName);
product_names_dictionary = CFDictionaryGetValue(display_dictionary, CFSTR(kDisplayProductName));
CFDictionaryGetKeysAndValues( product_names_dictionary, NULL, (const void**)&product_name);
CFShow(product_name);
}I haven't written it for multiple displays or error conditions (give me a break, I just woke up and wanted to try it out), but I can plug in CGDirectDisplayID's all day so that won't be a problem. Looks like this case is closed.
Ah, from CGDisplayConfiguration.h. I didn't look there 
Excellent, case closed!
Note that if you're in Cocoa, CFStringRef == NSString*, and CFDictionaryRef == NSDictionary*, so you can write the code a bit more nicely than you have

Excellent, case closed!
Note that if you're in Cocoa, CFStringRef == NSString*, and CFDictionaryRef == NSDictionary*, so you can write the code a bit more nicely than you have
OneSadCookie Wrote:Note that if you're in Cocoa, CFStringRef == NSString*, and CFDictionaryRef == NSDictionary*, so you can write the code a bit more nicely than you haveOkay, here's my attempt at making it prettier for Cocoa and more useful at the same time. Give it a display id and it'll give you a name. If any errors occur it should merely return "Unknown Display". I tested it and it seems to work great, but I don't know if the code is "correct".
Code:
#import <IOKit/graphics/IOGraphicsLib.h>
- (NSString *)getDisplayNameUsingID:(CGDirectDisplayID)display
{
NSDictionary *displayDictionary, *productNamesDictionary;
io_service_t service;
NSString *displayName;
service = CGDisplayIOServicePort(display);
displayDictionary = (NSDictionary *)IODisplayCreateInfoDictionary(service,
kIODisplayOnlyPreferredName);
if (displayDictionary != NULL)
{
productNamesDictionary = [displayDictionary
valueForKey:@kDisplayProductName];
if (productNamesDictionary != NULL)
displayName = [[productNamesDictionary allValues] objectAtIndex:0];
}
if (displayName != NULL)
return displayName;
else
return @"Unknown Display";
}
I don't think you should be autoreleasing the displayName should you?
Otherwise, looks good.
Otherwise, looks good.
I think you're right since I didn't alloc init displayName, so I removed the autorelease. Thanks.

