From 3c95a92e078e3d4362e661d621cfdfc63f36c34e Mon Sep 17 00:00:00 2001 From: dsl Date: Mon, 9 Jun 2003 18:48:40 +0000 Subject: [PATCH] More changes to improve sysinst: - pass 'menudesc' and 'arg' values to post_act() and exit_act() - add set_menu_numopt() for variable length menus - fix (badly broken) allocation/free of dynamic menus - option to allow default selection to be the exit line --- usr.bin/menuc/mdb.c | 20 +++--- usr.bin/menuc/menu_sys.def | 140 ++++++++++++++++++++----------------- usr.bin/menuc/menuc.1 | 9 +-- 3 files changed, 91 insertions(+), 78 deletions(-) diff --git a/usr.bin/menuc/mdb.c b/usr.bin/menuc/mdb.c index 986187837174..c19ed994eb36 100644 --- a/usr.bin/menuc/mdb.c +++ b/usr.bin/menuc/mdb.c @@ -1,4 +1,4 @@ -/* $NetBSD: mdb.c,v 1.31 2003/06/04 19:07:39 dsl Exp $ */ +/* $NetBSD: mdb.c,v 1.32 2003/06/09 18:48:40 dsl Exp $ */ /* * Copyright 1997 Piermont Information Systems Inc. @@ -187,8 +187,8 @@ write_menu_file (char *initcode) " WINDOW *mw;\n" " const char *helpstr;\n" " const char *exitstr;\n" - " void (*post_act)(void);\n" - " void (*exit_act)(void);\n" + " void (*post_act)(menudesc *, void *);\n" + " void (*exit_act)(menudesc *, void *);\n" "};\n" "\n" "/* defines for mopt field. */\n" @@ -197,6 +197,7 @@ write_menu_file (char *initcode) "#define MC_SCROLL 4\n" "#define MC_NOSHORTCUT 8\n" "#define MC_NOCLEAR 16\n" + "#define MC_DFLTEXIT 32\n" "#define MC_VALID 256\n" ); @@ -216,10 +217,11 @@ write_menu_file (char *initcode) "int new_menu(const char *title, menu_ent *opts, " "int numopts, \n" "\tint x, int y, int h, int w, int mopt,\n" - "\tvoid (*post_act)(void), " - "void (*exit_act)(void), " + "\tvoid (*post_act)(menudesc *, void *), " + "void (*exit_act)(menudesc *, void *), " "const char *help, const char *exit);\n" "void free_menu(int menu_no);\n" + "void set_menu_numopts(int, int);\n" ); (void) fprintf (out_file, "\n/* Menu names */\n"); @@ -254,8 +256,8 @@ write_menu_file (char *initcode) for (i=0; iinfo->postact.code)) { (void) fprintf (out_file, - "void menu_%d_postact(void);\n" - "void menu_%d_postact(void)\n{", i, i); + "static void menu_%d_postact(menudesc *menu, void *arg);\n" + "static void menu_%d_postact(menudesc *menu, void *arg)\n{", i, i); if (menus[i]->info->postact.endwin) (void) fprintf (out_file, "\tendwin();\n" "\t__m_endwin = 1;\n"); @@ -265,8 +267,8 @@ write_menu_file (char *initcode) } if (strlen(menus[i]->info->exitact.code)) { (void) fprintf (out_file, - "void menu_%d_exitact(void);\n" - "void menu_%d_exitact(void)\n{", i, i); + "static void menu_%d_exitact(menudesc *menu, void *arg);\n" + "static void menu_%d_exitact(menudesc *menu, void *arg)\n{", i, i); if (menus[i]->info->exitact.endwin) (void) fprintf (out_file, "\tendwin();\n" "\t__m_endwin = 1;\n"); diff --git a/usr.bin/menuc/menu_sys.def b/usr.bin/menuc/menu_sys.def index fc1de4db650a..0df07804a3d9 100644 --- a/usr.bin/menuc/menu_sys.def +++ b/usr.bin/menuc/menu_sys.def @@ -1,4 +1,4 @@ -/* $NetBSD: menu_sys.def,v 1.38 2003/06/04 19:07:39 dsl Exp $ */ +/* $NetBSD: menu_sys.def,v 1.39 2003/06/09 18:48:41 dsl Exp $ */ /* * Copyright 1997 Piermont Information Systems Inc. @@ -63,16 +63,15 @@ static menudesc *menus = menu_def; #ifdef DYNAMIC_MENUS static int num_menus = 0; -static int num_avail = 0; #define DYN_INIT_NUM 32 #endif /* prototypes for in here! */ -static void init_menu(struct menudesc *m); +static void init_menu(menudesc *m); static char opt_ch(int op_no); -static void draw_menu(struct menudesc *m); -static void process_help(struct menudesc *m, int num); -static void process_req(struct menudesc *m, int num, int req); +static void draw_menu(menudesc *m); +static void process_help(menudesc *m, int num); +static void process_req(menudesc *m, void *arg, int num, int req); static int menucmd(WINDOW *w); #ifndef NULL @@ -131,7 +130,7 @@ menucmd(WINDOW *w) } static void -init_menu(struct menudesc *m) +init_menu(menudesc *m) { int wmax; int hadd, wadd, exithadd; @@ -148,8 +147,6 @@ init_menu(struct menudesc *m) /* Calculate h? h == number of visible options. */ if (m->h == 0) m->h = m->numopts + exithadd; - else - m->h -= hadd; m->h = MIN(m->h, max_lines - m->y - hadd); if (m->h < m->numopts + exithadd) { @@ -230,7 +227,7 @@ opt_ch(int op_no) } static void -draw_menu_line(struct menudesc *m, int i, int cury, char opt, const char *text) +draw_menu_line(menudesc *m, int i, int cury, char opt, const char *text) { int hasbox = m->mopt & MC_NOBOX ? 0 : 1; @@ -247,7 +244,7 @@ draw_menu_line(struct menudesc *m, int i, int cury, char opt, const char *text) } static void -draw_menu(struct menudesc *m) +draw_menu(menudesc *m) { int opt; int hasbox, cury, maxy; @@ -275,6 +272,12 @@ draw_menu(struct menudesc *m) maxy += tadd; } + if (m->cursel == -1) { + m->cursel = m->numopts; + if (m->h <= m->numopts) + m->topline = m->numopts + 1 - m->h; + } + for (opt = m->topline; opt < m->numopts; opt++) { if (cury >= maxy) break; @@ -304,7 +307,7 @@ draw_menu(struct menudesc *m) static void /*ARGSUSED*/ -process_help(struct menudesc *m, int num) +process_help(menudesc *m, int num) { const char *help = m->helpstr; int lineoff = 0; @@ -375,16 +378,10 @@ process_help(struct menudesc *m, int num) mbeep(); } while (again); } while (winin != 'q'); - - /* Restore current menu */ - wclear(stdscr); - wrefresh(stdscr); - if (m->post_act) - (*m->post_act)(); } static void -process_req(struct menudesc *m, int num, int req) +process_req(menudesc *m, void *arg, int num, int req) { int ch; int hasexit = (m->mopt & MC_NOEXITOPT ? 0 : 1); @@ -414,15 +411,15 @@ process_req(struct menudesc *m, int num, int req) m->topline -= 1; break; + case REQ_HELP: + process_help(m, num); + /* FALLTHROUGH */ + case REQ_REDISPLAY: wclear(stdscr); wrefresh(stdscr); if (m->post_act) - (*m->post_act)(); - break; - - case REQ_HELP: - process_help(m, num); + (*m->post_act)(m, arg); break; case REQ_SCROLLUP: @@ -518,7 +515,6 @@ menu_init(void) return 2; (void)memset(menus, 0, sizeof(menudesc) * num_menus); (void)memcpy(menus, menu_def, sizeof(menudesc) * DYN_MENU_START); - num_avail = num_menus - DYN_MENU_START; #endif __menu_init = 1; @@ -533,7 +529,7 @@ process_menu(int num, void *arg) int last_num; menu_ent *opt; - struct menudesc *m; + menudesc *m; m = &menus[num]; @@ -553,9 +549,12 @@ process_menu(int num, void *arg) if (m->mw == NULL) init_menu(m); - /* Always preselect option 0 and display from 0! */ - m->cursel = 0; + /* Default to select option 0 and display from 0 */ m->topline = 0; + if ((m->mopt & (MC_DFLTEXIT | MC_NOEXITOPT)) == MC_DFLTEXIT) + m->cursel = -1; + else + m->cursel = 0; while (!done) { last_num = num; @@ -566,11 +565,11 @@ process_menu(int num, void *arg) } /* Process the display action */ if (m->post_act) - (*m->post_act)(); + (*m->post_act)(m, arg); draw_menu(m); while ((req = menucmd(m->mw)) != REQ_EXECUTE) - process_req(m, num, req); + process_req(m, arg, num, req); sel = m->cursel; if (!(m->mopt & MC_NOCLEAR)) { @@ -608,7 +607,7 @@ process_menu(int num, void *arg) if (m->mw == NULL) init_menu(m); if (m->post_act) - (*m->post_act)(); + (*m->post_act)(m,arg); } } @@ -619,7 +618,7 @@ process_menu(int num, void *arg) /* Process the exit action */ if (m->exit_act) - (*m->exit_act)(); + (*m->exit_act)(m, arg); } /* Control L is end of standard routines, remaining only for dynamic. */ @@ -630,15 +629,13 @@ static int double_menus(void) { menudesc *temp; + int sz = sizeof(menudesc) * num_menus; - temp = malloc(sizeof(menudesc) * num_menus * 2); + temp = realloc(menus, sz * 2); if (temp == NULL) return 0; - (void)memset(temp, 0, sizeof(menudesc) * num_menus * 2); - (void)memcpy(temp, menus, sizeof(menudesc) * num_menus); - free(menus); + (void)memset(temp + num_menus, 0, sz); menus = temp; - num_avail = num_menus; num_menus *= 2; return 1; @@ -647,37 +644,37 @@ double_menus(void) int new_menu(const char *title, menu_ent *opts, int numopts, int x, int y, int h, int w, int mopt, - void (*post_act)(void), void (*exit_act)(void), + void (*post_act)(menudesc *, void *), + void (*exit_act)(menudesc *, void *), const char * help, const char *exit) { int ix; - - /* Check for free menu entry. */ - if (num_avail == 0) - if (!double_menus()) - return -1; + menudesc *m; /* Find free menu entry. */ - for (ix = DYN_MENU_START; ix < num_menus && menus[ix].mopt & MC_VALID; - ix++) /* do nothing */; - - /* if ix == num_menus ... panic */ + for (ix = DYN_MENU_START; ; ix++) { + if (ix > num_menus && !double_menus()) + return -1; + if (!(menus[ix].mopt & MC_VALID)) + break; + } /* Set Entries */ - menus[ix].title = title ? title : ""; - menus[ix].opts = opts; - menus[ix].numopts = numopts; - menus[ix].x = x; - menus[ix].y = y; - menus[ix].h = h; - menus[ix].w = w; - menus[ix].mopt = mopt | MC_VALID; - menus[ix].post_act = post_act; - menus[ix].exit_act = exit_act; - menus[ix].helpstr = help; - menus[ix].exitstr = exit ? exit : "Exit"; + m = menus + ix; + m->title = title ? title : ""; + m->opts = opts; + m->numopts = numopts; + m->x = x; + m->y = y; + m->h = h; + m->w = w; + m->mopt = mopt | MC_VALID; + m->post_act = post_act; + m->exit_act = exit_act; + m->helpstr = help; + m->exitstr = exit ? exit : "Exit"; - init_menu(&menus[ix]); + init_menu(m); return ix; } @@ -685,9 +682,22 @@ new_menu(const char *title, menu_ent *opts, int numopts, void free_menu(int menu_no) { - if (menu_no < num_menus) { - menus[menu_no].mopt &= ~MC_VALID; - if (menus[menu_no].mw != NULL) - delwin(menus[menu_no].mw); - } + menudesc *m; + + if (menu_no < 0 || menu_no >= num_menus) + return; + + m = menus + menu_no; + if ((m->mopt & MC_VALID)) + return; + if (m->mw != NULL) + delwin(m->mw); + memset(m, 0, sizeof *m); +} + +void +set_menu_numopts(int menu, int numopts) +{ + + menus[menu].numopts = numopts; } diff --git a/usr.bin/menuc/menuc.1 b/usr.bin/menuc/menuc.1 index b70496fcd4e6..e3f95262ec81 100644 --- a/usr.bin/menuc/menuc.1 +++ b/usr.bin/menuc/menuc.1 @@ -1,4 +1,4 @@ -.\" $NetBSD: menuc.1,v 1.17 2003/06/04 19:07:39 dsl Exp $ +.\" $NetBSD: menuc.1,v 1.18 2003/06/09 18:48:41 dsl Exp $ .\" .\" Copyright 1997 Piermont Information Systems Inc. .\" All rights reserved. @@ -363,8 +363,8 @@ struct menudesc { WINDOW *mw; const char *helpstr; const char *exitstr; - void (*post_act)(void); - void (*exit_act)(void); + void (*post_act)(struct menudesc *, void *); + void (*exit_act)(struct menudesc *, void *); } menudesc ; /* defines for mopt field. */ @@ -376,7 +376,8 @@ struct menudesc { int new_menu (char * title, menu_ent * opts, int numopts, int x, int y, int h, int w, int mopt, - void (*post_act)(void), void (*exit_act)(void), char * help); + void (*post_act)(struct menudesc *, void *), + void (*exit_act)(struct menudesc *, void *), char *help); void free_menu (int menu_no); .Ed