#include "autotrak.h" #include #include "function.h" #include "extmem.h" /* Tom Jennings Communitree Group 1047 Sutter St San Francisco CA 94109 (415)-441-3088 mru: 24 Apr 91 new: 25 Jun 90 Menu execution engine. */ extern MENU initscrn; /* top of the tree -- defined in MENU.C */ static MENU *last_menu = NOMENU; /* last menu drawn */ static WINDOW *top_window; /* first window inited this menu */ static short first_time; /* flag first execution */ /* This is the high level state machine engine. */ void engine() { int i; /* These windows are drawn before all others, and are never removed, since they are in common with all menus. (The simulate and debug windows overwrite them, but are restored upon their returns.) (Oh yeah -- upon exit to DOS, we brute-force restore the original 'screen' data. */ init_window(&screen); /* clear the screen */ init_window(&fkeyback); /* draw the Fkey background */ init_window(&menust); /* menu name */ for (i= 0; i < FKEYS; i++) { /* draw all the Fkey boxes */ init_window(fkeys[i]); } top_window= fkeys[--i]; /* point to last window */ /* Draw the main menu now, then fall into the main menu execution loop. */ current_menu= &initscrn; /* set as new current menu */ /* Poll for a keyboard character. If there is a function for this menu, execute it, passing it the keystroke. (If it has a use within that function, it's returned as 0. It also allows the menu function to 'lookahead' to see if it is about to be closed (ie. keystroke == F7.)) Check to see if its a change-menu key (ie. an Fkey), if so, change menus (and return the character as 0.) If after all that the key isnt used, it was an illegal key. Also gives the function (if any) a first-time flag, to do one time initialization. */ while (1) { draw_menu(); /* (possibly) draw the menu */ current_char= keyhit(); /* get a kbd char (else 0) */ switch (current_char) { /* some are global */ case KEY_CTL_F10: case KEY_CTL_F11: exitdos(); break; case KEY_F12: /* help */ notsimulated(); current_char= NUL; } if ((int)(current_menu-> func)) /* if a function defined, */ (*current_menu-> func)(first_time); /* execute it */ first_time= 0; /* then clear it */ switch_state(); /* possibly switch state */ if (current_char != NUL) beep(); /* unused (illegal) character */ } } /* Given the current keystroke (or 0) and the current menu definition, change to another menu as indicated. When we switch menus, the millisecond clock is cleared (used by functions to do "processing") and zaps the last-day and second counters so that the clock will update immediately, if it is used. */ switch_state() { int i; switch (current_char) { case KEY_F1: i= 0; break; /* convert Fkeys */ case KEY_F2: i= 1; break; /* to indices */ case KEY_F3: i= 2; break; case KEY_F4: i= 3; break; case KEY_F5: i= 4; break; case KEY_F6: i= 5; break; case KEY_F7: i= 6; break; default: return; /* (no change) */ } if (current_menu-> fk[i].next != NOMENU) { /* if Fkey defined */ current_menu= current_menu-> fk[i].next;/* change states */ draw_menu(); current_char= NUL; /* keystroke eaten */ } } /* Given a menu structure, fill in the screen to match. Unlink any previous screen (there will be except the first time). */ static draw_menu() { int i; if (current_menu == last_menu) /* if no change, */ return; /* do nothing */ cursoroff(); /* dont need this */ if (top_window-> next_window) /* if there is one, */ unlinkchain(top_window-> next_window); /* unlink previous windows */ w_fill(&menust,current_menu-> title); /* display menu name */ status(current_menu-> stat); /* fill the status box */ for (i= 0; i < FKEYS; i++) { /* draw all the Fkey boxes */ w_fill(fkeys[i],current_menu-> fk[i].text); } for (i= 0; current_menu-> window_list[i] != NOWINDOW; i++) { init_window(current_menu-> window_list[i]); /* init all the optional windows */ } for (i= 0; i < sizeof(current_menu-> data); i++) current_menu-> data[i]= 0; /* initialize the data area */ millisec= 0L; /* reset the timer */ last_sec= -1; /* trigger clock display */ first_time= 1; /* flag the first execution */ last_menu= current_menu; /* remember it */ }