#include <mach/mach.h>
#include <mach/thread_switch.h>
#include <sys/file.h>
#include <sys/stat.h>
#include <string.h>
#include <stdlib.h>
#include <CoreFoundation/CoreFoundation.h>
#include <IOKit/IOKitLib.h>
#include <IOKit/graphics/IOGraphicsLib.h>
#include "IOGraphicsLibPrivate.h"
#include <IOKit/graphics/IOGraphicsEngine.h>
#include <IOKit/ndrvsupport/IOMacOSVideo.h>
#include <IOKit/iokitmig.h>
extern void ATIMach64GARegister(void);
static int builtinsDone = 0;
#define kUseOvrModeList 1
#define kUseOvrDefault 1
enum {
kAquaMinWidth = 800,
kAquaMinHeight = 600
};
static kern_return_t
IOFramebufferServerOpen( mach_port_t connect );
kern_return_t
IOFramebufferOpen(
io_service_t service,
task_port_t owningTask,
unsigned int type,
io_connect_t * connect )
{
kern_return_t kr;
kr = io_service_open( service, owningTask, type, connect );
if( (KERN_SUCCESS == kr) && (type == kIOFBServerConnectType))
kr = IOFramebufferServerOpen( *connect );
return( kr );
}
kern_return_t
IOFBCreateSharedCursor( mach_port_t connect,
unsigned int version,
unsigned int maxWidth, unsigned int maxHeight )
{
IOFramebufferServerOpen( connect );
return( IOConnectMethodScalarIScalarO( connect, 0,
3, 0,
version, maxWidth, maxHeight ));
}
extern kern_return_t
IOFBGetFramebufferInformationForAperture( mach_port_t connect,
IOPixelAperture aperture,
IOFramebufferInformation * info )
{
IOPixelInformation pixelInfo;
IODisplayModeID mode;
IOIndex depth;
kern_return_t err;
err = IOFBGetCurrentDisplayModeAndDepth( connect, &mode, &depth );
if( err)
return( err);
err = IOFBGetPixelInformation( connect, mode, depth, aperture, &pixelInfo );
if( err)
return( err);
err = IOFBGetFramebufferOffsetForAperture( connect, aperture,
&info->baseAddress);
info->activeWidth = pixelInfo.activeWidth;
info->activeHeight = pixelInfo.activeHeight;
info->bytesPerRow = pixelInfo.bytesPerRow;
info->bytesPerPlane = pixelInfo.bytesPerPlane;
info->bitsPerPixel = pixelInfo.bitsPerPixel;
info->pixelType = pixelInfo.pixelType;
info->flags = pixelInfo.flags;
return( err);
}
extern kern_return_t
IOFBGetFramebufferOffsetForAperture( mach_port_t connect,
IOPixelAperture aperture,
IOByteCount * offset )
{
return( IOConnectMethodScalarIScalarO( connect, 8,
1, 1,
aperture,
offset ));
}
extern kern_return_t
IOFBSetBounds( mach_port_t connect,
IOGBounds * rect )
{
IOByteCount len = 0;
return( IOConnectMethodStructureIStructureO( connect, 9,
sizeof( *rect), &len,
rect, NULL ));
}
kern_return_t
IOFBGetCurrentDisplayModeAndDepth( mach_port_t connect,
IODisplayModeID * displayMode,
IOIndex * depth )
{
kern_return_t err;
err = IOConnectMethodScalarIScalarO( connect, 2,
0, 2,
displayMode, depth );
return( err );
}
extern kern_return_t
IOFBGetPixelFormat( mach_port_t connect,
IODisplayModeID mode,
IOIndex depth,
IOPixelAperture aperture,
IOPixelEncoding * pixelFormat )
{
IOPixelInformation pixelInfo;
kern_return_t err;
err = IOFBGetPixelInformation( connect, mode, depth, aperture, &pixelInfo );
if( err)
return( err);
strncpy( *pixelFormat, pixelInfo.pixelFormat, kIOMaxPixelBits );
return( err);
}
extern kern_return_t
IOFBSetCLUT( mach_port_t connect,
UInt32 startIndex,
UInt32 numEntries,
IOOptionBits options,
IOColorEntry * colors )
{
return( IOConnectMethodScalarIStructureI( connect, 16,
2, numEntries * sizeof( IOColorEntry),
startIndex, options,
colors ));
}
extern kern_return_t
IOFBSetGamma( mach_port_t connect,
UInt32 channelCount,
UInt32 dataCount,
UInt32 dataWidth,
void * data )
{
return( IOConnectMethodScalarIStructureI( connect, 11,
3, ((dataWidth + 7) / 8) * dataCount * channelCount,
channelCount, dataCount, dataWidth,
data ));
}
extern kern_return_t
IOFBAcknowledgePM( io_connect_t connect )
{
return( IOConnectMethodScalarIScalarO( connect, 14,
0, 0 ));
}
extern kern_return_t
IOFBSet444To555Table( io_connect_t connect,
const unsigned char * table )
{
return( IOConnectMethodScalarIStructureI( connect, 15,
1, 16 * sizeof( UInt8),
0, table ));
}
extern kern_return_t
IOFBSet555To444Table( io_connect_t connect,
const unsigned char * table )
{
return( IOConnectMethodScalarIStructureI( connect, 15,
1, 32 * sizeof( UInt8),
1, table ));
}
extern kern_return_t
IOFBSet256To888Table( io_connect_t connect,
const unsigned int * table )
{
return( IOConnectMethodScalarIStructureI( connect, 15,
1, 256 * sizeof( UInt32),
2, table ));
}
extern kern_return_t
IOFBSet888To256Table( io_connect_t connect,
const unsigned char * table )
{
return( IOConnectMethodScalarIStructureI( connect, 15,
1, 5 * 256 * sizeof( UInt8),
3, table ));
}
kern_return_t
IOFBGetDisplayModeCount( io_connect_t connect,
UInt32 * count )
{
return( IOConnectMethodScalarIScalarO( connect, 6,
0, 1,
count ));
}
kern_return_t
IOFBGetDisplayModes( io_connect_t connect,
UInt32 count,
IODisplayModeID * allDisplayModes )
{
IOByteCount len;
len = count * sizeof( IODisplayModeID);
return( IOConnectMethodStructureIStructureO( connect, 7,
0, &len, NULL, (void *) allDisplayModes ));
}
static void
IOFBMakeNumKeys( const void * key, const void * value, void * context )
{
CFStringRef str = key;
CFMutableDictionaryRef newTOvr = context;
const char * cStr;
char * buffer = NULL;
UInt32 timing;
cStr = CFStringGetCStringPtr( str, kCFStringEncodingMacRoman);
if( !cStr) {
CFIndex bufferSize = CFStringGetLength(str) + 1;
buffer = malloc( bufferSize);
if( buffer && CFStringGetCString( str, buffer, bufferSize, kCFStringEncodingMacRoman))
cStr = buffer;
}
if( cStr) {
timing = strtol( cStr, 0, 0 );
CFDictionarySetValue( newTOvr, (const void *) timing, value );
}
if( buffer)
free( buffer);
}
static CFDictionaryRef
IOFBLookupModeOverrides( io_connect_t connect )
{
static CFMutableDictionaryRef connectModeDict = 0;
io_service_t framebuffer;
CFDictionaryRef modeDict, oldOvr = 0;
CFMutableDictionaryRef newModeDict, ovr;
CFTypeRef obj;
if( !connectModeDict)
connectModeDict = CFDictionaryCreateMutable( kCFAllocatorDefault, (CFIndex) 0,
(CFDictionaryKeyCallBacks *) 0,
&kCFTypeDictionaryValueCallBacks );
if( !connectModeDict)
return( 0 );
ovr = (CFMutableDictionaryRef)
CFDictionaryGetValue( connectModeDict, (const void *) connect );
if( !ovr) do {
if( kIOReturnSuccess != IOConnectGetService( connect, &framebuffer ))
continue;
oldOvr = IODisplayCreateInfoDictionary( framebuffer, kNilOptions );
IOObjectRelease( framebuffer );
if( !oldOvr)
continue;
ovr = CFDictionaryCreateMutable( kCFAllocatorDefault, (CFIndex) 0,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks );
if( !ovr)
continue;
CFDictionarySetValue( connectModeDict, (const void *) connect, ovr );
CFRelease( ovr );
modeDict = CFDictionaryGetValue( oldOvr, CFSTR("tovr") );
if( modeDict && (newModeDict = CFDictionaryCreateMutable(
kCFAllocatorDefault, (CFIndex) 0,
(CFDictionaryKeyCallBacks *) 0,
&kCFTypeDictionaryValueCallBacks )))
{
CFDictionarySetValue( ovr, CFSTR("tovr"), newModeDict );
CFRelease( newModeDict );
CFDictionaryApplyFunction( modeDict, &IOFBMakeNumKeys, newModeDict );
}
modeDict = CFDictionaryGetValue( oldOvr, CFSTR("tinf") );
if( modeDict && (newModeDict = CFDictionaryCreateMutable(
kCFAllocatorDefault, (CFIndex) 0,
(CFDictionaryKeyCallBacks *) 0,
&kCFTypeDictionaryValueCallBacks )))
{
CFDictionarySetValue( ovr, CFSTR("tinf"), newModeDict );
CFRelease( newModeDict );
CFDictionaryApplyFunction( modeDict, &IOFBMakeNumKeys, newModeDict );
}
if( (obj = CFDictionaryGetValue( oldOvr, CFSTR(kDisplayHorizontalImageSize)) ))
CFDictionarySetValue( ovr, CFSTR(kDisplayHorizontalImageSize), obj );
if( (obj = CFDictionaryGetValue( oldOvr, CFSTR(kDisplayVerticalImageSize)) ))
CFDictionarySetValue( ovr, CFSTR(kDisplayVerticalImageSize), obj );
} while( false );
if( oldOvr)
CFRelease( oldOvr );
return( ovr );
}
struct DMTimingOverrideRec {
UInt32 timingOverrideVersion;
UInt32 timingOverrideAttributes; UInt32 timingOverrideSetFlags; UInt32 timingOverrideClearFlags; UInt32 timingOverrideReserved[16]; };
typedef struct DMTimingOverrideRec DMTimingOverrideRec;
struct DMDisplayTimingInfoRec {
UInt32 timingInfoVersion;
UInt32 timingInfoAttributes; SInt32 timingInfoRelativeQuality; SInt32 timingInfoRelativeDefault; UInt32 timingInfoReserved[16]; };
typedef struct DMDisplayTimingInfoRec DMDisplayTimingInfoRec;
#define desireDPI (75.0)
#define mmPerInch (25.4)
kern_return_t
IOFBGetDefaultDisplayMode( io_connect_t connect,
IODisplayModeID * displayMode, IOIndex * displayDepth )
{
IODisplayModeID * modes;
SInt32 bestDefault, rDefault;
SInt32 bestQuality, rQuality;
IODisplayModeID bestMode = 0;
IODisplayModeInformation bestInfo, info;
CFDictionaryRef ovr, tinf;
CFDataRef modetinf;
CFNumberRef num;
IOReturn err;
UInt32 modeCount;
DMDisplayTimingInfoRec * tinfRec;
Boolean better;
SInt32 i;
float desireHPix, desireVPix;
ovr = IOFBLookupModeOverrides( connect );
if( ovr)
tinf = CFDictionaryGetValue( ovr, CFSTR("tinf") );
else
tinf = 0;
desireHPix = desireVPix = 0;
if( ovr && (num = CFDictionaryGetValue( ovr, CFSTR(kDisplayHorizontalImageSize) ))) {
CFNumberGetValue( num, kCFNumberFloatType, &desireHPix );
if( desireHPix)
desireHPix = desireHPix / mmPerInch * desireDPI;
}
if( ovr && (num = CFDictionaryGetValue( ovr, CFSTR(kDisplayVerticalImageSize) ))) {
CFNumberGetValue( num, kCFNumberFloatType, &desireVPix );
if( desireVPix)
desireVPix = desireVPix / mmPerInch * desireDPI;
}
err = IOFBGetDisplayModeCount( connect, &modeCount );
if( kIOReturnSuccess == err) {
modes = (IODisplayModeID *) calloc( modeCount, sizeof( IODisplayModeID));
err = IOFBGetDisplayModes( connect, modeCount, modes );
} else {
modes = 0;
modeCount = 0;
}
bestQuality = bestDefault = 0;
if( kIOReturnSuccess == err) for( i = 0; i < modeCount; i++) {
better = false;
err = IOFBGetDisplayModeInformation( connect, modes[i], &info );
if( kIOReturnSuccess != err)
continue;
if( 0 == (info.flags & kDisplayModeValidFlag))
continue;
if( 0 == info.maxDepthIndex)
continue;
if( tinf
&& (modetinf = CFDictionaryGetValue( tinf, (const void *) info.reserved[0] ))) {
tinfRec = (DMDisplayTimingInfoRec *) CFDataGetBytePtr(modetinf);
rQuality = tinfRec->timingInfoRelativeQuality;
rDefault = tinfRec->timingInfoRelativeDefault;
} else
rQuality = rDefault = 0;
if( (info.nominalWidth < kAquaMinWidth) || (info.nominalHeight < kAquaMinHeight))
rDefault--;
if( !bestMode)
better = true;
else {
#if 1
if( (bestInfo.flags & kDisplayModeSafeFlag)
&& (0 == (info.flags & kDisplayModeSafeFlag)))
continue;
#else
if( 0 == (info.flags & kDisplayModeSafeFlag))
continue;
#endif
if( rDefault < bestDefault)
continue;
better = (rDefault > bestDefault);
if( !better) {
better = ((bestDefault <= 0) && (0 != (info.flags & kDisplayModeDefaultFlag)));
if( !better) {
if( (info.nominalWidth == bestInfo.nominalWidth)
&& (info.nominalHeight == bestInfo.nominalHeight))
better = (info.refreshRate > bestInfo.refreshRate);
else {
if( !better && desireHPix && desireVPix) {
SInt32 delta1, delta2;
delta1 = ((abs(info.nominalWidth - ((SInt32)desireHPix) ))
+ abs(info.nominalHeight - ((SInt32)desireVPix) ));
delta2 = (abs(bestInfo.nominalWidth - ((SInt32)desireHPix) )
+ abs(bestInfo.nominalHeight - ((SInt32)desireVPix) ));
better = (delta1 < delta2);
}
}
}
}
}
if( better) {
bestMode = modes[i];
bestQuality = rQuality;
bestDefault = rDefault;
bestInfo = info;
}
}
if( modes)
free( modes );
if( bestMode) {
*displayMode = bestMode;
if( bestInfo.maxDepthIndex == 2)
*displayDepth = 2;
else
*displayDepth = 1;
}
return( kIOReturnSuccess );
}
kern_return_t
IOFBGetDisplayModeInformation( io_connect_t connect,
IODisplayModeID displayMode,
IODisplayModeInformation * info )
{
kern_return_t kr;
IOByteCount len;
CFDictionaryRef ovr = 0;
CFDictionaryRef tovr;
CFDataRef modetovr;
DMTimingOverrideRec * tovrRec;
len = sizeof( IODisplayModeInformation);
kr = IOConnectMethodScalarIStructureO( connect, 5,
1, &len, displayMode, info );
if( kUseOvrModeList && (kr == kIOReturnSuccess)) do {
ovr = IOFBLookupModeOverrides( connect );
if( !ovr)
continue;
tovr = CFDictionaryGetValue( ovr, CFSTR("tovr") );
if( !tovr)
continue;
modetovr = CFDictionaryGetValue( tovr, (const void *) info->reserved[0] );
if( !modetovr)
continue;
tovrRec = (DMTimingOverrideRec *) CFDataGetBytePtr(modetovr);
info->flags &= ~tovrRec->timingOverrideClearFlags;
info->flags |= tovrRec->timingOverrideSetFlags;
} while( false );
return( kr );
}
static kern_return_t
IOFramebufferServerOpen( mach_port_t connect )
{
IODisplayModeID mode;
IOIndex depth;
IODisplayModeID startMode;
IOIndex startDepth;
UInt32 startFlags = 0;
IOReturn err;
IODisplayModeInformation info;
IODisplayInstallDetailedTimings( connect );
if( !builtinsDone) {
ATIMach64GARegister();
builtinsDone = 1;
}
if( kUseOvrDefault) {
do {
err = IOFBGetCurrentDisplayModeAndDepth( connect, &mode, &depth );
if( err)
continue;
startMode = mode;
startDepth = depth;
err = IOFBGetDisplayModeInformation( connect, startMode, &info);
if( err)
continue;
startFlags = info.flags;
if( (info.nominalWidth < kAquaMinWidth)
|| (info.nominalHeight < kAquaMinHeight)) {
err = kIOReturnNoResources;
continue;
}
if( (startDepth == 0) && (info.maxDepthIndex > 0))
startDepth = 1;
} while( false );
if( err
|| (startDepth == 0)
|| (startMode == kDisplayModeIDBootProgrammable)
|| ((startFlags & kDisplayModeValidFlag)
!= kDisplayModeValidFlag) ) {
IOFBGetDefaultDisplayMode( connect, &startMode, &startDepth );
}
if( (startMode != mode) || (startDepth != depth))
IOFBSetDisplayModeAndDepth( connect, startMode, startDepth );
}
return( kIOReturnSuccess );
}
kern_return_t
IOFBGetPixelFormats( io_connect_t connect,
IODisplayModeID displayMode,
IOIndex depth,
UInt32 * mask )
{
*mask = 1;
return( kIOReturnSuccess);
}
kern_return_t
IOFBGetPixelInformation( io_connect_t connect,
IODisplayModeID displayMode,
IOIndex depth,
IOPixelAperture aperture,
IOPixelInformation * pixelInfo )
{
IOByteCount len;
len = sizeof( IOPixelInformation);
return( IOConnectMethodScalarIStructureO( connect, 1,
3, &len,
displayMode, depth, aperture,
pixelInfo ));
}
kern_return_t
IOFBSetDisplayModeAndDepth( io_connect_t connect,
IODisplayModeID displayMode,
IOIndex depth )
{
return( IOConnectMethodScalarIScalarO( connect, 4,
2, 0,
displayMode, depth ));
}
kern_return_t
IOFBSetStartupDisplayModeAndDepth( io_connect_t connect,
IODisplayModeID displayMode,
IOIndex depth )
{
return( IOConnectMethodScalarIScalarO( connect, 3,
2, 0,
displayMode, depth ));
}
kern_return_t
IOFBSetNewCursor( io_connect_t connect,
void * cursor,
IOIndex frame,
IOOptionBits options )
{
return( IOConnectMethodScalarIScalarO( connect, 10,
3, 0,
cursor, frame, options ));
}
kern_return_t
IOFBSetCursorVisible( io_connect_t connect,
int visible )
{
return( IOConnectMethodScalarIScalarO( connect, 12,
1, 0,
visible ));
}
kern_return_t
IOFBSetCursorPosition( io_connect_t connect,
long int x,
long int y )
{
return( IOConnectMethodScalarIScalarO( connect, 13,
2, 0,
x, y ));
}
CFDictionaryRef
IOFBCreateDisplayModeDictionary( io_service_t framebuffer,
IODisplayModeID displayMode )
{
CFDictionaryRef infoDict;
CFStringRef string;
CFDictionaryRef modeDict = 0;
char keyBuf[12];
infoDict = IORegistryEntryCreateCFProperty( framebuffer, CFSTR(kIOFramebufferInfoKey),
kCFAllocatorDefault, kNilOptions );
if( infoDict ) {
sprintf( keyBuf, "%lx", displayMode );
string = CFStringCreateWithCString( kCFAllocatorDefault, keyBuf,
kCFStringEncodingMacRoman );
if( string) {
modeDict = CFDictionaryGetValue( infoDict, string );
CFRelease( string );
}
if( modeDict)
CFRetain( modeDict );
CFRelease( infoDict );
}
return( modeDict );
}
CFDictionaryRef
IOFBGetPixelInfoDictionary(
CFDictionaryRef modeDictionary,
IOIndex depth,
IOPixelAperture aperture )
{
char keyBuf[12];
CFStringRef string;
CFDictionaryRef pixelInfo = 0;
if( !modeDictionary)
return( 0 );
sprintf( keyBuf, "%lx", depth + (aperture << 16) );
string = CFStringCreateWithCString( kCFAllocatorDefault, keyBuf,
kCFStringEncodingMacRoman );
if( string) {
pixelInfo = CFDictionaryGetValue( modeDictionary, string );
CFRelease( string );
}
return( pixelInfo );
}
IOReturn
IOFBGetInterruptSemaphore( io_connect_t connect,
IOSelect interruptType,
semaphore_t * semaphore )
{
return( IOConnectMethodScalarIScalarO( connect, 15,
1, 1,
interruptType,
semaphore ));
}
#include <IOKit/graphics/IOGraphicsInterface.h>
#ifndef NO_CFPLUGIN
struct _BlitterVars {
IOGraphicsAcceleratorInterface ** interface;
IOBlitterPtr copyProc;
IOBlitterPtr fillProc;
IOBlitterPtr memCopyProc;
IOBlitSurface dest;
void * sid;
IOBlitterPtr copyRegionProc;
};
typedef struct _BlitterVars _BlitterVars;
kern_return_t
IOPSAllocateBlitEngine( io_service_t service,
void ** blitterRef, int * quality)
{
IOReturn err = kIOReturnSuccess;
_BlitterVars * vars;
IOGraphicsAcceleratorInterface ** interface = 0;
vars = (_BlitterVars *) calloc( 1, sizeof( _BlitterVars ));
if( !vars)
return( kIOReturnNoMemory);
do {
err = IOCreatePlugInInterfaceForService( service,
kIOGraphicsAcceleratorTypeID,
kIOGraphicsAcceleratorInterfaceID,
(IOCFPlugInInterface ***)&interface, (SInt32 *) quality );
if( err)
continue;
vars->interface = interface;
if( (*interface)->SetDestination) {
err = (*interface)->SetDestination(interface,
kIOBlitFramebufferDestination, NULL);
if( err)
continue;
}
err = (*interface)->GetBlitter(interface,
kIOBlitAllOptions,
(kIOBlitTypeCopyRects | kIOBlitCopyOperation),
kIOBlitSourceDefault,
&vars->copyProc);
if( err)
continue;
err = (*interface)->GetBlitter(interface,
kIOBlitAllOptions,
(kIOBlitTypeRects | kIOBlitCopyOperation),
kIOBlitSourceSolid,
&vars->fillProc);
if( err)
continue;
if( kIOReturnSuccess != (*interface)->GetBlitter(interface,
kIOBlitAllOptions,
(kIOBlitTypeCopyRegion | kIOBlitTypeOperationType0),
kIOBlitSourceFramebuffer,
&vars->copyRegionProc))
vars->copyRegionProc = 0;
if( kIOReturnSuccess != (*interface)->GetBlitter(interface,
kIOBlitAllOptions,
(kIOBlitTypeCopyRects | kIOBlitCopyOperation),
kIOBlitSourceMemory,
&vars->memCopyProc))
vars->memCopyProc = 0;
} while( FALSE );
if( err) {
if (interface)
IODestroyPlugInInterface((IOCFPlugInInterface **)interface);
free( vars );
vars = 0;
}
*blitterRef = (void *) vars;
return( err);
}
kern_return_t
IOPSBlitReset( void * blitterRef)
{
_BlitterVars * vars = (_BlitterVars *) blitterRef;
IOGraphicsAcceleratorInterface ** interface = vars->interface;
kern_return_t err = kIOReturnSuccess;
if( interface)
err = (*interface)->Reset(interface, kNilOptions);
vars->sid = 0;
return( err );
}
kern_return_t
IOPSBlitDeallocate( void * blitterRef)
{
_BlitterVars * vars = (_BlitterVars *) blitterRef;
IOGraphicsAcceleratorInterface ** interface = vars->interface;
kern_return_t err;
err = IODestroyPlugInInterface((IOCFPlugInInterface **)interface);
free( vars );
return( err );
}
kern_return_t
IOPSBlitIdle( void * blitterRef)
{
_BlitterVars * vars = (_BlitterVars *) blitterRef;
IOGraphicsAcceleratorInterface ** interface = vars->interface;
kern_return_t err;
err = (*interface)->WaitComplete(interface, kIOBlitWaitAll2D );
return( err );
}
kern_return_t
IOFBSynchronize( void * blitterRef,
UInt32 x, UInt32 y, UInt32 w, UInt32 h, UInt32 options )
{
_BlitterVars * vars = (_BlitterVars *) blitterRef;
IOGraphicsAcceleratorInterface ** interface;
IOReturn err;
if( !vars)
return( kIOReturnBadArgument);
interface = vars->interface;
err = (*interface)->Synchronize(interface, options, x, y, w, h );
return( err );
}
kern_return_t
IOFBBeamPosition( void * blitterRef, UInt32 options, SInt32 * position )
{
_BlitterVars * vars = (_BlitterVars *) blitterRef;
IOGraphicsAcceleratorInterface ** interface = vars->interface;
IOReturn err;
err = (*interface)->GetBeamPosition(interface, options, position);
return( err );
}
kern_return_t
IOPSBlitFill( void * blitterRef,
int x, int y, int w, int h, int data )
{
_BlitterVars * vars = (_BlitterVars *) blitterRef;
IOGraphicsAcceleratorInterface ** interface = vars->interface;
IOReturn err;
IOBlitRectangles rects;
if( vars->sid) {
err = (*interface)->SetDestination(interface, kIOBlitFramebufferDestination, 0);
vars->sid = 0;
if( err)
return( err );
}
rects.count = 1;
rects.rects[0].x = x;
rects.rects[0].y = y;
rects.rects[0].width = w;
rects.rects[0].height = h;
err = (*vars->fillProc)(interface,
kNilOptions,
(kIOBlitTypeRects | kIOBlitCopyOperation),
(kIOBlitSourceSolid | kIOBlitDestFramebuffer),
&rects.operation,
(void *) data);
if( kIOReturnSuccess == err)
(*interface)->Flush(interface, kNilOptions);
return( err );
}
kern_return_t
IOPSBlitInvert( void * blitterRef,
int x, int y, int w, int h )
{
_BlitterVars * vars = (_BlitterVars *) blitterRef;
IOGraphicsAcceleratorInterface ** interface = vars->interface;
IOReturn err;
IOBlitRectangles rects;
if( vars->sid) {
err = (*interface)->SetDestination(interface, kIOBlitFramebufferDestination, 0);
vars->sid = 0;
if( err)
return( err );
}
rects.count = 1;
rects.rects[0].x = x;
rects.rects[0].y = y;
rects.rects[0].width = w;
rects.rects[0].height = h;
err = (*vars->fillProc)(interface,
kNilOptions,
(kIOBlitTypeRects | kIOBlitCopyOperation),
(kIOBlitSourceSolid | kIOBlitDestFramebuffer),
&rects.operation,
(void *) 0xffffffff);
if( kIOReturnSuccess == err)
(*interface)->Flush(interface, kNilOptions);
return( err );
}
kern_return_t
IOPSBlitCopy( void * blitterRef,
int src_x, int src_y, int width, int height,
int dst_x, int dst_y )
{
return( IOFBBlitVRAMCopy( blitterRef, src_x, src_y, width, height,
dst_x, dst_y, 1 * (kIOFBBlitBeamSync) ));
}
kern_return_t
IOFBBlitVRAMCopy( void * blitterRef,
int sourceX, int sourceY, int width, int height,
int x, int y, IOOptionBits options )
{
_BlitterVars * vars = (_BlitterVars *) blitterRef;
IOGraphicsAcceleratorInterface ** interface = vars->interface;
IOReturn err;
IOBlitCopyRectangles rects;
if( vars->sid) {
err = (*interface)->SetDestination(interface, kIOBlitFramebufferDestination, 0);
vars->sid = 0;
if( err)
return( err );
}
rects.count = 1;
rects.rects[0].x = x;
rects.rects[0].y = y;
rects.rects[0].width = width;
rects.rects[0].height = height;
rects.rects[0].sourceX = sourceX;
rects.rects[0].sourceY = sourceY;
err = (*vars->copyProc)(interface,
options,
(kIOBlitTypeCopyRects | kIOBlitCopyOperation),
kIOBlitSourceDefault,
&rects.operation,
0);
if( kIOReturnSuccess == err)
(*interface)->Flush(interface, kNilOptions);
return( err );
}
kern_return_t
IOFBBlitSurfaceCopy( void * blitterRef, IOOptionBits options, void * surfaceID,
IOAccelDeviceRegion * region, UInt32 surfaceX, UInt32 surfaceY )
{
IOReturn err = kIOReturnSuccess;
_BlitterVars * vars = (_BlitterVars *) blitterRef;
IOGraphicsAcceleratorInterface ** interface = vars->interface;
IOBlitCopyRegion op;
if( 0 == vars->copyRegionProc)
return( kIOReturnUnsupported );
if( surfaceID != vars->sid) do {
if( surfaceID) {
err = (*interface)->AllocateSurface(interface, kIOBlitHasCGSSurface, &vars->dest, surfaceID);
if( err)
continue;
err = (*interface)->SetDestination(interface, kIOBlitSurfaceDestination, &vars->dest);
} else
err = (*interface)->SetDestination(interface, kIOBlitFramebufferDestination, 0);
if( err)
continue;
vars->sid = surfaceID;
} while( false );
if( err)
return( err );
op.region = region;
op.deltaX = surfaceX;
op.deltaY = surfaceY;
err = (*vars->copyRegionProc)(interface,
options,
(kIOBlitTypeCopyRegion | kIOBlitTypeOperationType0),
kIOBlitSourceFramebuffer,
&op.operation,
(void *) 0);
if( kIOReturnSuccess == err)
(*interface)->Flush(interface, kNilOptions);
return( err );
}
#if 0
kern_return_t
IOFBSetupFIFOBurst( void * blitterRef,
UInt32 x, UInt32 y, UInt32 w, UInt32 h,
UInt32 options, void ** burstRef )
{
_BlitterVars * vars = (_BlitterVars *) blitterRef;
IOReturn err;
boolean_t wait;
do {
IOSharedLockLock( &vars->context->contextLock );
wait = (kIOReturnBusy == (
err = vars->procs.setupFIFOBurst( vars->chipRef, x, y, w, h,
options, burstRef )));
IOSharedLockUnlock( &vars->context->contextLock, wait );
} while( wait );
return( err );
}
kern_return_t
IOFBCommitMemory( void * blitterRef,
vm_address_t start, vm_size_t length, IOOptionBits options,
void ** memoryRef, IOByteCount * offset )
{
_BlitterVars * vars = (_BlitterVars *) blitterRef;
IOReturn err;
unsigned int len;
int params[ 3 ];
params[0] = start;
params[1] = length;
params[2] = options;
len = 2;
err = io_connect_method_scalarI_scalarO( vars->connect, 2,
params, 3, params, &len);
if( kIOReturnSuccess == err) {
*memoryRef = (void *) params[0];
*offset = params[1];
}
return( err );
}
kern_return_t
IOFBReleaseMemory( void * blitterRef, void * memoryRef )
{
_BlitterVars * vars = (_BlitterVars *) blitterRef;
IOReturn err;
unsigned int len;
IOPSBlitIdle( blitterRef );
len = 0;
err = io_connect_method_scalarI_scalarO( vars->connect, 3,
(int *) &memoryRef, 1, NULL, &len);
return( err );
}
#endif
kern_return_t
IOFBMemoryCopy( void * blitterRef,
UInt32 x, UInt32 y,
UInt32 width, UInt32 height,
UInt32 srcByteOffset, UInt32 srcRowBytes,
SInt32 * token)
{
_BlitterVars * vars = (_BlitterVars *) blitterRef;
IOGraphicsAcceleratorInterface ** interface = vars->interface;
IOReturn err;
IOBlitMemory source;
IOBlitCopyRectangles rects;
if( vars->sid) {
err = (*interface)->SetDestination(interface, kIOBlitFramebufferDestination, 0);
vars->sid = 0;
if( err)
return( err );
}
rects.count = 1;
rects.rects[0].x = x;
rects.rects[0].y = y;
rects.rects[0].width = width;
rects.rects[0].height = height;
rects.rects[0].sourceX = 0;
rects.rects[0].sourceY = 0;
source.memory.ref = 0; source.byteOffset = srcByteOffset;
source.rowBytes = srcRowBytes;
err = (*vars->memCopyProc)(interface,
kNilOptions,
(kIOBlitTypeCopyRects | kIOBlitCopyOperation),
kIOBlitSourceMemory,
&rects.operation,
(void *) &source);
return( err );
}
#else
kern_return_t
IOPSAllocateBlitEngine( io_connect_t framebuffer, void ** blitterRef, int * quality)
{ return kIOReturnUnsupported; }
kern_return_t
IOPSBlitReset( void * blitterRef)
{ return kIOReturnUnsupported; }
kern_return_t
IOPSBlitDeallocate( void * blitterRef )
{ return kIOReturnUnsupported; }
kern_return_t
IOPSBlitIdle( void * blitterRef )
{ return kIOReturnUnsupported; }
kern_return_t
IOFBWaitForCompletion( void * blitterRef, SInt32 token )
{ return kIOReturnUnsupported; }
kern_return_t
IOFBSynchronize( void * blitterRef, UInt32 x, UInt32 y, UInt32 w, UInt32 h, UInt32 options )
{ return kIOReturnUnsupported; }
kern_return_t
IOFBBeamPosition( void * blitterRef, UInt32 options, SInt32 * position )
{ return kIOReturnUnsupported; }
kern_return_t
IOPSBlitFill( void * blitterRef, int dst_x, int dst_y, int width, int height, int data )
{ return kIOReturnUnsupported; }
kern_return_t
IOPSBlitInvert( void * blitterRef, int x, int y, int w, int h )
{ return kIOReturnUnsupported; }
kern_return_t
IOPSBlitCopy( void * blitterRef, int src_x, int src_y, int width, int height, int dst_x, int dst_y )
{ return kIOReturnUnsupported; }
kern_return_t
IOFBBlitVRAMCopy( void * blitterRef, int sourceX, int sourceY, int width, int height, int x, int y, IOOptionBits options )
{ return kIOReturnUnsupported; }
kern_return_t
IOFBMemoryCopy( void * blitterRef, UInt32 x, UInt32 y, UInt32 width, UInt32 height, UInt32 srcByteOffset, UInt32 srcRowBytes, SInt32 * token)
{ return kIOReturnUnsupported; }
kern_return_t
IOFBSetupFIFOBurst( void * blitterRef, UInt32 x, UInt32 y, UInt32 w, UInt32 h, UInt32 options, void ** burstRef )
{ return kIOReturnUnsupported; }
void
IOFBBurstWrite32( void * p1, void * p2, void * p3, void * p4, void * p5, void * p6, void * p7, void * p8 )
{ return kIOReturnUnsupported; }
void
IOFBSetBurstRef( void * burstRef )
{ return kIOReturnUnsupported; }
kern_return_t
IOFBCommitMemory( void * blitterRef, vm_address_t start, vm_size_t length, IOOptionBits options, void ** memoryRef, IOByteCount * offset )
{ return kIOReturnUnsupported; }
kern_return_t
IOFBReleaseMemory( void * blitterRef, void * memoryRef )
{ return kIOReturnUnsupported; }
#endif