cSmallDaemon.c

/*
 *  cSmallDaemon
 *
 *  7/92 Greg Robbins         based on code by C.K. Haun
 *
 *  This is a minimal faceless background application for System 7.
 *
 *  It demonstrates how to install and dispatch Apple events, as well
 *  as the other bare essentials for a faceless background app.
 *
 *  The file type for this application should be 'APPL' if it will be launched
 *  like an application or 'appe' if it will be placed into the Extensions
 *  folder and launched at startup.  'appe' files can also have an INIT resource 
 *  to put up an icon (using ShowInit) at startup.
 */
 
#include "AppleEvents.h"
#include "GestaltEqu.h"
 
#define kSleepMax 216000  // long sleep time (in ticks) to avoid stealing cycles
                          // an app which does something on null events might
                          // sleep less
 
Boolean gAppleEventsFlag, gQuitFlag;
long gSleepVal;
 
#ifdef powerc
   QDGlobals    qd;
#endif
 
 
// Apple event handlers to be installed
 
pascal OSErr DoAEOpenApplication(AppleEvent * theAppleEvent,
                                 AppleEvent * replyAppleEvent, 
                                 long refCon)
{
#pragma unused (theAppleEvent, replyAppleEvent, refCon)
    return noErr;
}
 
pascal OSErr DoAEOpenDocuments(AppleEvent * theAppleEvent,
                               AppleEvent * replyAppleEvent, 
                               long refCon)
{
#pragma unused (theAppleEvent, replyAppleEvent, refCon)
    return errAEEventNotHandled;
}
 
pascal OSErr DoAEPrintDocuments(AppleEvent * theAppleEvent,
                                AppleEvent * replyAppleEvent, 
                                long refCon)
{
#pragma unused (theAppleEvent, replyAppleEvent, refCon)
    return errAEEventNotHandled;
}
 
pascal OSErr DoAEQuitApplication(AppleEvent * theAppleEvent,
                                 AppleEvent * replyAppleEvent, 
                                 long refCon)
{
#pragma unused (theAppleEvent, replyAppleEvent, refCon)
    gQuitFlag = true;
    return noErr;
}
 
void InitAppleEventsStuff(void)
// install Apple event handlers
{
    OSErr retCode;
    
    if (gAppleEventsFlag) {
        
        retCode = AEInstallEventHandler(kCoreEventClass, kAEOpenApplication,
                    NewAEEventHandlerProc (DoAEOpenApplication), 0, false);
                                        
        if (retCode == noErr)
            retCode = AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments,
                    NewAEEventHandlerProc (DoAEOpenDocuments), 0, false);
 
        if (retCode == noErr)
            retCode = AEInstallEventHandler(kCoreEventClass, kAEPrintDocuments,
                    NewAEEventHandlerProc (DoAEPrintDocuments), 0, false);
        if (retCode == noErr)
            retCode = AEInstallEventHandler(kCoreEventClass, kAEQuitApplication,
                    NewAEEventHandlerProc (DoAEQuitApplication), 0, false);
        
        if (retCode != noErr) DebugStr("\pInstall event handler failed");
        // a better way to indicate an error is to post a notification                  
    }
}
 
void DoHighLevelEvent(EventRecord * theEventRecPtr)
// high-level event dispatching
{
    (void) AEProcessAppleEvent(theEventRecPtr);
}
 
 
main()
{
    OSErr retCode;
    long gestResponse;
    
    EventRecord mainEventRec;
    Boolean eventFlag;
    
    // faceless background apps only get a 2K stack by default.  If necessary,
    // increase the stack size here (by calling GetApplLimit to find the current
    // heap limit, and SetApplLimit to set it to a lower address, thus reserving
    // more space for the stack)
    
    // initialize QuickDraw globals
    
    InitGraf(&qd.thePort);
    
    // initialize application globals
    
    gQuitFlag = false;
    gSleepVal = kSleepMax;
    
    // is the Apple Event Manager available?
    retCode = Gestalt(gestaltAppleEventsAttr, &gestResponse);
    if (retCode == noErr &&
        (gestResponse & (1 << gestaltAppleEventsPresent)) != 0)
        gAppleEventsFlag = true;
    else gAppleEventsFlag = false;
 
    // install Apple event handlers
    InitAppleEventsStuff();
    
    // main event loop
    
    while (!gQuitFlag) {
        eventFlag = WaitNextEvent(everyEvent, &mainEventRec, gSleepVal, nil);
        
        if (mainEventRec.what == kHighLevelEvent)
            DoHighLevelEvent(&mainEventRec);
            
        // during testing, I like to call GetKeys here and check if the CapsLock
        // key is down.  If it is, set gQuitFlag so the program will exit.
    }
}