Annotation of qemu/roms/seabios/tools/kconfig/lxdialog/menubox.c, revision 1.1

1.1     ! root        1: /*
        !             2:  *  menubox.c -- implements the menu box
        !             3:  *
        !             4:  *  ORIGINAL AUTHOR: Savio Lam ([email protected])
        !             5:  *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap ([email protected])
        !             6:  *
        !             7:  *  This program is free software; you can redistribute it and/or
        !             8:  *  modify it under the terms of the GNU General Public License
        !             9:  *  as published by the Free Software Foundation; either version 2
        !            10:  *  of the License, or (at your option) any later version.
        !            11:  *
        !            12:  *  This program is distributed in the hope that it will be useful,
        !            13:  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
        !            14:  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        !            15:  *  GNU General Public License for more details.
        !            16:  *
        !            17:  *  You should have received a copy of the GNU General Public License
        !            18:  *  along with this program; if not, write to the Free Software
        !            19:  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
        !            20:  */
        !            21: 
        !            22: /*
        !            23:  *  Changes by Clifford Wolf ([email protected])
        !            24:  *
        !            25:  *  [ 1998-06-13 ]
        !            26:  *
        !            27:  *    *)  A bugfix for the Page-Down problem
        !            28:  *
        !            29:  *    *)  Formerly when I used Page Down and Page Up, the cursor would be set 
        !            30:  *        to the first position in the menu box.  Now lxdialog is a bit
        !            31:  *        smarter and works more like other menu systems (just have a look at
        !            32:  *        it).
        !            33:  *
        !            34:  *    *)  Formerly if I selected something my scrolling would be broken because
        !            35:  *        lxdialog is re-invoked by the Menuconfig shell script, can't
        !            36:  *        remember the last scrolling position, and just sets it so that the
        !            37:  *        cursor is at the bottom of the box.  Now it writes the temporary file
        !            38:  *        lxdialog.scrltmp which contains this information. The file is
        !            39:  *        deleted by lxdialog if the user leaves a submenu or enters a new
        !            40:  *        one, but it would be nice if Menuconfig could make another "rm -f"
        !            41:  *        just to be sure.  Just try it out - you will recognise a difference!
        !            42:  *
        !            43:  *  [ 1998-06-14 ]
        !            44:  *
        !            45:  *    *)  Now lxdialog is crash-safe against broken "lxdialog.scrltmp" files
        !            46:  *        and menus change their size on the fly.
        !            47:  *
        !            48:  *    *)  If for some reason the last scrolling position is not saved by
        !            49:  *        lxdialog, it sets the scrolling so that the selected item is in the
        !            50:  *        middle of the menu box, not at the bottom.
        !            51:  *
        !            52:  * 02 January 1999, Michael Elizabeth Chastain ([email protected])
        !            53:  * Reset 'scroll' to 0 if the value from lxdialog.scrltmp is bogus.
        !            54:  * This fixes a bug in Menuconfig where using ' ' to descend into menus
        !            55:  * would leave mis-synchronized lxdialog.scrltmp files lying around,
        !            56:  * fscanf would read in 'scroll', and eventually that value would get used.
        !            57:  */
        !            58: 
        !            59: #include "dialog.h"
        !            60: 
        !            61: static int menu_width, item_x;
        !            62: 
        !            63: /*
        !            64:  * Print menu item
        !            65:  */
        !            66: static void do_print_item(WINDOW * win, const char *item, int line_y,
        !            67:                           int selected, int hotkey)
        !            68: {
        !            69:        int j;
        !            70:        char *menu_item = malloc(menu_width + 1);
        !            71: 
        !            72:        strncpy(menu_item, item, menu_width - item_x);
        !            73:        menu_item[menu_width - item_x] = '\0';
        !            74:        j = first_alpha(menu_item, "YyNnMmHh");
        !            75: 
        !            76:        /* Clear 'residue' of last item */
        !            77:        wattrset(win, dlg.menubox.atr);
        !            78:        wmove(win, line_y, 0);
        !            79: #if OLD_NCURSES
        !            80:        {
        !            81:                int i;
        !            82:                for (i = 0; i < menu_width; i++)
        !            83:                        waddch(win, ' ');
        !            84:        }
        !            85: #else
        !            86:        wclrtoeol(win);
        !            87: #endif
        !            88:        wattrset(win, selected ? dlg.item_selected.atr : dlg.item.atr);
        !            89:        mvwaddstr(win, line_y, item_x, menu_item);
        !            90:        if (hotkey) {
        !            91:                wattrset(win, selected ? dlg.tag_key_selected.atr
        !            92:                         : dlg.tag_key.atr);
        !            93:                mvwaddch(win, line_y, item_x + j, menu_item[j]);
        !            94:        }
        !            95:        if (selected) {
        !            96:                wmove(win, line_y, item_x + 1);
        !            97:        }
        !            98:        free(menu_item);
        !            99:        wrefresh(win);
        !           100: }
        !           101: 
        !           102: #define print_item(index, choice, selected)                            \
        !           103: do {                                                                   \
        !           104:        item_set(index);                                                \
        !           105:        do_print_item(menu, item_str(), choice, selected, !item_is_tag(':')); \
        !           106: } while (0)
        !           107: 
        !           108: /*
        !           109:  * Print the scroll indicators.
        !           110:  */
        !           111: static void print_arrows(WINDOW * win, int item_no, int scroll, int y, int x,
        !           112:                         int height)
        !           113: {
        !           114:        int cur_y, cur_x;
        !           115: 
        !           116:        getyx(win, cur_y, cur_x);
        !           117: 
        !           118:        wmove(win, y, x);
        !           119: 
        !           120:        if (scroll > 0) {
        !           121:                wattrset(win, dlg.uarrow.atr);
        !           122:                waddch(win, ACS_UARROW);
        !           123:                waddstr(win, "(-)");
        !           124:        } else {
        !           125:                wattrset(win, dlg.menubox.atr);
        !           126:                waddch(win, ACS_HLINE);
        !           127:                waddch(win, ACS_HLINE);
        !           128:                waddch(win, ACS_HLINE);
        !           129:                waddch(win, ACS_HLINE);
        !           130:        }
        !           131: 
        !           132:        y = y + height + 1;
        !           133:        wmove(win, y, x);
        !           134:        wrefresh(win);
        !           135: 
        !           136:        if ((height < item_no) && (scroll + height < item_no)) {
        !           137:                wattrset(win, dlg.darrow.atr);
        !           138:                waddch(win, ACS_DARROW);
        !           139:                waddstr(win, "(+)");
        !           140:        } else {
        !           141:                wattrset(win, dlg.menubox_border.atr);
        !           142:                waddch(win, ACS_HLINE);
        !           143:                waddch(win, ACS_HLINE);
        !           144:                waddch(win, ACS_HLINE);
        !           145:                waddch(win, ACS_HLINE);
        !           146:        }
        !           147: 
        !           148:        wmove(win, cur_y, cur_x);
        !           149:        wrefresh(win);
        !           150: }
        !           151: 
        !           152: /*
        !           153:  * Display the termination buttons.
        !           154:  */
        !           155: static void print_buttons(WINDOW * win, int height, int width, int selected)
        !           156: {
        !           157:        int x = width / 2 - 16;
        !           158:        int y = height - 2;
        !           159: 
        !           160:        print_button(win, gettext("Select"), y, x, selected == 0);
        !           161:        print_button(win, gettext(" Exit "), y, x + 12, selected == 1);
        !           162:        print_button(win, gettext(" Help "), y, x + 24, selected == 2);
        !           163: 
        !           164:        wmove(win, y, x + 1 + 12 * selected);
        !           165:        wrefresh(win);
        !           166: }
        !           167: 
        !           168: /* scroll up n lines (n may be negative) */
        !           169: static void do_scroll(WINDOW *win, int *scroll, int n)
        !           170: {
        !           171:        /* Scroll menu up */
        !           172:        scrollok(win, TRUE);
        !           173:        wscrl(win, n);
        !           174:        scrollok(win, FALSE);
        !           175:        *scroll = *scroll + n;
        !           176:        wrefresh(win);
        !           177: }
        !           178: 
        !           179: /*
        !           180:  * Display a menu for choosing among a number of options
        !           181:  */
        !           182: int dialog_menu(const char *title, const char *prompt,
        !           183:                 const void *selected, int *s_scroll)
        !           184: {
        !           185:        int i, j, x, y, box_x, box_y;
        !           186:        int height, width, menu_height;
        !           187:        int key = 0, button = 0, scroll = 0, choice = 0;
        !           188:        int first_item =  0, max_choice;
        !           189:        WINDOW *dialog, *menu;
        !           190: 
        !           191: do_resize:
        !           192:        height = getmaxy(stdscr);
        !           193:        width = getmaxx(stdscr);
        !           194:        if (height < 15 || width < 65)
        !           195:                return -ERRDISPLAYTOOSMALL;
        !           196: 
        !           197:        height -= 4;
        !           198:        width  -= 5;
        !           199:        menu_height = height - 10;
        !           200: 
        !           201:        max_choice = MIN(menu_height, item_count());
        !           202: 
        !           203:        /* center dialog box on screen */
        !           204:        x = (COLS - width) / 2;
        !           205:        y = (LINES - height) / 2;
        !           206: 
        !           207:        draw_shadow(stdscr, y, x, height, width);
        !           208: 
        !           209:        dialog = newwin(height, width, y, x);
        !           210:        keypad(dialog, TRUE);
        !           211: 
        !           212:        draw_box(dialog, 0, 0, height, width,
        !           213:                 dlg.dialog.atr, dlg.border.atr);
        !           214:        wattrset(dialog, dlg.border.atr);
        !           215:        mvwaddch(dialog, height - 3, 0, ACS_LTEE);
        !           216:        for (i = 0; i < width - 2; i++)
        !           217:                waddch(dialog, ACS_HLINE);
        !           218:        wattrset(dialog, dlg.dialog.atr);
        !           219:        wbkgdset(dialog, dlg.dialog.atr & A_COLOR);
        !           220:        waddch(dialog, ACS_RTEE);
        !           221: 
        !           222:        print_title(dialog, title, width);
        !           223: 
        !           224:        wattrset(dialog, dlg.dialog.atr);
        !           225:        print_autowrap(dialog, prompt, width - 2, 1, 3);
        !           226: 
        !           227:        menu_width = width - 6;
        !           228:        box_y = height - menu_height - 5;
        !           229:        box_x = (width - menu_width) / 2 - 1;
        !           230: 
        !           231:        /* create new window for the menu */
        !           232:        menu = subwin(dialog, menu_height, menu_width,
        !           233:                      y + box_y + 1, x + box_x + 1);
        !           234:        keypad(menu, TRUE);
        !           235: 
        !           236:        /* draw a box around the menu items */
        !           237:        draw_box(dialog, box_y, box_x, menu_height + 2, menu_width + 2,
        !           238:                 dlg.menubox_border.atr, dlg.menubox.atr);
        !           239: 
        !           240:        if (menu_width >= 80)
        !           241:                item_x = (menu_width - 70) / 2;
        !           242:        else
        !           243:                item_x = 4;
        !           244: 
        !           245:        /* Set choice to default item */
        !           246:        item_foreach()
        !           247:                if (selected && (selected == item_data()))
        !           248:                        choice = item_n();
        !           249:        /* get the saved scroll info */
        !           250:        scroll = *s_scroll;
        !           251:        if ((scroll <= choice) && (scroll + max_choice > choice) &&
        !           252:           (scroll >= 0) && (scroll + max_choice <= item_count())) {
        !           253:                first_item = scroll;
        !           254:                choice = choice - scroll;
        !           255:        } else {
        !           256:                scroll = 0;
        !           257:        }
        !           258:        if ((choice >= max_choice)) {
        !           259:                if (choice >= item_count() - max_choice / 2)
        !           260:                        scroll = first_item = item_count() - max_choice;
        !           261:                else
        !           262:                        scroll = first_item = choice - max_choice / 2;
        !           263:                choice = choice - scroll;
        !           264:        }
        !           265: 
        !           266:        /* Print the menu */
        !           267:        for (i = 0; i < max_choice; i++) {
        !           268:                print_item(first_item + i, i, i == choice);
        !           269:        }
        !           270: 
        !           271:        wnoutrefresh(menu);
        !           272: 
        !           273:        print_arrows(dialog, item_count(), scroll,
        !           274:                     box_y, box_x + item_x + 1, menu_height);
        !           275: 
        !           276:        print_buttons(dialog, height, width, 0);
        !           277:        wmove(menu, choice, item_x + 1);
        !           278:        wrefresh(menu);
        !           279: 
        !           280:        while (key != KEY_ESC) {
        !           281:                key = wgetch(menu);
        !           282: 
        !           283:                if (key < 256 && isalpha(key))
        !           284:                        key = tolower(key);
        !           285: 
        !           286:                if (strchr("ynmh", key))
        !           287:                        i = max_choice;
        !           288:                else {
        !           289:                        for (i = choice + 1; i < max_choice; i++) {
        !           290:                                item_set(scroll + i);
        !           291:                                j = first_alpha(item_str(), "YyNnMmHh");
        !           292:                                if (key == tolower(item_str()[j]))
        !           293:                                        break;
        !           294:                        }
        !           295:                        if (i == max_choice)
        !           296:                                for (i = 0; i < max_choice; i++) {
        !           297:                                        item_set(scroll + i);
        !           298:                                        j = first_alpha(item_str(), "YyNnMmHh");
        !           299:                                        if (key == tolower(item_str()[j]))
        !           300:                                                break;
        !           301:                                }
        !           302:                }
        !           303: 
        !           304:                if (i < max_choice ||
        !           305:                    key == KEY_UP || key == KEY_DOWN ||
        !           306:                    key == '-' || key == '+' ||
        !           307:                    key == KEY_PPAGE || key == KEY_NPAGE) {
        !           308:                        /* Remove highligt of current item */
        !           309:                        print_item(scroll + choice, choice, FALSE);
        !           310: 
        !           311:                        if (key == KEY_UP || key == '-') {
        !           312:                                if (choice < 2 && scroll) {
        !           313:                                        /* Scroll menu down */
        !           314:                                        do_scroll(menu, &scroll, -1);
        !           315: 
        !           316:                                        print_item(scroll, 0, FALSE);
        !           317:                                } else
        !           318:                                        choice = MAX(choice - 1, 0);
        !           319: 
        !           320:                        } else if (key == KEY_DOWN || key == '+') {
        !           321:                                print_item(scroll+choice, choice, FALSE);
        !           322: 
        !           323:                                if ((choice > max_choice - 3) &&
        !           324:                                    (scroll + max_choice < item_count())) {
        !           325:                                        /* Scroll menu up */
        !           326:                                        do_scroll(menu, &scroll, 1);
        !           327: 
        !           328:                                        print_item(scroll+max_choice - 1,
        !           329:                                                   max_choice - 1, FALSE);
        !           330:                                } else
        !           331:                                        choice = MIN(choice + 1, max_choice - 1);
        !           332: 
        !           333:                        } else if (key == KEY_PPAGE) {
        !           334:                                scrollok(menu, TRUE);
        !           335:                                for (i = 0; (i < max_choice); i++) {
        !           336:                                        if (scroll > 0) {
        !           337:                                                do_scroll(menu, &scroll, -1);
        !           338:                                                print_item(scroll, 0, FALSE);
        !           339:                                        } else {
        !           340:                                                if (choice > 0)
        !           341:                                                        choice--;
        !           342:                                        }
        !           343:                                }
        !           344: 
        !           345:                        } else if (key == KEY_NPAGE) {
        !           346:                                for (i = 0; (i < max_choice); i++) {
        !           347:                                        if (scroll + max_choice < item_count()) {
        !           348:                                                do_scroll(menu, &scroll, 1);
        !           349:                                                print_item(scroll+max_choice-1,
        !           350:                                                           max_choice - 1, FALSE);
        !           351:                                        } else {
        !           352:                                                if (choice + 1 < max_choice)
        !           353:                                                        choice++;
        !           354:                                        }
        !           355:                                }
        !           356:                        } else
        !           357:                                choice = i;
        !           358: 
        !           359:                        print_item(scroll + choice, choice, TRUE);
        !           360: 
        !           361:                        print_arrows(dialog, item_count(), scroll,
        !           362:                                     box_y, box_x + item_x + 1, menu_height);
        !           363: 
        !           364:                        wnoutrefresh(dialog);
        !           365:                        wrefresh(menu);
        !           366: 
        !           367:                        continue;       /* wait for another key press */
        !           368:                }
        !           369: 
        !           370:                switch (key) {
        !           371:                case KEY_LEFT:
        !           372:                case TAB:
        !           373:                case KEY_RIGHT:
        !           374:                        button = ((key == KEY_LEFT ? --button : ++button) < 0)
        !           375:                            ? 2 : (button > 2 ? 0 : button);
        !           376: 
        !           377:                        print_buttons(dialog, height, width, button);
        !           378:                        wrefresh(menu);
        !           379:                        break;
        !           380:                case ' ':
        !           381:                case 's':
        !           382:                case 'y':
        !           383:                case 'n':
        !           384:                case 'm':
        !           385:                case '/':
        !           386:                case 'h':
        !           387:                case '?':
        !           388:                case 'z':
        !           389:                case '\n':
        !           390:                        /* save scroll info */
        !           391:                        *s_scroll = scroll;
        !           392:                        delwin(menu);
        !           393:                        delwin(dialog);
        !           394:                        item_set(scroll + choice);
        !           395:                        item_set_selected(1);
        !           396:                        switch (key) {
        !           397:                        case 'h':
        !           398:                        case '?':
        !           399:                                return 2;
        !           400:                        case 's':
        !           401:                        case 'y':
        !           402:                                return 3;
        !           403:                        case 'n':
        !           404:                                return 4;
        !           405:                        case 'm':
        !           406:                                return 5;
        !           407:                        case ' ':
        !           408:                                return 6;
        !           409:                        case '/':
        !           410:                                return 7;
        !           411:                        case 'z':
        !           412:                                return 8;
        !           413:                        case '\n':
        !           414:                                return button;
        !           415:                        }
        !           416:                        return 0;
        !           417:                case 'e':
        !           418:                case 'x':
        !           419:                        key = KEY_ESC;
        !           420:                        break;
        !           421:                case KEY_ESC:
        !           422:                        key = on_key_esc(menu);
        !           423:                        break;
        !           424:                case KEY_RESIZE:
        !           425:                        on_key_resize();
        !           426:                        delwin(menu);
        !           427:                        delwin(dialog);
        !           428:                        goto do_resize;
        !           429:                }
        !           430:        }
        !           431:        delwin(menu);
        !           432:        delwin(dialog);
        !           433:        return key;             /* ESC pressed */
        !           434: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.