يتم إهمال سغديسبلايوسرفيسيبورت في نظام التشغيل س > = 10.9, كيفية استبدال?

StackOverflow https://stackoverflow.com//questions/20025868

سؤال

فعلت التطبيق صغير للسماح بسرعة تغيير دقة الشاشة على شاشات متعددة.أريد إظهار اسم المنتج كعنوان للشاشة ، ومن السهل جدا العثور عليه باستخدام هذا الرمز:

NSDictionary *deviceInfo = (__bridge NSDictionary *)IODisplayCreateInfoDictionary(CGDisplayIOServicePort(dispID), kIODisplayOnlyPreferredName);

NSDictionary *localizedNames = [deviceInfo objectForKey:[NSString stringWithUTF8String:kDisplayProductName]];

if([localizedNames count] > 0) {
    _title = [localizedNames objectForKey:[[localizedNames allKeys] objectAtIndex:0]];
} else {
    _title = @"Unknown display";
}

لكن CGDisplayIOServicePort هو إهمال في نظام التشغيل س > = 10.9 وتقول وثائق أبل لا يوجد بديل.كيفية العثور على منفذ الخدمة أو اسم المنتج دون استخدام هذه الطريقة?

حاولت تكرار من خلال إو التسجيل وحاول استخدام IOServiceGetMatchingServices طريقة للعثور على خدمات العرض ولكن أنا لست على دراية جدا مع إو التسجيل لذلك لم أتمكن من العثور على حل.

شكرا للمساعدة!

هل كانت مفيدة؟

المحلول

يبدو أن مشاركة إيون غاب عن جزء من المعلومات لإغلاق هذه المناقشة.مع القليل من البحث ، وجدت أن يوسرفيسبورتفرومكغديسبلايد ليس أبي الذي يوفر أبل.بدلا من ذلك ، انها قطعة من شفرة المصدر المفتوح وجدت هنا:https://github.com/glfw/glfw/blob/e0a6772e5e4c672179fc69a90bcda3369792ed1f/src/cocoa_monitor.m

أنا نسخ يوسرفيسبورتفرومكغديسبلايد وأيضا 'جيتديسبلاينام' منه.أنا في حاجة اثنين من القرص لجعلها تعمل على نظام التشغيل س 10.10.

  1. إزالة التعليمات البرمجية للتعامل مع الرقم التسلسلي في إيوسرفيسيبورتفرومكغديسبلايد.(كفديكتيوناريجيتفالو ل كديسبلايسيريالنومبر يعود فارغة بالنسبة لي.)
  2. إزالة مشروع معين خطأ التعامل مع التعليمات البرمجية في جيتديسبلاينام.

إذا كنت بحاجة إلى مزيد من المعلومات

  • قضية تعقب المشكلة:github.com/glfw/glfw/issues/165
  • الالتزام من أجل الحل:github.com/glfw/glfw/commit/e0a6772e5e4c672179fc69a90bcda3369792ed1f

أود أن أشكر ماثيو هنري الذي قدم الرمز هناك.

نصائح أخرى

هنا هو بلدي يأخذ على هذه القضية.بدأت أيضا مع رمز من غلفو 3.1 ، ملف كوكو_مونيتور.m.
ولكن كان لي لتعديله بطرق مختلفة من قال هيروشي ، حتى هنا يذهب:

// Get the name of the specified display
- (NSString*) screenNameForDisplay: (NSNumber*) screen_id
{
    CGDirectDisplayID displayID = [screen_id unsignedIntValue];

    io_service_t serv = [self IOServicePortFromCGDisplayID: displayID];
    if (serv == 0)
        return @"unknown";

    CFDictionaryRef info = IODisplayCreateInfoDictionary(serv, kIODisplayOnlyPreferredName);
    IOObjectRelease(serv);

    CFStringRef display_name;
    CFDictionaryRef names = CFDictionaryGetValue(info, CFSTR(kDisplayProductName));

    if ( !names ||
         !CFDictionaryGetValueIfPresent(names, CFSTR("en_US"), (const void**) & display_name)  )
    {
        // This may happen if a desktop Mac is running headless
        CFRelease( info );
        return @"unknown";
    }

    NSString * displayname = [NSString stringWithString: (__bridge NSString *) display_name];
    CFRelease(info);
    return displayname;
}


// Returns the io_service_t (an int) corresponding to a CG display ID, or 0 on failure.
// The io_service_t should be released with IOObjectRelease when not needed.

- (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 displayInfo;
        CFNumberRef vendorIDRef;
        CFNumberRef productIDRef;
        CFNumberRef serialNumberRef;

        displayInfo = IODisplayCreateInfoDictionary( serv, kIODisplayOnlyPreferredName );

        Boolean success;
        success =  CFDictionaryGetValueIfPresent( displayInfo, CFSTR(kDisplayVendorID),  (const void**) & vendorIDRef );
        success &= CFDictionaryGetValueIfPresent( displayInfo, CFSTR(kDisplayProductID), (const void**) & productIDRef );

        if ( !success )
        {
            CFRelease(displayInfo);
            continue;
        }

        SInt32 vendorID;
        CFNumberGetValue( vendorIDRef, kCFNumberSInt32Type, &vendorID );
        SInt32 productID;
        CFNumberGetValue( productIDRef, kCFNumberSInt32Type, &productID );

        // If a serial number is found, use it.
        // Otherwise serial number will be nil (= 0) which will match with the output of 'CGDisplaySerialNumber'
        SInt32 serialNumber = 0;
        if ( CFDictionaryGetValueIfPresent(displayInfo, CFSTR(kDisplaySerialNumber), (const void**) & serialNumberRef) )
        {
            CFNumberGetValue( serialNumberRef, kCFNumberSInt32Type, &serialNumber );
        }

        // If the vendor and product id along with the serial don't match
        // then we are not looking at the correct monitor.
        // NOTE: The serial number is important in cases where two monitors
        //       are the exact same.
        if( CGDisplayVendorNumber(displayID) != vendorID ||
            CGDisplayModelNumber(displayID)  != productID ||
            CGDisplaySerialNumber(displayID) != serialNumber )
        {
            CFRelease(displayInfo);
            continue;
        }

        servicePort = serv;
        CFRelease(displayInfo);
        break;
    }

    IOObjectRelease(iter);
    return servicePort;
}

هذا يعمل بشكل جيد بالنسبة لي في شاشة التوقف كتبت تحت ماك 10.11 (كابيتان).اختبرت ذلك مع المدمج في عرض بلدي ماكبوكبرو وشاشة أبل متصلة عبر الصاعقة.

NSString* screenNameForDisplay(CGDirectDisplayID displayID)
{
    NSString *screenName = nil;
    io_service_t service = IOServicePortFromCGDisplayID(displayID);
    if (service)
    {
        NSDictionary *deviceInfo = (NSDictionary *)IODisplayCreateInfoDictionary(service, kIODisplayOnlyPreferredName);
        NSDictionary *localizedNames = [deviceInfo objectForKey:[NSString stringWithUTF8String:kDisplayProductName]];

        if ([localizedNames count] > 0) {
            screenName = [[localizedNames objectForKey:[[localizedNames allKeys] objectAtIndex:0]] retain];
        }

        [deviceInfo release];
    }
    return [screenName autorelease];
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top