Original Version by Louis Tremblet CERN ECP/DS
Modified by Jason Leake RAL
Menulib is a collection of C callable functions allowing simple (basic) user interaction with a running program. Menu items are selected with keyboard input only (no mouse and no arrow keys). Applications making use of this package can even run on a dumb terminal though better results will be achieved on a VT100 compatible terminal or VT100 terminal emulator. Menulib is hierarchical, thus allowing the use of sub-menus for more complex processing.
#include "menu.h" void menu_init()
#include "menu.h" menu_t *menu_define(title) char *title;
struct menu { char title[ ]; struct menu_item *first_item_ptr; } menu_t;
#include "menu.h" menu_item_t *menu_add_item(mp, key, text, isvalid, action, hasdata) menu_t *mp; char key; char *text; int isvalid; int (*action)(); int hasdata;
struct menu_item { struct menu_item *prev; struct menu_item *next; char key; int valid; int (*action)(); item_data_t *data_p; } menu_item_t; typedef enum { integer_type, float_type, enum_type, toggle_type, string_type, text_type } valtyp_t; struct item_data { valtyp_t type; int value; float fvalue; int limits[2]; char valtxt[ ] [ ]; } item_data_t;
#include "menu.h" menu_item_t *menu_find_item(key, mp) char key; menu_t *mp;
struct menu_item { struct menu_item *prev; struct menu_item *next; char key; int valid; int (*action)(); item_data_t *data_p; } menu_item_t;
#include "menu.h" void menu_expose(mp) menu_t *mp;
Applications making use of the Menu package must be linked with: libmenu.a and libcurses. (or libcursesX.a if running from an xterm) or libtermcap.a
Linking on OS9 systems
Applications making use of the Menu package must be linked with: menulib.l and termlib.l
/* <test.c> Test program for the menu package */ #include#include "menu.h" static menu_t *mtp; static menu_item_t *mitp; int toggle_action(mp, mip) menu_t *mp; menu_item_t mip; { menu_find_item('0',mtp)->valid = menu_find_item('0',mtp)->valid ? 0 : 1; return 1; /* Normal return */ } int user_action(mp, mip) menu_t *mp; menu_item_t mip; { menu_item_t *mitp; printf("\\n\\n\\n You selected key item (%c)\\n", mip->key); printf("Press "); scanf("%*c"); return 1; /* Normal return */ } int quit_action() { return 0; /* Quit return */ } main() { menu_init (); mtp = menu_define ("Main menu"); mitp= menu_add_item (mtp, '0', "Item0: initially invalid item", 0, NULL, 0); mitp= menu_add_item (mtp, '1', "Item1: validate/invalidate item 0", 1, toggle_action, 0); mitp= menu_add_item (mtp, '2', "Item2: integer data, action", 1, user_action, 1); mitp->data_p->type = integer_type; /* integer only */ mitp->data_p->value = 17; /* default value */ mitp->data_p->limits[0] = 1; /* lower limit */ mitp->data_p->limits[1] = 99; /* upper limit */ mitp= menu_add_item (mtp, '3', "Item3: float data, action", 1, user_action, 1); mitp->data_p->type = float_type; /* floating only */ mitp->data_p->fvalue = 3.14159; /* default value */ mitp= menu_add_item (mtp, '4', "Item4: toggle data, action", 1, user_action, 1); mitp->data_p->type = toggle_type; /* toggle only */ mitp->data_p->value = 0; /* default value */ strcpy(mitp->data_p->valtxt[0], "ON"); /* text for 1st comtponent */ strcpy(mitp->data_p->valtxt[1], "OFF"); /* text for 2nd comtponent */ mitp= menu_add_item (mtp, '5', "Item5: enum data, action", 1, user_action, 1); mitp->data_p->type = enum_type; /* enumeration only */ mitp->data_p->limits[0] = 3; /* number of components */ strcpy(mitp->data_p->valtxt[0], "Low"); /* text for 1st comtponent */ strcpy(mitp->data_p->valtxt[1], "Medium"); /* text for 2nd comtponent */ strcpy(mitp->data_p->valtxt[2], "High"); /* text for 3rd comtponent */ mitp= menu_add_item (mtp, '6', "Item6: string data, action", 1, user_action, 1); mitp->data_p->type = string_type; /* string only */ mitp->data_p->value = 32; /* maximum length of string */ strcpy(mitp->data_p->valtxt[0], "a string with 32 chars max"); /* initial value */ menu_add_item (mtp, 'Q', "return action, no data", 1, quit_action, 0); menu_expose (mtp); /* On return, the user has chosen to exit */ }