Retired Document
Important: This sample code may not represent best practices for current development. The project may use deprecated symbols and illustrate technologies and techniques that are no longer recommended.
AEventStuff.c
/* |
File: AEvents.c |
Contains: This file contains an assortment of functions to deal with |
the Apple Events needed to set the OS 9 desktop. The majority of |
the functionality below came from MoreAppleEvents, but it was not |
yet carbonized (to my knowledge) when I created this sample, so I could |
not directly link with the library that comes with that example. |
Special thanks to GeoWar for help in this area. |
Written by: |
Copyright: Copyright © 1991-1999 by Apple Computer, Inc., All Rights Reserved. |
You may incorporate this Apple sample source code into your program(s) without |
restriction. This Apple sample source code has been provided "AS IS" and the |
responsibility for its operation is yours. You are not permitted to redistribute |
this Apple sample source code as "Apple sample source code" after having made |
changes. If you're going to re-distribute the source, we require that you make |
it clear in the source that the code was descended from Apple sample source |
code, but that you've made changes. |
*/ |
#include "Snapshot.h" |
static int gNumMonitors = 0; |
OSErr SetDesktopPict(AEDesc* pAEDesc,SInt32 pIndex) |
{ |
OSErr anErr = noErr; |
AppleEvent theEvent = {typeNull, nil}; // always init AEDescs |
ProcessSerialNumber tPSN; |
gNumMonitors = 0; // zero monitor count |
{ |
GDHandle tGDHandle = DMGetFirstScreenDevice(true); |
while (tGDHandle) |
{ |
gNumMonitors++; // bump count |
tGDHandle = DMGetNextScreenDevice(tGDHandle,true); |
} |
} |
if (gNumMonitors == 0) |
gNumMonitors = 1; |
// Launch reciever if it's not already running. |
anErr = LaunchProcessBySignature('APPC', 'apcp',&tPSN); |
if (anErr != noErr) |
return anErr; |
//moreisbetter or AEHelpers |
anErr = AEHMakeEventSignatureTarget('APPC', 'apcp', kAECoreSuite, kAESetData, &theEvent); |
if (anErr == noErr) // if it worked |
{ |
AEDesc containerObj = {typeNull, nil}; // always init AEDescs |
AEDesc propertyObject = {typeNull, nil}; // always init AEDescs |
anErr = MakePictureProperty(pIndex,&containerObj, &propertyObject); |
if (anErr == noErr) // if it worked |
{ |
anErr = AEPutParamDesc(&theEvent, keyDirectObject, &propertyObject); |
AEDisposeDesc(&propertyObject); // Always dispose ASAP |
if (anErr == noErr) // if it worked |
{ |
AEDesc tAEObject = {typeNull, nil}; // always init AEDescs |
anErr = AECoerceDesc(pAEDesc,typeAlias,&tAEObject); // coerce pAEDesc to type alias |
if (anErr == noErr) // if it worked |
{ |
anErr = AEPutParamDesc(&theEvent, keyAEData, &tAEObject); |
AEDisposeDesc(&tAEObject); // Always dispose ASAP |
if (anErr == noErr) // if it worked |
{ |
anErr = AEHSendEventNoReturnValue(nil, &theEvent); |
} |
} |
} |
} |
AEDisposeDesc(&theEvent); // Always dispose ASAP |
} |
if (anErr != noErr) |
DebugStr("\p|Set_DesktopPict-I-Error;error r30;"); |
return anErr; |
} |
OSErr MakePictureProperty(SInt32 pIndex, |
AEDesc* containerObjPtr, |
AEDesc* propertyObjPtr) |
{ |
AEDesc longAEDesc = {typeNull, nil}; // always init AEDescs |
SInt32 index = ((pIndex - 1) % gNumMonitors) + 1; |
OSErr anErr = AECreateDesc(typeSInt32, &index, sizeof(long), &longAEDesc); |
if (anErr == noErr) // if it worked |
{ |
AEDesc cmonAEDesc = {typeNull, nil}; // always init AEDescs |
// 'cmon' is nth (pIndex) color monitor object |
anErr = CreateObjSpecifier('cmon',containerObjPtr,formAbsolutePosition,&longAEDesc,false,&cmonAEDesc); |
AEDisposeDesc(&longAEDesc); // Always dispose ASAP |
if (anErr == noErr) // if it worked |
{ |
AEDesc dpicDesc = {typeNull, nil}; // always init AEDescs |
OSType dpicOSType = 'dpic'; // Desktop Picture |
anErr = AECreateDesc('type', &dpicOSType, sizeof(OSType), &dpicDesc); |
if (anErr == noErr) // if it worked |
{ |
anErr = CreateObjSpecifier(typeProperty,&cmonAEDesc,formPropertyID,&dpicDesc,false,propertyObjPtr); |
AEDisposeDesc(&cmonAEDesc); // Always dispose ASAP |
} |
} |
} |
return anErr; |
} |
pascal OSErr OHMakeAliasDescFromFSSpec( const FSSpecPtr fssPtr, |
AEDesc *aliasDescPtr ) |
{ |
OSErr anErr = noErr; |
AliasHandle aliasHandle; |
anErr = NewAlias( nil, fssPtr, &aliasHandle); |
if ( anErr == noErr && aliasHandle == nil ) |
{ |
anErr = paramErr; |
} |
if ( anErr == noErr ) |
{ |
anErr = OHMakeAliasDesc( aliasHandle, aliasDescPtr ); |
DisposeHandle( (Handle)aliasHandle ); |
} |
return anErr; |
}//end MakeAliasObject |
pascal OSErr OHMakeAliasDesc( const AliasHandle aliasHandle, |
AEDesc *aliasDescPtr ) |
{ |
OSErr anErr = noErr; |
char handleState = HGetState( (Handle)aliasHandle ); |
HLock( (Handle)aliasHandle ); |
anErr = AECreateDesc( typeAlias, *aliasHandle, GetHandleSize( (Handle)aliasHandle ), aliasDescPtr ); |
HSetState( (Handle)aliasHandle, handleState ); |
return anErr; |
}//end MakeAliasObject |
pascal OSErr AEHMakeEventSignatureTarget( const OSType targetType, |
const OSType targetCreator, |
const AEEventClass eventClass, |
const AEEventID eventID, |
AppleEvent *theEventPtr ) |
{ |
OSErr anErr = noErr; |
ProcessSerialNumber psn = { kNoProcess, kNoProcess }; |
anErr = FindProcessBySignature( targetType, targetCreator, &psn ); |
if ( anErr == noErr ) |
{ |
anErr = AEHMakeEventProcessTarget( &psn, eventClass, eventID, theEventPtr ); |
} |
return anErr; |
}//end AEHMakeEventSignatureTarget |
pascal OSErr AEHMakeEventProcessTarget( const ProcessSerialNumberPtr psnPtr, |
const AEEventClass eventClass, |
const AEEventID eventID, |
AppleEvent *theEventPtr ) |
{ |
OSErr anErr = noErr; |
AEDesc targetAppDesc = { typeNull, nil }; |
anErr = AECreateDesc (typeProcessSerialNumber, psnPtr, sizeof( ProcessSerialNumber ), &targetAppDesc); |
if ( anErr == noErr ) |
{ |
anErr = AECreateAppleEvent( eventClass, eventID, &targetAppDesc, |
kAutoGenerateReturnID, kAnyTransactionID, theEventPtr); |
} |
AEDisposeDesc( &targetAppDesc ); |
return anErr; |
}//end AEHMakeEventProcessTarget |
pascal OSErr AEHSendEventNoReturnValue( const AEIdleUPP idleProcUPP, |
const AppleEvent *theEvent ) |
{ |
OSErr anErr = noErr; |
AppleEvent theReply = { typeNull, nil }; |
AESendMode sendMode; |
if ( idleProcUPP == nil ) |
sendMode = kAENoReply; |
else |
sendMode = kAEWaitReply; |
anErr = AESend( theEvent, &theReply, sendMode, kAENormalPriority, kNoTimeOut, idleProcUPP, nil ); |
if ( anErr == noErr && sendMode == kAEWaitReply ) |
{ |
anErr = AEHGetHandlerError( &theReply ); |
} |
(void) AEDisposeDesc( &theReply ); |
return anErr; |
}//end AEHSendEventNoReturnValue |
pascal OSErr AEHGetHandlerError( const AppleEvent *reply ) |
{ |
OSErr anErr = noErr; |
OSErr handlerErr; |
DescType actualType; |
long actualSize; |
if ( reply->descriptorType != typeNull ) // there's a reply, so there may be an error |
{ |
OSErr getErrErr = noErr; |
getErrErr = AEGetParamPtr( reply, keyErrorNumber, typeShortInteger, &actualType, |
&handlerErr, sizeof( OSErr ), &actualSize ); |
if ( getErrErr != errAEDescNotFound ) // found an errorNumber parameter |
{ |
anErr = handlerErr; // so return it's value |
} |
} |
return anErr; |
}//end AEHGetHandlerError |
pascal OSErr FindProcessBySignature( const OSType targetType, |
const OSType targetCreator, |
ProcessSerialNumberPtr psnPtr ) |
{ |
OSErr anErr = noErr; |
Boolean lookingForProcess = true; |
ProcessInfoRec infoRec; |
infoRec.processInfoLength = sizeof( ProcessInfoRec ); |
infoRec.processName = nil; |
infoRec.processAppSpec = nil; |
psnPtr->lowLongOfPSN = kNoProcess; |
psnPtr->highLongOfPSN = kNoProcess; |
while ( lookingForProcess ) |
{ |
anErr = GetNextProcess( psnPtr ); |
if ( anErr != noErr ) |
{ |
lookingForProcess = false; |
} |
else |
{ |
anErr = GetProcessInformation( psnPtr, &infoRec ); |
if ( ( anErr == noErr ) |
&& ( infoRec.processType == targetType ) |
&& ( infoRec.processSignature == targetCreator ) ) |
{ |
lookingForProcess = false; |
} |
} |
} |
return anErr; |
}//end FindProcessBySignature |
OSErr LaunchProcessBySignature( |
const OSType pTargetType,const OSType pTargetCreator,ProcessSerialNumberPtr psnPtr) |
{ |
FSSpec appFSSpec; |
OSErr anErr = FindProcessBySignature(pTargetType, pTargetCreator, psnPtr); |
if (anErr == noErr) // already running |
return anErr; |
// It's not already running, so look for it (as an APPL) in the desktop database |
if (pTargetType == 'APPL') |
anErr = Find_DTDB_APPL(pTargetCreator,&appFSSpec); |
// If we haven't found it yet, search all the volumes |
if (anErr != noErr) |
anErr = Search_Volumes(pTargetType,pTargetCreator,&appFSSpec); |
// we found it, so try to launch it |
if (anErr == noErr) |
{ |
LaunchParamBlockRec tLaunchPB; |
tLaunchPB.launchBlockID = extendedBlock; |
tLaunchPB.launchEPBLength = extendedBlockLen; |
tLaunchPB.launchFileFlags = nil; |
tLaunchPB.launchControlFlags = launchContinue + launchNoFileFlags + launchDontSwitch; |
tLaunchPB.launchAppSpec = &appFSSpec; |
anErr = LaunchApplication(&tLaunchPB); |
if (anErr == noErr) |
*psnPtr = tLaunchPB.launchProcessSN; |
} |
return anErr; |
} |
OSErr Search_Volumes(const OSType pTargetType,const OSType pTargetCreator,FSSpec* pFSSpecPtr) |
{ |
SInt16 index; |
OSErr anErr = noErr; |
for (index = 1;;index++) // for each volume... |
{ |
XVolumeParam tXVPV; |
tXVPV.ioCompletion = nil; |
tXVPV.ioNamePtr = nil; |
tXVPV.ioVolIndex = index; |
anErr = PBXGetVolInfoSync(&tXVPV); // get its ioVRefNum |
if (anErr == nsvErr) // if no such volume... |
anErr = afpItemNotFound; // ...return application information not found |
if (anErr != noErr) // on error... |
break; // ...break |
anErr = Search_Volume(tXVPV.ioVRefNum,pTargetType,pTargetCreator,pFSSpecPtr); |
if (anErr == noErr) // if we found it... |
break; // ...break |
} |
return anErr; |
} |
OSErr Search_Volume(const SInt16 pVRefNum,const OSType pTargetType,const OSType pTargetCreator,FSSpec* pFSSpecPtr) |
{ |
CSParamPtr tCSParamPtr; |
OSErr anErr; |
if (!pFSSpecPtr) |
return paramErr; |
tCSParamPtr = (CSParamPtr) NewPtrClear(sizeof(CSParam)); |
if (tCSParamPtr == nil) |
return MemError(); |
// initialize the parameter block |
tCSParamPtr->ioVRefNum = pVRefNum; |
tCSParamPtr->ioMatchPtr = pFSSpecPtr; |
tCSParamPtr->ioSearchBits = fsSBFlFndrInfo; |
tCSParamPtr->ioReqMatchCount = 1; // only looking for 1 |
tCSParamPtr->ioSearchTime = 0; // no timeout |
tCSParamPtr->ioSearchInfo1 = (CInfoPBPtr) NewPtrClear(sizeof(CInfoPBRec)); |
tCSParamPtr->ioSearchInfo2 = (CInfoPBPtr) NewPtrClear(sizeof(CInfoPBRec)); |
if (tCSParamPtr->ioSearchInfo1 && tCSParamPtr->ioSearchInfo2) |
{ |
// Now see if we can create an 2K optimization buffer |
tCSParamPtr->ioOptBuffer = NewPtr(2048); |
if (tCSParamPtr->ioOptBuffer) |
tCSParamPtr->ioOptBufSize = 2048; |
else |
tCSParamPtr->ioOptBufSize = 0; // no buffer, sorry |
tCSParamPtr->ioSearchInfo1->hFileInfo.ioNamePtr = nil; |
tCSParamPtr->ioSearchInfo2->hFileInfo.ioNamePtr = nil; |
tCSParamPtr->ioSearchInfo1->hFileInfo.ioFlFndrInfo.fdType = pTargetType; |
tCSParamPtr->ioSearchInfo1->hFileInfo.ioFlFndrInfo.fdCreator = pTargetCreator; |
tCSParamPtr->ioSearchInfo2->hFileInfo.ioFlFndrInfo.fdCreator = 0xFFFFFFFF; |
tCSParamPtr->ioSearchInfo2->hFileInfo.ioFlFndrInfo.fdType = 0xFFFFFFFF; |
anErr = PBCatSearchSync(tCSParamPtr); // search sync |
// if ((anErr != noErr) || (tCSParamPtr->ioActMatchCount == 0)) |
} |
else |
anErr = MemError(); |
// no matter what happened, kill all the memory we allocated |
if (tCSParamPtr->ioSearchInfo1) |
DisposePtr((Ptr)tCSParamPtr->ioSearchInfo1); |
if (tCSParamPtr->ioSearchInfo2) |
DisposePtr((Ptr)tCSParamPtr->ioSearchInfo2); |
if (tCSParamPtr->ioOptBuffer) |
DisposePtr((Ptr)tCSParamPtr->ioOptBuffer); |
DisposePtr((Ptr)tCSParamPtr); |
return(anErr); |
} |
OSErr Find_DTDB_APPL(const OSType pTargetCreator,FSSpec* pFSSpecPtr) |
{ |
SInt16 index; |
OSErr anErr = noErr; |
for (index = 1;;index++) // for each volume... |
{ |
XVolumeParam tXVPV; |
DTPBRec deskTopDBRec; |
tXVPV.ioCompletion = nil; |
tXVPV.ioNamePtr = nil; |
tXVPV.ioVolIndex = index; |
anErr = PBXGetVolInfoSync(&tXVPV); // get its ioVRefNum |
if (anErr == nsvErr) // if no such volume... |
anErr = afpItemNotFound; // ...return application information not found |
if (anErr != noErr) // on error... |
break; // ...break |
// now get the DTDB for this volume |
deskTopDBRec.ioNamePtr = nil; |
deskTopDBRec.ioVRefNum = tXVPV.ioVRefNum; |
anErr = PBDTGetPath( &deskTopDBRec ); |
if (anErr != noErr) |
break; |
// look in this DTDB for the app with this creator |
deskTopDBRec.ioCompletion = nil; |
deskTopDBRec.ioNamePtr = pFSSpecPtr->name; |
deskTopDBRec.ioIndex = 0; |
deskTopDBRec.ioFileCreator = pTargetCreator; |
anErr = PBDTGetAPPLSync( &deskTopDBRec ); |
if (anErr == noErr) // found it |
{ // stuff our FSSpec |
pFSSpecPtr->vRefNum = deskTopDBRec.ioVRefNum; |
pFSSpecPtr->parID = deskTopDBRec.ioAPPLParID; |
break; |
} |
} |
return anErr; |
} |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-10-10