| EV_eventLoop | Function (ROM Call 0x158)

events.h

void EV_eventLoop (void);

Enters the loop in which main event messages are collected and dispatched.

EV_eventLoop enters the (endless) loop in which main events are collected and dispatched to the current application. In the normal operation of the calculator (i.e. when no user program is running), the TIOS is just in this loop. Calling this function in the user program makes sense (and may be very useful if you are happy with set of events which are processed in this function) only if the program installs a custom event handler using EV_captureEvents function, so the events may be trapped by the user program.
Here is the exact description what happens in the each iteration of this loop (not in exact order, but this is not important):

- If there are no activities (keypresses etc.) for a long time, and if the timer APD_TIMER expires (see OSRegisterTimer), the calculator is turned off.
- If a key is pressed, the event CM_KEYPRESS is send (using EV_sendEvent) to the current application. Note if the current application is "Home screen", this may cause evaluation of the input line (if the pressed key was ENTER key), including execution of user programs, etc. This may also cause changing of the current application (for example, if the user pressed APPS key).
- If there is a string in the event paste buffer (see EV_sendString), the content of the buffer is processed exactly as if all codes in the buffer are typed from the keyboard (i.e. a sequence of CM_KEYPRESS events are send to the current application).
- If there is no keypress, if the cursor is enabled (see CU_start) and if CURSOR_TIMER expires (see OSRegisterTimer), CM_BLINK event is send to the current application.
- If a global variable which contains the error code is non-zero, an error dialog is displayed (using ERD_dialog).
- If there are twin symbols (see SymAddTwin) in the VAT table, they are deleted. This performs cleaning up the RAM after executing of archived programs.
- If painting is enabled (see EV_suspendPainting and EV_restorePainting), event CM_WPAINT is send using EV_paintOneWindow function.
- If there are no other activities, CM_IDLE event is send to the current application, and the function idle is called.

Note that when an user ASM program is started, the current application is always "Home screen", until the user changes the current application using EV_startApp or installs thier own event driven "task" using EV_captureEvents. So, if you simply call EV_eventLoop in the your program, without previous usage of EV_captureEvents or EV_startApp, you will have an illusion that you are not in the your program but in the home screen, because all collected events will be dispatched to the "Home screen" application. Note that in this case, there is no way to exit this loop, and your program will stay "resident" and "locked" in the memory forever, although you will not be aware of the fact that your program is still "running" - you will be able to execute everything, including running other programs etc.
As EV_eventLoop enters the endless loop, the only method (and this is the proposed method in TIOS) to exit the loop is to throw an error from the user event handler installed using EV_captureEvents. This is possible because in the event loop there are no error handlers in place, so ER_throw passes control to the previous level of error handler. In terms of normal operation (i.e. while you are typing in the home screen) this is handled by EV_centralDispatcher, which restarts the event loop. However, in custom event handling it is used to return from the event loop to the calling code. To achieve this, you need to catch errors using ER_catch or using TRY ... ONERR ... ENDTRY construction. So, the typical usage of EV_eventLoop function in user programs is:

    EV_captureEvents (UserHandler);
    TRY
      EV_eventLoop ();                // The only way to exit from this is
    ONERR                             // to throw an error from the event handler!
      EV_captureEvents (NULL);
    ENDTRY

Of course, user handler must decide what to do with events dispatched by EV_eventLoop. Very nice example of usage of this methodology is given in textedit.h header file. Another example may be found with the description of CAT_dialog function. These principles are used often in the TIOS. For example, error dialogs are principally implemented as follows (although there are no obvious reasons why events are used in this example):

    void ERD_EventHandler(EVENT *ev)
    {
      if (ev->Type == CM_KEYPRESS)
        switch (ev->Key.Code)
          {
            case KEY_ENTER: ER_throw (1);
              // Exit from event loop: ENTER key pressed
            case KEY_ESC: ER_throw (2);
              // Another exit: ESC key pressed
            case KEY_OFF: EV_defaultHandler (ev);
              // OFF key pressed: allow the machine to be switched off
          }
    }

    short ERD_dialog(short err_no, short prog_flag)
    {
      EV_captureEvents (ERD_EventHandler);
      // Display the dialog
      TRY
        EV_eventLoop();
      ONERR
        switch(errCode)
          {
            case 1: // Restore the screen and return KEY_ENTER code
            case 2: // Restore the screen and return KEY_ESC code
          }
      ENDTRY
    }

To exit from EV_eventLoop, the best idea is to throw error codes less than 8, as they are never used as error codes in normal error handling.

Uses: EV_paintOneWindow, EV_sendEvent, EV_sendEventSide, ERD_dialog, HToESI, kbhit, ngetchx, ST_busy, CU_cursorState, idle, off, OSClearBreak, OSEnableBreak, OSTimerExpired, OSTimerRestart, XR_stringPtr, ERD_dismissNotice, ERD_notice, EV_currentApp, EV_errorCode, LoadSymFromFindHandle, OO_firstACB, SymDelTwin, SymFindFirst, SymFindNext, ROM Call 0x424, ROM Call 0x471
Used by: EV_centralDispatcher, EV_defaultHandler, cmd_input, cmd_inputstr, cmd_prompt, Dialog, ERD_dialog, EV_quit, GT_Trace