1/*
2 * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License").  You may not use this file except in compliance with the
9 * License.  Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
11 *
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
17 * License for the specific language governing rights and limitations
18 * under the License.
19 *
20 * @APPLE_LICENSE_HEADER_END@
21 */
22
23
24#include <libkern/OSAtomic.h>
25#include <IOKit/IOUserClient.h>
26
27#define IOFRAMEBUFFER_PRIVATE
28#include <IOKit/IOHibernatePrivate.h>
29#include <IOKit/graphics/IODisplay.h>
30#include <IOKit/graphics/IOGraphicsPrivate.h>
31#include <IOKit/IOPlatformExpert.h>
32#include <IOKit/IODeviceTreeSupport.h>
33#include <IOKit/IOKitKeys.h>
34#include <IOKit/IOLib.h>
35#include <IOKit/assert.h>
36
37/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
38
39const OSSymbol * gIODisplayParametersKey;
40const OSSymbol * gIODisplayGUIDKey;
41
42const OSSymbol * gIODisplayValueKey;
43const OSSymbol * gIODisplayMinValueKey;
44const OSSymbol * gIODisplayMaxValueKey;
45
46const OSSymbol * gIODisplayContrastKey;
47const OSSymbol * gIODisplayBrightnessKey;
48const OSSymbol * gIODisplayLinearBrightnessKey;
49const OSSymbol * gIODisplayUsableLinearBrightnessKey;
50const OSSymbol * gIODisplayBrightnessFadeKey;
51const OSSymbol * gIODisplayHorizontalPositionKey;
52const OSSymbol * gIODisplayHorizontalSizeKey;
53const OSSymbol * gIODisplayVerticalPositionKey;
54const OSSymbol * gIODisplayVerticalSizeKey;
55const OSSymbol * gIODisplayTrapezoidKey;
56const OSSymbol * gIODisplayPincushionKey;
57const OSSymbol * gIODisplayParallelogramKey;
58const OSSymbol * gIODisplayRotationKey;
59const OSSymbol * gIODisplayOverscanKey;
60const OSSymbol * gIODisplayVideoBestKey;
61const OSSymbol * gIODisplaySelectedColorModeKey;
62
63const OSSymbol * gIODisplayRedGammaScaleKey;
64const OSSymbol * gIODisplayGreenGammaScaleKey;
65const OSSymbol * gIODisplayBlueGammaScaleKey;
66const OSSymbol * gIODisplayGammaScaleKey;
67
68const OSSymbol * gIODisplayParametersTheatreModeKey;
69const OSSymbol * gIODisplayParametersTheatreModeWindowKey;
70
71const OSSymbol * gIODisplayMCCSVersionKey;
72const OSSymbol * gIODisplayTechnologyTypeKey;
73const OSSymbol * gIODisplayUsageTimeKey;
74const OSSymbol * gIODisplayFirmwareLevelKey;
75
76const OSSymbol * gIODisplaySpeakerVolumeKey;
77const OSSymbol * gIODisplaySpeakerSelectKey;
78const OSSymbol * gIODisplayMicrophoneVolumeKey;
79const OSSymbol * gIODisplayAmbientLightSensorKey;
80const OSSymbol * gIODisplayAudioMuteAndScreenBlankKey;
81const OSSymbol * gIODisplayAudioTrebleKey;
82const OSSymbol * gIODisplayAudioBassKey;
83const OSSymbol * gIODisplayAudioBalanceLRKey;
84const OSSymbol * gIODisplayAudioProcessorModeKey;
85const OSSymbol * gIODisplayPowerModeKey;
86const OSSymbol * gIODisplayManufacturerSpecificKey;
87
88const OSSymbol * gIODisplayPowerStateKey;
89const OSSymbol * gIODisplayControllerIDKey;
90const OSSymbol * gIODisplayCapabilityStringKey;
91
92const OSSymbol * gIODisplayParametersCommitKey;
93const OSSymbol * gIODisplayParametersDefaultKey;
94const OSSymbol * gIODisplayParametersFlushKey;
95
96const OSSymbol * gIODisplayFadeTime1Key;
97const OSSymbol * gIODisplayFadeTime2Key;
98const OSSymbol * gIODisplayFadeTime3Key;
99const OSSymbol * gIODisplayFadeStyleKey;
100
101static const OSSymbol * gIODisplayFastBootEDIDKey;
102static IODTPlatformExpert * gIODisplayFastBootPlatform;
103static OSData *  gIODisplayZeroData;
104
105enum {
106    kIODisplayMaxUsableState  = kIODisplayMaxPowerState - 1
107};
108
109enum
110{
111    kIODisplayBlankValue   = 0x100,
112    kIODisplayUnblankValue = 0x200,
113};
114
115/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
116
117#undef super
118#define super IOService
119
120OSDefineMetaClassAndAbstractStructorsWithInit( IODisplay, IOService, IODisplay::initialize() )
121
122/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
123
124struct EDID
125{
126    UInt8       header[8];
127    UInt8       vendorProduct[4];
128    UInt8       serialNumber[4];
129    UInt8       weekOfManufacture;
130    UInt8       yearOfManufacture;
131    UInt8       version;
132    UInt8       revision;
133    UInt8       displayParams[5];
134    UInt8       colorCharacteristics[10];
135    UInt8       establishedTimings[3];
136    UInt16      standardTimings[8];
137    UInt8       detailedTimings[72];
138    UInt8       extension;
139    UInt8       checksum;
140};
141
142/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
143
144void IODisplay::initialize( void )
145{
146    gIODisplayParametersKey     = OSSymbol::withCStringNoCopy(
147                                  kIODisplayParametersKey );
148    gIODisplayGUIDKey           = OSSymbol::withCStringNoCopy(
149                                        kIODisplayGUIDKey );
150    gIODisplayValueKey          = OSSymbol::withCStringNoCopy(
151                                        kIODisplayValueKey );
152    gIODisplayMinValueKey       = OSSymbol::withCStringNoCopy(
153                                        kIODisplayMinValueKey );
154    gIODisplayMaxValueKey       = OSSymbol::withCStringNoCopy(
155                                        kIODisplayMaxValueKey );
156    gIODisplayContrastKey       = OSSymbol::withCStringNoCopy(
157                                        kIODisplayContrastKey );
158    gIODisplayBrightnessKey     = OSSymbol::withCStringNoCopy(
159                                        kIODisplayBrightnessKey );
160    gIODisplayLinearBrightnessKey = OSSymbol::withCStringNoCopy(
161                                        kIODisplayLinearBrightnessKey );
162    gIODisplayUsableLinearBrightnessKey = OSSymbol::withCStringNoCopy(
163                                        kIODisplayUsableLinearBrightnessKey );
164    gIODisplayBrightnessFadeKey = OSSymbol::withCStringNoCopy(
165                                        kIODisplayBrightnessFadeKey );
166    gIODisplayHorizontalPositionKey = OSSymbol::withCStringNoCopy(
167                                          kIODisplayHorizontalPositionKey );
168    gIODisplayHorizontalSizeKey = OSSymbol::withCStringNoCopy(
169                                        kIODisplayHorizontalSizeKey );
170    gIODisplayVerticalPositionKey = OSSymbol::withCStringNoCopy(
171                                        kIODisplayVerticalPositionKey );
172    gIODisplayVerticalSizeKey   = OSSymbol::withCStringNoCopy(
173                                        kIODisplayVerticalSizeKey );
174    gIODisplayTrapezoidKey      = OSSymbol::withCStringNoCopy(
175                                        kIODisplayTrapezoidKey );
176    gIODisplayPincushionKey     = OSSymbol::withCStringNoCopy(
177                                        kIODisplayPincushionKey );
178    gIODisplayParallelogramKey  = OSSymbol::withCStringNoCopy(
179                                        kIODisplayParallelogramKey );
180    gIODisplayRotationKey       = OSSymbol::withCStringNoCopy(
181                                        kIODisplayRotationKey );
182
183    gIODisplayOverscanKey       = OSSymbol::withCStringNoCopy(
184                                        kIODisplayOverscanKey );
185    gIODisplayVideoBestKey      = OSSymbol::withCStringNoCopy(
186                                        kIODisplayVideoBestKey );
187    gIODisplaySelectedColorModeKey = OSSymbol::withCStringNoCopy(
188                                        kIODisplaySelectedColorModeKey );
189    gIODisplayRedGammaScaleKey = OSSymbol::withCStringNoCopy(
190                                        kIODisplayRedGammaScaleKey );
191    gIODisplayGreenGammaScaleKey = OSSymbol::withCStringNoCopy(
192                                        kIODisplayGreenGammaScaleKey );
193    gIODisplayBlueGammaScaleKey = OSSymbol::withCStringNoCopy(
194                                        kIODisplayBlueGammaScaleKey );
195    gIODisplayGammaScaleKey = OSSymbol::withCStringNoCopy(
196                                        kIODisplayGammaScaleKey );
197
198    gIODisplayParametersCommitKey = OSSymbol::withCStringNoCopy(
199                                        kIODisplayParametersCommitKey );
200    gIODisplayParametersDefaultKey = OSSymbol::withCStringNoCopy(
201                                         kIODisplayParametersDefaultKey );
202    gIODisplayParametersFlushKey = OSSymbol::withCStringNoCopy(
203                                         kIODisplayParametersFlushKey );
204
205    gIODisplayParametersTheatreModeKey = OSSymbol::withCStringNoCopy(
206                                            kIODisplayTheatreModeKey);
207    gIODisplayParametersTheatreModeWindowKey = OSSymbol::withCStringNoCopy(
208                                            kIODisplayTheatreModeWindowKey);
209
210    gIODisplayMCCSVersionKey = OSSymbol::withCStringNoCopy(
211                                            kIODisplayMCCSVersionKey);
212    gIODisplayTechnologyTypeKey = OSSymbol::withCStringNoCopy(
213                                            kIODisplayTechnologyTypeKey);
214    gIODisplayUsageTimeKey = OSSymbol::withCStringNoCopy(
215                                            kIODisplayUsageTimeKey);
216    gIODisplayFirmwareLevelKey = OSSymbol::withCStringNoCopy(
217                                            kIODisplayFirmwareLevelKey);
218    gIODisplaySpeakerVolumeKey = OSSymbol::withCStringNoCopy(
219                                            kIODisplaySpeakerVolumeKey);
220    gIODisplaySpeakerSelectKey = OSSymbol::withCStringNoCopy(
221                                            kIODisplaySpeakerSelectKey);
222    gIODisplayMicrophoneVolumeKey = OSSymbol::withCStringNoCopy(
223                                            kIODisplayMicrophoneVolumeKey);
224    gIODisplayAmbientLightSensorKey = OSSymbol::withCStringNoCopy(
225                                            kIODisplayAmbientLightSensorKey);
226    gIODisplayAudioMuteAndScreenBlankKey = OSSymbol::withCStringNoCopy(
227                                            kIODisplayAudioMuteAndScreenBlankKey);
228    gIODisplayAudioTrebleKey = OSSymbol::withCStringNoCopy(
229                                            kIODisplayAudioTrebleKey);
230    gIODisplayAudioBassKey = OSSymbol::withCStringNoCopy(
231                                            kIODisplayAudioBassKey);
232    gIODisplayAudioBalanceLRKey = OSSymbol::withCStringNoCopy(
233                                            kIODisplayAudioBalanceLRKey);
234    gIODisplayAudioProcessorModeKey = OSSymbol::withCStringNoCopy(
235                                            kIODisplayAudioProcessorModeKey);
236    gIODisplayPowerModeKey = OSSymbol::withCStringNoCopy(
237                                            kIODisplayPowerModeKey);
238    gIODisplayManufacturerSpecificKey = OSSymbol::withCStringNoCopy(
239                                            kIODisplayManufacturerSpecificKey);
240
241    gIODisplayPowerStateKey = OSSymbol::withCStringNoCopy(
242                                            kIODisplayPowerStateKey);
243
244	gIODisplayControllerIDKey = OSSymbol::withCStringNoCopy(
245											kIODisplayControllerIDKey);
246	gIODisplayCapabilityStringKey = OSSymbol::withCStringNoCopy(
247											kIODisplayCapabilityStringKey);
248
249	gIODisplayFadeTime1Key = OSSymbol::withCStringNoCopy("fade-time1");
250	gIODisplayFadeTime2Key = OSSymbol::withCStringNoCopy("fade-time2");
251	gIODisplayFadeTime3Key = OSSymbol::withCStringNoCopy("fade-time3");
252	gIODisplayFadeStyleKey = OSSymbol::withCStringNoCopy("fade-style");
253
254    IORegistryEntry * entry;
255    if ((entry = getServiceRoot())
256     && (0 != entry->getProperty("has-safe-sleep")))
257    {
258        gIODisplayFastBootPlatform = OSDynamicCast(IODTPlatformExpert, IOService::getPlatform());
259        gIODisplayFastBootEDIDKey  = OSSymbol::withCStringNoCopy( kIODisplayFastBootEDIDKey );
260        gIODisplayZeroData         = OSData::withCapacity(0);
261    }
262}
263
264/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
265
266IOService * IODisplay::probe(   IOService *     provider,
267                              SInt32 *  score )
268{
269    fConnection = OSDynamicCast(IODisplayConnect, provider);
270
271    return (this);
272}
273
274IODisplayConnect * IODisplay::getConnection( void )
275{
276    return (fConnection);
277}
278
279
280IOReturn IODisplay::getGammaTableByIndex(
281    UInt32 * /* channelCount */, UInt32 * /* dataCount */,
282    UInt32 * /* dataWidth */, void ** /* data */ )
283{
284    return (kIOReturnUnsupported);
285}
286
287void IODisplayUpdateNVRAM( IOService * entry, OSData * property )
288{
289    if (true && gIODisplayFastBootPlatform)
290    {
291        while (entry && !entry->inPlane(gIODTPlane))
292        {
293            entry = entry->getProvider();
294        }
295        if (entry)
296        {
297            gIODisplayFastBootPlatform->writeNVRAMProperty(entry, gIODisplayFastBootEDIDKey,
298                                                            property);
299        }
300    }
301}
302
303void IODisplay::searchParameterHandlers(IORegistryEntry * entry)
304{
305    IORegistryIterator *        iter;
306    IODisplayParameterHandler * parameterHandler;
307
308    iter = IORegistryIterator::iterateOver(entry, gIOServicePlane,
309                                           kIORegistryIterateRecursively);
310    if (!iter) return;
311	do
312	{
313		iter->reset();
314		while( (entry = iter->getNextObject()))
315		{
316			if (!(parameterHandler = OSDynamicCast(IODisplayParameterHandler, entry)))
317				continue;
318			addParameterHandler(parameterHandler);
319		}
320	}
321	while (!iter->isValid());
322	iter->release();
323}
324
325bool IODisplay::start( IOService * provider )
326{
327    IOFramebuffer *     framebuffer;
328    uintptr_t           connectFlags;
329    OSData *            edidData;
330    EDID *              edid;
331    uint32_t            vendor = 0;
332    uint32_t            product = 0;
333    uint32_t            serial = 0;
334
335    if (!super::start(provider))
336        return (false);
337
338    if (!fConnection)
339        // as yet unmatched display device (ADB)
340        return (true);
341
342    framebuffer = fConnection->getFramebuffer();
343    assert( framebuffer );
344
345    fConnection->getAttributeForConnection(kConnectionFlags, &connectFlags);
346    uint32_t flagsData = (uint32_t) connectFlags;
347    setProperty(kIODisplayConnectFlagsKey, &flagsData, sizeof(flagsData));
348
349    edidData = OSDynamicCast( OSData, getProperty( kIODisplayEDIDKey ));
350    if (!edidData)
351    {
352        readFramebufferEDID();
353        edidData = OSDynamicCast( OSData, getProperty( kIODisplayEDIDKey ));
354    }
355
356    if (edidData)
357    {
358        do
359        {
360            edid = (EDID *) edidData->getBytesNoCopy();
361            DEBG(framebuffer->thisName, " EDID v%d.%d\n", edid->version, edid->revision );
362
363            if (edid->version != 1)
364                continue;
365            // vendor
366            vendor = (edid->vendorProduct[0] << 8) | edid->vendorProduct[1];
367
368#if 0
369			if (true && (0x10ac == vendor))
370			{
371				vendor = 0;
372				edidData = 0;
373				edid = 0;
374				removeProperty(kIODisplayEDIDKey);
375				break;
376			}
377#endif
378
379            // product
380            product = (edid->vendorProduct[3] << 8) | edid->vendorProduct[2];
381
382			serial = (edid->serialNumber[3] << 24)
383				   | (edid->serialNumber[2] << 16)
384				   | (edid->serialNumber[1] << 8)
385				   | (edid->serialNumber[0]);
386			if (serial == 0x01010101) serial = 0;
387
388            DEBG(framebuffer->thisName, " vendor/product/serial 0x%02x/0x%02x/0x%x\n",
389											vendor, product, serial );
390        }
391        while (false);
392    }
393
394    IODisplayUpdateNVRAM(this, edidData);
395
396    do
397    {
398        UInt32  sense, extSense;
399        UInt32  senseType, displayType;
400
401        if (kIOReturnSuccess != fConnection->getAttributeForConnection(
402                    kConnectionSupportsAppleSense, NULL))
403            continue;
404
405        if (kIOReturnSuccess != framebuffer->getAppleSense(
406                    fConnection->getConnection(),
407                    &senseType, &sense, &extSense, &displayType))
408            continue;
409
410        setProperty( kAppleDisplayTypeKey, displayType, 32);
411        setProperty( kAppleSenseKey, ((sense & 0xff) << 8) | (extSense & 0xff), 32);
412
413        if (0 == vendor)
414        {
415            vendor = kDisplayVendorIDUnknown;
416            if (0 == senseType)
417                product = ((sense & 0xff) << 8) | (extSense & 0xff);
418            else
419                product = (displayType & 0xff) << 16;
420        }
421    }
422    while (false);
423
424    if (0 == vendor)
425    {
426        vendor = kDisplayVendorIDUnknown;
427        product = kDisplayProductIDGeneric;
428    }
429
430    if (0 == getProperty(kDisplayVendorID))
431        setProperty( kDisplayVendorID, vendor, 32);
432    if (0 == getProperty(kDisplayProductID))
433        setProperty( kDisplayProductID, product, 32);
434    if (0 == getProperty(kDisplaySerialNumber))
435        setProperty( kDisplaySerialNumber, serial, 32);
436
437    enum
438    {
439        kMaxKeyLen = 1024,
440        kMaxKeyVendorProduct = 20 /* "-12345678-12345678" */
441    };
442    int pathLen = kMaxKeyLen - kMaxKeyVendorProduct;
443    char * prefsKey = IONew(char, kMaxKeyLen);
444
445    if (prefsKey)
446    {
447        bool ok = false;
448        OSObject * obj;
449        OSData * data;
450        if ((obj = copyProperty("AAPL,display-alias", gIOServicePlane)))
451        {
452            ok = (data = OSDynamicCast(OSData, obj));
453            if (ok)
454                pathLen = snprintf(prefsKey, kMaxKeyLen, "Alias:%d/%s",
455                                ((uint32_t *) data->getBytesNoCopy())[0], getName());
456            obj->release();
457        }
458        if (!ok)
459            ok = getPath(prefsKey, &pathLen, gIOServicePlane);
460        if (ok)
461        {
462            snprintf(prefsKey + pathLen, kMaxKeyLen - pathLen, "-%x-%x", (int) vendor, (int) product);
463            const OSSymbol * sym = OSSymbol::withCString(prefsKey);
464            if (sym)
465            {
466                setProperty(kIODisplayPrefKeyKey, (OSObject *) sym);
467                sym->release();
468            }
469        }
470        IODelete(prefsKey, char, kMaxKeyLen);
471    }
472
473    OSNumber * num;
474    if ((num = OSDynamicCast(OSNumber, framebuffer->getProperty(kIOFBTransformKey))))
475    {
476        if ((kIOScaleSwapAxes | kIOFBSwapAxes) & num->unsigned32BitValue())
477            setName("AppleDisplay-Portrait");
478    }
479
480    // display parameter hooks
481
482    IODisplayParameterHandler * parameterHandler;
483
484	searchParameterHandlers(framebuffer);
485
486    if (OSDynamicCast(IOBacklightDisplay, this))
487    {
488        OSDictionary * matching = nameMatching("backlight");
489        OSIterator *   iter = NULL;
490        IOService  *   look;
491        if (matching)
492        {
493            iter = getMatchingServices(matching);
494            matching->release();
495        }
496        if (iter)
497        {
498            look = OSDynamicCast(IOService, iter->getNextObject());
499            if (look) searchParameterHandlers(look);
500            iter->release();
501        }
502    }
503
504    if ((parameterHandler = OSDynamicCast(IODisplayParameterHandler,
505                                            framebuffer->getProperty(gIODisplayParametersKey))))
506    {
507        addParameterHandler(parameterHandler);
508    }
509
510    doUpdate();
511
512    // initialize power management of the display
513
514    fDisplayPMVars = IONew(IODisplayPMVars, 1);
515    assert( fDisplayPMVars );
516    bzero(fDisplayPMVars, sizeof(IODisplayPMVars));
517
518    fDisplayPMVars->maxState = kIODisplayMaxPowerState;
519    fDisplayPMVars->currentState = kIODisplayMaxPowerState;
520
521    initPowerManagement( provider );
522
523	uint32_t options = 0;
524	if (NULL != OSDynamicCast(IOBacklightDisplay, this))
525		options |= kIODisplayOptionBacklight;
526	if (fDisplayPMVars->minDimState)
527		options |= kIODisplayOptionDimDisable;
528
529    framebuffer->displayOnline(this, +1, options);
530
531    fNotifier = framebuffer->addFramebufferNotification(
532                    &IODisplay::_framebufferEvent, this, NULL );
533
534    registerService();
535
536    return (true);
537}
538
539bool IODisplay::addParameterHandler( IODisplayParameterHandler * parameterHandler )
540{
541    OSArray * array;
542    array = OSDynamicCast(OSArray, fParameterHandler);
543
544    if (array && ((unsigned int) -1 != array->getNextIndexOfObject(parameterHandler, 0)))
545        return (true);
546
547    if (!parameterHandler->setDisplay(this))
548        return (false);
549
550    if (!array)
551    {
552        array = OSArray::withCapacity(2);
553        if (!array)
554            return (false);
555       fParameterHandler = (IODisplayParameterHandler *) array;
556    }
557
558    array->setObject(parameterHandler);
559
560    return (true);
561}
562
563bool IODisplay::removeParameterHandler( IODisplayParameterHandler * parameterHandler )
564{
565    OSArray * array;
566
567    if (parameterHandler == fParameterHandler)
568    {
569        fParameterHandler->release();
570        fParameterHandler = 0;
571        return (true);
572    }
573
574    array = OSDynamicCast(OSArray, fParameterHandler);
575    if (array)
576    {
577        unsigned int idx = array->getNextIndexOfObject(parameterHandler, 0);
578        if (idx != (unsigned int)-1)
579        {
580            array->removeObject(idx);
581            return (true);
582        }
583    }
584    return (false);
585}
586
587void IODisplay::stop( IOService * provider )
588{
589    if (fConnection)
590    {
591        fConnection->getFramebuffer()->displayOnline(this, -1, 0);
592        fConnection = 0;
593    }
594
595    IODisplayUpdateNVRAM(this, 0);
596
597    if ( initialized )
598        PMstop();
599    if (fNotifier)
600    {
601        fNotifier->remove();
602        fNotifier = 0;
603    }
604
605	removeProperty(gIODisplayParametersKey);
606}
607
608void IODisplay::free()
609{
610    if (fParameterHandler)
611    {
612        fParameterHandler->release();
613        fParameterHandler = 0;
614    }
615    super::free();
616}
617
618IOReturn IODisplay::readFramebufferEDID( void )
619{
620    IOReturn            err;
621    IOFramebuffer *     framebuffer;
622    OSData *            data;
623    IOByteCount         length;
624    EDID                readEDID;
625    UInt8               edidBlock[128];
626    UInt32              index;
627    UInt32              numExts;
628
629    assert( fConnection );
630    framebuffer = fConnection->getFramebuffer();
631    assert( framebuffer );
632
633    do
634    {
635        err = fConnection->getAttributeForConnection(
636                  kConnectionSupportsHLDDCSense, NULL );
637        if (err)
638            continue;
639
640        if (!framebuffer->hasDDCConnect(fConnection->getConnection()))
641        {
642            err = kIOReturnUnsupported;
643            continue;
644        }
645        length = sizeof( EDID);
646        err = framebuffer->getDDCBlock( fConnection->getConnection(),
647                                        1, kIODDCBlockTypeEDID, 0, (UInt8 *) &readEDID, &length );
648        if (err || (length != sizeof(EDID)))
649            continue;
650
651
652        data = OSData::withBytes( &readEDID, sizeof( EDID ));
653        if (!data)
654            continue;
655
656        numExts = readEDID.extension;
657        for (index = 2; index < (2 + numExts); index++)
658        {
659            length = sizeof(EDID);
660            err = framebuffer->getDDCBlock( fConnection->getConnection(),
661                                            index, kIODDCBlockTypeEDID, 0, edidBlock, &length );
662            if (err || (length != sizeof(EDID)))
663                break;
664            if (0 == bcmp(edidBlock, &readEDID, sizeof(EDID)))
665                break;
666            if (!data->appendBytes(edidBlock, sizeof(EDID)))
667                break;
668        }
669
670        setProperty( kIODisplayEDIDKey, data );
671        data->release();
672    }
673    while (false);
674
675    return (err);
676}
677
678IOReturn IODisplay::getConnectFlagsForDisplayMode(
679    IODisplayModeID mode, UInt32 * flags )
680{
681    IOReturn            err;
682    IOFramebuffer *     framebuffer;
683
684    assert( fConnection );
685    framebuffer = fConnection->getFramebuffer();
686    assert( framebuffer );
687
688    err = framebuffer->connectFlags(
689              fConnection->getConnection(),
690              mode, flags );
691
692    if (kIOReturnUnsupported == err)
693    {
694        *flags = kDisplayModeValidFlag | kDisplayModeSafeFlag;
695        err = kIOReturnSuccess;
696    }
697
698    return (err);
699}
700
701/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
702
703OSDictionary * IODisplay::getIntegerRange( OSDictionary * params,
704        const OSSymbol * sym, SInt32 * value, SInt32 * min, SInt32 * max )
705{
706    OSNumber *          num;
707
708    params = OSDynamicCast( OSDictionary, params->getObject( sym ));
709
710    if (params)
711    {
712        do
713        {
714            if (value)
715            {
716                num = OSDynamicCast( OSNumber, params->getObject(gIODisplayValueKey));
717                if (!num)
718                    continue;
719                *value = num->unsigned32BitValue();
720            }
721            if (min)
722            {
723                num = OSDynamicCast( OSNumber, params->getObject(gIODisplayMinValueKey));
724                if (!num)
725                    continue;
726                *min = num->unsigned32BitValue();
727            }
728            if (max)
729            {
730                num = OSDynamicCast( OSNumber, params->getObject(gIODisplayMaxValueKey));
731                if (!num)
732                    continue;
733                *max = num->unsigned32BitValue();
734            }
735            return (params);
736        }
737        while (false);
738    }
739
740    return (false);
741}
742
743bool IODisplay::setForKey( OSDictionary * params, const OSSymbol * sym,
744                           SInt32 value, SInt32 min, SInt32 max )
745{
746    SInt32 adjValue;
747    bool ok;
748
749    // invert rotation
750    if (sym == gIODisplayRotationKey)
751        adjValue = max - value + min;
752    else
753        adjValue = value;
754
755    if ((ok = doIntegerSet(params, sym, adjValue)))
756        updateNumber(params, gIODisplayValueKey, value);
757
758    return (ok);
759}
760
761IOReturn IODisplay::setProperties( OSObject * properties )
762{
763    IOReturn                    err = kIOReturnSuccess;
764    OSDictionary *              dict;
765    OSDictionary *              dict2;
766    OSSymbol *                  sym;
767    IODisplayParameterHandler * parameterHandler;
768    OSArray *                   array;
769    OSDictionary *              displayParams;
770    OSDictionary *              params;
771    OSNumber *                  valueNum;
772    OSObject *                  valueObj;
773    OSDictionary *              valueDict;
774    OSIterator *                iter;
775    SInt32                      min, max, value;
776    bool                        doCommit = false;
777    bool                        allOK = true;
778    bool                        ok;
779
780    IOFramebuffer *             framebuffer = NULL;
781
782    if (isInactive())
783        return (kIOReturnNotReady);
784
785    if (fConnection)
786        framebuffer = fConnection->getFramebuffer();
787    if (!framebuffer)
788        return (kIOReturnNotReady);
789
790    framebuffer->fbLock();
791
792    parameterHandler = OSDynamicCast(IODisplayParameterHandler, fParameterHandler);
793    if (parameterHandler)
794    {
795        err = parameterHandler->setProperties( properties );
796        if (kIOReturnUnsupported == err)
797            err = kIOReturnSuccess;
798    }
799    else if ((array = OSDynamicCast(OSArray, fParameterHandler)))
800    {
801        for (unsigned int i = 0;
802            (parameterHandler = OSDynamicCast(IODisplayParameterHandler, array->getObject(i)));
803            i++)
804        {
805            err = parameterHandler->setProperties( properties );
806            if (kIOReturnUnsupported == err)
807                err = kIOReturnSuccess;
808        }
809    }
810
811    dict = OSDynamicCast(OSDictionary, properties);
812    if (!dict || !(displayParams = OSDynamicCast(OSDictionary, copyProperty(gIODisplayParametersKey))))
813    {
814        framebuffer->fbUnlock();
815        return (kIOReturnUnsupported);
816    }
817
818    dict2 = OSDynamicCast(OSDictionary, dict->getObject(gIODisplayParametersKey));
819    if (dict2)
820        dict = dict2;
821
822    if ((properties != displayParams) && dict->getObject(gIODisplayParametersDefaultKey))
823    {
824        params = OSDynamicCast( OSDictionary,
825                                displayParams->getObject(gIODisplayParametersDefaultKey));
826        doIntegerSet( params, gIODisplayParametersDefaultKey, 0 );
827        doUpdate();
828        setProperties( displayParams );
829    }
830
831    iter = OSCollectionIterator::withCollection( dict );
832    if (iter)
833    {
834        OSSymbol * doLast = 0;
835
836        for (; ; allOK &= ok)
837        {
838            sym = (OSSymbol *) iter->getNextObject();
839            if (!sym)
840            {
841                if (doLast)
842                {
843                    sym = doLast;
844                    doLast = 0;
845                }
846                else
847                    break;
848            }
849            else if (sym == gIODisplayVideoBestKey)
850            {
851                doLast = sym;
852                ok = true;
853                continue;
854            }
855
856            if (sym == gIODisplayParametersCommitKey)
857            {
858                if (properties != displayParams)
859                    doCommit = true;
860                ok = true;
861                continue;
862            }
863            if (sym == gIODisplayParametersDefaultKey)
864            {
865                ok = true;
866                continue;
867            }
868
869            OSData * valueData = OSDynamicCast( OSData, dict->getObject(sym) );
870            if (valueData)
871            {
872                ok = doDataSet( sym, valueData );
873                continue;
874            }
875
876            ok = false;
877            if (0 == (params = getIntegerRange(displayParams, sym, 0, &min, &max)))
878                continue;
879
880            valueObj = dict->getObject(sym);
881            if (!valueObj)
882                continue;
883            if ((valueDict = OSDynamicCast(OSDictionary, valueObj)))
884                valueObj = valueDict->getObject( gIODisplayValueKey );
885            valueNum = OSDynamicCast( OSNumber, valueObj );
886            if (!valueNum)
887                continue;
888            value = valueNum->unsigned32BitValue();
889
890            if (value < min) value = min;
891            if (value > max) value = max;
892
893			if (kIOGDbgForceBrightness & gIOGDebugFlags)
894			{
895				if (sym == gIODisplayLinearBrightnessKey) continue;
896				if (sym == gIODisplayBrightnessKey)
897				{
898					value = (((max - min) * 3) / 4 + min);
899					updateNumber(params, gIODisplayValueKey, value);
900				}
901			}
902
903            ok = setForKey( params, sym, value, min, max );
904        }
905        iter->release();
906    }
907
908    if (doCommit)
909        doIntegerSet( OSDynamicCast( OSDictionary, displayParams->getObject(gIODisplayParametersCommitKey)),
910                      gIODisplayParametersCommitKey, 0 );
911
912    doIntegerSet( OSDynamicCast( OSDictionary, displayParams->getObject(gIODisplayParametersFlushKey)),
913                  gIODisplayParametersFlushKey, 0 );
914
915    framebuffer->fbUnlock();
916
917    displayParams->release();
918
919    return (allOK ? err : kIOReturnError);
920}
921
922bool IODisplay::updateNumber( OSDictionary * params, const OSSymbol * key,
923                              SInt32 value )
924{
925    OSNumber * num;
926
927    if ((OSCollection::kImmutable & params->setOptions(0, 0))
928		&& (num = (OSNumber *) params->getObject(key)))
929    {
930        num->setValue(value);
931	}
932    else
933    {
934        num = OSNumber::withNumber( value, 32 );
935        if (num)
936        {
937            params->setObject( key, num );
938            num->release();
939        }
940    }
941    return (num != 0);
942}
943
944bool IODisplay::addParameter( OSDictionary * params, const OSSymbol * paramName,
945                              SInt32 min, SInt32 max )
946{
947    OSDictionary *      paramDict;
948    bool                ok = true;
949
950    paramDict = (OSDictionary *) params->getObject(paramName);
951    if (!paramDict)
952    {
953        paramDict = OSDictionary::withCapacity(3);
954        if (!paramDict)
955            return (false);
956        params->setObject(paramName, paramDict);
957        paramDict->release();
958    }
959
960    paramDict->setCapacityIncrement(1);
961
962    updateNumber(paramDict, gIODisplayMinValueKey, min);
963    updateNumber(paramDict, gIODisplayMaxValueKey, max);
964    if (!paramDict->getObject(gIODisplayValueKey))
965        updateNumber(paramDict, gIODisplayValueKey, min);
966
967    return (ok);
968}
969
970bool IODisplay::setParameter( OSDictionary * params, const OSSymbol * paramName,
971                              SInt32 value )
972{
973    OSDictionary *      paramDict;
974    bool                ok = true;
975
976    paramDict = (OSDictionary *) params->getObject(paramName);
977    if (!paramDict)
978        return (false);
979
980    // invert rotation
981    if (paramName == gIODisplayRotationKey)
982    {
983        SInt32 min, max;
984        getIntegerRange( params, paramName, NULL, &min, &max );
985        value = max - value + min;
986    }
987
988    updateNumber( paramDict, gIODisplayValueKey, value );
989
990    return (ok);
991}
992
993IOReturn IODisplay::_framebufferEvent( OSObject * _self, void * ref,
994                                       IOFramebuffer * framebuffer, IOIndex event, void * info )
995{
996    IODisplay * self = (IODisplay *) _self;
997
998    return (self->framebufferEvent(framebuffer , event, info));
999}
1000
1001IOReturn IODisplay::framebufferEvent( IOFramebuffer * framebuffer,
1002                                      IOIndex event, void * info )
1003{
1004    IOReturn       err;
1005    OSDictionary * displayParams;
1006
1007    switch (event)
1008    {
1009        case kIOFBNotifyDisplayModeDidChange:
1010
1011            displayParams = OSDynamicCast(OSDictionary, copyProperty(gIODisplayParametersKey));
1012            if (doUpdate() && displayParams)
1013                setProperties(displayParams);
1014            if (displayParams)
1015                displayParams->release();
1016            /* fall thru */
1017
1018        default:
1019            err = kIOReturnSuccess;
1020            break;
1021    }
1022
1023    return (err);
1024}
1025
1026UInt32 gIODisplayFadeTime1;
1027UInt32 gIODisplayFadeTime2;
1028UInt32 gIODisplayFadeTime3;
1029UInt32 gIODisplayFadeStyle;
1030
1031bool IODisplay::doIntegerSet( OSDictionary * params,
1032                              const OSSymbol * paramName, UInt32 value )
1033{
1034    IODisplayParameterHandler * parameterHandler;
1035    OSArray *                   array;
1036    bool                        ok = false;
1037
1038    if (gIODisplayFadeTime1Key == paramName)
1039    {
1040    	gIODisplayFadeTime1 = value;
1041        return (true);
1042    }
1043    if (gIODisplayFadeTime2Key == paramName)
1044    {
1045    	gIODisplayFadeTime2 = value;
1046        return (true);
1047    }
1048    if (gIODisplayFadeTime3Key == paramName)
1049    {
1050    	gIODisplayFadeTime3 = value;
1051        return (true);
1052    }
1053    if (gIODisplayFadeStyleKey == paramName)
1054    {
1055    	gIODisplayFadeStyle = value;
1056        return (true);
1057    }
1058
1059    parameterHandler = OSDynamicCast(IODisplayParameterHandler, fParameterHandler);
1060
1061    if (parameterHandler)
1062        ok = parameterHandler->doIntegerSet(params, paramName, value);
1063
1064    else if ((array = OSDynamicCast(OSArray, fParameterHandler)))
1065    {
1066        for (unsigned int i = 0;
1067            !ok && (parameterHandler = OSDynamicCast(IODisplayParameterHandler, array->getObject(i)));
1068            i++)
1069        {
1070            ok = parameterHandler->doIntegerSet(params, paramName, value);
1071        }
1072    }
1073
1074    return (ok);
1075}
1076
1077bool IODisplay::doDataSet( const OSSymbol * paramName, OSData * value )
1078{
1079    IODisplayParameterHandler * parameterHandler;
1080    OSArray *                   array;
1081    bool                        ok = false;
1082
1083    parameterHandler = OSDynamicCast(IODisplayParameterHandler, fParameterHandler);
1084
1085    if (parameterHandler)
1086        ok = parameterHandler->doDataSet(paramName, value);
1087
1088    else if ((array = OSDynamicCast(OSArray, fParameterHandler)))
1089    {
1090        for (unsigned int i = 0;
1091            !ok && (parameterHandler = OSDynamicCast(IODisplayParameterHandler, array->getObject(i)));
1092            i++)
1093        {
1094            ok = parameterHandler->doDataSet(paramName, value);
1095        }
1096    }
1097
1098    return (ok);
1099}
1100
1101bool IODisplay::doUpdate( void )
1102{
1103    IODisplayParameterHandler * parameterHandler;
1104    OSArray *                   array;
1105    bool                        ok = true;
1106
1107    parameterHandler = OSDynamicCast(IODisplayParameterHandler, fParameterHandler);
1108
1109    if (parameterHandler)
1110        ok = parameterHandler->doUpdate();
1111
1112    else if ((array = OSDynamicCast(OSArray, fParameterHandler)))
1113    {
1114        for (unsigned int i = 0;
1115            (parameterHandler = OSDynamicCast(IODisplayParameterHandler, array->getObject(i)));
1116            i++)
1117        {
1118            ok &= parameterHandler->doUpdate();
1119        }
1120    }
1121
1122    return (ok);
1123}
1124
1125/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1126
1127/*
1128    This is the power-controlling driver for a display. It also acts as an
1129    agent of the policy-maker for display power which is the DisplayWrangler.
1130    The Display Wrangler calls here to lower power by one state when it senses
1131    no user activity.  It also calls here to make the display usable after it
1132    has been idled down, and it also calls here to make the display barely
1133    usable if it senses a power emergency (e.g. low battery).
1134
1135    This driver assumes a video display, and it calls the framebuffer driver
1136    to control the sync signals.  Non-video display drivers (e.g. flat panels)
1137    subclass IODisplay and override this and other appropriate methods.
1138 */
1139
1140void IODisplay::initPowerManagement( IOService * provider )
1141{
1142    static const IOPMPowerState defaultPowerStates[kIODisplayNumPowerStates] = {
1143        // version,
1144        // capabilityFlags, outputPowerCharacter, inputPowerRequirement,
1145        { 1, 0,                                     0, 0,           0,0,0,0,0,0,0,0 },
1146        { 1, 0,                                     0, 0,           0,0,0,0,0,0,0,0 },
1147        { 1, IOPMDeviceUsable,                      0, kIOPMPowerOn, 0,0,0,0,0,0,0,0 },
1148        { 1, IOPMDeviceUsable | IOPMMaxPerformance, 0, kIOPMPowerOn, 0,0,0,0,0,0,0,0 }
1149        // staticPower, unbudgetedPower, powerToAttain, timeToAttain, settleUpTime,
1150        // timeToLower, settleDownTime, powerDomainBudget
1151    };
1152    IOPMPowerState ourPowerStates[kIODisplayNumPowerStates];
1153
1154    OSDictionary * displayParams;
1155    SInt32         value, min, max;
1156
1157    bcopy(defaultPowerStates, ourPowerStates, sizeof(ourPowerStates));
1158    displayParams = OSDynamicCast(OSDictionary, copyProperty(gIODisplayParametersKey));
1159    if (displayParams)
1160    {
1161        if (getIntegerRange(displayParams, gIODisplayAudioMuteAndScreenBlankKey,
1162                             &value, &min, &max))
1163        {
1164            if ((max >= kIODisplayBlankValue)
1165                || (kIOGDbgK59Mode & gIOGDebugFlags))
1166            {
1167                fDisplayPMVars->minDimState = 1;
1168            }
1169        }
1170        displayParams->release();
1171    }
1172    fDisplayPMVars->currentState = kIODisplayMaxPowerState;
1173
1174    // initialize superclass variables
1175    PMinit();
1176    // attach into the power management hierarchy
1177    provider->joinPMtree(this);
1178
1179    // register ourselves with policy-maker (us)
1180    registerPowerDriver(this, ourPowerStates, kIODisplayNumPowerStates);
1181}
1182
1183
1184/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1185// setDisplayPowerState
1186//
1187// Called by the display wrangler when it decides there hasn't been user
1188// activity for a while.  We drop one power level.  This can be called by the
1189// display wrangler before we have been completely initialized, or:
1190// The DisplayWrangler has sensed user activity after we have idled the
1191// display and wants us to make it usable again.  We are running on its
1192// workloop thread.  This can be called before we are completely
1193// initialized.
1194
1195void IODisplay::setDisplayPowerState(unsigned long state)
1196{
1197    if (initialized)
1198    {
1199        if (state)
1200        {
1201            state--;
1202            if (state < fDisplayPMVars->minDimState)
1203                state = fDisplayPMVars->minDimState;
1204        }
1205        fDisplayPMVars->displayIdle = (state != fDisplayPMVars->maxState);
1206        changePowerStateToPriv(state);
1207    }
1208}
1209
1210/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1211// obsolete
1212void IODisplay::dropOneLevel(void)		{}
1213void IODisplay::makeDisplayUsable(void)	{}
1214
1215/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1216// setPowerState
1217//
1218// Called by the superclass to change the display power state.
1219
1220IOReturn IODisplay::setPowerState( unsigned long powerState, IOService * whatDevice )
1221{
1222    OSDictionary * displayParams;
1223
1224    if (fDisplayPMVars->minDimState)
1225    {
1226        displayParams = OSDynamicCast(OSDictionary, copyProperty(gIODisplayParametersKey));
1227        if (displayParams)
1228        {
1229            doIntegerSet(displayParams, gIODisplayAudioMuteAndScreenBlankKey,
1230                                (powerState > fDisplayPMVars->minDimState)
1231                                    ? kIODisplayUnblankValue : kIODisplayBlankValue);
1232            if (kIOGDbgK59Mode & gIOGDebugFlags)
1233            {
1234                doIntegerSet(displayParams, gIODisplayBrightnessKey,
1235                                (powerState > fDisplayPMVars->minDimState)
1236                                    ? 255 : 0);
1237            }
1238            displayParams->release();
1239        }
1240    }
1241
1242    return (kIOReturnSuccess);
1243}
1244
1245/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1246// maxCapabilityForDomainState
1247//
1248// This simple device needs only power.  If the power domain is supplying
1249// power, the display can go to its highest state.  If there is no power
1250// it can only be in its lowest state, which is off.
1251
1252unsigned long IODisplay::maxCapabilityForDomainState( IOPMPowerFlags domainState )
1253{
1254    if (domainState & IOPMPowerOn)
1255        return (kIODisplayMaxPowerState);
1256    else
1257        return (0);
1258}
1259
1260
1261/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1262// initialPowerStateForDomainState
1263//
1264// The power domain may be changing state.  If power is on in the new
1265// state, that will not affect our state at all.  In that case return
1266// what our current state is.  If domain power is off, we can attain
1267// only our lowest state, which is off.
1268
1269unsigned long IODisplay::initialPowerStateForDomainState( IOPMPowerFlags domainState )
1270{
1271    if (domainState & IOPMPowerOn)
1272        // domain has power
1273        return (kIODisplayMaxPowerState);
1274    else
1275        // domain is down, so display is off
1276        return (kIODisplayMaxPowerState);
1277    return (0);
1278}
1279
1280
1281/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1282// powerStateForDomainState
1283//
1284// The power domain may be changing state.  If power is on in the new
1285// state, that will not affect our state at all.  In that case ask the ndrv
1286// what our current state is.  If domain power is off, we can attain
1287// only our lowest state, which is off.
1288
1289unsigned long IODisplay::powerStateForDomainState( IOPMPowerFlags domainState )
1290{
1291    if (domainState & IOPMPowerOn)
1292        // domain has power
1293        return (getPowerState());
1294    else
1295        // domain is down, so display is off
1296        return (0);
1297}
1298
1299/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1300
1301class AppleDisplay : public IODisplay
1302{
1303    OSDeclareDefaultStructors(AppleDisplay)
1304};
1305
1306#undef super
1307#define super IODisplay
1308
1309OSDefineMetaClassAndStructors(AppleDisplay, IODisplay)
1310
1311/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1312
1313
1314#undef super
1315#define super IOService
1316
1317OSDefineMetaClass( IODisplayParameterHandler, IOService )
1318OSDefineAbstractStructors( IODisplayParameterHandler, IOService )
1319
1320/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1321
1322OSMetaClassDefineReservedUnused(IODisplay, 0);
1323OSMetaClassDefineReservedUnused(IODisplay, 1);
1324OSMetaClassDefineReservedUnused(IODisplay, 2);
1325OSMetaClassDefineReservedUnused(IODisplay, 3);
1326OSMetaClassDefineReservedUnused(IODisplay, 4);
1327OSMetaClassDefineReservedUnused(IODisplay, 5);
1328OSMetaClassDefineReservedUnused(IODisplay, 6);
1329OSMetaClassDefineReservedUnused(IODisplay, 7);
1330OSMetaClassDefineReservedUnused(IODisplay, 8);
1331OSMetaClassDefineReservedUnused(IODisplay, 9);
1332OSMetaClassDefineReservedUnused(IODisplay, 10);
1333OSMetaClassDefineReservedUnused(IODisplay, 11);
1334OSMetaClassDefineReservedUnused(IODisplay, 12);
1335OSMetaClassDefineReservedUnused(IODisplay, 13);
1336OSMetaClassDefineReservedUnused(IODisplay, 14);
1337OSMetaClassDefineReservedUnused(IODisplay, 15);
1338OSMetaClassDefineReservedUnused(IODisplay, 16);
1339OSMetaClassDefineReservedUnused(IODisplay, 17);
1340OSMetaClassDefineReservedUnused(IODisplay, 18);
1341OSMetaClassDefineReservedUnused(IODisplay, 19);
1342
1343OSMetaClassDefineReservedUnused(IODisplayParameterHandler, 0);
1344OSMetaClassDefineReservedUnused(IODisplayParameterHandler, 1);
1345OSMetaClassDefineReservedUnused(IODisplayParameterHandler, 2);
1346OSMetaClassDefineReservedUnused(IODisplayParameterHandler, 3);
1347OSMetaClassDefineReservedUnused(IODisplayParameterHandler, 4);
1348OSMetaClassDefineReservedUnused(IODisplayParameterHandler, 5);
1349OSMetaClassDefineReservedUnused(IODisplayParameterHandler, 6);
1350OSMetaClassDefineReservedUnused(IODisplayParameterHandler, 7);
1351OSMetaClassDefineReservedUnused(IODisplayParameterHandler, 8);
1352OSMetaClassDefineReservedUnused(IODisplayParameterHandler, 9);
1353
1354/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1355