home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1997 January / macformat46.iso / Shareware Plus / Developers / Library / Grant's CGI Framework / Grant's CGI Framework / grantscgi / Util / main.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-09-20  |  7.4 KB  |  331 lines

  1. /*****
  2.  *
  3.  *    Grant's CGI Shell (Common Grant Interface :-)
  4.  *        http://arpp.carleton.ca/cgi/framework/
  5.  *
  6.  *    main.c
  7.  *
  8.  *    by Grant Neufeld
  9.  *
  10.  *    Copyright ©1995,1996 by Grant Neufeld
  11.  *
  12.  *    http://arpp.carleton.ca/cgi/framework/
  13.  *    gneufeld@ccs.carleton.ca
  14.  *    grant@acm.org
  15.  *
  16.  *    This source may be freely used as long as the copyright notice is kept in the source.
  17.  *    I ask that you let me know of any enhancements (read: bug fixes) to this code.
  18.  *    I would also like copies of (or discounts on) anything you produce using this code, please.
  19.  *
  20.  *****/
  21.  
  22. #define __MainSegment__    1
  23.  
  24. #include "MyConfiguration.h"
  25.  
  26. #include <string.h>
  27. #include <Threads.h>
  28. //#if __profile__ && __MWERKS__
  29. //#include <Profiler.h>
  30. //#endif
  31.  
  32. #include "constants.h"
  33. #include "globals.h"
  34.  
  35. #include "DebugUtil.h"
  36. #include "ErrorUtil.h"
  37. #include "EventUtil.h"
  38. #include "MemoryUtil.h"
  39. #include "MenuFunc.h"
  40. #include "ProcessUtil.h"
  41. #include "Quit.h"
  42. #include "Startup.h"
  43.  
  44.  
  45. /***  LOCAL VARIABLES  ***/
  46.  
  47. static    RgnHandle    vTheMouseRgn;
  48.     
  49.  
  50. /***  LOCAL PROTOTYPES ***/
  51.  
  52. static    void    mainEventLoop        ( void );
  53. static    void    startupToolbox        ( void );
  54. static    Boolean    initAppMemory        ( void );
  55. static    OSErr    initStackGrow        ( Size );
  56.         
  57.  
  58. /***  FUNCTIONS  ***/
  59.  
  60. /* Application entry point. */
  61. void
  62. main ( void )
  63. {
  64.     /* Application is not set to quit */
  65.     gQuit = false;
  66.     
  67.     /* Included here because of InitWindows() allocation of non-relocatable blocks.
  68.         This needs to be done before any other code segments are loaded.
  69.         IM:Processes 7-5 */
  70.     /* initialize standard toolbox managers */
  71.     startupToolbox ();
  72.     
  73.     /* Included here because of MoreMasters() allocation of non-relocatable blocks.
  74.         This needs to be done before any other code segments are loaded.
  75.         IM:Processes 7-5 */
  76.     if ( !(initAppMemory()) )
  77.     {
  78.         /* inform user of insufficient memory */
  79.         ErrorStartup ( kerrStartupMemory );
  80.         ExitToShell  ();
  81.     }
  82.     
  83. //•moved to CGI.c
  84. //    #if __profile__ && __MWERKS__
  85. //    gProfileOn = !( ProfilerInit ( collectDetailed, bestTimeBase, 20, 5 ) );
  86. //    #endif
  87.     
  88.     /* do all the needed application setup */
  89.     StartupApplication ();
  90.     
  91.     /* main loop for handling system and user events */
  92.     mainEventLoop ();
  93.     
  94. //    #if __profile__ && __MWERKS__
  95. //    if ( gProfileOn )
  96. //    {
  97. //        ProfilerDump("\p" kProfileNameStr "-" kProcessorString ".prof");
  98. //        ProfilerTerm();
  99. //    }
  100. //    #endif
  101.     
  102.     ExitToShell ();
  103. } /* main */
  104.  
  105.  
  106. /* main loop for handling system and user events.
  107.     Continuously loop until application is set to quit. */
  108. static void
  109. mainEventLoop ( void )
  110. {
  111.     #if !(kCompileWithQuitOnLowMemory)
  112.     OSErr            theErr;
  113.     #endif
  114.     Boolean            eventResult;
  115.     EventRecord        event;
  116.     short            loopCounter;
  117.     
  118.     while ( !gQuit )
  119.     {
  120.         #if !(kCompileWithQuitOnLowMemory)
  121.         /* if app doesn't quit on low memory, may need to recover emergency mem */
  122.         /* IM-Memory: 1-48 */
  123.         if ( !(IsEmergencyMemAvail()) )
  124.         {
  125.             theErr = RecoverEmergencyMemory ();
  126.             if ( theErr != noErr )
  127.             {
  128.                 gQuit = true;
  129.             }
  130.         }
  131.         #endif
  132.         
  133.         #if kCompileWithThreadsOptional
  134.         if ( gHasThreadMgr )
  135.         {
  136.         #endif
  137.             /* Yield more often if there are any sub-threads. The 'more often'
  138.                 depends on how many sub-threads there are */
  139.             if ( gThreadTotal > 1 )
  140.             {
  141.                 for ( loopCounter = nil; loopCounter < gThreadTotal; loopCounter++ )
  142.                 {
  143.                     ThreadYield ( nil, false );
  144.                 }
  145.             }
  146.             else
  147.             {
  148.                 /* just yield once if there are no sub-threads, or only one */
  149.                 ThreadYield ( nil, false );
  150.             }
  151.         #if kCompileWithThreadsOptional
  152.         }
  153.         #endif
  154.         
  155.         if ( !gQuit )
  156.         {
  157.             /* wait until the next event */
  158.             eventResult = WaitNextEvent ( everyEvent, &event, gSleepTicks, nil );
  159.             if ( eventResult != nil )
  160.             {
  161.                 /* there is an event */
  162.                 /* figure out which event and process it */
  163.                 switch ( event.what ) 
  164.                 {
  165.                     case kHighLevelEvent:
  166.                         doHighLevelEvent ( &event );
  167.                         break;
  168.                     
  169.                     #if kCompileWithForeground
  170.                     /* these are interface events, only applicable if this is a
  171.                         forground application. Faceless background applications
  172.                         will not receive these events */
  173.                     
  174.                     case mouseDown:    
  175.                         doMouseDown ( &event );
  176.                         break;
  177.                     
  178.                     case mouseUp:
  179.                         doMouseUp ( &event );
  180.                         break;
  181.                     
  182.                     case keyDown:
  183.                         doKeyDown ( &event );
  184.                         break;
  185.                     
  186.                     case autoKey:
  187.                         doAutoKey ( &event );
  188.                         break;
  189.                     
  190.                     /* typically not sent to the application. IM-MTE: 2-28 */
  191.                     case keyUp:
  192.                         doKeyUp ( &event );
  193.                         break;
  194.                     
  195.                     case activateEvt:
  196.                         doActivateEvent ( &event );
  197.                         break;
  198.         
  199.                     case updateEvt:
  200.                         doUpdateEvent ( &event );
  201.                         break;
  202.                     
  203.                     /* suspend or resume */
  204.                     case osEvt:
  205.                         doOsEvt ( &event );
  206.                         break;
  207.                     
  208.                     /* disk inserted */
  209.                     case diskEvt:
  210.                         doDiskEvt ( &event );
  211.                         break;
  212.                     
  213.                     #endif    /* kCompileWithForeground */
  214.                     
  215.                     default:
  216.                         doIdle ( &event );
  217.                         break;
  218.                 }
  219.             }
  220.             else
  221.             {
  222.                 /* no event */
  223.                 doIdle ( &event );
  224.             }
  225.         }
  226.         
  227.         if ( gQuit )
  228.         {
  229.             /* the quit flag has been set, prepare to quit. If the quit
  230.                 preparation fails, the flag will be reset and we'll continue
  231.                 with the event loop. */
  232.             QuitPrepare ( true );
  233.         }
  234.     }
  235. } /* mainEventLoop */
  236.  
  237.  
  238. /***  INITIALIZATION  ***/
  239. #pragma mark -
  240.  
  241. /* initialize standard toolbox managers */
  242. static void
  243. startupToolbox ( void )
  244. {
  245.     InitGraf    ( (Ptr)(&qd.thePort) );    /* InitGraf must be first */
  246.     
  247.     #if kCompileWithForeground
  248.     /* initialize interface managers */
  249.     
  250.     InitFonts    ();
  251.     InitWindows    ();
  252.     InitMenus    ();                        /* InitMenus must be after InitWindows */
  253.     FlushEvents    ( everyEvent, nil );    /* IM-MTE: 2-93 */
  254.     TEInit        ();
  255.     InitDialogs    ( nil );                /* InitDialogs must be after TEInit */
  256.     InitCursor    ();
  257.     
  258.     #endif
  259. } /* startupToolbox */
  260.  
  261.  
  262. /* Return true if memory initialization was successful. */
  263. static Boolean
  264. initAppMemory ( void )
  265. {
  266.     short         mstrPtrsAllocated;
  267.     long         freeMemAvail;
  268.     Boolean        success;
  269. //    Handle        sacrificeHandle;
  270.     
  271.     #if !(kCompileWithForeground)
  272.     /* Background only apps get a default 8K stack instead of 24K.
  273.         Increase stack size if set to background only - just to be on the safe side */
  274.     success = ( initStackGrow(16384) == noErr );
  275.     #endif
  276.     
  277.     /* NOTE: MaxApplZone must be called before any memory is allocated by threads
  278.         other than the main (application) thread. */
  279.     /* maximize available memory in the application heap */
  280.     MaxApplZone ();
  281.     
  282.     freeMemAvail = FreeMem ();
  283.     if ( freeMemAvail < kMinSegSize )
  284.     {
  285.         /* not enough memory for application to run */
  286.         success = false;
  287.     }
  288.     else
  289.     {
  290.         /* to avoid memory fragmentation, allocate master pointers at bottom of heap */
  291.         for ( mstrPtrsAllocated = 0; mstrPtrsAllocated < kMoreMasterCalls; mstrPtrsAllocated++ )
  292.         {
  293.             MoreMasters ();
  294.         }
  295.         
  296.         success = InitializeEmergencyMemory ( nil );
  297.     }
  298.     
  299. //    /* Allocate a 1K memory block, force it to the top of the heap, and lock it.
  300. //       This block is not used for anything - it is put at the top of the heap
  301. //       as a sacrifice because sometimes MacSLIP's VBL task trashes the end of 
  302. //       the heap.
  303. //       from "NewsWatcher" 'newswatcher.c' */
  304. //    sacrificeHandle = MemoryNewHandle ( 1024, nil );
  305. //    if ( sacrificeHandle != nil )
  306. //    {
  307. //        HLockHi ( sacrificeHandle );
  308. //    }
  309.     
  310.     return success;
  311. } /* initAppMemory */
  312.  
  313.  
  314. /*  */
  315. static OSErr
  316. initStackGrow ( Size increaseSize )
  317. {
  318.     OSErr theErr;
  319.     
  320.     my_assert ( (increaseSize % 1024) == nil, "\pinitStackGrow: size is not multiple of 1024" );
  321.     
  322.     /* Increase the stack size by lowering the heap limit. */
  323.     SetApplLimit ( (Ptr)(((unsigned long)GetApplLimit()) - increaseSize) );
  324.     theErr = MemError ();
  325.     
  326.     return theErr;
  327. } /* initStackGrow */
  328.  
  329.  
  330. /*** EOF ***/
  331.