AEHelpers.c

/*
    File:       AEHelpers.c
 
    Contains:   Functions to help you when you are building and sending Apple events.
 
    Written by: Andy Bachorski  
 
    Copyright:  Copyright © 1996-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.
 
    Change History (most recent first):
                7/22/1999   Karl Groethe    Updated for Metrowerks Codewarror Pro 2.1
                
 
*/
//  Constant used to #undef PASCAL when not compiling a library
#define COMPILING_MORE_FINDER_EVENTS    true
 
//  System includes
#include <AERegistry.h>
#include <AEObjects.h>
#include <AEPackObject.h>
#include <Aliases.h>
#include <Gestalt.h>
#include <Icons.h>
 
#include <stdio.h>
#include <stdlib.h>
 
//  MoreFinderEvents includes
#include "FinderRegistry.h"
#include "MoreFinderEvents.h"
#include "TrapUtils.h"
 
//  Export symbols in this header for shared libraries
#pragma export on
#include "AEHelpers.h"
#pragma export off
 
 
// *****************************************************************************
//  Private Prototypes
// *****************************************************************************
 
pascal  OSErr   MyIconAction (ResType theIconType,
                           Handle *theIcon,
                           void *myDataPtr);
                           
/*
    Used by AEHMakeIconFamilyRecord, passed to ForEachIconDo as the IconAction
    function. Puts each icon in an icon suite into the descriptor record passed
    in the myDataPtr parameter.
*/
 
// ************************************************************************************************
 
pascal  OSErr   FindProcessBySignature( const OSType targetType,
                                        const OSType targetCreator,
                                        ProcessSerialNumberPtr psnPtr )
{
    OSErr       anErr = noErr;
    Boolean     foundTheProcess = false;
    
    ProcessInfoRec  infoRec;
    
    infoRec.processInfoLength = sizeof( ProcessInfoRec );
    infoRec.processName = nil;
    infoRec.processLocation = nil;
    infoRec.processAppSpec = nil;
    
    psnPtr->lowLongOfPSN = kNoProcess;
    psnPtr->highLongOfPSN = kNoProcess;
 
    while ( !foundTheProcess )
    {
        anErr = GetNextProcess( psnPtr );
        if ( anErr == noErr )
        {
            anErr = GetProcessInformation( psnPtr, &infoRec );
            if ( ( anErr == noErr )
                 && ( infoRec.processType == targetType )
                 && ( infoRec.processSignature == targetCreator ) )
            {
                foundTheProcess = true;
            }
        }
    }
    
    return anErr;
 
}//end FindProcessBySignature
 
// ************************************************************************************************
 
pascal  OSErr   AEHMakeAppleEventSignatureTarget( const OSType targetType,
                                                  const OSType targetCreator,
                                                  const AEEventClass eventClass,
                                                  const AEEventID eventID,
                                                        AppleEvent *theEvent )
{
    OSErr   anErr = noErr;
    
    ProcessSerialNumber     psn = { kNoProcess, kNoProcess };
    
    anErr = FindProcessBySignature( targetType, targetCreator, &psn );
    if ( anErr == noErr )
    {
        anErr = AEHMakeEventProcessTarget( &psn, eventClass, eventID, theEvent );
    }
    return anErr;
}//end AEHMakeAppleEventSignatureTarget
 
// ************************************************************************************************
 
pascal  OSErr   AEHMakeEventProcessTarget( const ProcessSerialNumberPtr psnPtr,
                                           const AEEventClass eventClass,
                                           const AEEventID eventID,
                                                 AppleEvent *theEvent )
{
    OSErr   anErr = noErr;
    AEDesc  targetAppDesc = { typeNull, nil };
    
    anErr = AECreateDesc (typeProcessSerialNumber, psnPtr, sizeof( ProcessSerialNumber ), &targetAppDesc);
 
    if ( anErr == noErr )
    {
        anErr = AECreateAppleEvent( eventClass, eventID, &targetAppDesc,
                                    kAutoGenerateReturnID, kAnyTransactionID, theEvent);
    }
    
    AEDisposeDesc( &targetAppDesc );
    
    return anErr;
}//end AEHMakeEventProcessTarget
 
// ************************************************************************************************
 
pascal  OSErr   AEHMakeEventTargetID( const TargetID *targetIDPtr,
                                      const AEEventClass eventClass,
                                      const AEEventID eventID,
                                            AppleEvent *theEvent )
{
    OSErr   anErr = noErr;
    AEDesc  targetAppDesc = { typeNull, nil };
    
    anErr = AECreateDesc (typeTargetID, targetIDPtr, sizeof( TargetID ), &targetAppDesc);
 
    if ( anErr == noErr )
    {
        anErr = AECreateAppleEvent( eventClass, eventID, &targetAppDesc,
                                    kAutoGenerateReturnID, kAnyTransactionID, theEvent);
    }
    
    AEDisposeDesc( &targetAppDesc );
    
    return anErr;
}//end AEHMakeEventProcessTarget
 
// ************************************************************************************************
 
pascal  OSErr   AEHMakeAliasDescFromFSSpec( const FSSpecPtr fssPtr,
                                            AEDesc *aliasDesc )
{
    OSErr           anErr = noErr;
    AliasHandle     aliasHandle;
    
    NewAlias( nil, fssPtr, &aliasHandle);
 
    if ( aliasHandle == nil )
    {
        anErr = paramErr;
    }
    else
    {
        anErr = AEHMakeAliasDesc( aliasHandle, aliasDesc );
        DisposeHandle( (Handle)aliasHandle );
    }
        
    return anErr;
}//end MakeAliasObject
 
// ************************************************************************************************
 
pascal  OSErr   AEHMakeAliasDesc( const AliasHandle aliasHandle,
                                        AEDesc *aliasDesc )
{
    OSErr   anErr = noErr;
    
    char    handleState = HGetState( (Handle)aliasHandle );
    HLock( (Handle)aliasHandle );
    
    anErr = AECreateDesc( typeAlias, *aliasHandle, GetHandleSize( (Handle)aliasHandle ), aliasDesc );
    
    HSetState( (Handle)aliasHandle, handleState );
    
    return anErr;
}//end MakeAliasObject
 
// ************************************************************************************************
 
pascal  OSErr   AEHMakeAliasObjectFromFSSpec( const FSSpecPtr fssPtr,
                                                    AEDesc *containerObj,
                                                    AEDesc *aliasObject )
{
    OSErr           anErr = noErr;
    AliasHandle     aliasHandle;
    
    anErr = NewAlias( nil, fssPtr, &aliasHandle);
    if ( aliasHandle == nil )
    {
        anErr = paramErr;
    }
    
    if ( anErr == noErr )
    {
        anErr = AEHMakeAliasObject( aliasHandle, containerObj, aliasObject );
    }
    
    DisposeHandle( (Handle)aliasHandle );
    
    return anErr;
}//end MakeAliasObject
 
// ************************************************************************************************
 
pascal  OSErr   AEHMakeAliasObject( const AliasHandle aliasHandle,
                                          AEDesc *containerObj,
                                          AEDesc *aliasObject )
{
    OSErr   anErr = noErr;
    AEDesc  aliasDesc;
 
    char    handleState = HGetState( (Handle)aliasHandle );
    HLock( (Handle)aliasHandle );
    
    anErr = AECreateDesc( typeAlias, *aliasHandle, GetHandleSize( (Handle)aliasHandle ), &aliasDesc );
    HSetState( (Handle)aliasHandle, handleState );
    
    if ( anErr == noErr )
    {
        anErr = CreateObjSpecifier( typeAlias, containerObj, formAbsolutePosition,
                                    &aliasDesc, true, aliasObject );
        AEDisposeDesc( &aliasDesc );
    }
    
    return anErr;
}//end MakeAliasObject
 
// ************************************************************************************************
 
pascal  OSErr   AEHMakePropertyObject( const DescType propType,
                                             AEDesc *containerObj,
                                             AEDesc *propertyObj )
{
    OSErr   anErr = noErr;
    AEDesc  propDesc;
    
    anErr = AECreateDesc( typeType, &propType, sizeof( propType ), &propDesc );
    
    if ( anErr == noErr )
    {
        anErr = CreateObjSpecifier( cProperty, containerObj, formPropertyID,
                                    &propDesc, true, propertyObj );
        AEDisposeDesc( &propDesc );
    }
    
    return anErr;
}//end MakePropertyObject
 
// ************************************************************************************************
 
pascal  OSErr   AEHMakeProcessObject( const ProcessSerialNumber *psnPtr,
                                             AEDesc *containerObj,
                                             AEDesc *propertyObj )
{
    OSErr   anErr = noErr;
    AEDesc  psnDesc;
    
    anErr = AECreateDesc( typeProcessSerialNumber, psnPtr, sizeof( ProcessSerialNumber ), &psnDesc );
    
    if ( anErr == noErr )
    {
        anErr = CreateObjSpecifier( cProperty, containerObj, formPropertyID,
                                    &psnDesc, true, propertyObj );
        AEDisposeDesc( &psnDesc );
    }
    
    return anErr;
}//end MakePropertyObject
 
// ************************************************************************************************
 
pascal  OSErr   AEHMakeSelectionObject( const DescType selection,
                                              AEDesc *containerObj,
                                              AEDesc *selectionObject )
{
    OSErr   anErr = noErr;
    
    AEDesc  selectionDesc = { typeNull, nil };
    
    anErr = AECreateDesc( typeAbsoluteOrdinal, &selection, sizeof( selection ), &selectionDesc );
 
    if ( anErr == noErr )
    {
        anErr = CreateObjSpecifier( cObject, containerObj, formAbsolutePosition,
                                    &selectionDesc, true, selectionObject );
    }           
    return anErr;
}
 
// ************************************************************************************************
 
pascal  OSErr   AEHMakeIconSuite( const AEDescList *iconFamilyRecPtr,
                                        Handle *iconSuitePtr )
{
 
    static  DescType    iconTypes[] = { typeIconAndMask, type8BitIcon, type4BitIcon,
                                        typeSmallIconAndMask, typeSmall8BitIcon, typeSmall4BitIcon };
    const   long        iconTypesCnt = 6;
    
    OSErr   anErr = noErr;
    
    AEDescList  iconList = { typeNull, nil };
    
    anErr = AECoerceDesc( iconFamilyRecPtr, typeAERecord, &iconList );
    
    if ( anErr == noErr )
    {
        anErr = NewIconSuite( iconSuitePtr );
        
        if ( anErr == noErr )
        {
            long    index;
            AEDesc  iconDataDesc = { typeNull, nil };
            
            for ( index = 0; index < iconTypesCnt; index++ )
            {
                anErr = AEGetKeyDesc( &iconList, iconTypes[ index ],
                                      typeWildCard, &iconDataDesc );
                if ( anErr == noErr )
                {
                    anErr = AddIconToSuite( iconDataDesc.dataHandle,
                                            *iconSuitePtr, iconTypes[ index ] );
                }
            }
        }
    }
    AEDisposeDesc( &iconList );
 
    return anErr;
}
 
// ************************************************************************************************
 
pascal  OSErr   MyIconAction( ResType theIconType,
                              Handle *theIcon,
                              void *myDataPtr)
{
    OSErr   anErr = noErr;
    
    if ( *theIcon != nil )  // only add the icon if it's really there
    {
        AEDescList *iconFamilyRecPtr = (AEDescList*)myDataPtr;
        
        anErr = AEPutKeyPtr( iconFamilyRecPtr, theIconType, theIconType,
                             **theIcon, GetHandleSize( *theIcon ) );
    }
        
    return anErr;
}//end MyIconAction
 
// ************************************************************************************************
 
pascal  OSErr   AEHMakeIconFamilyRecord( const Handle iconSuite,
                                         const IconSelectorValue iconSelector,
                                               AEDescList *iconFamilyRecPtr )
{
    OSErr   anErr = noErr;
    AEDescList  iconList = { typeNull, nil };
    
    static  IconActionUPP iconActionUPP;
    
    if ( iconActionUPP == nil )
    {
        iconActionUPP = NewIconActionProc( &MyIconAction );
    }
    
    // create a record for the icon family
    anErr = AECreateList( nil, 0, true, &iconList );
    
    if ( anErr == noErr )
    {
        ForEachIconDo( iconSuite, iconSelector,
                       iconActionUPP, &iconList );
        
        anErr = AECoerceDesc( &iconList, typeIconFamily, iconFamilyRecPtr );
        AEDisposeDesc( &iconList );
    }
 
    return anErr;
}
 
 
 
// ************************************************************************************************
 
pascal  OSErr   AEHGetHandlerError( const AppleEvent *reply )
{
    OSErr       anErr = noErr;
    
    DescType    actualType;
    long        actualSize;
    long        handlerErr;
    
    if ( reply->descriptorType != typeNull )    // there's a reply, so there may be an error
    {
        OSErr   getErrErr = noErr;
        
        getErrErr = AEGetParamPtr( reply, keyErrorNumber, typeLongInteger, &actualType,
                                    &handlerErr, sizeof( long ), &actualSize );
        
        if ( getErrErr != errAEDescNotFound )   // found an errorNumber parameter
        {
            anErr = handlerErr;             // so return it's value
        }
    }
    return anErr;
}//end AEHGetHandlerError
 
// ************************************************************************************************
 
pascal  Boolean AEHSimpleIdleFunction( EventRecord *event,
                                      long *sleepTime,
                                      RgnHandle *mouseRgn )
{
#pragma unused( event )
    *sleepTime = 30;
    *mouseRgn = nil;
    
    return ( false );
}//end AEHSimpleIdleFunction
 
// ********************************************************
 
pascal Boolean HasAppleEvents( void )
{
    OSErr   anErr = noErr;
    
    Boolean     hasAppleEvents = false;
    
    if ( TrapAvailable( _Gestalt ) )
    {
        long    response;
        
        if ( Gestalt( gestaltAppleEventsAttr, &response ) == noErr )
        {
            hasAppleEvents = ( response & (1L << gestaltAppleEventsPresent) );
        }
    }
    else
    {
        hasAppleEvents = false;
    }
    
    return hasAppleEvents ;
}//end HasAppleEvents
 
// ********************************************************
 
pascal Boolean FinderCallsAEProcess( void )
{
    OSErr   anErr = noErr;
    
    Boolean     finderCallsAEProcess = false;
    
    if ( TrapAvailable( _Gestalt ) )
    {
        long    response;
        
        if ( Gestalt( gestaltFinderAttr, &response ) == noErr )
        {
            finderCallsAEProcess = ( response & (1L << gestaltFinderCallsAEProcess) );
        }
    }
    else
    {
        finderCallsAEProcess = false;
    }
    
    return finderCallsAEProcess ;
}//end FinderCallsAEProcess
 
// ********************************************************
 
pascal Boolean FinderIsOSLCompliant( void )
{
    OSErr   anErr = noErr;
    
    Boolean     finderIsOSLCompliant = false;
    
    if ( TrapAvailable( _Gestalt ) )
    {
        long    response;
        
        if ( Gestalt( gestaltFinderAttr, &response ) == noErr )
        {
            finderIsOSLCompliant = ( response & (1L << gestaltOSLCompliantFinder) );
        }
    }
    else
    {
        finderIsOSLCompliant = false;
    }
    
    return finderIsOSLCompliant ;
}//end FinderIsOSLCompliant
 
// ********************************************************