/* * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * * The contents of this file constitute Original Code as defined in and * are subject to the Apple Public Source License Version 1.1 (the * "License"). You may not use this file except in compliance with the * License. Please obtain a copy of the License at * http://www.apple.com/publicsource and read it before using this file. * * This 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 OR NON-INFRINGEMENT. Please see the * License for the specific language governing rights and limitations * under the License. * * @APPLE_LICENSE_HEADER_END@ */ #include #include #include #include #include #include #include #include #include #include "IOGraphicsLibPrivate.h" #include #include #include // -- builtins 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, /*index*/ 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, /*index*/ 1, 1, aperture, offset )); } extern kern_return_t IOFBSetBounds( mach_port_t connect, IOGBounds * rect ) { IOByteCount len = 0; return( IOConnectMethodStructureIStructureO( connect, 9, /*index*/ 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, /*index*/ 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, /* index */ 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, /* index */ 3, ((dataWidth + 7) / 8) * dataCount * channelCount, channelCount, dataCount, dataWidth, data )); } extern kern_return_t IOFBAcknowledgePM( io_connect_t connect ) { return( IOConnectMethodScalarIScalarO( connect, 14, /*index*/ 0, 0 )); } extern kern_return_t IOFBSet444To555Table( io_connect_t connect, const unsigned char * table ) { return( IOConnectMethodScalarIStructureI( connect, 15, /* index */ 1, 16 * sizeof( UInt8), 0, table )); } extern kern_return_t IOFBSet555To444Table( io_connect_t connect, const unsigned char * table ) { return( IOConnectMethodScalarIStructureI( connect, 15, /* index */ 1, 32 * sizeof( UInt8), 1, table )); } extern kern_return_t IOFBSet256To888Table( io_connect_t connect, const unsigned int * table ) { return( IOConnectMethodScalarIStructureI( connect, 15, /* index */ 1, 256 * sizeof( UInt32), 2, table )); } extern kern_return_t IOFBSet888To256Table( io_connect_t connect, const unsigned char * table ) { return( IOConnectMethodScalarIStructureI( connect, 15, /* index */ 1, 5 * 256 * sizeof( UInt8), 3, table )); } kern_return_t IOFBGetDisplayModeCount( io_connect_t connect, UInt32 * count ) { return( IOConnectMethodScalarIScalarO( connect, 6, /*index*/ 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, /*index*/ 0, &len, NULL, (void *) allDisplayModes )); } // Display mode information 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; // flags UInt32 timingOverrideSetFlags; // VDTimingInfoRec.csTimingFlags |= timingOverrideSetFlags UInt32 timingOverrideClearFlags; // VDTimingInfoRec.csTimingFlags &= (~timingOverrideClearFlags) UInt32 timingOverrideReserved[16]; // reserved }; typedef struct DMTimingOverrideRec DMTimingOverrideRec; struct DMDisplayTimingInfoRec { UInt32 timingInfoVersion; UInt32 timingInfoAttributes; // flags SInt32 timingInfoRelativeQuality; // quality of the timing SInt32 timingInfoRelativeDefault; // relative default of the timing UInt32 timingInfoReserved[16]; // reserved }; 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; // make sure it does 16bpp 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, /*index*/ 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 ); // -- builtins 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) ) { // look for default IOFBGetDefaultDisplayMode( connect, &startMode, &startDepth ); } if( (startMode != mode) || (startDepth != depth)) IOFBSetDisplayModeAndDepth( connect, startMode, startDepth ); } return( kIOReturnSuccess ); } // Mask of pixel formats available in mode and depth 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, /*index*/ 3, &len, displayMode, depth, aperture, pixelInfo )); } kern_return_t IOFBSetDisplayModeAndDepth( io_connect_t connect, IODisplayModeID displayMode, IOIndex depth ) { return( IOConnectMethodScalarIScalarO( connect, 4, /*index*/ 2, 0, displayMode, depth )); } kern_return_t IOFBSetStartupDisplayModeAndDepth( io_connect_t connect, IODisplayModeID displayMode, IOIndex depth ) { return( IOConnectMethodScalarIScalarO( connect, 3, /*index*/ 2, 0, displayMode, depth )); } kern_return_t IOFBSetNewCursor( io_connect_t connect, void * cursor, IOIndex frame, IOOptionBits options ) { return( IOConnectMethodScalarIScalarO( connect, 10, /*index*/ 3, 0, cursor, frame, options )); } kern_return_t IOFBSetCursorVisible( io_connect_t connect, int visible ) { return( IOConnectMethodScalarIScalarO( connect, 12, /*index*/ 1, 0, visible )); } kern_return_t IOFBSetCursorPosition( io_connect_t connect, long int x, long int y ) { return( IOConnectMethodScalarIScalarO( connect, 13, /*index*/ 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, /*index*/ 1, 1, interruptType, semaphore )); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #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, /*index*/ 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, /*index*/ (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 /* NO_CFPLUGIN */ /* We need these symbols to exist to prevent link errors in clients. Have them all return an error. */ 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 /* !NO_CFPLUGIN */