ETI menus

Calling the menu driver

The menu driver checks whether the virtualized character passed to it is an ETI menu request. If so, it performs the request and reports the results. If the character is not a menu request, the menu driver checks if the character is data, that is, a printable ASCII character. If so, it enters the character in the pattern buffer and looks for the first match among the item names. If no match is found, the menu driver deletes the character from the pattern buffer and returns E_NO_MATCH. If the character is not recognized as a menu request or data, the menu driver assumes the character is an application-defined command and returns E_UNKNOWN_COMMAND.

To illustrate a sample design for calling the menu driver, we will consider a program that permits interaction with a menu of astrological signs. ``Sample menu output (2)'' displays the menu.

   | Aries       The Ram         |
   | Taurus      The Bull        |
   | Gemini      The Twins       |
   | Cancer      The Crab        |
   | Leo         The Lion        |
   | Virgo       The Virgin      |
   | Libra       The Balance     |
   | Scorpio     The Scorpion    |
   | Sagittarius The Archer      |
   | Capricorn   The Goat        |
   | Aquarius    The Water Bearer|
   | Pisces      The Fishes      |

Sample menu output (2)

You have already seen much of the astrological sign program in previous examples. Its function get_request, for instance, appeared in ``Sample routine that translates keys into menu requests''. ``Sample program calling the menu driver'' shows its remaining routines.

   	/* This program displays a sample menu.

Omitted here are the key mapping defined by get_request; application-defined routines display_menu and erase_menu; and the curses initialization routine start_curses */

#include <string.h> #include <menu.h>

static char * PGM = (char *) 0; /* program name */

static int my_driver (m, c) /* handle application commands */ MENU * m; int c; { switch (c) { case QUIT: return TRUE; break; } beep (); /* signal error */ return FALSE; }

main (argc, argv) int argc; char * argv[]; { WINDOW * w; MENU * m; ITEM ** i; ITEM ** make_items (); void free_items (); int c, done = FALSE;

PGM = argv[0]; start_curses ();

if (! (m = new_menu (make_items ()))) error ("error return from new_menu", NULL);

display_menu (m);

/* interact with user */

w = menu_win (m);

while (! done) { switch (menu_driver (m, c = get_request (w))) { case E_OK: break; case E_UNKNOWN_COMMAND: done = my_driver (m, c); break; default: beep (); /* signal error */ break; } } erase_menu (m); end_curses (); i = menu_items (m); free_menu (m); free_items (i); exit (0); }

typedef struct { char * name; char * desc; } ITEM_RECORD;

/* item definitions */

static ITEM_RECORD signs [] = { "Aries", "The Ram", "Taurus", "The Bull", "Gemini", "The Twins", "Cancer", "The Crab", "Leo", "The Lion", "Virgo", "The Virgin", "Libra", "The Balance", "Scorpio", "The Scorpion", "Sagittarius", "The Archer", "Capricorn", "The Goat", "Aquarius", "The Water Bearer", "Pisces", "The Fishes", (char *) 0, (char *) 0, };

#define MAX_ITEM 512

static ITEM * items [MAX_ITEM + 1]; /* item buffer */

static ITEM ** make_items () /* create the items */ { int i;

for (i = 0; i < MAX_ITEM && signs[i].name; ++i) items[i] = new_item (signs[i].name, signs[i].desc);

items[i] = (ITEM *) 0; return items; }

static void free_items (i) /* free the items */ ITEM ** i; { while (*i) free_item (*i++); }

Sample program calling the menu driver

Function main first calls the application-defined routine make_items to create the items from the array signs. The value returned is passed to new_menu to create the menu. Function main then initializes curses using start_curses and displays the menu using display_menu.

In its while loop, main repeatedly calls menu_driver with the character returned by get_request. If the menu driver does not recognize the character as a request or data, it returns E_UNKNOWN_COMMAND, whereupon the application-defined routine my_driver is called with the same character. Routine my_driver processes the application-defined commands. In this example, there is only one, QUIT. If the character passed does not signify QUIT, my_driver signals an error and returns FALSE and the signal prompts the user to re-enter the character. If the character passed is the QUIT character, my_driver returns TRUE. In turn, this sets done to TRUE, and the while loop is exited.

Finally, main erases the menu, terminates low-level ETI (curses), frees the menu and its items, and exits the program.

This example shows a typical design for calling the menu driver, but it is only one of several ways you can structure a menu application.

If the menu_driver recognizes and processes the input character argument, it returns E_OK. In the following error situations, the menu_driver returns the indicated value:

system error

NULL menu

called from init/term routines E_NOT_POSTED menu is not posted E_UNKNOWN_COMMAND unknown command E_NO_MATCH item match failed E_REQUEST_DENIED recognized request failed

NOTE: Because the menu driver calls the initialization and termination routines described in the next section, it may not be called from within them. Any attempt to do so returns E_BAD_STATE.

Next topic: Establishing item and menu initialization and termination routines
Previous topic: Integer ranges for ETI key values and MENU requests

© 2004 The SCO Group, Inc. All rights reserved.
UnixWare 7 Release 7.1.4 - 27 April 2004