Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/usr.bin/menuc - Call delwin() when we stop displaying a wind...



details:   https://anonhg.NetBSD.org/src/rev/bed74c91e9f4
branches:  trunk
changeset: 555594:bed74c91e9f4
user:      dsl <dsl%NetBSD.org@localhost>
date:      Sat Nov 22 22:18:32 2003 +0000

description:
- Call delwin() when we stop displaying a window, saves space and newwin
  is fast enough anyway.  Lets the calling code change some fields (eg
  the title for the 'yes/no' menu) between calls.
- Don't update m->x, m->y, m->w the changed values aren't needed once
  the window has been created.
- Allow the window title to span multiple lines.
- Fix a nasty bug caused by having pointers into the memory area freed
  by realloc when creating lots of dynamic menus.
- Fix check that ought to have allowed dynamic menus to be deleted.

diffstat:

 usr.bin/menuc/menu_sys.def |  155 ++++++++++++++++++++++----------------------
 1 files changed, 78 insertions(+), 77 deletions(-)

diffs (291 lines):

diff -r 4be9eddd12dc -r bed74c91e9f4 usr.bin/menuc/menu_sys.def
--- a/usr.bin/menuc/menu_sys.def        Sat Nov 22 21:53:28 2003 +0000
+++ b/usr.bin/menuc/menu_sys.def        Sat Nov 22 22:18:32 2003 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: menu_sys.def,v 1.49 2003/11/20 13:03:44 dsl Exp $      */
+/*     $NetBSD: menu_sys.def,v 1.50 2003/11/22 22:18:32 dsl Exp $      */
 
 /*
  * Copyright 1997 Piermont Information Systems Inc.
@@ -137,30 +137,43 @@
        int wmax;
        int hadd, wadd, exithadd;
        int i;
-       const char *title;
+       int x, y, w;
+       const char *title, *tp, *ep;
 
+       x = m->x;
+       y = m->y;
+       w = m->w;
+       wmax = 0;
        hadd = ((m->mopt & MC_NOBOX) ? 0 : 2);
        wadd = ((m->mopt & MC_NOBOX) ? 2 : 4);
 
        if (m->title && *(title = MSG_XLAT(m->title)) != 0) {
-               wmax = strlen(title);
-               hadd += 2;
+               /* Allow multiple line titles */
+               for (tp = title; ep = strchr(tp, '\n'); tp = ep + 1) {
+                       i = ep - tp;
+                       wmax = MAX(wmax, i);
+                       hadd++;
+               }
+               hadd++;
+               i = strlen(tp);
+                       wmax = MAX(wmax, i);
+               if (i != 0)
+                       hadd++;
        } else {
                m->title = NULL;
                title = "untitled";
-               wmax = 0;
        }
        exithadd = ((m->mopt & MC_NOEXITOPT) ? 0 : 1);
 
 #ifdef MSG_DEFS_H
-       if (m->y == -1)
-               m->y = msg_row();
+       if (y == -1)
+               y = msg_row();
 #endif
 
        /* Calculate h? h == number of visible options. */
        if (m->h == 0)
                m->h = m->numopts + exithadd;
-       m->h = MIN(m->h, max_lines - m->y - hadd);
+       m->h = MIN(m->h, max_lines - y - hadd);
 
        if (m->h < m->numopts + exithadd || m->mopt & MC_ALWAYS_SCROLL) {
                if (!(m->mopt & (MC_SCROLL | MC_ALWAYS_SCROLL)) || m->h < 3) {
@@ -174,20 +187,9 @@
                m->h--;
        } else
                m->mopt &= ~MC_SCROLL;
-#if 0
-       /* check for screen fit */
-       if (m->y + m->h + hadd > max_lines) {
-               endwin();
-               (void)fprintf(stderr,
-                   "Screen too short (%d + %d + %d > %d) for menu \"%s\"\n",
-                       m->y, m->h, hadd, max_lines, title);
-               exit(1);
-
-       }
-#endif
 
        /* Calculate w? */
-       if (m->w == 0) {
+       if (w == 0) {
                int l;
                if (m->mopt & (MC_SCROLL | MC_ALWAYS_SCROLL)) {
                        l = strlen(scrolltext);
@@ -199,30 +201,30 @@
                                l += 3;
                        wmax = MAX(wmax, l);
                }
-               m->w = wmax;
+               w = wmax;
        }
 
        /* check and adjust for screen fit */
-       if (m->w + wadd > max_cols) {
+       if (w + wadd > max_cols) {
                endwin();
                (void)fprintf(stderr,
                        "Screen too narrow for menu \"%s\"\n", title);
                exit(1);
 
        }
-       if (m->x == -1)
-               m->x = (max_cols - (m->w + wadd)) / 2;  /* center */
-       else if (m->x + m->w + wadd > max_cols)
-               m->x = max_cols - (m->w + wadd);        /* right align */
+       if (x == -1)
+               x = (max_cols - (w + wadd)) / 2;        /* center */
+       else if (x + w + wadd > max_cols)
+               x = max_cols - (w + wadd);      /* right align */
 
        /* Get the windows. */
-       m->mw = newwin(m->h + hadd, m->w + wadd, m->y, m->x);
+       m->mw = newwin(m->h + hadd, w + wadd, y, x);
 
        if (m->mw == NULL) {
                endwin();
                (void)fprintf(stderr,
                        "Could not create window (%d + %d, %d + %d, %d, %d) for menu \"%s\"\n",
-                       m->h, hadd, m->w, wadd, m->y, m->x, title);
+                       m->h, hadd, w, wadd, y, x, title);
                exit(1);
        }
        keypad(m->mw, TRUE); /* enable multi-key assembling for win */
@@ -279,28 +281,27 @@
        int hasbox, cury, maxy;
        int tadd;
        int hasexit = (m->mopt & MC_NOEXITOPT ? 0 : 1);
+       const char *tp, *ep;
        
-       if (m->mopt & MC_NOBOX) {
-               cury = 0;
-               maxy = m->h;
-               hasbox = 0;
-       } else {
-               cury = 1;
-               maxy = m->h + 1;
-               hasbox = 1;
-       }
+       hasbox = (m->mopt & MC_NOBOX ? 0 : 1);
 
        /* Clear the window */
        wclear(m->mw);
 
+       tadd = hasbox;
        if (m->title) {
-               mvwaddstr(m->mw, hasbox, hasbox, " ");
-               waddstr(m->mw, MSG_XLAT(m->title));
-               tadd = 2;
-               cury += tadd;
-               maxy += tadd;
-       } else
-               tadd = 0;
+               for (tp = MSG_XLAT(m->title); ; tp = ep + 1) {
+                       ep = strchr(tp , '\n');
+                       mvwaddnstr(m->mw, tadd++, hasbox + 1, tp,
+                           ep ? ep - tp : -1);
+                       if (ep == NULL || *ep == 0)
+                               break;
+               }
+               tadd++;
+       }
+
+       cury = tadd;
+       maxy = getmaxy(m->mw) - hasbox;
 
        if (m->cursel == -1) {
                m->cursel = m->numopts;
@@ -336,7 +337,7 @@
        if (!(m->mopt & MC_NOBOX))
                box(m->mw, 0, 0);
 
-       wmove(m->mw, tadd + hasbox + m->cursel - m->topline, hasbox);
+       wmove(m->mw, tadd + m->cursel - m->topline, hasbox);
        wrefresh(m->mw);
 }
 
@@ -573,16 +574,13 @@
 process_menu(int num, void *arg)
 {
        int sel = 0;
-       int req, done;
-       int last_num;
+       int req;
        menu_ent *opt;
 
        menudesc *m;
 
        m = &menus[num];
 
-       done = FALSE;
-
        /* Initialize? */
        if (menu_init()) {
                __menu_initerror();
@@ -602,8 +600,7 @@
        else
                m->cursel = 0;
 
-       while (!done) {
-               last_num = num;
+       for (;;) {
                if (__m_endwin) {
                        wclear(stdscr);
                        wrefresh(stdscr);
@@ -626,32 +623,32 @@
                }
 
                /* Process the items */
-               if (sel < m->numopts) {
-                       opt = &m->opts[sel];
-                       if (opt->opt_flags & OPT_IGNORE)
+               if (sel >= m->numopts)
+                       /* exit option */
+                       break;
+
+               opt = &m->opts[sel];
+               if (opt->opt_flags & OPT_IGNORE)
+                       continue;
+               if (opt->opt_flags & OPT_ENDWIN) {
+                       endwin();
+                       __m_endwin = 1;
+               }
+               if (opt->opt_action && (*opt->opt_action)(m, arg))
+                       break;
+
+               if (opt->opt_menu != -1) {
+                       if (!(opt->opt_flags & OPT_SUB)) {
+                               num = opt->opt_menu;
+                               delwin(m->mw);
+                               m->mw = NULL;
+                               m = &menus[num];
                                continue;
-                       if (opt->opt_flags & OPT_ENDWIN) {
-                               endwin();
-                               __m_endwin = 1;
                        }
-                       if (opt->opt_action)
-                               done = (*opt->opt_action)(m, arg);
-                       if (opt->opt_menu != -1) {
-                               if (opt->opt_flags & OPT_SUB)
-                                       process_menu(opt->opt_menu, arg);
-                               else
-                                       num = opt->opt_menu;
-                       }
-
-                        if (opt->opt_flags & OPT_EXIT) 
-                                done = TRUE;
-                               
-               } else
-                       done = TRUE;
-
-               /* Reselect m just in case */
-               if (num != last_num)
-                       m = &menus[num];
+                       process_menu(opt->opt_menu, arg);
+               }
+               if (opt->opt_flags & OPT_EXIT)
+                       break;
        }
 
        if (m->mopt & MC_NOCLEAR) {
@@ -662,6 +659,8 @@
        /* Process the exit action */
        if (m->exit_act)
                (*m->exit_act)(m, arg);
+       delwin(m->mw);
+       m->mw = NULL;
 }
 
 /* Control L is end of standard routines, remaining only for dynamic. */
@@ -674,10 +673,12 @@
        menudesc *temp;
        int sz = sizeof(menudesc) * num_menus;
 
-       temp  = realloc(menus, sz * 2);
+       temp  = malloc(sz * 2);
        if (temp == NULL)
                return 0;
+       (void)memcpy(temp, menus, sz);
        (void)memset(temp + num_menus, 0, sz);
+       /* We must not free 'menus', the code may have a pointer to it */
        menus = temp;
        num_menus *= 2;
 
@@ -731,7 +732,7 @@
                return;
 
        m = menus + menu_no;
-       if ((m->mopt & MC_VALID))
+       if (!(m->mopt & MC_VALID))
                return;
        if (m->mw != NULL)
                delwin(m->mw);



Home | Main Index | Thread Index | Old Index