static pascal Boolean MoreDriveSupportFileExchangeInternal(DriverRefNum refNum, SInt16 drive) // An internal version of MoreDriveSupportFileExchange that allows // you to pass in the refNum and the drive number. You can pass // in 0 for either refNum or drive (but not both) and the routine // will do the appropriate mapping. { DriverGestaltParam pb; Boolean result; MoreAssertQ( (refNum < 0 && drive >= 0 && (drive == 0 || MoreGetDriveRefNum(drive) == refNum)) || (refNum == 0 && drive > 0) ); if (refNum == 0) { refNum = MoreGetDriveRefNum(drive); } result = false; if ( MoreDriveSupportsDriverGestaltInternal(refNum) ) { pb.ioVRefNum = drive; pb.ioCRefNum = refNum; pb.csCode = kDriverGestaltCode; pb.driverGestaltSelector = kdgAPI; if ( PBStatusSync((ParmBlkPtr) &pb) == noErr && GetDriverGestaltAPIResponse(&pb)->partitionCmds & 0x01 ) { result = true; } } return result; }
static OSErr GetGammaTable (GDHandle hGD, GammaTblPtr * ppTableGammaOut) { VDGammaRecord DeviceGammaRec; CntrlParam cParam; OSErr err; cParam.ioCompletion = NULL; cParam.ioNamePtr = NULL; cParam.ioVRefNum = 0; cParam.ioCRefNum = (**hGD).gdRefNum; cParam.csCode = cscGetGamma; *(Ptr *)cParam.csParam = (Ptr) &DeviceGammaRec; err = PBStatusSync( (ParmBlkPtr)&cParam ); *ppTableGammaOut = (GammaTblPtr)(DeviceGammaRec.csGTable); return err; }
static OSErr GetGammaTable (GDHandle hGD, GammaTblPtr * ppTableGammaOut) { VDGammaRecord DeviceGammaRec; CntrlParam cParam; OSErr err; cParam.ioCompletion = NULL; /* set up control params */ cParam.ioNamePtr = NULL; cParam.ioVRefNum = 0; cParam.ioCRefNum = (**hGD).gdRefNum; cParam.csCode = cscGetGamma; /* Get Gamma commnd to device */ *(Ptr *)cParam.csParam = (Ptr) &DeviceGammaRec; /* record for gamma */ err = PBStatusSync( (ParmBlkPtr)&cParam ); /* get gamma */ *ppTableGammaOut = (GammaTblPtr)(DeviceGammaRec.csGTable); /* pull table out of record */ return err; }
OSErr RVGetCurrentVideoSetting (VideoRequestRecPtr requestRecPtr) { unsigned long displayMgrVersion; OSErr error = paramErr; CntrlParam pBlock; VDSwitchInfoRec switchInfo; AuxDCEHandle theDCE; VDSwitchInfoRec videoMode; requestRecPtr->availBitDepth = 0; // init to default - you can do it if it is important to you requestRecPtr->availHorizontal = 0; requestRecPtr->availVertical = 0; requestRecPtr->availFlags = 0; requestRecPtr->displayMode = -1; requestRecPtr->depthMode = -1; requestRecPtr->switchInfo.csMode = 0; requestRecPtr->switchInfo.csData = 0; requestRecPtr->switchInfo.csPage = 0; requestRecPtr->switchInfo.csBaseAddr = 0; requestRecPtr->switchInfo.csReserved = 0; Gestalt(gestaltDisplayMgrVers, (long*)&displayMgrVersion); if (requestRecPtr->screenDevice) { if (displayMgrVersion >= 0x00020000) { // get the info the DM 2.0 way error = DMGetDisplayMode(requestRecPtr->screenDevice, &switchInfo); if (noErr == error) { requestRecPtr->depthMode = switchInfo.csMode; requestRecPtr->displayMode = switchInfo.csData; requestRecPtr->switchInfo.csMode = switchInfo.csMode; requestRecPtr->switchInfo.csData = switchInfo.csData; } return (error); // we (maybe) set the world back to a known setting } else { // get the info the DM 1.0 way videoMode.csMode = -1; // init to bogus value videoMode.csData = -1; // init to bogus value pBlock.ioNamePtr = nil; pBlock.ioCRefNum = (*(requestRecPtr->screenDevice))->gdRefNum; pBlock.csCode = cscGetCurMode; *(Ptr *)&pBlock.csParam[0] = (Ptr)&videoMode; error = PBStatusSync((ParmBlkPtr )&pBlock); // ask the driver first....since we trust it the most if ( noErr == error && ((-1 == videoMode.csMode) || (-1 == videoMode.csData)) ) error = statusErr; if (noErr != error) // if the driver has no clue fill it videoMode by hand as a last resort { theDCE = (AuxDCEHandle)GetDCtlEntry((*(requestRecPtr->screenDevice))->gdRefNum); if( theDCE ) { videoMode.csData = (unsigned char)(*theDCE)->dCtlSlotId; videoMode.csMode = (*(requestRecPtr->screenDevice))->gdMode; error = noErr; } } if (noErr == error) // Set our data { requestRecPtr->displayMode = videoMode.csData; requestRecPtr->depthMode = videoMode.csMode; requestRecPtr->switchInfo.csMode = videoMode.csMode; requestRecPtr->switchInfo.csData = videoMode.csData; } return (error); // we (maybe) set the world back to a known setting } } return (-1); }
extern pascal OSErr MoreGetDriveSize(SInt16 drive, UInt32 *sizeInBlocks) // See comment in interface part. { OSErr err; DrvQElPtr drvQEl; CntrlParam pb; FormatListRec formatList[kFormatListEntryCount]; SInt16 formatIndex; Boolean foundFormat; Str255 driverName; DrvSts status; MoreAssertQ(drive > 0); MoreAssertQ(sizeInBlocks != nil); // Start by finding the drive queue element for // the drive, and by making sure that there's a disk // in the drive. err = MoreUTFindDriveQ(drive, &drvQEl); if (err == noErr) { if ( MoreGetDriveFlags(drvQEl)->diskInPlace <= 0 ) { err = offLinErr; } } // Wow, this is harder than it should be, all because of the // silly ".Sony" driver. The basic problem is that // the ".Sony" driver doesn't store the disk size in the // drive queue element like every other disk drive on the // planet. The solution is a three step process as described // in the comments below. if (err == noErr) { // Step 1. If the driver supports the kReturnFormatList status call, // use it to get a list of formats for the drive and then // return the format marked as current. pb.ioNamePtr = nil; pb.ioVRefNum = drvQEl->dQDrive; pb.ioCRefNum = drvQEl->dQRefNum; pb.csCode = kReturnFormatList; pb.csParam[0] = kFormatListEntryCount; *((FormatListRec **) &pb.csParam[1]) = formatList; err = PBStatusSync( (ParmBlkPtr) &pb); if (err == noErr) { foundFormat = false; for (formatIndex = 0; formatIndex < pb.csParam[0]; formatIndex++) { if ((formatList[formatIndex].formatFlags & diCIFmtFlagsCurrentMask) != 0) { *sizeInBlocks = formatList[formatIndex].volSize; foundFormat = true; } } if ( ! foundFormat ) { // Hmmm, this isn't good. The disk driver returned a format // list but none of the formats were marked as "current". // We handle this correctly but, in debug builds, we'll also // drop into MacsBug, just to let you know this is happening. MoreAssertQ(false); err = paramErr; } } else { // ¥¥¥ The logic here is slightly screwed up. The problem is that // I can't tell whether the kReturnFormatList call failed because // the driver just doesn't support it, or because the driver failed // to get the information for some other reason. If that driver // happens to be the ".Sony" driver, I'm going to take a wrong step // next. // // For example, say that there's a 1.4MB disk in the floppy drive // and I call kReturnFormatList and it fails with an error because // of a cosmic ray. I then test the driver name, find that it's // ".Sony", call DriveStatus, and then return noErr with a size // of either 400KB or 800KB. Not good. // // You might think this is an unlikely occurence, but it's exactly // what happens when there's no disk in the floppy drive. I've // special-cased that away above, but the general problem still stands. // // What are the alternatives? I could special case the error // result from kReturnFormatList and only run this code if I get // statusErr. But can you guarantee that all ".Sony" drives // return statusErr for an unrecognised status code? I thought not. // Beyond that, I can't think of any options. So this code // stands. It's probably never going to bite anyone, but it's // worth noting here, just in case. Besides, this is what // the equivalent routine in MoreFiles does (-: // // -- Quinn, 3 Mar 1999 // Step 2. If that doesn't work, then look at the driver. If it's // the ".Sony" driver (and this will be a really old ".Sony" driver // because new ones support kReturnFormatList), special case // the possible media types. err = TradGetDriverInformation(drvQEl->dQRefNum, nil, nil, driverName, nil); if (err == noErr) { if ( EqualString(driverName, "\p.Sony", false, true) ) { err = DriveStatus(drvQEl->dQDrive, &status); if (err == noErr) { if ( status.twoSideFmt == 0 ) { *sizeInBlocks = 400 * 2; } else { *sizeInBlocks = 800 * 2; } } } else { // Step 3. If it's not the ".Sony" driver, get the size out of the // drive queue element. if (drvQEl->qType == 0) { // Old style drive, with just 16 bits of size information // in dQDrvSz. *sizeInBlocks = drvQEl->dQDrvSz; } else { // New style drive, with 32 bits of size information spread // between dQDrvSz and dQDrvSz2. *sizeInBlocks = (((UInt32 ) drvQEl->dQDrvSz2) * 65536) + (UInt32 ) drvQEl->dQDrvSz; } } }