The <events.h> header file


  
This header file contains the following functions:
ABT_dialog                  CAT_dialog                 EV_captureEvents
EV_centralDispatcher        EV_clearPasteString        EV_defaultHandler
EV_eventLoop                EV_getAppID                EV_getc
EV_getSplitRect             EV_notifySwitchGraph       EV_paintOneWindow
EV_paintWindows             EV_registerMenu            EV_restorePainting
EV_sendEvent                EV_sendEventSide           EV_sendString
EV_setCmdCheck              EV_setCmdState             EV_setFKeyState
EV_startApp                 EV_startSide               EV_startTask
EV_suspendPainting          EV_switch                  MO_currentOptions
MO_defaults                 MO_digestOptions           MO_isMultigraphTask
MO_modeDialog               MO_notifyModeChange        MO_sendQuit
the following global variables:
EV_hook                     ModeSettings
and the following predefined types:
Bool                        EVENT                      EVENT_HANDLER
EventIDs                    HANDLE                     MO_OPTIONS
NULL                        PaintFlags                 SCR_RECT
ST_ACTIVITIES               StandardTaskIDs            StartTypes
WIN_RECT                    WINDOW                     WinFlags
NOTE: Event driving functions are intended mainly for making flash applications, although some of them may be useful even in user programs. Anyway, they are intended for serious programmers, not for the beginners. Don't try to make an event driven application if you don't understand well what is written here!


Functions


EVENT_HANDLER EV_captureEvents (EVENT_HANDLER NewHandler);

Sets the event message handler (i.e. installs an event driven application).

EV_captureEvents sets a new event message handler to the routine pointed to by NewHandler, overriding any current handler. NewHandler is the pointer of type EVENT_HANDLER, which is the pointer to a void function (i.e. procedure) which accept one parameter of EVENT type. If NewHandler is NULL, EV_captureEvents restores the standard event handler (which depends of the current application like "Home Screen", "Graph", etc.). EV_captureEvents returns the pointer to the previous installed event handler.

Any event handler is, in fact, an event driven application. All built-in flash applications like "Home screen", "Graph", "Text editor", "Geometry" etc. and all add-in flash applications are event driven applications. Also, "About" and "Catalog" dialogs and "Error message" dialogs are also event driven applications (maybe the word "applets" is better for them). The whole idea of event driving is as follows: instead of having an application which has an internal "main loop" in which all processing are performed, an event driven application accepts a message (or event), checks the type of the event (a keypress is, for example, one type of the event), process it, then exits immediately after processing the event. So, the user need to make a loop in which necessary events are collected and dispatched (using EV_sendEvent) to the application. The main advance of such approach is in the fact that the main loop is under the control of the user, even if the application itself may be written by somebody else. So, the user can decide in the loop what events will be send to an application etc. This would not be possible if the "main loop" is the part of the application itself. For example, if the user makes a loop in which events are dispatched to two or more applications, it is easy to estabilish a kind of multitasking. Note that each modern operating system (for example Windows or UNIX) is based on such event dispatching/handling mechanism!

To understand more about event driving applications, you need to read about all other functions in this header file (especially EV_eventLoop, EV_sendEvent and EV_defaultHandler may be very useful in user programs). Probably the most frequent usage of these functions in user programs will be to access the text editor application (see textedit.h header file), which is event driven. In this header file, there is also a good example about using some of event functions.

NOTE: If you want to "hook" on the existing event handler instead to complete overriding the current handler, it is better to use EV_hook.

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):
Note that when an user ASM program is started, the current application is always "Home screen", until the user change the current application using EV_startApp or install the own event driven "task" using EV_captureEvents. So, if you simple 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 is 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 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.

void EV_centralDispatcher (void);

Enters the main controlling loop of the TIOS.

As the name suggests this is the main controlling loop of the entire TIOS. This functions initializes all installed applications by sending CM_INIT event to them, starts the "Home screen" application, then calls EV_eventLoop under an error handler, so if any error appeared during execution of the event loop, it will be catched by the error handler, which will first dispatch the error code to ERD_process then restart the event loop.

NOTE: As far as I know, there is no any need to call this function from your program. This will enter the endless loop, which can not be broken even by throwing an error from the event handler (the method used to exit from EV_eventLoop), because the event loop is now executed under the internal error handler (maybe the only method to exit from such loop is using longjmp from the event handler, but I don't believe that such barbaric method would leave the system in a stable state).

short EV_getAppID (char *TaskName);

Finds a task ID number for an application.

EV_getAppID returns a task ID number for the task/application whose internal name is TaskName, or returns -1 if the application is not found. Each application (including both built-in applications and external Flash applications) has a unique internal name (max. 8 characters). This function is introduced to make compatibility with all AMS versions, because task ID numbers are inconsistent between AMS versions. On AMS 1.xx, built-in flash applications has fixed ID numbers attached to them, but on AMS 2.xx the task ID is simply the handle of the application control block (this is why it is quite hard to add flash applications on AMS 1.xx). So, always use EV_getAppID to determine the task ID number for an application Internal names of built-in applications are given in the following table:

Application nameInternal name
Home screenTIHOME
Y= EditorTIEQUED
Window EditorTIWINDED
GraphTIGRAPH
TableTITABLED
Data/Matrix EditorTIDMED
Program EditorTIPRGMED
Text EditorTITEXTED
Numeric SolverTIINSLVR
Self TestTISLFTST

NOTE: Although this function was not officially introduced before AMS 2.xx, it is here implemented to work even on AMS 1.xx! However, there is one difference between this function, and the function with the same name in Flash Studio SDK. This implementation of EV_getAppID returns -1 if the application is not found, but EV_getAppID from Flash Studio SDK returns zero under the same conditions. The convention used in Flash Studio is not consistent with the fact that "Home screen" application has the ID number 0 on AMS 1.xx. That's why the value for "not found" is slightly changed in this implementation.

void EV_sendEvent (short TaskID, EVENT *event);

Sends an event message from the current side.

EV_sendEvent sends the event message described in the structure pointed to by event to the task/application with ID number TaskID (see below for more info about task IDs). Note that the user need to pre-fill only Type field of the event structure and eventually extra field (if the message has extra information attached). All other fields will be filled by EV_sendEvent function before sending the message.

The Type field of the event structure is interpreted as following: Here is the description what EV_sendEvent exactly does: Note that task ID numbers are inconsistent between AMS versions, so always call EV_getAppID before to determine an appropriate task ID, or use special task IDs AP_CURRENT, AP_RUNNING and AP_NONE, which are AMS-independent.

If you want to send an event from the user event handler, you can enter into the infinite recursion. Here is an example how to avoid this. The following program will change the behaviour of the ENTER key to behave like pressing DIAMOND+ENTER. So, run the following program. After this, the ENTER key will behave like DIAMOND+ENTER (note that the program is "resident": it is active for whole time, although you have feeling that you are in "Home screen" for example). The ENTER key will remain redefined until the user press DIAMOND+ENTER. After this, the original function of the ENTER key is restored, and the program finishes working.
#include <tigcclib.h>

int _ti89, _ti92plus;

void Handler (EVENT *ev)
{
  if (ev->Type == CM_KEYPRESS)
    {
      if (ev->extra.Key.Code == KEY_DIAMOND + KEY_ENTER)
        ER_throwVar (1);
      if (ev->extra.Key.Code == KEY_ENTER)
        ev->extra.Key.Code = KEY_DIAMOND + KEY_ENTER;
    }
  EV_captureEvents (NULL);       // Send the event to the default
  EV_sendEvent (AP_CURRENT,ev);  // application handler, but be careful
  EV_captureEvents (Handler);    // to avoid infinite recursion!
}

void _main (void)
{
  EV_captureEvents (Handler);
  TRY
    EV_eventLoop();
  ONERR
    EV_captureEvents(NULL);
  ENDTRY
}
Of course, this program is not extremely useful: the much easier method to achieve the same functionality is to turn the calculator in "APPROX" mode. But, note that this is just an example, which should give you an idea how to redefine the keyboard.

NOTE: The destination application does not have to be started or active to receive messages. You should first start the application using EV_startApp if it is important that the application be on the screen before it receives an event.

void EV_sendEventSide (short TaskID, EVENT *event, unsigned short Side);

Sends an event message from the given side.

EV_sendEventSide is very similar to EV_sendEvent. The only difference is in the fact that EV_sendEventSide fills the field Side of the event structure with the value of parameter Side. EV_sendEvent fills this field with the current side number (0 = left or top side, 1 = right or bottom side). This field allows message handler to determine from which side (of course, in split screen mode) the message is sent, so it allows some primitive kind of multitasking.

void EV_defaultHandler (EVENT *event);

Processes an event message using the default handler.

EV_defaultHandler performs some default actions with most common messages (event is the pointer to the message which need to be processed). This function is very useful in user event handlers, and it is often called to process any unhandled messages in handlers. Not all messages are supported in EV_defaultHandler. This is a list of supported message types (unsupported types are simply ignored) together with the description of the action performed by EV_defaultHandler:

CM_ACTIVATE Registers and starts the menu for the running application (see EV_registerMenu).
CM_DEACTIVATE Ends custom and normal menus.
CM_KEYPRESS Handles tokens, system and mode keys. This is maybe the most useful action performed by EV_defaultHandler. If the keypress is a simple key (i.e. a single character), nothing will happen. If the keypress is a token (like "sin", "ln" etc.), the appropriate string is send (as a CM_STRING message) to the application. The summary effects will be that the application will receive token as a sequence of single keypresses. So, tokens are all sent via EV_sendString and do not have to be processed as single keypresses (note that this will not cause problems if called from user event handlers, although it may cause the recursion; see textedit.h header file for an useful example). If the keypress is system or mode key (see QSysKey and QModeKey), the corresponding action associated with the key (for example, opening a menu or a dialog) will be performed (see the example below this table). The chosen menu item is then sent as a CM_STRING message to the current application (note however that VAR-LINK uses a CM_HSTRING message instead), except for toolbar menus, where an appropriate menu ID is send as a message. Command keypresses STO, RCL, SWITCH, MODE, APPS, MEM, INS, CUT, PASTE etc. and OFF key (code 4363) are also handled via this handler, and all of them cause usual actions (keypresses like CUT, PASTE etc. only send an appropriate message to the application).
CM_STRING Pastes the string in the event paste buffer. More precise, it sets an internal static pointer to points to event->extra.pasteText and does not nothing more. The event loop (see EV_eventLoop) will then send the string as individual keypresses to the current application. This means that the paste buffer is exported from the code, so this allows pasting large amounts of text.
CM_HSTRING Frees the memory associated with handle event->extra.hPasteText.
CM_STORE Sends CM_KEYPRESS event filled with key code 22 (right arrow) to the current application.
CM_RECALL Performs usual actions for the RCL key (open Recall dialog, etc.). After execution of the Recall dialog, the content of the variable is sent to the current application as a CM_STRING message.

Useful examples for this functions may be found in textedit.h header file. Here is another simple example which ilustrates how you can open the "CHAR" menu. This may be useful if you want to make your user input routine which allows inserting extra characters:
EVENT ev;
...
ev.Type = CM_KEYPRESS;
ev.extra.Key.Code = KEY_CHAR;
EV_defaultHandler (&ev);
After execution of the menu, the selected character will be send as the event to the current application (it may be captured through an user event handler).

void EV_clearPasteString (void);

Clears the event paste buffer.

EV_clearPasteString clears event paste buffer, i.e. clears the static pointer to the paste buffer (see default action for CM_STRING message in EV_defaultHandler), and eventually frees the memory occupied for dinamically pasted string (sent via CM_HSTRING message).

void EV_sendString (unsigned short XR_String);

Sends XR string to the running application.

EV_sendString is an internal function which sends the XR string (see XR_stringPtr) to the running application via CM_STRING message. XR_String is the code of the XR string which will be send.

unsigned short EV_getc (unsigned short busy, EVENT *event);

Waits for the keypress, then fills an event structure with the keypress.

EV_getc is a function similar like ngetchx. It waits for a keypress, and returns the keycode of the keypress. But, in addition to ngetchx, it also fills the structure pointed to by event with appropriate CM_KEYPRESS event. Parameter busy may be ACTIVITY_IDLE, ACTIVITY_BUSY, ACTIVITY_PAUSED or ACTIVITY_NORMAL (these constants are defined in enum ST_ACTIVITIES). This parameter determines the indicator in the status line which will be displayed (see ST_busy for more info).

If there is no keypress and the cursor timer expires (cca 0.5 seconds), the message CM_BLINK is stored in the event structure instead, and the function returns zero (no keypresses). Also, this routine puts the calculator into low power mode until a character is available, and it will automatically power down the calculator if a key has not been pressed after a few minutes.

short EV_paintOneWindow (void);

Repaints the topmost window.

EV_paintOneWindows searches through a linked list of windows (see wingraph.h header file) for the first window which has WF_DIRTY flag set. If the founded window is visible (i.e. if WF_VISIBLE flag is set), the CM_WPAINT message is sent to the application which is the owner of the window (note that WinOpen stores the task ID of the current application in TaskID field of the WINDOW structure). See also notes about EV_sendEvent. After sending this message, WF_DIRTY flag of the window is cleared, and this flag is set in all other windows in the linked list of windows which overlap with this window (because repainting of this window may cause trashing of another windows).

EV_paintOneWindow returns TRUE if the window was "painted" (more precise, if CM_WPAINT message is sent), else returns FALSE (i.e. if none to paint).

Here is an example which ilustrates that painting of all TIOS windows is "event driven". Suppose that you make very simplified loop which "simulates" normal behaviour of the calculator when it is in the home screen:
while (TRUE)
  {
    EV_getc (ACTIVITY_NORMAL, &ev);
    EV_sendEvent (AP_CURRENT, &ev);
  }
If you try this program, you will notice that although you can type in statements, execute user programs etc. from this loop, nothing happens on the screen when you type in 2 + 3 <ENTER> (i.e. result 5 is not displayed). This is because the "Home screen" application didn't receive a message which forces redrawing of the Home screen. You can see that everything will be correct if you make the following loop:
while (TRUE)
  {
    EV_getc (ACTIVITY_NORMAL, &ev);
    EV_sendEvent (AP_CURRENT, &ev);
    EV_paintOneWindow ();
  }

void EV_paintWindows (void);

Repaints all windows.

If painting is enabled (see EV_suspendPainting), EV_paintWindows repeatedly calls EV_paintOneWindow until it returns FALSE (no more to paint). So, the effect will be "repainting" of all "dirty" windows.

short EV_suspendPainting (void);

Suspends window painting.

EV_suspendPainting sets a flag which indicates that window painting is suspended (see EV_eventLoop and EV_paintWindows). Returns PAINTING_ENABLED or PAINTING_SUSPENDED depending of whether painting was enabled or disabled before calling this function (these constants are defined in enum PaintFlags), so the returned value may be later used in EV_restorePainting function.

short EV_restorePainting (short blockPaint);

Restores previous state of window painting.

EV_restorePainting suspends or enables window painting, depending of whether blockPaint is PAINTING_ENABLED or PAINTING_SUSPENDED (these constants are defined in enum PaintFlags). The main purpose of this function is to restore previous state after usage of EV_suspendPainting function. EV_restorePainting also returns previous state of painting enable flag (PAINTING_ENABLED or PAINTING_SUSPENDED) before calling this function.

WIN_RECT *EV_getSplitRect (unsigned short Side);

Gets the screen rectangle for a given side.

EV_getSplitRect consults various calculator mode settings ("Split Screen": "FULL", "LEFT-RIGHT" or "TOP-BOTTOM" and "Split Aspect Ratio": "1:1", "1:2" or "2:1") to determine dimensions of the rectangular area in which the application will be executed. Parameter Side determines wanted side, and it need to be s 0 or 1 (0 = left or top side, 1 = right or bottom side). EV_getSplitRect returns the static pointer to the SCR_RECT structure which describes the determined rectangular area.

void EV_startTask (unsigned short StartType);

Starts a particular task in the running application.

EV_startTask sends CM_STARTTASK message to the running application. Field StartType of the event structure will be filled from StartType parameter of this function (this is the only message in which StartType field is significant). Field r (in extra field) of the event structure will be filled from the result of executing EV_getSplitRect function (with current side given to it as the parameter). How StartType will be interpreted, depends of the concrete application. Usually, three types of "starting" are supported: AP_START_CURRENT, AP_START_NEW and AP_START_OPEN (these constants are defined in enum StartTypes. For example, Text and Data/Matrix editor may be started in three submodes: "Current", "Open" and "New". Under normal circumstances, you should start another task with AP_START_CURRENT.

void EV_startApp (short TaskID, unsigned short StartType);

Starts an application from any state.

EV_startApp is dedicated to "start the application". It changes current application to TaskID and sends a sequence of messages to it (how they will be interpreted depends of the concrete application), so this command may be used for changing the current application.

It is not likely that following information will be very useful for you (except if you are an expert who wants to make a new high perfomance flash application), but anyway here is the pseudo-code which describes what exactly EV_startApp does:
if TaskID is equal to the current application
   if StartType is AP_START_CURRENT
      send CM_START_CURRENT to the current application
   else {change task}
      send CM_UNFOCUS, CM_DEACTIVATE and CM_ENDTASK to the current application
      call EV_startTask, passing StartTask to it
      send CM_ACTIVATE and CM_FOCUS to the current application
   endif
else {new application}
   send CM_UNFOCUS and CM_DEACTIVATE to the current application
   if TaskID is equal to the application on the other side
      and if the calculator is in "two-graph" mode
         or TaskID is not "Graph", "Window Editor", "Table" nor "Y= Editor"
            set current application to TaskID
            invert current side
            call EV_notifySwitchGraph
            if StartType is not AP_START_CURRENT
               send CM_ENDTASK to the new application
               call EV_startTask, passing StartTask to it
            endif
   else
      send CM_ENDTASK to the current application
      set current application to TaskID
      call EV_startTask, passing StartTask to it
   endif
   send CM_ACTIVATE and CM_FOCUS to the new application
endif
Under normal circumstances, you should start another application with StartType set to AP_START_CURRENT.

NOTE: Task ID numbers are inconsistent between AMS versions (see EV_getAppID for more info). So, if you for example want to start the "Numeric Solver" application, the AMS-independent way for doing this is
EV_startApp (EV_getAppID ("TIINSLVR"), AP_START_CURRENT);
Also, some common applications (like "Graph", "Table" or "Home screen") may be started safely using some commands from bascmd.h header file.

void EV_startSide (short *saveTaskID, short TaskID, unsigned short Side);

Starts the given side.

EV_startSide first sends CM_STARTTASK message to the application with ID number TaskID. Field StartType of the event structure will be set to AP_START_CURRENT, and field r (in extra field) of the event structure will be filled from the result of executing EV_getSplitRect function (with Side given to it as the parameter). See EV_startTask. This is all if the current side is not equal to Side, else messages CM_ACTIVATE and CM_FOCUS will also be send to the task TaskID and side Side (using EV_sendEventSide). EV_startSide also fills the variable pointed to by saveTaskID with TaskID (I don't know what is purpose of this). See also EV_startApp.

void EV_switch (void);

Performs switching of sides.

EV_switch performs side switching. It does nothing if the current "Split Screen" mode is "FULL". Else, it sends CM_UNFOCUS and CM_DEACTIVATE messages, inverts current side, sets the current application to the application on the other side, calls EV_notifySwitchGraph, and finally, sends CM_ACTIVATE and CM_FOCUS messages to the new application.

NOTE: In AMS 2.xx, this function is extended to allow switching between the current application and the application which last ran before the current application.

void EV_notifySwitchGraph (void);

Notify appropriate applications of graph switching.

EV_notifySwitchGraph does nothing if the calculator is not in "two-graph" mode, else sends CM_SWITCH_GRAPH message to "Graph", "Window Editor", "Table" and "Y= Editor" applications (these applications are so-called "multigraph" applications).

void EV_registerMenu (void *MenuPtr);

Attaches a menu to an application.

Applications can register toolbar menus with the system event handler. EV_registerMenu registers the toolbar menu pointed to by MenuPtr with the current application. MenuPtr is exactly the same pointer as expected in MenuBegin function. Note that registering the menu will not automatically display nor activate the menu. The application will draw the menu (using MenuBegin) on receiving of CM_ACTIVATE message. So if you for example attach a new menu on the "Home screen" application, you need to send CM_ACTIVATE message to it too. Also, before calling EV_registerMenu, CM_ACTIVATE message should to be send to the application.

When a menu is attached to the application, each keypress event (CM_KEYPRESS message) which represents keys F1, F2 etc. activates the menu (more precise, it is dispatched to MenuKey function). After execution of MenuKey, the value returned from it (this is ret_val of the selected item, see MenuAddText) is send as the event to the application. So, ret_val for each menu item must be carefully planed: if you want to have "Cut" option in the menu, its ret_val needs to be 0x720 (CM_MENU_CUT). Options which represents tokens (as in "Algebra" and "Calc" submenus) have ret_val less than 0x500, because tokens are send as XR strings (see XR_stringPtr). If you planed to create a serious event driven applications which have toolbar menus (flash application for example), it must behave on the same way (i.e. its event handler must process F-key events as described), and it must respond on CM_ACTIVATE message as described above. Of course, how to put an application in Flash ROM without TI certificate and TI professional SDK is greater problem...

NOTE: Sending NULL to EV_registerMenu unattach the toolbar menu from the application. Here is a dirty example which first removes menu from the "Home screen" application, then changes parameters of "Home screen" parent window to expand "Home screen" stack area into the menu area (but note that only reset would restore the original state after execution of this program):
EVENT ev;
ev.Type = CM_DEACTIVATE;
EV_sendEvent (AP_CURRENT, &ev);
EV_registerMenu (NULL);
ev.Type = CM_ACTIVATE;
EV_sendEvent (AP_CURRENT, &ev);
FirstWindow->Client.xy.y0 = 0;
FirstWindow->Window.xy.y0 = 0;
FirstWindow->Clip.xy.y0 = 0;

void EV_setFKeyState (unsigned short Item, short State, short Redraw);

Changes the status (active/inactive) of a toolbox in the menu associated with current application.

EV_setFKeyState changes the status of the toolbox Item (0 = first, 1 = second etc.) which belongs to the menu associated with the current application (see also MenuTopStat). State is a Boolean value: when it is TRUE, the toolbox will be active, and when it is FALSE, the toolbox will be inactive (i.e. it will be dimmed, and it can not be selected).

EV_setFKeyState also can force redrawing of the menu after changing state: to do this, set Boolean parameter Redraw to TRUE. Avoid menu redraw flicker when enabling/disabling several function keys by specifying FALSE for redraw in all but the last call to this routine.

void EV_setCmdState (unsigned short cmd, short State);

Changes the status (active/inactive) of a menu command in the current application.

EV_setCmdState is similar to EV_setFKeyState, but works with command pulldown menus associated with main toolbar menu which belongs to the current application. EV_setCmdState changes status of the command item which has its ret_val (see EV_registerMenu) equal to the cmd. For example, if you execute
EV_setCmdState (CM_MENU_CUT, FALSE);
in your program, you will see that "Cut" command in the "Home screen" menu will be disabled (note that "Home screen" is the current application if you didn't use EV_startApp in your program). CM_MENU_CUT is, of course, code of "Cut" menu command. See also MenuSubStat.

void EV_setCmdCheck (unsigned short cmd, short State);

Checks/unchecks menu command in the current application (???).

This is suspicious function related to (also suspicious) MenuCheck from menus.h header file. In according to info presented by Gareth James, EV_setCmdCheck checks/unchecks items in command pulldown menus associated with main toolbar menu which belongs to the current application. EV_setCmdCheck should check/uncheck the command item which has its ret_val (see EV_registerMenu) equal to the cmd. State should be a Boolean value: TRUE for checking and FALSE for unchecking, although value 2 is also considered from some reason. But, note that I didn't succeed to make this function working, I don't know why. Any info is welcomed.

void MO_currentOptions (void);

Fills in options structure from current mode settings.

MO_currentOptions fills the structure pointed to by ModeSettings from current mode settings. It should always be called before using MO_digestOptions.

void MO_defaults (void);

Sets default mode settings.

MO_defaults resets options structure (i.e. fills the structure pointed to by ModeSettings with default settings), then calls MO_digestOptions to dispatch these settings to applications.

void MO_digestOptions (short Folder);

Updates system mode settings from options structure.

MO_digestOptions "digests" options from ModeSettings structure into the various TIOS system variables. It should be changed after each change of options structure to notify the calculator about changes. This routine may change the status line indicators. It also notifies all applications about eventual changes, if there was any essential changes (using MO_notifyModeChange). If new mode settings need change of current application or side, it may also quit an application (see MO_sendQuit), switch sides, start a new applications/tasks etc. which in fact means sending a sequence of messages to applications (see EV_startApp etc.).

Parameter Folder is the index (ordinal number) of the current folder in the folder list. Under normal conditions, you should always pass zero to this parameter. The mode dialog box calls MO_digestOptions with non-zero argument to indicate which folder name is highlighted in the "Current Folder" popup menu.

short MO_isMultigraphTask (short TaskID);

Checks whether a task is multigraph task.

MO_isMultigraphTask returns TRUE if the task with ID number TaskID is "Y= Editor", "Window Editor", "Graph" or "Table" (these tasks are tasks which may be doubled in two different part of the screen), else returns FALSE.

void MO_notifyModeChange (short Flags);

Sends mode change notify message to all applications.

MO_notifyModeChange sends CM_MODE_CHANGE message to all applications (note that "Graph" application will first receive this message). This function also has one parameter Flags which is ignored on AMS 1.xx, but used in AMS 2.xx. It contains a set of flags which describes what exactly was changed. This parameter is attached to message in the extra field of the message, so it gives more info to applications what they need to check. At the moment, I don't have exact information what each bit in Flags represent.

void MO_sendQuit (short TaskID, short Side);

Quits an application on given side.

MO_sendQuit quits an application on side Side (0 = left/top, 1 = right/bottom). This is what pressing on QUIT key does. More precise, if Side is equal to the current side, the side will receive CM_UNFOCUS and CM_DEACTIVATE messages. After this, the application will receive CM_ENDTASK message. Finally, the application on side Side will be set to CM_NULL. If the application on side Side is already CM_NULL, nothing will be performed.

NOTE: If you don't understand what "quiting" means, try MO_sendQuit(AP_CURRENT, 0) from your program to "quit" the "Home screen" application. You will notice that the menu will dissappear. Later, executing commands will not show results in the home screen, because "repainting" of the "Home screen" window will be suspended (the application is set to CM_NULL).

void MO_modeDialog (void);

Executes "MODE" dialog.

MO_modeDialog opens the "MODE" dialog, and allows the user to set mode options. If the user pressed ENTER key, MO_digestOptions will be called to "digest" new settings to TIOS. If the user pressed ESC key, nothing will happen. In each case, the dialog will be removed from the screen after pressing ENTER or ESC.

void CAT_dialog (void);

Starts "CATALOG" dialog "applet".

"CATALOG" dialog is an event driven "applet". CAT_dialog draws the dialog on the screen, installs its own event handler, then exits (without stopping the caller program). It does not enter into a loop (like normal dialogs does) which ends only on pressing ENTER or ESC. Its event handler restores previously installed handler after pressing ENTER or ESC, but if the pressed key was ENTER key, the selected command from the catalog is send as CM_STRING message after restoring the user handler (which need to be captured via user event handler). That's why it is not so easy to use CAT_dialog in user programs, but this is also not very hard. Here is an example, which opens a "CATALOG" dialog, and displays in the help screen a message which tells what the user selected from the catalog:
#include <events.h>
#include <string.h>
#include <statline.h>

int _ti89, _ti92plus;

char *ptr = NULL;  // Global data must be initialized in "nostub" mode

void Handler (EVENT *ev)
{
  if (ev->Type == CM_STRING) ptr = ev->extra.pasteText;
  ER_throwVar (1);
}

void _main (void)
{
  EVENT ev;
  char buffer[100];
  ptr = NULL;
  EV_captureEvents (Handler);
  CAT_dialog ();
  TRY
    EV_eventLoop ();
  ONERR
    EV_captureEvents (NULL);
  ENDTRY
  if (ptr != NULL)
    {
      sprintf (buffer, "You selected \"%s\".", ptr);
      ST_helpMsg (buffer);
    }
  else ST_helpMsg ("You pressed ESC.");
  ev.Type = CM_UNFOCUS;                    // This is more due to some
  EV_sendEvent (AP_CURRENT, &ev);          // aesthetical reasons
}
Note that it is important that EV_captureEvents must be called before calling of CAT_dialog. This example is a good test whether you understand principles of event handling or not.

void ABT_dialog (void);

Starts "ABOUT" dialog "applet".

"ABOUT" dialog is an event driven "applet", which works exactly like "CATALOG" dialog applet. See CAT_dialog for more info about event driven dialogs.

Global variables


EVENT_HANDLER EV_hook;

EV_hook is a global pointer variable which points to the "hook" event handler (or NULL if there is no "hook" handler installed. Hook handler hooks events like EV_captureEvents, however, the application handler (either default application handler or user handler installed with EV_captureEvents) is still called afterwards (see EV_sendEvent for more info. This is probably meant for debugging purposes as it is never used in TIOS.

Using EV_hook you can capture all messages and process them as you like, without overriding current handlers. So, you can use it to change behaviour of some events, or add new functionalities. DoorsOS for example uses EV_hook to add SHIFT+ON feature. You also can hook the APPS key and display a different menu in which your application set will be listed (then you can start your own event driven application via EV_captureEvents). If you understood principles described in this info file, this is not so hard. If you didn't understand what is written here, don't try to play with this...

MO_OPTIONS *const ModeSettings;

ModeSettings is the constant pointer to MO_OPTIONS structure, which keeps all mode settings together. But note that this structure is "auxilary": TIOS consults other variables to check various mode settings when necessary. So, values in this structure are actual only after calling MO_currentOptions, and after changing one or more values in this structure, you need to call MO_digestOptions to inform TIOS about changes. So, if you want for example to change "Display Digits" settings to "FIX 4" and "Complex Format" to "POLAR", you should do:
MO_currentOptions ();
ModeSettings->Fix = 5;
ModeSettings->Complex = 3;
MO_digestOptions (0);

Predefined types


enum Bool

Bool is enumerated type for describing true or false values. It is defined as
enum Bool {FALSE, TRUE};

enum EventIDs

EventIDs is enumerated type for describing ID numbers of system messages (they are stored in Type field of EVENT structure. All possible ID numbers (everything is in hex) are described in the following table. "Extra field" describes which subfield in extra union field of EVENT structure is used for storing extra information (if any).

Code Message name Description Extra field
700 CM_IDLE Idle (idle is called after message sent). This message is sent to the active application when there are no other events to process. The application might use this event to take care of some background processing or update an animated display. This message is used for example in spinning of 3D graph.  
701 CM_INIT Init application. This message is sent from EV_centralDispatcher after a reset or when batteries are inserted.  
702 CM_STARTTASK Start Task (in rect r). This message is sent to a task when it is being started. r is a rectangle with the requested window location and size chosen by the user from the mode screen settings. The application passes it to WinOpen to create its initial window. StartType field of the message is checked here (see EV_startTask), because some applications display a "Current/Open/New" submenu on the APPS menu, so this field is needed to tell the application which submenu command was selected by the user. r
703 CM_ACTIVATE Activate. Applications usually respond to this message by highlighting their window border to make it apparent to the user which application is active, by setting menu command states, and by updating (or activating) registered menus (see EV_registerMenu.  
704 CM_FOCUS Focus. Applications usually respond to this message by getting Mode options, and by giving the focus to the application editor (see TE_focus in textedit.h header file). This usually means making the cursor flashing.  
705 CM_UNFOCUS UnFocus. Usually used on switching sides. When used on the text editor, it means turning of the cursor flashing.  
706 CM_DEACTIVATE DeActivate. This message is sent to the active application to inform it that it no longer holds the interactive center of attention. Applications usually respond to this message by hiding menus and releasing the memory occupied by them.  
707 CM_ENDTASK End Task. Applications usually respond to this message by hiding windows and doing various cleanups.  
708 CM_START_CURRENT Start current. This message only notifies the current application that the user has chosen to start the same application again. Usually ignored.  
710 CM_KEYPRESS Keypress. This is the most common event. Note that a lot of system and mode events (opening system menus, dialogs etc.) are also processed as keypresses. They all have correct keypresses attached to them (usually DIAMOND + ...). Tokens are usually send via EV_sendString and do not have to be processed as single keypresses. All special keypresses may be passed to EV_defaultHandler for further processing. Key
720 CM_MENU_CUT Menu command: Cut. Dedicated for cutting selected text to the clipboard. All similar (text editing) events should eventually be handled by TE_handleEvent (the default text editor handler).  
721 CM_MENU_COPY Menu command: Copy. Dedicated for copying selected text to the clipboard. Should eventually be handled by the default text editor handler.  
722 CM_MENU_PASTE Menu command: Paste. Dedicated for pasting text from the clipboard to the edit buffer at the cursor position, replacing any eventually selected text. Should eventually be handled by the default text editor handler.  
723 CM_STRING Paste static (constant) text into the event paste buffer (in fact, it only sets a pointer to PasteText). See EV_eventLoop and EV_sendString. PasteText
724 CM_HSTRING Paste dynamic text, associated with a handle. The handle is released back to the heap by the default text edit handler after the paste is complete. hPasteText
725 CM_DEL DEL (backspace) keypress. Dedicated for deleting selected text, or one character to the left of the cursor if no text is selected. Should eventually be handled by the default text editor handler.  
726 CM_CLR CLR keypress. Dedicated for clearing selected text (if no text is selected, clear from cursor to end of edit buffer, and if cursor is at end of edit buffer, clear all text from edit buffer). Should eventually be handled by the default text editor handler.  
727 CM_MENU_CLEAR Menu command: Clear. The application should decide decides what it means.  
728 CM_MENU_FIND Menu command: Find. The application should decide decides what it means.  
730 CM_INSERT Insert key. Dedicated for switching between text insert mode and overstrike mode. Should eventually be handled by the default text editor handler.  
740 CM_BLINK Flash cursor (0.5 sec timer expired, see EV_eventLoop).  
750 CM_STORE "Store" keypress. The default handler convert this message to the right arrow character.  
751 CM_RECALL "RCL" keypress. The default event handler displays a dialog box for the user to enter the name of a variable to recall. The chosen variable’s contents are pasted at the edit cursor.  
760 CM_WPAINT Paint window. Pointer to a window which need to be painted is attached. Applications should check to see if it belongs to the application and to redraw it if it is. See EV_paintWindows. These are not sent to the capturing hook, unless an application ID number is set to CM_NULL (force redraw). WinOpen stores the current application ID number in TaskId field of WINDOW structure. w
770 CM_MENU_OPEN Menu command: Open... (the application should decide how to handle this and similar event messages; there are no default actions for them).  
771 CM_MENU_SAVE_AS Menu command: Save Copy As...  
772 CM_MENU_NEW Menu command: New...  
773 CM_MENU_FORMAT Menu command: Format...  
774 CM_MENU_ABOUT Menu command: About...  
780 CM_MODE_CHANGE Notify Mode Change (see MO_notifyModeChange).  
781 CM_SWITCH_GRAPH Notify Switch Graph (this message is sent to "Graph", "Window Editor", "Table" and "Y= Editor" applications only).  
7C0 CM_GEOMETRY Geometry Open Data.  

enum StandardTaskIDs

StandardTaskIDs is enumerated type which describes standard task "magic" numbers which works independently on actual task ID numbers, so they are AMS-independent (see EV_sendEvent). It is defined as
enum StandardTaskIDs {AP_NULL = -3, AP_RUNNING = -2, AP_CURRENT = -1};
"Running" application is the application which has attached and activated toolbar menu (this does not need to be equal to "Current" application). "Null" application is special value used for overriding CM_WPAINT block (see EV_sendEvent). See also MO_sendQuit.

enum StartTypes

StartTypes is a pseudo-enumeration which describes standard "start types" used in EV_startTask command, on such way to be compatible with all AMS versions. It is defined using macros, but it behaves as it is defined as
enum StartTypes {AP_START_CURRENT = 0, AP_START_NEW = 0x10,
  AP_START_OPEN = 0x20, AP_START_ERROR = 0x30};
on AMS 1.xx, and
enum StartTypes {AP_START_CURRENT = 0, AP_START_NEW = 1,
  AP_START_OPEN = 2, AP_START_ERROR = 3};
on AMS 2.xx.

enum PaintFlags

PaintFlags is enumerated type which described constants used in EV_suspendPainting and EV_restorePainting functions. It is defined as
enum PaintFlags {PAINTING_ENABLED = 0, PAINTING_SUSPENDED = 2}

enum WinFlags

WinFlags is enumerated type for describing various flags which control the window manager. These flags are used in WinOpen command, and they are stored in WINDOW structure. Usage of some of them are still not very clear to me. See WinOpen to see what I know about them (any additional info is welcomed). WinFlags is defined as
enum WinFlags {WF_SYS_ALLOC = 0x0001, WF_STEAL_MEM = 0x0002,
  WF_DONT_REALLOC = 0x0004, WF_ROUNDEDBORDER = 0x0008,
  WF_SAVE_SCR = 0x0010, WF_DUP_SCR = 0x0020, WF_TTY = 0x0040,
  WF_ACTIVE = 0x0080, WF_NOBORDER = 0x0100, WF_NOBOLD = 0x0200,
  WF_DUP_ON = 0x0400, WF_VIRTUAL = 0x0800, WF_TITLE = 0x1000,
  WF_DIRTY = 0x2000, WF_TRY_SAVE_SCR = 0x4010, WF_VISIBLE = 0x8000};
WF_DIRTY and WF_VISIBLE are used in event driven applications, see EV_paintOneWindow function.

enum ST_ACTIVITIES

ST_ACTIVITIES is enumerated type which contains some constants used in EV_getc function. It is defined as
enum ST_ACTIVITIES {ACTIVITY_IDLE, ACTIVITY_BUSY, ACTIVITY_PAUSED,
  ACTIVITY_NORMAL};
For more info, see function ST_busy and enum ST_MODES from statline.h header file.

const NULL

NULL is a null-pointer value, defined as (void *) 0.

type EVENT_HANDLER

EVENT_HANDLER is a pointer type, which points to a void function (procedure) which accepts one parameter which is a pointer to EVENT type. It is defined as
typedef void (* EVENT_HANDLER) (EVENT *);
See EV_captureEvents and EV_hook for more info.

type HANDLE

HANDLE is a type which represents handles associated to allocated memory blocks. It is defined as
typedef unsigned short HANDLE;

type EVENT

EVENT is a structure which describes an event message which is used in event driven applications. It is defined as
typedef struct EventStruct
  {
    unsigned short Type;        // ID code of the message, see EventIDs
    unsigned short RunningApp;  // Task ID of the sender of the message
    unsigned short Side;        // Side from which message is send
    unsigned short StatusFlags; // Status line flags
    union
      { // Message-dependent extra information: see EventIDs
        WINDOW *w;
        WIN_RECT *r;
        char *pasteText;
        HANDLE hPasteText;
        struct
          {
            unsigned short Mod;  // Key modifiers (SHIFT, etc.)
            unsigned short Code; // Key code
          } Key;
      } extra;
    unsigned char StartType;   // Used only in CM_STARTTASK message
  } EVENT;

type MO_OPTIONS

MO_OPTIONS is a structure which collects all system mode settings together. All fields in this structure are in fact indices of appropriate menu options in "MODE" dialogs. The only exceptions are fields Split1App and Split2App: they contains task ID numbers of appropriate applications. This structure is defined as
typedef struct
  {
    unsigned short CurrentFolder;
    unsigned short SplitScreen;
    unsigned short NumGraphs;
    unsigned short Graph1;      // Graph mode for first application
    unsigned short Graph2;      // Graph mode for second application
    unsigned short Split1App;
    unsigned short Split2App;
    unsigned short SplitRatio;
    unsigned short Angle;
    unsigned short ExactApprox;
    unsigned short Fix;         // Display Digits
    unsigned short Exp;         // Exponential Form
    unsigned short Vector;
    unsigned short Complex;
    unsigned short Pretty;
    unsigned short Base;
    unsigned short UnitSystem;
    unsigned short CustomUnits;
  } MO_OPTIONS;

type WINDOW

WINDOW is the main window-describing structure which is used in all window-based TIOS functions. It is defied as
typedef struct WindowStruct
  {
    unsigned short Flags;      // Window flags
    unsigned char CurFont;     // Current font
    unsigned char CurAttr;     // Current attribute
    unsigned char Background;  // Current background attribute
    short TaskId;              // Task ID of owner
    short CurX, CurY;          // Current (x,y) position (relative coordinates)
    short CursorX, CursorY;    // Cursor (x,y) position
    SCR_RECT Client;           // Client region of the window (excludes border)
    SCR_RECT Window;           // Entire window region including border
    SCR_RECT Clip;             // Current clipping region
    SCR_RECT Port;             // Port region for duplicate screen
    unsigned short DupScr;     // Handle of the duplicated or saved screen area
    struct WindowStruct *Next; // Pointer to the next window in linked list
    char *Title;               // Pointer to the (optional) title
  } WINDOW;
See wingraph.h header file for more info.

type SCR_RECT

SCR_RECT is a scructure (more precise, an union) for defining a rectangular area using psysical screen coordinates. It is defined as
typedef union
  {
    struct
      {
        unsigned char x0, y0, x1, y1;
      } xy;
    unsigned long l;
  } SCR_RECT;
Instead of giving four coordinates x0, y0, x1 and y1, it is possible to give all together using a field l which is a packed long number. See graph.h and wingraph.h header files for more info.

type WIN_RECT

WIN_RECT is a scructure for defining a rectangular area using logical screen coordinates. It is defined as
typedef struct
  {
    short x0, y0, x1, y1;
  } WIN_RECT;
See graph.h and wingraph.h header files for more info.

Return to the main index