2014-06-22 5 views
5

Ich muss eine Anzeige in dem Maße eindeutig identifizieren, in dem die Anzeigen in der Tat charakteristisch unterschiedlich sind. So würden die gleichen Modelle von Displays, die an denselben physischen Port angeschlossen sind, nicht als unterschiedlich behandelt werden, sondern im Grunde alles andere.CGDirectDisplayID, mehrere GPUs, veraltet CGDisplayIOServicePort und eindeutig identifizierende Anzeigen

Wenn sich die System-GPU ändert, ändert sich auch die CGDirectDisplayID, jedoch nicht in einer dokumentierten Weise. Experimentieren zeigt an, dass sich die gleiche Bildschirm-ID um 2 unterscheidet, je nachdem, welche GPU verwendet wird.

CGDisplayID changing issues

Ein Weg, dies zu überwinden, wurde für die Anzeige eines IO-Registry-String zu erhalten:

io_service_t servicePort = CGDisplayIOServicePort (cgDisplayID); 
io_service_t root = IODisplayForFramebuffer (servicePort, kNilOptions); 
NSDictionary* ioRegistryDict = nil; 
NSString*  displayKey = nil; 

IORegistryEntryCreateCFProperties (root, (CFMutableDictionaryRef *)&ioRegistryDict, kCFAllocatorDefault, kNilOptions); 

if (ioRegistryDict) 
    displayKey = [ioRegistryDict objectForKey:@"IODisplayPrefsKey"]; 

Dies funktioniert gut, außer in 10,9, CGDisplayIOServicePort ist veraltet.

Angesichts all dieser und Apples Empfehlung, NSScreens nicht zu cachen (die sowieso nicht wirklich für diesen Zweck arbeiten), was ist der beste Weg, zuverlässig Bildschirme zu identifizieren, so dass ich (zum Beispiel) den Unterschied zwischen unterscheiden kann ein Bildschirm zu Hause und einer bei der Arbeit?

Ich möchte nicht auf die Bildschirmauflösung angewiesen sein, weil der Benutzer, der die Auflösung ändert, nicht als eine andere Anzeige betrachtet werden sollte. Derselbe Bildschirm auf verschiedenen GPUs sollte auch nicht als unterschiedlich betrachtet werden.

Ein sekundäres Ziel ist es, einen Weg zu finden, wie bei einer CGDirectDisplayID, wie kann ich feststellen, was die CGDirectDisplayID für den gleichen Bildschirm wäre, wenn ein GPU-Switch auftreten würde? Dies würde mir zumindest ermöglichen, die Anzeigen mit CGDirectDisplayID zu verfolgen, solange ich die beiden Ergebnisse der beiden GPU-Controller vergleichen könnte.

+0

Ich bin nicht genau sicher, welche Eigenschaften einer Anzeige Sie Ihre Vorstellung von "gleich" vs. "anders" beeinflussen möchten, aber Sie sollten die Quartz Display Services Funktionen wie "CGDisplayModelNumber()", "CGDisplaySerialNumber" betrachten() ',' CGDisplayUnitNumber() 'und' CGDisplayVendorNumber() '. –

+0

Die Quartz-Referenz besagt: "Beim Zuweisen einer Anzeige-ID berücksichtigt Quartz die folgenden Parameter: Hersteller, Modell, Seriennummer und Position in der E/A-Kit-Registrierung" Wenn ich mein MBP auf der integrierten GPU starte, bekomme ich: displayID : 2077805631. Auf der schnellen GPU (AMD Radeon) bekomme ich eine displayID: 69678016. In beiden Fällen sind Hersteller, Modell, s/n und Einheit gleich: 1552, 40143, 0, 0. Was verursacht Apple sonst noch? IDs sollen anders sein? – Trygve

+0

Ich weiß es nicht. Ich bezweifle, dass diese Liste erschöpfend sein sollte. Aber warum kümmert es dich? Ich dachte, du suchst nach einer Möglichkeit, ein Display zu identifizieren, das sich mit der GPU * nicht geändert hat. –

Antwort

0

Verwendung CFUUIDRef die erhalten werden können CGDisplayCreateUUIDFromDisplayID (CGDirectDisplayID DisplayID) verwendet wird, und Sie können die UUID zurück mit CGDisplayGetDisplayIDFromUUID (CFUUIDRef UUID)

Das ist, was ich verwende zeigt eindeutig zu identifizieren, selbst wenn ihre CGDirectDisplayID Änderungen . Diese Funktionen werden von Apple leider nicht ordnungsgemäß dokumentiert, aber meine Tests auf mehreren Macs mit mehreren Displays haben ergeben, dass der erhaltene CFUUIDRef eindeutig und konsistent ist, selbst wenn sich CGDirectDisplayID aus irgendeinem Grund ändert.

Diese API-Aufrufe sind in ApplicationServices in 10.7 - 10.12 und ColorSync seit 10.13 verfügbar.