home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C / Frameworks / TransSkel 3.24 / Misc / 3.07-SkelEventLoop next >
Encoding:
Text File  |  1996-01-17  |  3.3 KB  |  107 lines  |  [TEXT/KAHL]

  1. /*
  2.  * The rest of this file contains SkelEventLoop() as it was before the modifications
  3.  * made for 3.08.  I saved it to preserve for posterity the tortuous explanation
  4.  * of the "pseudo null event" problem.
  5.  */
  6.  
  7. /*
  8.  * Main loop.
  9.  *
  10.  * - Run background task if there is one.
  11.  * - Take care of DA's with SystemTask().
  12.  * - Pass event to event router.
  13.  * - If no event, call the "no-event" handler for the front window and for
  14.  * any other windows with idle procedures that are always supposed
  15.  * to run.  This is done in such a way that it is safe for idle procs
  16.  * to remove the window handler for their own window if they want
  17.  * (unlikely, but...)  This loop doesn't check whether the window is
  18.  * really a dialog window or not, but it doesn't have to, because such
  19.  * things always have a nil idle proc.
  20.  *    
  21.  * doneFlag is restored to its previous value upon exit.  This allows
  22.  * SkelEventLoop() to be called recursively.
  23.  */
  24.  
  25. void
  26. SkelEventLoop (void)
  27. {
  28. EventRecord    theEvent;
  29. WHHandle    wh, wh2;
  30. WindowPtr    w;
  31. Boolean        haveEvent;
  32. GrafPtr        tmpPort;
  33. Boolean        oldDoneFlag;
  34. long        waitTime;
  35. SkelWindIdleProcPtr    p;
  36.  
  37.     oldDoneFlag = doneFlag;        /* save in case this is a recursive call */
  38.     doneFlag = false;            /* set for this call */
  39.     while (!doneFlag)
  40.     {
  41.     /*
  42.      * Now watch carefully.  GetNextEvent() calls SystemEvent() to handle some
  43.      * DA events, and returns false if the event was handled.  However, in
  44.      * such cases the event record will still have the event that occurred,
  45.      * *not* a null event.  So haveEvent == false doesn't necessarily imply a
  46.      * null event.  You must explicitly check for it.
  47.      *
  48.      * Cannot ignore GetNextEvent() return value and assume the event contains
  49.      * a null event if the return value is false.
  50.      *
  51.      * Previous versions figured (wrongly) that haveEvent==false meant a null
  52.      * event had occurred, and passed it through to the event router, so
  53.      * that caret-blinking in dialog TextEdit items would occur.  But cmd-key
  54.      * equivalents while DA windows were in front, in particular, allowed
  55.      * already-processed DA events to get into the event router (as a
  56.      * presumptive null event, since haveEvent was false), and they got
  57.      * handled again because when the event record was examined, lo and behold,
  58.      * it had a cmd-key event!  So now this logic is used:
  59.      *
  60.      * If have a real event OR if the "non-event" is a true nullEvent,
  61.      * then process it.
  62.      */
  63.  
  64.         if (hasWNE)
  65.         {
  66.             waitTime = (inForeground ? fgWaitTime : bgWaitTime);
  67.             haveEvent = WaitNextEvent (eventMask, &theEvent, waitTime, nil);
  68.         }
  69.         else
  70.         {
  71.             SystemTask ();
  72.             haveEvent = GetNextEvent (eventMask, &theEvent);
  73.         }
  74.  
  75.         if (haveEvent || theEvent.what == nullEvent)
  76.             SkelRouteEvent (&theEvent);
  77.  
  78.         /*
  79.          * Run applicable window idle procs.  Make sure to save and restore
  80.          * the port, since idle procs for the non-active window may be run.
  81.          * None of them run when the application is suspended.
  82.          */
  83.  
  84.         if (inForeground && !haveEvent)    /* || theEvent.what == nullEvent ??? */
  85.         {
  86.             GetPort (&tmpPort);
  87.             for (wh = whList; wh != nil; wh = wh2)
  88.             {
  89.                 wh2 = (**wh).whNext;
  90.                 w = (**wh).whWind;
  91.                 if (w == FrontWindow () || !(**wh).whFrontOnly)
  92.                 {
  93.                     if ((p = (**wh).whIdle) != (SkelIdleProcPtr) nil)
  94.                     {
  95.                         if (!hasWNE)
  96.                             SystemTask ();
  97.                         SetPort (w);
  98.                         (*p) ();
  99.                     }
  100.                 }
  101.             }
  102.             SetPort (tmpPort);
  103.         }
  104.     }
  105.     doneFlag = oldDoneFlag;    /* restore in case this was a recursive call */
  106. }
  107.