/*
 * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
 *
 * @APPLE_LICENSE_HEADER_START@
 * 
 * Copyright (c) 1999-2003 Apple Computer, Inc.  All Rights Reserved.
 * 
 * This file contains Original Code and/or Modifications of Original Code
 * as defined in and that are subject to the Apple Public Source License
 * Version 2.0 (the 'License'). You may not use this file except in
 * compliance with the License. Please obtain a copy of the License at
 * http://www.opensource.apple.com/apsl/ and read it before using this
 * file.
 * 
 * The Original Code and all software distributed under the License are
 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
 * Please see the License for the specific language governing rights and
 * limitations under the License.
 * 
 * @APPLE_LICENSE_HEADER_END@
 */

#ifndef _IOKIT_IOFRAMEBUFFER_H
#define _IOKIT_IOFRAMEBUFFER_H

#include <IOKit/IOService.h>
#include <IOKit/IOInterruptEventSource.h>
#include <IOKit/graphics/IOGraphicsDevice.h>
#include <IOKit/graphics/IOFramebufferShared.h>
#include <IOKit/IOLib.h>

class IOFramebuffer;
class IOBufferMemoryDescriptor;

typedef void (*CursorBlitProc)(
                    IOFramebuffer * inst,
                    void * shmem,
                    volatile unsigned char *vramPtr,
                    unsigned int cursStart,
                    unsigned int vramRow,
                    unsigned int cursRow,
                    int width,
                    int height );

typedef void (*CursorRemoveProc)(
                    IOFramebuffer * inst,
                    void * shmem,
                    volatile unsigned char *vramPtr,
                    unsigned int vramRow,
                    int width,
                    int height );

enum {
   kHardwareCursorInfoMajorVersion		= 0x0001,
   kHardwareCursorInfoMinorVersion		= 0x0000
};

/*!
 * @struct IOHardwareCursorInfo
 * @abstract A structure defining the converted data of a hardware cursor.
 * @discussion This structure is used by IOFramebuffer to return the data of a hardware cursor by convertCursorImage() after conversion based on the IOHardwareCursorDescriptor passed to that routine.
 * @field majorVersion Set to kHardwareCursorInfoMajorVersion.
 * @field minorVersion Set to kHardwareCursorInfoMinorVersion.
 * @field cursorHeight The actual size of the cursor is returned.
 * @field cursorWidth The actual size of the cursor is returned.
 * @field colorMap Pointer to array of IOColorEntry structures, with the number of elements set by the numColors field of the IOHardwareCursorDescriptor. Zero should be passed for direct pixel formats.
 * @field hardwareCursorData Buffer to receive the converted cursor data.
 * @field reserved Reserved, set to zero.
 */

struct IOHardwareCursorInfo {
   UInt16		majorVersion;
   UInt16		minorVersion;
   UInt32		cursorHeight;
   UInt32		cursorWidth;
   // nil or big enough for hardware's max colors
   IOColorEntry *	colorMap;
   UInt8 *		hardwareCursorData;
   UInt32		reserved[6];
};
typedef struct IOHardwareCursorInfo IOHardwareCursorInfo;

typedef void * IOFBCursorRef;

struct IOFBCursorControlCallouts {
    IOReturn	(*setCursorImage) (void * self, void * ref,
                                    IOHardwareCursorDescriptor * description, IOFBCursorRef cursorImage);
    IOReturn	(*setCursorState) (void * self, void * ref,
                                    SInt32 x, SInt32 y, bool visible);
    UInt32	reserved[30];
};
typedef struct IOFBCursorControlCallouts IOFBCursorControlCallouts;

struct IOFBCursorControlAttribute {
    void *				self;
    void *				ref;
    const IOFBCursorControlCallouts *	callouts;
    UInt32				reserved[29];
};
typedef struct IOFBCursorControlAttribute IOFBCursorControlAttribute;

// clock & data values
enum {
    kIODDCLow				= 0,
    kIODDCHigh				= 1,
    kIODDCTristate			= 2
};
// ddcBlockType constants
enum {
    // EDID block type.
    kIODDCBlockTypeEDID			= 0
};

// ddcFlags constants
enum {
    // Force a new read of the EDID.
    kIODDCForceRead			= 0x00000001
};

enum {
    kDisabledInterruptState		= 0,
    kEnabledInterruptState		= 1
};

typedef void (*IOFBInterruptProc)( OSObject * target, void * ref );


typedef IOReturn (*IOFramebufferNotificationHandler)
	(OSObject * self, void * ref,
	IOFramebuffer * framebuffer, IOIndex event,
	void * info);

// IOFramebufferNotificationHandler events
enum {
    kIOFBNotifyDisplayModeWillChange	= 1,
    kIOFBNotifyDisplayModeDidChange	= 2,

    kIOFBNotifyWillSleep	= 3,
    kIOFBNotifyDidWake		= 4,

    kIOFBNotifyDidPowerOff	= 5,
    kIOFBNotifyWillPowerOn	= 6,

    kIOFBNotifyDidSleep		= kIOFBNotifyDidPowerOff,
    kIOFBNotifyWillWake		= kIOFBNotifyWillPowerOn,

    kIOFBNotifyWillPowerOff	= 7,
    kIOFBNotifyDidPowerOn	= 8,

    kIOFBNotifyWillChangeSpeed	= 9,
    kIOFBNotifyDidChangeSpeed	= 10
};

enum {
    kFBDisplayUsablePowerState		= 0x80000000,
    kFBDisplayPowerStateMask		= 0x0000ffff
};

#define kIOFBDependentIDKey	"IOFBDependentID"
#define kIOFBDependentIndexKey	"IOFBDependentIndex"

struct StdFBShmem_t;
class IOFramebufferUserClient;

/*! @class IOFramebuffer : public IOGraphicsDevice
    @abstract The base class for graphics devices to be made available as part of the desktop.
    @discussion The IOFramebuffer base class defines APIs used to publish a linear framebuffer device. Device driver writers should subclass this class to provide a X native driver. Mac OS X will also utilize 'ndrv' drivers via a subclass of IOFramebuffer IONDRVFramebuffer that does not require device driver writers to provide a X native driver.
    
    There are no in kernel clients of IOFramebuffer aside from rudimentary console and panic UI supported by the IOFramebuffer class. The IOFramebuffer class provides the IOUserClient implementation to allow the CoreGraphics server to provide the user accessible interface to all displays on a Mac OS X system, and this is further layered underneath application frameworks. Device driver writers should not need any knowledge of this part of the interfaces. Similarly the instance variables of IOFramebuffer are mostly used for cursor rendering which is handled by the IOFramebuffer class, and should be avoided by subclass implementors. Only IOFramebuffer methods with header documentation in this header are designed for subclasses to implement.

    IOFramebuffer provides simple dumb framebuffer operation - accceleration for 2D, 3D and video may be provided by a separate implementation of the IOAccelerator class.
*/

class IOFramebuffer : public IOGraphicsDevice
{
    friend class IOFramebufferUserClient;
    friend class IOFramebufferSharedUserClient;
    friend class IOGraphicsEngineClient;

    OSDeclareDefaultStructors(IOFramebuffer)

protected:
/*! @struct ExpansionData
    @discussion This structure will be used to expand the capablilties of this class in the future.
    */    
    struct ExpansionData { };

/*! @var reserved
    Reserved for future use.  (Internal use only)  */
    ExpansionData * reserved;

private:

protected:
    StdFBShmem_t *			priv;
    int					shmemClientVersion;
    IOBufferMemoryDescriptor *		sharedCursor;

    union {
        struct {
            /* Mapping tables used in cursor drawing to 5-5-5 displays. */
            unsigned char *	_bm34To35SampleTable;
            unsigned char *	_bm35To34SampleTable;
            /* Mapping tables used in cursor drawing to 8-bit RGB displays. */
            unsigned int *	_bm256To38SampleTable;
            unsigned char *	_bm38To256SampleTable;
        } 				t;
        UInt8 *				tables[ 4 ];
    } 					colorConvert;
    
    /* cursor blitting vars */
    CursorBlitProc			cursorBlitProc;
    CursorRemoveProc			cursorRemoveProc;

    IOGSize				maxCursorSize;
    void * 				_IOFramebuffer_reservedE[8];
    volatile unsigned char *		cursorSave;
    unsigned int			white;

    Point				nextCursorLoc;
    int					nextCursorFrame;
    SInt32				connectChange;
    semaphore_t				vblSemaphore;

    /* memory ranges */
    volatile unsigned char * 		frameBuffer;
    unsigned int			totalWidth;
    unsigned int			rowBytes;
    unsigned int			bytesPerPixel;

    IOMemoryMap *			vramMap;
    IOByteCount				vramMapOffset;
    OSArray *				userAccessRanges;
    unsigned int			suspended:1;
    unsigned int			captured:1;
    unsigned int			sleepConnectCheck:1;
    unsigned int                        messaged:1;
    unsigned int                       _IOFramebuffer_reservedC:28;
    IOFramebuffer * 			nextDependent;
    OSSet *				fbNotifications;

    class IOFramebufferUserClient *	  serverConnect;
    class IOFramebufferSharedUserClient * sharedConnect;

    unsigned int			opened:1;
    unsigned int			dead:1;
    unsigned int			configPending:1;
    unsigned int			serverNotified:1;
    unsigned int			serverState:1;
    unsigned int			serverPendingAck:1;
    unsigned int			isUsable:1;
    unsigned int			mirrored:1;
    unsigned int 			pendingPowerState:4;
    unsigned int			pendingPowerChange:1;
    unsigned int			pagingState:1;
    unsigned int			mirrorPrimary:1;
    unsigned int			mirrorSWCursor:1;

    bool				clutValid;
    bool				currentMono;
    bool				needCursorService;
    bool				haveVBLService;
    bool				haveHWCursor;
    bool				hwCursorLoaded;

    void *				serverMsg;
    IOInterruptEventSource *		deferredEvents;

    /* Reserved for future expansion. */
    int 				_IOFramebuffer_reserved[5];

private:
    struct IOFramebufferPrivate *	__private;

    OSMetaClassDeclareReservedUnused(IOFramebuffer, 0);
    OSMetaClassDeclareReservedUnused(IOFramebuffer, 1);
    OSMetaClassDeclareReservedUnused(IOFramebuffer, 2);
    OSMetaClassDeclareReservedUnused(IOFramebuffer, 3);
    OSMetaClassDeclareReservedUnused(IOFramebuffer, 4);
    OSMetaClassDeclareReservedUnused(IOFramebuffer, 5);
    OSMetaClassDeclareReservedUnused(IOFramebuffer, 6);
    OSMetaClassDeclareReservedUnused(IOFramebuffer, 7);
    OSMetaClassDeclareReservedUnused(IOFramebuffer, 8);
    OSMetaClassDeclareReservedUnused(IOFramebuffer, 9);
    OSMetaClassDeclareReservedUnused(IOFramebuffer, 10);
    OSMetaClassDeclareReservedUnused(IOFramebuffer, 11);
    OSMetaClassDeclareReservedUnused(IOFramebuffer, 12);
    OSMetaClassDeclareReservedUnused(IOFramebuffer, 13);
    OSMetaClassDeclareReservedUnused(IOFramebuffer, 14);
    OSMetaClassDeclareReservedUnused(IOFramebuffer, 15);
    OSMetaClassDeclareReservedUnused(IOFramebuffer, 16);
    OSMetaClassDeclareReservedUnused(IOFramebuffer, 17);
    OSMetaClassDeclareReservedUnused(IOFramebuffer, 18);
    OSMetaClassDeclareReservedUnused(IOFramebuffer, 19);
    OSMetaClassDeclareReservedUnused(IOFramebuffer, 20);
    OSMetaClassDeclareReservedUnused(IOFramebuffer, 21);
    OSMetaClassDeclareReservedUnused(IOFramebuffer, 22);
    OSMetaClassDeclareReservedUnused(IOFramebuffer, 23);
    OSMetaClassDeclareReservedUnused(IOFramebuffer, 24);
    OSMetaClassDeclareReservedUnused(IOFramebuffer, 25);
    OSMetaClassDeclareReservedUnused(IOFramebuffer, 26);
    OSMetaClassDeclareReservedUnused(IOFramebuffer, 27);
    OSMetaClassDeclareReservedUnused(IOFramebuffer, 28);
    OSMetaClassDeclareReservedUnused(IOFramebuffer, 29);
    OSMetaClassDeclareReservedUnused(IOFramebuffer, 30);
    OSMetaClassDeclareReservedUnused(IOFramebuffer, 31);


public:
    static void initialize();

    virtual bool requestTerminate( IOService * provider, IOOptionBits options );
    virtual IOService * IOFramebuffer::probe( IOService * provider, SInt32 * score );
    virtual bool start( IOService * provider );
    virtual void stop( IOService * provider );
    virtual void free();

    virtual IOReturn powerStateWillChangeTo ( IOPMPowerFlags, unsigned long, IOService* );
    virtual IOReturn powerStateDidChangeTo ( IOPMPowerFlags, unsigned long, IOService* );
    virtual IOReturn setPowerState( unsigned long powerStateOrdinal, IOService * device);
    virtual IOReturn setAggressiveness( unsigned long type, unsigned long newLevel );
    virtual IOReturn getAggressiveness( unsigned long type, unsigned long * currentLevel );
    virtual IOReturn newUserClient( task_t		owningTask,
                                    void * 		security_id,
                                    UInt32  		type,
                                    IOUserClient **	handler );

    virtual void hideCursor( void );
    virtual void showCursor( Point * cursorLoc, int frame );
    virtual void moveCursor( Point * cursorLoc, int frame );
    // virtual
    void resetCursor( void );

    virtual void getVBLTime( AbsoluteTime * time, AbsoluteTime * delta );

    virtual void getBoundingRect ( Bounds ** bounds );

    virtual IOReturn open( void );
    
    virtual void close( void );

    virtual bool isConsoleDevice( void );

    virtual IOReturn setupForCurrentConfig( void );

    virtual bool serializeInfo( OSSerialize * s );
    virtual bool setNumber( OSDictionary * dict, const char * key,
				UInt32 number );

    IONotifier * addFramebufferNotification(
            IOFramebufferNotificationHandler handler,
            OSObject * self, void * ref);

/*! @function getApertureRange
    @abstract Return reference to IODeviceMemory object representing memory range of framebuffer.
    @discussion IOFramebuffer subclasses must implement this method to describe the memory used by the framebuffer in the current mode. The OS will map this memory range into user space for client access - the range should only include vram memory not hardware registers.
    @param aperture The system will only access the aperture kIOFBSystemAperture.
    @result an IODeviceMemory instance. A reference will be consumed by the caller for each call of this method - the implementatation should create a new instance of IODeviceMemory for each call, or return one instance with a retain for each call.
*/

    virtual IODeviceMemory * getApertureRange( IOPixelAperture aperture ) = 0;

/*! @function getVRAMRange
    @abstract Return reference to IODeviceMemory object representing memory range of all the cards vram.
    @discussion IOFramebuffer subclasses should implement this method to describe all the vram memory available on the card. The OS will map this memory range into user space for client access - the range should only include vram memory not hardware registers.
    @result an IODeviceMemory instance. A reference will be consumed by the caller for each call of this method - the implementatation should create a new instance of IODeviceMemory for each call, or return one instance with a retain for each call.
*/

    virtual IODeviceMemory * getVRAMRange( void );

protected:

/*! @function handleEvent
    @abstract Notify IOFramebuffer superclass code of events.
    @discussion IOFramebuffer subclasses should call this IOFramebuffer method on certain power state changes.
    @param event The event that has occurred:<br>
    kIOFBNotifyWillPowerOff call before entering a state other than the maximum.<br>
    kIOFBNotifyDidPowerOn call after entering the maximum power state.<br>
    kIOFBNotifyWillPowerOff call before entering a state other than the maximum.<br>
    kIOFBNotifyDidPowerOn call after entering a state other than the maximum.<br>
    @param info None of the above events require additional info, pass zero.
    @result an IOReturn code, safely ignored.
*/

    IOReturn handleEvent( IOIndex event, void * info = 0 );


    IOReturn deliverFramebufferNotification(
                    IOIndex event, void * info = 0 );

#ifdef IOFRAMEBUFFER_PRIVATE
#include <IOKit/graphics/IOFramebufferPrivate.h>
#endif

public:
/*! @function enableController
    @abstract Perform first time setup of the framebuffer.
    @discussion IOFramebuffer subclasses should perform their initialization of the hardware here. The IOService start() method is not called at a time appropriate for this initialization.
    @result an IOReturn code. A return other than kIOReturnSuccess will prevent the system from using the device.
*/

    virtual IOReturn enableController( void );

/*! @function getPixelFormats
    @abstract List the pixel formats the framebuffer supports.
    @discussion IOFramebuffer subclasses must implement this method to return an array of strings representing the possible pixel formats available in the framebuffer.
    @result A const char * pointer. The string consists of a concatenation of each pixel format string separated by the NULL character. The commonly supported pixel formats for Mac OS X are defined as IO8BitIndexedPixels, IO16BitDirectPixels, IO32BitDirectPixels.
*/

    virtual const char * getPixelFormats( void ) = 0;

/*! @function getDisplayModeCount
    @abstract Return the number of display modes the framebuffer supports.
    @discussion IOFramebuffer subclasses must implement this method to return a count of the display modes available. This count should change unless a connection change is posted for the device indicated the framebuffer and/or display configuration has changed.
    @result A count of the display modes available.
*/

    virtual IOItemCount getDisplayModeCount( void ) = 0;

/*! @function getDisplayModes
    @abstract Return the number of display modes the framebuffer supports.
    @discussion IOFramebuffer subclasses must implement this method to return an array of display mode IDs available for the framebuffer. The IDs are defined by the driver in the range 0x00000001 - 0x7fffffff, and should be constant for a given display mode. 
    @param allDisplayModes A caller allocated buffer with the size given by the result of getDisplayModeCount().
    @result an IOReturn code. A return other than kIOReturnSuccess will prevent the system from using the device.
*/
 
    virtual IOReturn getDisplayModes( IODisplayModeID * allDisplayModes ) = 0;

/*! @function getInformationForDisplayMode
    @abstract Return information about a given display mode.
    @discussion IOFramebuffer subclasses must implement this method to return information in the IODisplayModeInformation structure for the display mode with the passed ID. 
    @param displayMode A display mode ID previously returned by getDisplayModes().
    @param info Pointer to a structure of type IODisplayModeInformation to be filled out by the driver. IODisplayModeInformation is documented in IOGraphicsTypes.h.
    @result an IOReturn code. A return other than kIOReturnSuccess will prevent the system from using the device.
*/

    virtual IOReturn getInformationForDisplayMode( IODisplayModeID displayMode,
                    IODisplayModeInformation * info ) = 0;

/*! @function getPixelFormatsForDisplayMode
    @abstract Obsolete.
    @discussion IOFramebuffer subclasses must implement this method to return zero. 
    @param displayMode Ignored.
    @param depth Ignored.
    @result Return zero.
*/

    virtual UInt64  getPixelFormatsForDisplayMode( IODisplayModeID displayMode,
                    IOIndex depth ) = 0;

/*! @function getPixelInformation
    @abstract Return information about the framebuffer format for a given display mode and depth.
    @discussion IOFramebuffer subclasses must implement this method to return information in the IOPixelInformation structure for the display mode with the passed ID, depth index and aperture. The aperture utilized by the system is always kIOFBSystemAperture. Drivers may define alternative apertures, being a view of the framebuffer in a different pixel format from the default.
    @param displayMode A display mode ID previously returned by getDisplayModes().
    @param depth An index from zero to the value of the maxDepthIndex field from the IODisplayModeInformation structure (inclusive).
    @param info Pointer to a structure of type IOPixelInformation to be filled out by the driver. IOPixelInformation is documented in IOGraphicsTypes.h.
    @result an IOReturn code. A return other than kIOReturnSuccess will prevent the system from using the device.
*/

    virtual IOReturn getPixelInformation(
	IODisplayModeID displayMode, IOIndex depth,
	IOPixelAperture aperture, IOPixelInformation * pixelInfo ) = 0;

/*! @function getCurrentDisplayMode
    @abstract Return the framebuffers current display mode and depth.
    @discussion IOFramebuffer subclasses must implement this method to return the current mode and depth.
    @param displayMode A display mode ID representing the current mode.
    @param depth An index indicating the depth configuration of the framebuffer. The index should range from zero to the value of the maxDepthIndex field from the IODisplayModeInformation structure for the display mode.
    @result an IOReturn code. A return other than kIOReturnSuccess will prevent the system from using the device.
*/

    virtual IOReturn getCurrentDisplayMode( IODisplayModeID * displayMode,
                            IOIndex * depth ) = 0;

/*! @function setCurrentDisplayMode
    @abstract Set the framebuffers current display mode and depth.
    @discussion IOFramebuffer subclasses should implement this method to set the current mode and depth. Other than at enableController() time, this is the only method that should change the framebuffer format and is synchronized with clients and attached accelerators to make sure access to the device is disallowed during the change.
    @param displayMode A display mode ID representing the new mode.
    @param depth An index indicating the new depth configuration of the framebuffer. The index should range from zero to the value of the maxDepthIndex field from the IODisplayModeInformation structure for the display mode.
    @result an IOReturn code. A return other than kIOReturnSuccess will prevent the system from using the device.
*/

    virtual IOReturn setDisplayMode( IODisplayModeID displayMode,
                            IOIndex depth );

/*! @function setApertureEnable
    @abstract Enable an aperture on the framebuffer (usually unimplemented, no OS usage).
    @discussion IOFramebuffer subclasses may implement this method to set enable a non standard aperture. The system does not call this method.
    @param aperture A device specific aperture index.
    @param enable Device specific mask of options.
    @result an IOReturn code.
*/

    virtual IOReturn setApertureEnable( IOPixelAperture aperture,
		    IOOptionBits enable );

/*! @function setStartupDisplayMode
    @abstract Set the framebuffers display mode and depth to be used during boot and at startup.
    @discussion IOFramebuffer subclasses should implement this method to set the mode and depth to be used during boot and at startup, to reduce needed mode changes during boot when the display connection type is the same. If possible this mode should also be used by the OpenFirmware driver for the card.
    @param displayMode A display mode ID representing the new startup mode.
    @param depth An index indicating the new startup depth configuration of the framebuffer. The index should range from zero to the value of the maxDepthIndex field from the IODisplayModeInformation structure for the display mode.
    @result an IOReturn code.
*/

    virtual IOReturn setStartupDisplayMode( IODisplayModeID displayMode,
                            IOIndex depth );

/*! @function getCurrentDisplayMode
    @abstract Return the framebuffers display mode and depth to be used during boot and at startup.
    @discussion IOFramebuffer subclasses should implement this method to return the current mode and depth.
    @param displayMode A display mode ID representing the mode used during startup.
    @param depth An index indicating the depth configuration of the framebuffer used during startup. The index should range from zero to the value of the maxDepthIndex field from the IODisplayModeInformation structure for the display mode.
    @result an IOReturn code.
*/

    virtual IOReturn getStartupDisplayMode( IODisplayModeID * displayMode,
                            IOIndex * depth );

/*! @function setCLUTWithEntries
    @abstract Set the color lookup table to be used by the framebuffer in indexed modes.
    @discussion IOFramebuffer subclasses may implement this method to allow a palette to be set for indexed display modes. It will not be called on framebuffers in direct display modes.
    @param colors A pointer to an array of numEntries RGB color entries.
    @param index The index of the first entry to set.
    @param numEntries The number of entries in the table.
    @param options Options controlling the operation. <br>
    kSetCLUTByValue is set if the index field of each entry should be used to set the table sparsely, otherwise consecutive entries from the index parameter should be set.<br>
    kSetCLUTImmediately is set if the CLUT set should not be synchronized with the vertical blank, otherwise it should.<br>
    kSetCLUTWithLuminance is set if the CLUT should be set to a gray value equivalent in luminance to the passed color entry.<br>
    @result an IOReturn code.
*/

    virtual IOReturn setCLUTWithEntries( IOColorEntry * colors, UInt32 index,
                UInt32 numEntries, IOOptionBits options );

/*! @function setGammaTable
    @abstract Set the gamma table to be used by the framebuffer.
    @discussion IOFramebuffer subclasses should implement this method to allow a gamma table to be set. 
    @param channelCount Defines the number of channels in the supplied data. OS X will pass three for separate R, G, B data, or one if the same data should apply to all channels.
    @param dataCount The number of data entries per channel.
    @param dataWidth The number of bits in each entry. 8 for Mac OS X 10.1 and earlier, 16 for later releases.
    @param data The packed array of correction data. Data is passed for the R (or single) channel followed by the G & B channels. Each entry is one or two bytes (if dataWidth > 8).
    @result an IOReturn code.
*/

    virtual IOReturn setGammaTable( UInt32 channelCount, UInt32 dataCount,
                    UInt32 dataWidth, void * data );

/*! @function setAttribute
    @abstract Generic method to set some attribute of the framebuffer device.
    @discussion IOFramebuffer subclasses may implement this method to allow arbitrary attribute/value pairs to be set. 
    @param attribute Defines the attribute to be set. Some defined attributes are:<br> 
    kIOPowerAttribute The IOFramebuffer class implements most power management (IOService) methods. It calls the subclass to carry out the power management state change with this attribute. When carrying out power state changes, the subclass should call IOFramebuffer::handleEvent for certain changes - set that method for more information.
    @param value The new value for the attribute.
    @result an IOReturn code.
*/

    virtual IOReturn setAttribute( IOSelect attribute, UInt32 value );

/*! @function getAttribute
    @abstract Generic method to retrieve some attribute of the framebuffer device.
    @discussion IOFramebuffer subclasses may implement this method to allow arbitrary attribute/value pairs to be returned. 
    @param attribute Defines the attribute to be set. Some defined attributes are:<br> 
    kIOHardwareCursorAttribute If the device supports a hardware cursor and implements the setCursorImage() and setCursorState() calls it should return true for this attribute.
    @param value Returns the value for the attribute.
    @result an IOReturn code.
*/

    virtual IOReturn getAttribute( IOSelect attribute, UInt32 * value );

/*! @function getTimingInfoForDisplayMode
    @abstract Returns a timing description for a display mode.
    @discussion IOFramebuffer subclasses should implement this method to return timing information for a display mode. This allows the OS to enable display modes based on its knowledge of the connected display type. Two types of timing information are defined, by Apple defined constant, or by a detailed description of the timing parameters of the mode. 
    @param displayMode A display mode ID representing the mode to examine.
    @param info The driver returns the information for the display mode in this structure.<br>
    If the mode has an Apple defined constant, such as timingVESA_1024x768_75hz, it should be returned in the appleTimingID field. Otherwise the field should be set to timingInvalid.<br>
    If the driver is able to supply detailed timing information, it should return it in the detailedInfo.v2 field of the structure, otherwise the driver should clear the kIODetailedTimingValid flag from the flags field.<br>
    The IODetailedTimingInformationV2 structure is documented in IOGraphicsTypes.h
    @result an IOReturn code. A return other than kIOReturnSuccess will prevent the system from using the device.
*/

    virtual IOReturn getTimingInfoForDisplayMode(
		IODisplayModeID displayMode, IOTimingInformation * info );

/*! @function validateDetailedTiming
    @abstract Reports whether a detailed timing is able to be programmed with the device.
    @discussion IOFramebuffer subclasses may implement programmable mode functionality where the OS is able to install modes described by a detailed timing into the driver. 
    @param description A pointer to a IODetailedTimingInformationV2 structure. The driver should examine this description and change any fields that it cannot implement to reflect its closest possible implementation.
    @param descripSize sizeof(IODetailedTimingInformationV2)
    @result an IOReturn code. A return other than kIOReturnSuccess will prevent the system from installing the programmable mode.
*/

    virtual IOReturn validateDetailedTiming(
                    void * description, IOByteCount descripSize );

/*! @function setDetailedTimings
    @abstract Installs an array of OS programmed detailed timings to be made available by the driver.
    @discussion IOFramebuffer subclasses may implement programmable mode functionality where the OS is able to install modes described by a detailed timing into the driver. The driver needs to add these modes to its internal mode list if it provides this functionality.
    @param array An OSArray of OSData objects. Each OSData contains one IODetailedTimingInformationV2 structure. All the data described by the array should be copied or retained by this call until the next invocation of this method.
    @result an IOReturn code. A return other than kIOReturnSuccess will prevent the system from installing the programmable modes.
*/

    virtual IOReturn setDetailedTimings( OSArray * array );

/*! @function getConnectionCount
    @abstract Reports the number of display connections the device supports, driven from one framebuffer.
    @discussion IOFramebuffer subclasses may implement functionality where a single framebuffer drives multiple displays. This is not recommended or fully supported and instead multihead cards should implement multiple instances of IOFramebuffer objects to provide full functionality.
    @result A count of the number of display connections reported by the framebuffer. Current versions of OS X only support one connection completely.
*/

    virtual IOItemCount getConnectionCount( void );


/*! @function setAttributeForConnection
    @abstract Generic method to set some attribute of the framebuffer device, specific to one display connection.
    @discussion IOFramebuffer subclasses may implement this method to allow arbitrary attribute/value pairs to be set, specific to one display connection. 
    @param attribute Defines the attribute to be set. Some defined attributes are:<br> 
    kIOCapturedAttribute If the device supports hotplugging displays, it should disable the generation of hot plug interrupts when the attribute kIOCapturedAttribute is set to true.
    @param value The new value for the attribute.
    @result an IOReturn code.
*/

    virtual IOReturn setAttributeForConnection( IOIndex connectIndex,
                    IOSelect attribute, UInt32 value );

/*! @function getAttributeForConnection
    @abstract Generic method to retrieve some attribute of the framebuffer device, specific to one display connection.
    @discussion IOFramebuffer subclasses may implement this method to allow arbitrary attribute/value pairs to be returned, specific to one display connection. 
    @param attribute Defines the attribute to be returned. Some defined attributes are:<br> 
    kConnectionSupportsHLDDCSense If the framebuffer supports the DDC methods hasDDCConnect() and getDDCBlock() it should return success (and no value) for this attribute.
    @param value Returns the value for the attribute.
    @result an IOReturn code.
*/

    virtual IOReturn getAttributeForConnection( IOIndex connectIndex,
                    IOSelect attribute, UInt32  * value );

/*! @function convertCursorImage
    @abstract Utility method of IOFramebuffer to convert cursor image to a hardware cursor format.
    @discussion IOFramebuffer subclasses may implement hardware cursor functionality, if so they should pass the cursor image given by the  setCursorImage() method, with a description of their hardware cursor format, to this helper function to this routine to convert the image to one suitable for the hardware.
    @param cursorImage Opaque cursor parameter from the setCursorImage() call.
    @param description Describes the cursor format supported by the driver.
    @param cursor Structure describing the drivers allocated buffer to receive the converted image.
    @result a bool indicating the conversion was successful.
*/

    virtual bool convertCursorImage( void * cursorImage,
		IOHardwareCursorDescriptor * description,
                IOHardwareCursorInfo * cursor );

/*! @function setCursorImage
    @abstract Set a new image for the hardware cursor.
    @discussion IOFramebuffer subclasses may implement hardware cursor functionality, if so they should implement this method to change the hardware cursor image. The image should be passed to the convertCursorImage() method with each type of cursor format the hardware supports until success, if all fail the hardware cursor should be hidden and kIOReturnUnsupported returned.
    @param cursorImage Opaque cursor description. This should be passed to the convertCursorImage() method to convert to a format specific to the hardware.
    @result An IOReturn code.
*/

    virtual IOReturn setCursorImage( void * cursorImage );

/*! @function setCursorState
    @abstract Set a new position and visibility for the hardware cursor.
    @discussion IOFramebuffer subclasses may implement hardware cursor functionality, if so they should implement this method to change the position and visibility of the cursor.
    @param x Left coordinate of the cursor image. A signed value, will be negative if the cursor's hot spot and position place it partly offscreen.
    @param y Top coordinate of the cursor image. A signed value, will be negative if the cursor's hot spot and position place it partly offscreen.
    @param visible Visible state of the cursor.
    @result An IOReturn code.
*/

    virtual IOReturn setCursorState( SInt32 x, SInt32 y, bool visible );

/*! @function flushCursor
    @abstract Perform any needed cache flushing after software cursor rendering.
    @discussion IOFramebuffer implements software cursor functionality when a hardware cursor is unavailable. Some hardware may need to flush a cache after the processor has finished lifting and dropping the software cursor.
*/

    virtual void flushCursor( void );

/*! @function getAppleSense
    @abstract Return display sense information for legacy Apple sensing.
    @discussion Hardware that supports simple display sensing, or the classic 3 pin Apple sensing described in Designing Cards and Drivers, should implement this method to return sense information.
    @param connectIndex Index of the display connection, from zero to the value of getConnectionCount().
    @param senseType Return zero to indicate legacy Apple sensing.
    @param primary Return the value of the primary Apple sense code.
    @param extended Return the value of the secondary Apple sense code.
    @param displayType Return an Apple defined constant for the type of display sensed. For example, kVGAConnect, kNTSCConnect, kPALConnect etc.
    @result An IOReturn code.
*/

    virtual IOReturn getAppleSense( IOIndex connectIndex,
            UInt32 * senseType,
            UInt32 * primary,
            UInt32 * extended,
            UInt32 * displayType );

/*! @function connectFlags
    @abstract Return display sense information for legacy Apple sensing.
    @discussion Hardware that supports simple display sensing, or the classic 3 pin Apple sensing described in Designing Cards and Drivers, should implement this method to return mode flags relative to the sensed display. If this method is unimplemented, all modes have are given the flags kDisplayModeValidFlag | kDisplayModeSafeFlag.
    @param connectIndex Index of the display connection, from zero to the value of getConnectionCount().
    @param displayMode A display mode ID.
    @param flags Return the flags value for the given mode with the connected display. Flags are:<br>
    kDisplayModeValidFlag - mode is considered valid for the connected display by the driver.
    kDisplayModeSafeFlag - mode is considered safe (not requiring mode change confirmation) for the connected display by the driver.
    kDisplayModeDefaultFlag - mode is considered default for the connected display by the driver.
    @result An IOReturn code.
*/

    virtual IOReturn connectFlags( IOIndex connectIndex,
                    IODisplayModeID displayMode, IOOptionBits * flags );

    //// IOLowLevelDDCSense - obsolete, do not implement

    virtual void setDDCClock( IOIndex connectIndex, UInt32 value );
    virtual void setDDCData( IOIndex connectIndex, UInt32 value );
    virtual bool readDDCClock( IOIndex connectIndex );
    virtual bool readDDCData( IOIndex connectIndex );
    virtual IOReturn enableDDCRaster( bool enable );

/*! @function hasDDCConnect
    @abstract Return display DDC connect state.
    @discussion Hardware that supports DDC/EDID display sensing should implement this method to return true if a DDC display is detected. They should also return success for the connection attribute kConnectionSupportsHLDDCSense (from getAttributeForConnection()).
    @param connectIndex Index of the display connection, from zero to the value of getConnectionCount().
    @result True if a DDC display is detected.
*/

    virtual bool hasDDCConnect( IOIndex connectIndex );

/*! @function getDDCBlock
    @abstract Return display EDID data.
    @discussion Hardware that supports DDC/EDID display sensing should implement this method to return EDID data in 128 byte blocks.
    @param connectIndex Index of the display connection, from zero to the value of getConnectionCount().
    @param blockNumber Block number, ranging from one to the number of blocks return by the display.
    @param blockType kIODDCBlockTypeEDID will be passed. 
    @param options No options are currently defined.
    @param data Caller allocated buffer to receive the blocks data.
    @param length In/out parameter - callers allocated buffer size, driver returns actual size.
    @result An IOReturn code.
*/

    virtual IOReturn getDDCBlock( IOIndex connectIndex, UInt32 blockNumber,
                    IOSelect blockType, IOOptionBits options,
                    UInt8 * data, IOByteCount * length );

/*! @function registerForInterruptType
    @abstract Set callbacks for driver to call on interrupt events.
    @discussion The IOFramebuffer class will call its subclasses to set callbacks to be called on interrupt events generated by hardware events. Only two are currently in use - vertical blank interrupts and connection changed interrupts.
    @param interruptType One of these constants:<br>
    kIOFBVBLInterruptType Specifying a vertical blanking interrupt.
    kIOFBConnectInterruptType Specify the display connection should be resensed.
    @param proc C callback to be called by the driver when the specified event occurs.
    @param target Target parameter for the callback proc.
    @param ref Ref parameter for the callback proc.
    @param interruptRef The subclass should return an opaque reference to the installed interrupt handler, for use with unregisterInterrupt() and setInterruptState().
    @result An IOReturn code.
*/

    virtual IOReturn registerForInterruptType( IOSelect interruptType,
            	    IOFBInterruptProc proc, OSObject * target, void * ref,
		    void ** interruptRef );

/*! @function unregisterInterrupt
    @abstract Remove a callback previously installed by registerForInterruptType().
    @discussion Remove a callback previously installed by registerForInterruptType().
    @param interruptRef The interruptRef returned from the registerForInterruptType call that installed the interrupt.
    @result An IOReturn code.
*/

    virtual IOReturn unregisterInterrupt( void * interruptRef );

/*! @function unregisterInterrupt
    @abstract Enable or disable a callback previously installed by registerForInterruptType().
    @discussion Enable or disable a callback previously installed by registerForInterruptType().
    @param state True or false to enable the callback.
    @result An IOReturn code.
*/

    virtual IOReturn setInterruptState( void * interruptRef, UInt32 state );

    virtual IOReturn getNotificationSemaphore( IOSelect interruptType,
                                               semaphore_t * semaphore );
};

#endif /* ! _IOKIT_IOFRAMEBUFFER_H */
