home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / Mark Pilgrim / Kant Generator Pro 1.0.1 / source / Shell ƒ / main.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-10-30  |  11.2 KB  |  407 lines  |  [TEXT/MMCC]

  1. #define USE_MERCUTIO        1
  2.  
  3. #include "main.h"
  4. #include "apple events.h"
  5. #include "integrity.h"
  6. #include "menus.h"
  7. #include "prefs.h"
  8. #include "environment.h"
  9. #include "error.h"
  10. #include "print meat.h"
  11. #include "graphics.h"
  12. #include "graphics dispatch.h"
  13. #include "window layer.h"
  14. #include "program globals.h"
  15. #include "kant.h"
  16. #include <AppleEvents.h>
  17. #include <EPPC.h>
  18. #if USE_MERCUTIO
  19. #include "Mercutio API.h"
  20. #endif
  21.  
  22. static    short            gTheCurrentModifiers;
  23.  
  24. void main(void)
  25. {
  26.     Boolean            programIntegrityVerified;
  27.     Boolean            programIntegritySet;
  28.     
  29.     /* do integrity check before anything else; see integrity.c for details */
  30.     programIntegrityVerified=DoIntegrityCheck(&programIntegritySet);
  31.     
  32.     /* standard program initialization stuff */
  33.     MaxApplZone();    
  34.     InitGraf(&qd.thePort);
  35.     InitFonts();
  36.     FlushEvents(everyEvent, 0);
  37.     InitWindows();
  38.     InitMenus();
  39.     TEInit();
  40.     InitDialogs(0L);
  41.     InitCursor();
  42.     GetDateTime((unsigned long*)&qd.randSeed);
  43.     
  44.     InitTheWindowLayer();
  45.     
  46.     if (!InitTheEnvironment())            /* gestalt checks and variable initialization */
  47.         HandleError(kSystemTooOld, TRUE, TRUE);        /* less than system 7.0 */
  48.     
  49.     if (!programIntegrityVerified)    /* integrity check failed */
  50.         HandleError(kProgramIntegrityNotVerified, TRUE, FALSE);
  51.     
  52.     if (programIntegritySet)    /* integrity check freshly installed */
  53.         HandleError(kProgramIntegritySet, FALSE, TRUE);
  54.     
  55.     PrefsError(PreferencesInit());    /* get prefs (create if necessary) */
  56.     
  57.     if (!InitTheMenus())        /* get menus from .rsrc and draw menu bar */
  58.         HandleError(kProgramIntegrityNotVerified, TRUE, FALSE);
  59.         
  60.     InitThePrinting();
  61.     
  62.     InitTheProgram();
  63.     
  64.     EventLoop();                    /* where it all happens (see below) */
  65.     
  66.     ShutDownEnvironment(TRUE);        /* where it all ends (see below) */
  67.     
  68.     ExitToShell();
  69. }
  70.  
  71. void EventLoop(void)
  72. {
  73.     while (!gDone)    /* gDone set by choosing "Quit" menu item or by "quit" apple event */
  74.         HandleSingleEvent(TRUE);
  75. }
  76.  
  77. Boolean HandleSingleEvent(Boolean allowContextSwitching)
  78. {
  79.     EventRecord        theEvent;
  80.     WindowPtr        front;
  81.     
  82.     if (!gCustomCursor)
  83.         SetCursor(&qd.arrow);
  84.     HiliteMenu(0);            /* normalize menubar */
  85.     
  86.     gFrontWindowIndex=0;
  87.     gFrontWindowIsOurs=FALSE;
  88.     front=FrontWindow();
  89.     if (front!=0L)    /* if there's a front window, see if it's one of ours */
  90.     {
  91.         if (WindowHasLayer(front))
  92.         {
  93.             SetPort(front);
  94.             gFrontWindowIsOurs=TRUE;
  95.             gFrontWindowIndex=GetWindowIndex(front);
  96.         }
  97.     }
  98.         
  99.     /* get an event from the queue */
  100.     WaitNextEvent(everyEvent, &theEvent, gIsInBackground ? gBackgroundWaitTime : gForegroundWaitTime, 0L);
  101.     gTheCurrentModifiers=theEvent.modifiers;
  102.     
  103.     DispatchEvents(theEvent, allowContextSwitching);    /* handle the event we just got */
  104.     
  105.     return (theEvent.what!=nullEvent);
  106. }
  107.  
  108. short GetTheModifiers(void)
  109. {
  110.     return gTheCurrentModifiers;
  111. }
  112.  
  113. void DispatchEvents(EventRecord theEvent, Boolean allowContextSwitching)
  114. {
  115.     Point            thisPoint;
  116.     short            index;
  117.     WindowPtr        theWindow;
  118.     Boolean            thisWindowIsOurs;
  119.     unsigned char    theChar;
  120.     long            dummy;
  121.     
  122.     thisWindowIsOurs=FALSE;
  123.     /* for update/activate events, see if the window in question is one of ours */
  124.     if ((theEvent.what==activateEvt) || (theEvent.what==updateEvt))
  125.     {
  126.         thisWindowIsOurs=WindowHasLayer((WindowPtr)theEvent.message);
  127.         if (thisWindowIsOurs)
  128.             index=GetWindowIndex((WindowPtr)theEvent.message);
  129.     }
  130.     else if (gFrontWindowIsOurs)    /* if front window is ours, get its window index */
  131.         index=gFrontWindowIndex;
  132.     else index=-1;
  133.     
  134.     switch (theEvent.what)
  135.     {
  136.         case nullEvent:    /* ain't nuthin' happenin' */
  137.             if (gKludgeIter<3)
  138.             {
  139.                 gKludgeIter++;
  140.             }
  141.             else
  142.             {
  143.                 if (gNeedToOpenWindow)
  144.                 {
  145.                     OpenTheIndWindow(kMainWindow);
  146.                     gNeedToOpenWindow=FALSE;
  147.                 }
  148.             }
  149.             
  150.             if (gFrontWindowIsOurs)        /* give control to window dispatch to handle null */
  151.             {
  152.                 thisPoint=theEvent.where;
  153.                 GlobalToLocal(&thisPoint);
  154.                 theWindow=FrontWindow();
  155.                 if ((WindowHasLayer(theWindow)) && (WindowIsFloat(theWindow)))
  156.                 {
  157.                     if (IdleWindowDispatch(index, thisPoint)==kPassThrough)
  158.                     {
  159.                         if ((theWindow=GetFrontDocumentWindow())!=0L)
  160.                         {
  161.                             index=GetWindowIndex(theWindow);
  162.                             SetPort(theWindow);
  163.                             thisPoint=theEvent.where;
  164.                             GlobalToLocal(&thisPoint);
  165.                             IdleWindowDispatch(index, thisPoint);
  166.                         }
  167.                     }
  168.                 }
  169.                 else
  170.                 {
  171.                     IdleWindowDispatch(index, thisPoint);
  172.                 }
  173.             }
  174.             break;
  175.         case mouseDown:    /* mouse button pressed */
  176.             HandleMouseDown(theEvent, allowContextSwitching);    /* see below for mousedown handling */
  177.             break;
  178.         case keyDown:    /* key pressed */
  179.         case autoKey:    /* key help down */
  180.             theChar=(char)(theEvent.message & charCodeMask);
  181.             if (theEvent.modifiers & cmdKey)
  182.             {
  183.                 AdjustMenus();
  184. #if USE_MERCUTIO
  185.                 dummy=PowerMenuKey(theEvent.message, theEvent.modifiers, gBuildMenu);
  186.                 if (dummy==0L)
  187. #endif
  188.                     dummy=MenuKey(theChar);
  189.                 HandleMenu(dummy);
  190.             }
  191.             else if (gFrontWindowIsOurs)    /* --> window's dispatch for keydown */
  192.             {
  193.                 theWindow=FrontWindow();
  194.                 if ((WindowHasLayer(theWindow)) && (WindowIsFloat(theWindow)))
  195.                 {
  196.                     if (KeyDownDispatch(index, theChar)==kPassThrough)
  197.                     {
  198.                         if ((theWindow=GetFrontDocumentWindow())!=0L)
  199.                         {
  200.                             index=GetWindowIndex(theWindow);
  201.                             KeyDownDispatch(index, theChar);
  202.                         }
  203.                     }
  204.                 }
  205.                 else
  206.                 {
  207.                     KeyDownDispatch(index, theChar);
  208.                 }
  209.             }
  210.             break;
  211.         case diskEvt:    /* disk insert */
  212.             if (HiWord(theEvent.message)!=noErr)    /* bad disk inserted */
  213.             {
  214.                 DILoad();    /* load disk initialization package */
  215.                 SetPt(&thisPoint, 120, 120);
  216.                 DIBadMount(thisPoint, theEvent.message);    /* give format? dialog */
  217.                 DIUnload();    /* unload 'cuz we certainly don't need it */
  218.             }
  219.             break;
  220.         case updateEvt:    /* window update */
  221.             theWindow=(WindowPtr)theEvent.message;    /* which window? */
  222.             
  223.             BeginUpdate(theWindow);        /* means: "OK, we're dealing with this now" */
  224.             
  225.             if (thisWindowIsOurs)        /* one of ours?  see graphics.c */
  226.                 UpdateTheWindow(theWindow);
  227.             
  228.             EndUpdate(theWindow);        /* means: "OK, we're done updating now" */
  229.             break;
  230.         case activateEvt:    /* window activate or deactivate */
  231.             if (thisWindowIsOurs)        /* one of ours?  send message to window dispatch */
  232.             {
  233.                 if (gIgnoreNextActivateEvent)
  234.                     gIgnoreNextActivateEvent=FALSE;
  235.                 else
  236.                 {
  237.                     if ((theEvent.modifiers & activeFlag)!=0)
  238.                         ActivateWindowDispatch(index);
  239.                     else
  240.                         DeactivateWindowDispatch(index);
  241.                 }
  242.             }
  243.             break;
  244.         case osEvt:            /* suspend or resume program execution (switch in/out) */
  245.             if (((theEvent.message>>24)&0x0FF)==suspendResumeMessage)
  246.             {
  247.                 /* keep track of whether we're in the background or foreground */
  248.                 gIsInBackground=((theEvent.message&resumeFlag)==0);
  249.                 
  250.                 if (gFrontWindowIsOurs)        /* send activate/deactivate to front window */
  251.                 {
  252.                     if (gIsInBackground)
  253.                         DeactivateWindowDispatch(index);
  254.                     else
  255.                         ActivateWindowDispatch(index);
  256.                 }
  257.                 
  258.                 /* if we just came into the foreground and we have a pending error,
  259.                    now's the time to display it */
  260.                 if ((!gIsInBackground) && (gPendingErrorRec.resultCode!=allsWell))
  261.                 {
  262.                     if (gHasNotificationManager)
  263.                         NMRemove(&gPendingErrorRec.notificationRec);        /* remove notification request */
  264.                     HandleError(gPendingErrorRec.resultCode, gPendingErrorRec.isFatal,
  265.                         gPendingErrorRec.isSmall);    /* display alert, see error.c */
  266.                     gPendingErrorRec.resultCode=allsWell;        /* ...now it is */
  267.                 }
  268.                 
  269.                 if (!gIsInBackground)
  270.                     RebuildModulesList();
  271.             }
  272.             break;
  273.         case kHighLevelEvent:    /* apple event */
  274.             AEProcessAppleEvent(&theEvent);        /* see apple events.c */
  275.             break;
  276.     }
  277. }
  278.  
  279. void HandleMouseDown(EventRecord theEvent, Boolean allowContextSwitching)
  280. {
  281.     WindowPtr        theWindow;
  282.     short            windowCode;
  283.     long            windSize;
  284.     GrafPtr            oldPort;
  285.     Rect            sizeRect;
  286.     short            index;
  287.     Point            theLocalPoint;
  288.     Boolean            thisWindowIsOurs;
  289.     long            mSelect;
  290.     
  291.     windowCode=FindWindow(theEvent.where, &theWindow);    /* which window? */
  292.  
  293.     thisWindowIsOurs=FALSE;
  294.     thisWindowIsOurs=WindowHasLayer(theWindow);
  295.     if ((thisWindowIsOurs=WindowHasLayer(theWindow))==TRUE)
  296.         index=GetWindowIndex(theWindow);
  297.     else
  298.         index=-1;
  299.     
  300.     switch (windowCode)
  301.     {
  302.         case inMenuBar:        /* in menu bar; let system take over */
  303.             AdjustMenus();
  304.             mSelect=MenuSelect(theEvent.where);
  305. //            mSelect=ManualMenuSelect(2);
  306.             HandleMenu(mSelect);
  307.             break;
  308.         case inContent:        /* in window content */
  309.             if (!MySelectWindow(theWindow))        /* didn't need to change front windows */
  310.             {
  311.                 if (gFrontWindowIsOurs)    /* inform window dispatch of mousedown */
  312.                 {
  313.                     theLocalPoint=theEvent.where;
  314.                     SetPort(theWindow);
  315.                     GlobalToLocal(&theLocalPoint);
  316.                     MouseDownDispatch(index, theLocalPoint);
  317.                 }
  318.             }
  319.             break;
  320.         case inSysWindow:    /* in system window (desk accessory) */
  321.             if (allowContextSwitching)
  322.                 SystemClick(&theEvent, theWindow);    /* let the system deal with it */
  323.             break;
  324.         case inDrag:        /* in drag _region_, that is */
  325.             /* the accepted way to draw a window */
  326.             DragWindow(theWindow, theEvent.where, &((**GetGrayRgn()).rgnBBox));
  327.             if (thisWindowIsOurs)    /* update window bounds in window data struct */
  328.             {
  329.                 SetWindowBounds(theWindow,
  330.                     (*(((WindowPeek)theWindow)->contRgn))->rgnBBox);
  331.                 theLocalPoint.v=GetWindowBounds(theWindow).top;
  332.                 theLocalPoint.h=GetWindowBounds(theWindow).left;
  333.                 SetWindowTopLeft(theWindow, theLocalPoint);
  334.                 MySelectWindow(theWindow);
  335.             }
  336.             break;
  337.         case inGoAway:        /* close box */
  338.             /* the accepted way to track a close box attempt */
  339.             if (TrackGoAway(theWindow, theEvent.where))
  340.                 DoTheCloseThing((WindowPeek)theWindow);        /* see menus.c */
  341.             break;
  342.         case inGrow:        /* grow box */
  343.             /* the accepted way to grow a window */
  344.             if (thisWindowIsOurs)
  345.             {
  346.                 if (GetGrowSizeDispatch(index, &sizeRect)==kFailure)
  347.                     sizeRect=qd.screenBits.bounds;
  348.             }
  349.             else sizeRect=qd.screenBits.bounds;
  350.             
  351.             windSize=GrowWindow(theWindow, theEvent.where, &sizeRect);
  352.             if (windSize!=0)
  353.             {
  354.                 GetPort(&oldPort);
  355.                 SetPort(theWindow);
  356.                 EraseRect(&theWindow->portRect);
  357.                 SizeWindow(theWindow, LoWord(windSize), HiWord(windSize), TRUE);
  358.                 InvalRect(&theWindow->portRect);
  359.                 SetPort(oldPort);
  360.                 
  361.                 if (thisWindowIsOurs)    /* update window bounds in window data struct */
  362.                 {
  363.                     GrowWindowDispatch(index);
  364.                     SetWindowBounds(theWindow,
  365.                         (*(((WindowPeek)theWindow)->contRgn))->rgnBBox);
  366.                     theLocalPoint.v=GetWindowBounds(theWindow).top;
  367.                     theLocalPoint.h=GetWindowBounds(theWindow).left;
  368.                     SetWindowTopLeft(theWindow, theLocalPoint);
  369.                 }
  370.             }
  371.             break;
  372.         case inZoomIn:        /* zoom box */
  373.         case inZoomOut:
  374.             /* the accepted way to track a zoom attempt */
  375.             if (TrackBox(theWindow, theEvent.where, windowCode))
  376.             {
  377.                 GetPort(&oldPort);
  378.                 SetPort(theWindow);
  379.                 ZoomWindow(theWindow, windowCode, FALSE);
  380.                 InvalRect(&theWindow->portRect);
  381.                 SetPort(oldPort);
  382.             }
  383.             
  384.             if (thisWindowIsOurs)    /* update window bounds in window data struct */
  385.             {
  386.                 ZoomWindowDispatch(index);
  387.                 SetWindowBounds(theWindow,
  388.                     (*(((WindowPeek)theWindow)->contRgn))->rgnBBox);
  389.                 theLocalPoint.v=GetWindowBounds(theWindow).top;
  390.                 theLocalPoint.h=GetWindowBounds(theWindow).left;
  391.                 SetWindowTopLeft(theWindow, theLocalPoint);
  392.             }
  393.             break;
  394.     }
  395. }
  396.  
  397. void ShutDownEnvironment(Boolean fullShutdown)
  398. {
  399.     SaveThePrefs();
  400.     if (fullShutdown)
  401.     {
  402.         ShutDownTheProgram();        /* program-specific cleanup */
  403.         ShutDownTheWindowLayer();    /* do shutdown dispatch for all windows we've used */
  404.         ShutDownTheMenus();            /* release menu resources */
  405.     }
  406. }
  407.